No conflicts.
Change-Id: Ia0b6529e06e5f2a9c3c1bb49dd31870df7d4cea0
if(NOT GMX_OPENMP)
GMX_TEST_CXXFLAG(CXXFLAGS_PRAGMA "-Wno-unknown-pragmas" GMXC_CXXFLAGS)
endif()
+ # Once we get rid of most extern "C" declarations, this can hopefully go away.
+ GMX_TEST_CXXFLAG(CXXFLAGS_WARN_PEDANTIC "-Wno-return-type-c-linkage" GMXC_CXXFLAGS)
GMX_TEST_CXXFLAG(CXXFLAGS_WARN "-Wall -Wno-unused-function" GMXC_CXXFLAGS)
GMX_TEST_CXXFLAG(CXXFLAGS_WARN_EXTRA "-Wextra -Wno-missing-field-initializers -Wpointer-arith" GMXC_CXXFLAGS)
endif()
# The GROMACS convention is that these are the version number of the next
# release that is going to be made from this branch.
set(GMX_VERSION_MAJOR 5)
-set(GMX_VERSION_MINOR 1)
+set(GMX_VERSION_MINOR 2)
set(GMX_VERSION_PATCH 0)
# The suffix, on the other hand, is used mainly for betas and release
# candidates, where it signifies the most recent such release from
# this branch; it will be empty before the first such release, as well
# as after the final release is out.
-set(GMX_VERSION_SUFFIX "-rc1")
+set(GMX_VERSION_SUFFIX "")
# Conventionally with libtool, any ABI change must change the major
# version number, the minor version number should change if it's just
# here. The important thing is to minimize the chance of third-party
# code being able to dynamically link with a version of libgromacs
# that might not work.
-set(LIBRARY_SOVERSION_MAJOR 1)
+set(LIBRARY_SOVERSION_MAJOR 2)
set(LIBRARY_SOVERSION_MINOR 0)
set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
You may use an all-lowercase name with underscores if your class closely
resembles an external construct (e.g., a standard library construct) named
that way.
-* C++ interfaces are named with a ``Interface`` suffix, and abstract base
- classes with an ``Abstract`` prefix.
+* C++ interfaces are named with an ``I`` prefix, such as in ICommandLineModule.
+ This keeps interfaces identifiable, without introducing too much clutter
+ (as the interface is typically used quite widely, spelling out
+ ``Interface`` would make many of the names unnecessarily long).
+* Abstract base classes are typically named with an ``Abstract`` prefix.
* Member variables are named with a trailing underscore.
* Accessors for a variable ``foo_`` are named ``foo()`` and ``setFoo()``.
* Global variables are named with a ``g_`` prefix.
The above logic to find the installation prefix is in
``src/gromacs/commandline/cmdlineprogramcontext.cpp``. Note that code that
links to ``libgromacs`` can provide an alternative implementation for
-``gmx::ProgramContextInterface`` for locating the data files, and is then fully
+``gmx::IProgramContext`` for locating the data files, and is then fully
responsible of the above considerations.
Information about the used data directories is printed into the console output
In addition to ``src/testutils/``, some of the module test directories may
provide reusable test code that is used in higher-level tests. For example,
the ``src/gromacs/analysisdata/tests/`` provides test fixtures, a mock
-implementation for gmx::AnalysisDataModuleInterface, and some helper classes
+implementation for gmx::IAnalysisDataModule, and some helper classes
that are also used in ``src/gromacs/trajectoryanalysis/tests/``.
These cases are handled using CMake object libraries that are linked to all the
test binaries that need them.
"""Scan the file contents and initialize information based on it."""
# TODO: Consider a more robust regex.
include_re = r'^\s*#\s*include\s+(?P<quote>["<])(?P<path>[^">]*)[">]'
- define_re = r'^\s*#.*define\s+(\w*)'
+ define_re = r'^\s*#.*define(?:01)?\s+(\w*)'
current_block = None
with open(self._abspath, 'r') as scanfile:
contents = scanfile.read()
return IncludeGroup.gmx_test
return IncludeGroup.gmx_general
+ def _split_path(self, path):
+ """Split include path into sortable compoments.
+
+ Plain string on the full path in the #include directive causes some
+ unintuitive behavior, so this splits the path into a tuple at
+ points that allow more natural sorting: primary sort criterion is the
+ directory name, followed by the basename (without extension) of the
+ included file.
+ """
+ path_components = list(os.path.split(path))
+ path_components[1] = os.path.splitext(path_components[1])
+ return tuple(path_components)
+
+ def _join_path(self, path_components):
+ """Reconstruct path from the return value of _split_path."""
+ return os.path.join(path_components[0], ''.join(path_components[1]))
+
def get_sortable_object(self, include):
"""Produce a sortable, opaque object for an include.
including_file = include.get_including_file()
group = self._get_gmx_group(including_file, included_file)
path = self._get_path(included_file, group, including_file)
- return (group, os.path.split(path), include)
+ return (group, self._split_path(path), include)
def format_include(self, obj, prev):
"""Format an #include directive after sorting."""
match = re.match(include_re, line)
assert match
if include.is_system():
- path = '<{0}>'.format(os.path.join(obj[1][0], obj[1][1]))
+ path = '<{0}>'.format(self._join_path(obj[1]))
else:
- path = '"{0}"'.format(os.path.join(obj[1][0], obj[1][1]))
+ path = '"{0}"'.format(self._join_path(obj[1]))
result.append('{0}{1}{2}\n'.format(match.group('head'), path, match.group('tail')))
return result
====================
All modules within the wrapper binary are implemented as classes that implement
-the gmx::CommandLineModuleInterface interface. There is generally some helper
+the gmx::ICommandLineModule interface. There is generally some helper
class in between:
* General C++ modules typically use gmx::Options for their command-line
handling. Instead of each module implementing parsing and help separately
- with identical code, they implement gmx::CommandLineOptionsModuleInterface
+ with identical code, they implement gmx::ICommandLineOptionsModule
instead. The framework then provides a bridge class that contains the
- common code and wraps gmx::CommandLineOptionsModuleInterface into a
- gmx::CommandLineModuleInterface.
+ common code and wraps gmx::ICommandLineOptionsModule into a
+ gmx::ICommandLineModule.
* For C++ trajectory analysis modules, there is a general implementation for
running the gmx::TrajectoryAnalysisModule subclasses in cmdlinerunner.cpp.
* For old C-style %main() functions, see \ref section_wrapperbinary_cmain.
module.
After the above translations, the internal help module handles all the help
-output. All the help is organized into a hierarchy of gmx::HelpTopicInterface
+output. All the help is organized into a hierarchy of gmx::IHelpTopic
instances. The help module internally creates a root help topic that is
printed with `gmx help`. If there are additional words after the `gmx help`
command, then those are taken to specify the topic to show in the hierarchy.
gmx::CommandLineModuleManager internally creates a help topic for each added
module. These topics are shown when `gmx help` _module_ is invoked.
They forward the request to the actual module (to
-gmx::CommandLineModuleInterface::writeHelp()).
+gmx::ICommandLineModule::writeHelp()).
In addition to the topics created internally, gmx::CommandLineModuleManager
provides methods to add additional help topics. Currently, this is used to
If this option is set, the help module loops through all the modules in the
binary, writing help for each into a separate file. The help module writes
common headers and footers, and asks the actual module to write the
-module-specific content (with gmx::CommandLineModuleInterface::writeHelp(),
+module-specific content (with gmx::ICommandLineModule::writeHelp(),
using a different help context than for console output).
Additionally, a list of all the modules is generated (`gromacs.7` for man
digraph analysisdata_overview {
rankdir = BT
dataobject [label="data object\n(subclass of gmx::AbstractAnalysisData)"]
- datamodule1 [label="data module\n(implements gmx::AnalysisDataModuleInterface)"]
+ datamodule1 [label="data module\n(implements gmx::IAnalysisDataModule)"]
datamodule2 [label="data module\nthat also provides data"]
datamodule3 [label="data module"]
datamodule1 -> dataobject
to the data object. Examples of such operations are averaging, histogramming,
and plotting the data into a file. Some data modules are provided by the \ref
module_analysisdata module. To implement new ones, it is necessary to create a
-class that implements gmx::AnalysisDataModuleInterface.
+class that implements gmx::IAnalysisDataModule.
In many cases, such data modules also provide data that can be processed
further, acting as data objects themselves. This makes it possible to attach
more details.
Note that this list is manually maintained, so it may not always be up-to-date.
A comprehensive list can be found by looking at the inheritance graph of
-gmx::AnalysisDataModuleInterface, but the list here is more user-friendly.
+gmx::IAnalysisDataModule, but the list here is more user-friendly.
<dl>
<dt>gmx::AnalysisDataAverageModule</dt>
To declare input data for the tool (typically, command-line options, including
input files and selections), \ref module_options module is used.
-The analysis tool code receives a pre-initialized gmx::Options object in one of
-its initialization methods, and fills it with its input options.
+The analysis tool code receives an instance of gmx::IOptionsContainer for one of
+its initialization methods, and uses it to provide its input options.
Basic options are declared in basicoptions.h, and also gmx::SelectionOption is
used in the same manner. For each option, the tool declares a local variable
that will receive the value for that option. After the options are parsed from
the command line (by the framework), the tool code can read the values from
-these variables. The option declarations, and other information filled into
-the gmx::Options object, are also used to provide help to the user (also
+these variables. The option declarations filled into the
+gmx::IOptionsContainer object are also used to provide help to the user (also
handled by the framework).
See the documentation for gmx::TrajectoryAnalysisModule and the
[options module documentation](\ref module_options) for more details.
the facilities provided by \ref module_commandline. There are a few
different alternatives, depending on how much control you want to give
\Gromacs:
- - For C++ code, you can implement gmx::CommandLineOptionsModuleInterface and
+ - For C++ code, you can implement gmx::ICommandLineOptionsModule and
use gmx::runCommandLineModule() to execute it. This interface assumes
the use of the gmx::Options mechanism for declaring command-line options
(see \ref module_options).
- For a lower-level interface, gmx::CommandLineModuleInterface can be used,
+ For a lower-level interface, gmx::ICommandLineModule can be used,
but this requires you to implement `-h` output and command-line parsing
yourself (possibly using classes that \Gromacs provides).
- For C code, you can use gmx_run_cmain() to wrap an existing C main
routines. This allows you to write your own handling for command line
options from scratch. This is also discussed in \ref module_commandline.
- For most control, you can use gmx::init() to do basic initialization, create
- your own implementation for gmx::ProgramContextInterface, and set that using
+ your own implementation for gmx::IProgramContext, and set that using
gmx::setProgramContext(). This allows you to customize how the \Gromacs
library shows the name of the program in messages, as well as how it locates
its own data files.
public:
AnalysisTemplate();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
void
-AnalysisTemplate::initOptions(Options *options,
+AnalysisTemplate::initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"analysis groups."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("o")
.filetype(eftPlot).outputFile()
-586
+592
If You Want Something Done You Have to Do It Yourself_(Highlander II)
I Live the Life They Wish They Did_(Tricky)
Jesus Built My Hotrod_(Ministry)
In science, truth always wins._(Max Perutz)
Creativity in science, as in art, cannot be organized. It arises spontaneously from individual talent. Well-run laboratories can foster it, but hierarchical organizations, inflexible bureaucratic rules, and mountains of futile paperwork can kill it._(Max Perutz)
Every electron is sacred._(Greg McMullan, on Cryo-EM detectors)
+Science adjusts its views based on what's observed. Faith is the denial of observation so that belief can be preserved._(Tim Minchin)
+Isn’t this enough? Just this world? Just this beautiful, complex wonderfully unfathomable world? How does it so fail to hold our attention that we have to diminish it with the invention of cheap, man-made myths and monsters?_(Tim Minchin)
+If you open your mind too much, your brains will fall out._(Tim Minchin)
+"Everything organic and natural is good" - ignoring the fact that organic natural substances include arsenic and poo and crocodiles. And everything chemical is bad, ignoring the fact that... everything is chemicals._(Tim Minchin)
+A program that has not been tested does not work._(Bjarne Stroustrup)
+You could give Aristotle a tutorial. And you could thrill him to the core of his being. Such is the privilege of living after Newton, Darwin, Einstein, Planck, Watson, Crick and their colleagues._(Richard Dawkins)
/* IEEE754 floating-point format. Memory layout is defined by macros
* GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER and GMX_IEEE754_BIG_ENDIAN_WORD_ORDER.
*/
-#cmakedefine GMX_FLOAT_FORMAT_IEEE754
+#cmakedefine01 GMX_FLOAT_FORMAT_IEEE754
/* Work around broken calloc() */
#cmakedefine GMX_BROKEN_CALLOC
/* Do not optimize FFTW setups (not needed with SSE FFT kernels) */
-#cmakedefine GMX_DISABLE_FFTW_MEASURE
-
-/* Use Built-in FFTPACK FFT library */
-#cmakedefine GMX_FFT_FFTPACK
+#cmakedefine01 GMX_DISABLE_FFTW_MEASURE
/* Use FFTW3 FFT library */
-#cmakedefine GMX_FFT_FFTW3
-
-/* Use Intel MKL FFT library */
-#cmakedefine GMX_FFT_MKL
+#cmakedefine01 GMX_FFT_FFTW3
/* Target platform is x86 or x86_64 */
#cmakedefine GMX_TARGET_X86
#cmakedefine GMX_CYGWIN
/** Define if we have sufficient C++11 support */
-#cmakedefine GMX_CXX11
+#cmakedefine01 GMX_CXX11
/* GCC bug in AVX maskload/maskstore arguments - worked around internally */
#cmakedefine GMX_SIMD_X86_AVX_GCC_MASKLOAD_BUG
#define GMX_SIMD_ACCURACY_BITS_DOUBLE @GMX_SIMD_ACCURACY_BITS_DOUBLE@
/* Integer byte order is big endian. */
-#cmakedefine GMX_INTEGER_BIG_ENDIAN
+#cmakedefine01 GMX_INTEGER_BIG_ENDIAN
/* Use our own instead of system XDR libraries */
-#cmakedefine GMX_INTERNAL_XDR
+#cmakedefine01 GMX_INTERNAL_XDR
/* Compile to use TNG library */
#cmakedefine GMX_USE_TNG
/* Add support for tracing using Extrae */
-#cmakedefine HAVE_EXTRAE
+#cmakedefine01 HAVE_EXTRAE
/* Use MPI (with mpicc) for parallelization */
#cmakedefine GMX_LIB_MPI
/* Maximum number of OpenMP threads supported */
#define GMX_OPENMP_MAX_THREADS @GMX_OPENMP_MAX_THREADS@
-/* Use if can't rename checkpoints */
-#cmakedefine GMX_NO_RENAME
+/* Use if we cannot rename checkpoints */
+#cmakedefine01 GMX_NO_RENAME
/* Use (modified) Gamess-UK for QM-MM calculations */
-#cmakedefine GMX_QMMM_GAMESS
+#cmakedefine01 GMX_QMMM_GAMESS
/* Use (modified) Gaussian0x for QM-MM calculations */
-#cmakedefine GMX_QMMM_GAUSSIAN
+#cmakedefine01 GMX_QMMM_GAUSSIAN
/* Use (modified) Mopac 7 for QM-MM calculations */
-#cmakedefine GMX_QMMM_MOPAC
+#cmakedefine01 GMX_QMMM_MOPAC
/* Use ORCA for QM-MM calculations */
-#cmakedefine GMX_QMMM_ORCA
+#cmakedefine01 GMX_QMMM_ORCA
/* Use the GROMACS software 1/sqrt(x) */
#cmakedefine GMX_SOFTWARE_INVSQRT
#cmakedefine HAVE_PTHREAD_SETAFFINITY
/* Define for X-Windows */
-#cmakedefine GMX_X11
+#cmakedefine01 GMX_X11
/* Enable x86 gcc inline assembly */
#cmakedefine GMX_X86_GCC_INLINE_ASM
#cmakedefine HAVE_SCHED_H
/* Define to 1 if you have the POSIX <regex.h> header file. */
-#cmakedefine HAVE_POSIX_REGEX
+#cmakedefine01 HAVE_POSIX_REGEX
/* Define to 1 if you have the C++11 <regex> header file. */
-#cmakedefine HAVE_CXX11_REGEX
+#cmakedefine01 HAVE_CXX11_REGEX
/* Define to 1 if you have the sysconf() function */
#cmakedefine HAVE_SYSCONF
/* Bytes in IEEE fp word are in big-endian order if set, little-endian if not.
Only relevant when FLOAT_FORMAT_IEEE754 is defined. */
-#cmakedefine GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER
+#cmakedefine01 GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER
/* The two words in a double precision variable are in b ig-endian order if
set, little-endian if not. Do NOT assume this is the same as the byte
order! Only relevant when FLOAT_FORMAT_IEEE754 is defined. */
-#cmakedefine GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
+#cmakedefine01 GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
/* Define if SIGUSR1 is present */
-#cmakedefine HAVE_SIGUSR1
+#cmakedefine01 HAVE_SIGUSR1
/* Enable gromacs quotes */
-#cmakedefine GMX_COOL_QUOTES
+#cmakedefine01 GMX_COOL_QUOTES
/* default name mangling maybe wrong on exotic plattforms */
#define F77_FUNC(name,NAME) name ## _
/* Define if we have pipes */
-#cmakedefine HAVE_PIPES
+#cmakedefine01 HAVE_PIPES
/* Define if we have feenableexcept */
-#cmakedefine HAVE_FEENABLEEXCEPT
+#cmakedefine01 HAVE_FEENABLEEXCEPT
/* Define if we have zlib */
-#cmakedefine HAVE_ZLIB
+#cmakedefine01 HAVE_ZLIB
/*! \endcond */
+++ /dev/null
-/*
- *
- * This source code is part of
- *
- * G R O M A C S
- *
- * GROningen MAchine for Chemical Simulations
- *
- * VERSION 3.3.99_development_20071104
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2006, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
- *
- * And Hey:
- * Groningen Machine for Chemical Simulation
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include "macros.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/commandline/pargs.h"
-#include "copyrite.h"
-#include "txtdump.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/fileio/xtcio.h"
-#include "gromacs/fileio/enxio.h"
-#include "gromacs/utility/smalloc.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
-#include "txtdump.h"
-#include "gromacs/math/vec.h"
-
-static char *nm[5] = { "OW", "HW1", "HW2", "DW", "SW" };
-
-static void list_trn(char *fn)
-{
- static real mass[5] = { 15.9994, 1.008, 1.008, 0.0, 0.0 };
- int i,j=0,m,fpread,fpwrite,nframe;
- rvec *x,*v,*f,fmol[2],xcm[2],torque[j],dx;
- real mmm,len;
- matrix box;
- t_trnheader trn;
- gmx_bool bOK;
-
- printf("Going to open %s\n",fn);
- fpread = open_trn(fn,"r");
- fpwrite = open_tpx(NULL,"w");
- gmx_fio_setdebug(fpwrite,TRUE);
-
- mmm=mass[0]+2*mass[1];
- for(i=0; (i<5); i++)
- mass[i] /= mmm;
-
- nframe = 0;
- while (fread_trnheader(fpread,&trn,&bOK)) {
- snew(x,trn.natoms);
- snew(v,trn.natoms);
- snew(f,trn.natoms);
- if (fread_htrn(fpread,&trn,
- trn.box_size ? box : NULL,
- trn.x_size ? x : NULL,
- trn.v_size ? v : NULL,
- trn.f_size ? f : NULL)) {
-
- if (trn.x_size && trn.f_size) {
- printf("There are %d atoms\n",trn.natoms);
- for(j=0; (j<2); j++) {
- clear_rvec(xcm[j]);
- clear_rvec(fmol[j]);
- clear_rvec(torque[j]);
- for(i=5*j; (i<5*j+5); i++) {
- rvec_inc(fmol[j],f[i]);
- for(m=0; (m<DIM); m++)
- xcm[j][m] += mass[i%5]*x[i][m];
- }
- for(i=5*j; (i<5*j+5); i++) {
- rvec_dec(x[i],xcm[j]);
- cprod(x[i],f[i],dx);
- rvec_inc(torque[j],dx);
- rvec_inc(x[i],xcm[j]);
- }
- }
- pr_rvecs(stdout,0,"FMOL ",fmol,2);
- pr_rvecs(stdout,0,"TORQUE",torque,2);
- printf("Distance matrix Water1-Water2\n%5s","");
- for(j=0; (j<5); j++)
- printf(" %10s",nm[j]);
- printf("\n");
- for(j=0; (j<5); j++) {
- printf("%5s",nm[j]);
- for(i=5; (i<10); i++) {
- rvec_sub(x[i],x[j],dx);
- len = sqrt(iprod(dx,dx));
- printf(" %10.7f",len);
- }
- printf("\n");
- }
- }
- }
- sfree(x);
- sfree(v);
- sfree(f);
- nframe++;
- }
- if (!bOK)
- fprintf(stderr,"\nWARNING: Incomplete frame header: nr %d, t=%g\n",
- nframe,trn.t);
- close_tpx(fpwrite);
- close_trn(fpread);
-}
-
-int main(int argc,char *argv[])
-{
- static char *desc[] = {
- "[TT]gmxdump[tt] reads a run input file ([REF].tpr[ref]),",
- "a trajectory ([REF].trr[ref]/[REF].xtc[ref]) or an energy",
- "file ([REF].edr[ref]) and prints that to standard",
- "output in a readable format. This program is essential for",
- "checking your run input file in case of problems.[PAR]"
- };
- t_filenm fnm[] = {
- { efTRN, "-f", NULL, ffOPTRD }
- };
-#define NFILE asize(fnm)
- char *fn;
-
- /* Command line options */
-
- CopyRight(stdout,argv[0]);
- parse_common_args(&argc,argv,0,NFILE,fnm,0,NULL,
- asize(desc),desc,0,NULL);
-
- if (ftp2bSet(efTRN,NFILE,fnm)) {
- fn = ftp2fn(efTRN,NFILE,fnm);
- printf("Going to open %s\n",fn);
- list_trn(fn);
- }
-
- gmx_thanx(stderr);
-
- return 0;
-}
#include "gbutil.h"
#include "gromacs/math/vec.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/gmxfio.h"
typedef struct {
int resnr;
#include "gromacs/math/units.h"
#include "names.h"
#include "txtdump.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/topology/symtab.h"
#include "gromacs/fileio/strdb.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/math/units.h"
#include "names.h"
#include "txtdump.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/confio.h"
real pot(real x,real qq,real c6,real c12)
#include "wait.h"
#include "atomic.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** Fast (possibly busy-wait-based) lock type
*
* This lock type forms an intermediate between the spinlocks and mutexes:
TMPI_EXPORT
int tMPI_Lock_islocked(tMPI_Lock_t *lock);
-
+#ifdef __cplusplus
+}
+#endif
#endif /* TMPI_FASTLOCK_H_ */
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* gmx::AnalysisData and gmx::AnalysisArrayData. These classes are used to
* process and store raw data as produced by the analysis tool. They also
* provide an interface to attach data modules that implement
- * gmx::AnalysisDataModuleInterface.
+ * gmx::IAnalysisDataModule.
*
- * Modules that implement gmx::AnalysisDataModuleInterface form the second part
+ * Modules that implement gmx::IAnalysisDataModule form the second part
* of the module, and they provide functionality to do processing on the data.
* These modules can also derive from gmx::AbstractAnalysisData, allowing other
* modules to be attached to them to form a processing chain that best suits
* To use the functionality in this module, you typically declare one or more
* AnalysisData objects and set its properties. You then create some module
* objects and set their properties (see the list of classes that implement
- * gmx::AnalysisDataModuleInterface) and attach them to the data objects or to
+ * gmx::IAnalysisDataModule) and attach them to the data objects or to
* one another using gmx::AbstractAnalysisData::addModule(). Then you add the
* actual data values to the gmx::AnalysisData object, which automatically
* passes it on to the modules.
*
* <H3>Data Modules</H3>
*
- * Modules that derive from gmx::AnalysisDataModuleInterface can operate in two
+ * Modules that derive from gmx::IAnalysisDataModule can operate in two
* modes:
* - In _serial_ mode, the frames are presented to the module always in the
* order of increasing indices, even if they become ready in a different
* node [ shape=box ]
*
* start [ label="dataStarted()",
- * URL="\ref gmx::AnalysisDataModuleInterface::dataStarted()" ]
+ * URL="\ref gmx::IAnalysisDataModule::dataStarted()" ]
* pstart [ label="parallelDataStarted()",
- * URL="\ref gmx::AnalysisDataModuleInterface::parallelDataStarted()" ]
+ * URL="\ref gmx::IAnalysisDataModule::parallelDataStarted()" ]
* subgraph cluster_frame {
* label = "for each frame"
* framestart [ label="frameStarted()",
- * URL="\ref gmx::AnalysisDataModuleInterface::frameStarted()" ]
+ * URL="\ref gmx::IAnalysisDataModule::frameStarted()" ]
* pointsadd [ label="pointsAdded()",
- * URL="\ref gmx::AnalysisDataModuleInterface::pointsAdded()" ]
+ * URL="\ref gmx::IAnalysisDataModule::pointsAdded()" ]
* framefinish [ label="frameFinished()",
- * URL="\ref gmx::AnalysisDataModuleInterface::frameFinished()" ]
+ * URL="\ref gmx::IAnalysisDataModule::frameFinished()" ]
* serialfinish [ label="frameFinishedSerial()",
- * URL="\ref gmx::AnalysisDataModuleInterface::frameFinishedSerial()" ]
+ * URL="\ref gmx::IAnalysisDataModule::frameFinishedSerial()" ]
* }
* finish [ label="dataFinished()",
- * URL="\ref gmx::AnalysisDataModuleInterface::dataFinished()" ]
+ * URL="\ref gmx::IAnalysisDataModule::dataFinished()" ]
*
* start -> framestart
* pstart -> framestart
*
* New data modules can be implemented to perform custom operations that are
* not supported by the modules provided in this module. This is done by
- * creating a new class that implements gmx::AnalysisDataModuleInterface.
+ * creating a new class that implements gmx::IAnalysisDataModule.
* If the new module computes values that can be used as input for other
* modules, the new class should also derive from gmx::AbstractAnalysisData, and
* preferably use gmx::AnalysisDataStorage internally to implement storage of
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
void
-AbstractAnalysisData::applyModule(AnalysisDataModuleInterface *module)
+AbstractAnalysisData::applyModule(IAnalysisDataModule *module)
{
impl_->modules_.applyModule(this, module);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class AnalysisDataModuleInterface;
class AnalysisDataModuleManager;
class AnalysisDataFrameHeader;
class AnalysisDataFrameRef;
class AnalysisDataPointSetRef;
+class IAnalysisDataModule;
//! Smart pointer for managing a generic analysis data module.
-typedef boost::shared_ptr<AnalysisDataModuleInterface> AnalysisDataModulePointer;
+typedef boost::shared_ptr<IAnalysisDataModule> AnalysisDataModulePointer;
/*! \brief
* Abstract base class for all objects that provide data.
* storage (addModule() has the same problem if called after data is
* started).
*/
- void applyModule(AnalysisDataModuleInterface *module);
+ void applyModule(IAnalysisDataModule *module);
protected:
/*! \cond libapi */
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* \throws std::bad_alloc if out of memory.
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::dataStarted().
+ * in IAnalysisDataModule::dataStarted().
*
* The caller should retain the returned handle (or a copy of it), and
* pass it to finishData() after successfully adding all data.
*
* \param[in] frameIndex Index of the frame that has been finished.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::frameFinishedSerial().
+ * in IAnalysisDataModule::frameFinishedSerial().
*
* This method should be called sequentially for each frame, after data
* for that frame has been produced. It is not necessary to call this
*
* \param[in] handle Handle to destroy.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::dataFinished().
+ * in IAnalysisDataModule::dataFinished().
*
* \p handle must have been obtained from startData() of this object.
* The order of the calls with respect to the corresponding startData()
* \param[in] dx Error in x for the frame if applicable.
*
* \throws unspecified Any exception thrown by attached data
- * modules in AnalysisDataModuleInterface::frameStarted().
+ * modules in IAnalysisDataModule::frameStarted().
*
* Each \p index value 0, 1, ..., N (where N is the total number of
* frames) should be started exactly once by exactly one handle of an
*
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data
- * modules in AnalysisDataModuleInterface::pointsAdded().
+ * modules in IAnalysisDataModule::pointsAdded().
*
* Must be called after each point set for multipoint data, including
* the last (i.e., no values must be set between the last call to this
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
/*! \file
* \brief
- * Declares gmx::AnalysisDataModuleInterface and related convenience classes.
+ * Declares gmx::IAnalysisDataModule and related convenience classes.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
* \inlibraryapi
* \ingroup module_analysisdata
*/
-class AnalysisDataModuleInterface
+class IAnalysisDataModule
{
public:
/*! \brief
efAllowMultipleDataSets = 1<<4
};
- virtual ~AnalysisDataModuleInterface() {};
+ virtual ~IAnalysisDataModule() {};
/*! \brief
* Returns properties supported by the module.
* \inlibraryapi
* \ingroup module_analysisdata
*/
-class AnalysisDataModuleSerial : public AnalysisDataModuleInterface
+class AnalysisDataModuleSerial : public IAnalysisDataModule
{
public:
virtual ~AnalysisDataModuleSerial() {}
* \inlibraryapi
* \ingroup module_analysisdata
*/
-class AnalysisDataModuleParallel : public AnalysisDataModuleInterface
+class AnalysisDataModuleParallel : public IAnalysisDataModule
{
public:
virtual ~AnalysisDataModuleParallel() {}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* \param[in] bSet Value of the property to check against.
* \throws APIError if \p module is not compatible with the data.
*/
- void checkModuleProperty(const AnalysisDataModuleInterface &module,
+ void checkModuleProperty(const IAnalysisDataModule &module,
DataProperty property, bool bSet) const;
/*! \brief
* Checks whether a module is compatible with the data properties.
* Does not currently check the actual data (e.g., missing values), but
* only the dimensionality and other preset properties of the data.
*/
- void checkModuleProperties(const AnalysisDataModuleInterface &module) const;
+ void checkModuleProperties(const IAnalysisDataModule &module) const;
/*! \brief
* Present data already added to the data object to a module.
* been registered to the data object when the data was added.
*/
void presentData(AbstractAnalysisData *data,
- AnalysisDataModuleInterface *module);
+ IAnalysisDataModule *module);
//! List of modules added to the data.
ModuleList modules_;
void
AnalysisDataModuleManager::Impl::checkModuleProperty(
- const AnalysisDataModuleInterface &module,
+ const IAnalysisDataModule &module,
DataProperty property, bool bSet) const
{
bool bOk = true;
switch (property)
{
case eMultipleDataSets:
- if (bSet && !(flags & AnalysisDataModuleInterface::efAllowMultipleDataSets))
+ if (bSet && !(flags & IAnalysisDataModule::efAllowMultipleDataSets))
{
bOk = false;
}
break;
case eMultipleColumns:
- if (bSet && !(flags & AnalysisDataModuleInterface::efAllowMulticolumn))
+ if (bSet && !(flags & IAnalysisDataModule::efAllowMulticolumn))
{
bOk = false;
}
break;
case eMultipoint:
- if ((bSet && !(flags & AnalysisDataModuleInterface::efAllowMultipoint))
- || (!bSet && (flags & AnalysisDataModuleInterface::efOnlyMultipoint)))
+ if ((bSet && !(flags & IAnalysisDataModule::efAllowMultipoint))
+ || (!bSet && (flags & IAnalysisDataModule::efOnlyMultipoint)))
{
bOk = false;
}
void
AnalysisDataModuleManager::Impl::checkModuleProperties(
- const AnalysisDataModuleInterface &module) const
+ const IAnalysisDataModule &module) const
{
for (int i = 0; i < eDataPropertyNR; ++i)
{
}
void
-AnalysisDataModuleManager::Impl::presentData(AbstractAnalysisData *data,
- AnalysisDataModuleInterface *module)
+AnalysisDataModuleManager::Impl::presentData(AbstractAnalysisData *data,
+ IAnalysisDataModule *module)
{
if (state_ == eNotStarted)
{
"Cannot apply a modules in mid-frame");
module->dataStarted(data);
const bool bCheckMissing = bAllowMissing_
- && !(module->flags() & AnalysisDataModuleInterface::efAllowMissing);
+ && !(module->flags() & IAnalysisDataModule::efAllowMissing);
for (int i = 0; i < data->frameCount(); ++i)
{
AnalysisDataFrameRef frame = data->getDataFrame(i);
"Cannot add a data module in mid-frame");
impl_->presentData(data, module.get());
- if (!(module->flags() & AnalysisDataModuleInterface::efAllowMissing))
+ if (!(module->flags() & IAnalysisDataModule::efAllowMissing))
{
impl_->bAllowMissing_ = false;
}
}
void
-AnalysisDataModuleManager::applyModule(AbstractAnalysisData *data,
- AnalysisDataModuleInterface *module)
+AnalysisDataModuleManager::applyModule(AbstractAnalysisData *data,
+ IAnalysisDataModule *module)
{
impl_->checkModuleProperties(*module);
GMX_RELEASE_ASSERT(impl_->state_ == Impl::eFinished,
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/*! \libinternal \brief
* Encapsulates handling of data modules attached to AbstractAnalysisData.
*
- * See AnalysisDataModuleInterface and \ref module_analysisdata for more
+ * See IAnalysisDataModule and \ref module_analysisdata for more
* details on the notifications and the order in which they should be raised.
*
* \inlibraryapi
/*! \brief
* Identifies data properties to check with data modules.
*
- * \see AnalysisDataModuleInterface::Flag
+ * \see IAnalysisDataModule::Flag
*/
enum DataProperty
{
*
* \see AbstractAnalysisData::applyModule()
*/
- void applyModule(AbstractAnalysisData *data,
- AnalysisDataModuleInterface *module);
+ void applyModule(AbstractAnalysisData *data,
+ IAnalysisDataModule *module);
/*! \brief
* Notifies attached modules of the start of serial data.
* \param data Data object that is starting.
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::dataStarted().
+ * in IAnalysisDataModule::dataStarted().
*
* Should be called once, after data properties have been set with
* the methods in AbstractAnalysisData, and before any other
* derived from AbstractAnalysisData.
*
* This method initializes all modules for serial processing by calling
- * AnalysisDataModuleInterface::dataStarted().
+ * IAnalysisDataModule::dataStarted().
*/
void notifyDataStart(AbstractAnalysisData *data);
/*! \brief
* \param[in] options Parallelization properties of the input data.
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::parallelDataStarted().
+ * in IAnalysisDataModule::parallelDataStarted().
*
* Can be called instead of notifyDataStart() if \p data supports
* non-sequential creation of frames. Works as notifyDataStart(),
- * but instead calls AnalysisDataModuleInterface::parallelDataStarted()
+ * but instead calls IAnalysisDataModule::parallelDataStarted()
* and records whether the module supports the parallel mode.
* Subsequent notification calls then notify the modules according to
* the mode they accept.
*
* \param[in] header Header information for the frame that is starting.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::frameStarted().
+ * in IAnalysisDataModule::frameStarted().
*
* Should be called once for each frame, before notifyPointsAdd() calls
* for that frame.
*
* \param[in] header Header information for the frame that is starting.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::frameStarted().
+ * in IAnalysisDataModule::frameStarted().
*
* If notifyParallelDataStart() has been called, should be called once
* for each frame, before notifyParallelPointsAdd() calls for that
* frame-level data).
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::pointsAdded().
+ * in IAnalysisDataModule::pointsAdded().
*
* Can be called zero or more times for each frame.
* The caller should ensure that any column occurs at most once in the
* frame-level data).
* \throws APIError if any attached data module is not compatible.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::pointsAdded().
+ * in IAnalysisDataModule::pointsAdded().
*
* See notifyPointsAdd() for information on the structure of the point
* sets.
*
* \param[in] header Header information for the frame that is ending.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::frameFinished().
+ * in IAnalysisDataModule::frameFinished().
*
* Should be called once for each call of notifyFrameStart(), after any
* notifyPointsAdd() calls for the frame.
*
* \param[in] header Header information for the frame that is ending.
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::frameFinished().
+ * in IAnalysisDataModule::frameFinished().
*
* Should be called once for each call of notifyParallelFrameStart(),
* after any notifyParallelPointsAdd() calls for the frame.
* Notifies attached modules of the end of data.
*
* \throws unspecified Any exception thrown by attached data modules
- * in AnalysisDataModuleInterface::dataFinished().
+ * in IAnalysisDataModule::dataFinished().
*
* Should be called once, after all the other notification calls.
*/
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* Internal implementation class used to implement column modules.
*
* This class serves as a proxy between AbstractAnalysisData and the attached
- * AnalysisDataModuleInterface object. For each notification that
+ * IAnalysisDataModule object. For each notification that
* AbstractAnalysisData sends, it maps it such that only the relevant columns
- * are visible to the AnalysisDataModuleInterface. Similarly, it implements
+ * are visible to the IAnalysisDataModule. Similarly, it implements
* the frame access methods of AbstractAnalysisData such that only the relevant
* columns are returned.
*
* \ingroup module_analysisdata
*/
class AnalysisDataProxy : public AbstractAnalysisData,
- public AnalysisDataModuleInterface
+ public IAnalysisDataModule
{
public:
/*! \brief
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* data for use in analysis data modules that support parallel processing.
* The object is initialized by setting the desired dimensionality with
* setDataSetCount() and setColumnCount(), followed by a call to init(),
- * typically in AnalysisDataModuleInterface::parallelDataStarted(),
+ * typically in IAnalysisDataModule::parallelDataStarted(),
*
* After initialization, frameData() can be used to access the data for a given
* frame, independently from other frames. This works if the assumptions about
* over all frames in a lock-free manner.
*
* frameDataSet() is provided for convenience when only a single data set
- * needs to be accessed (typically in AnalysisDataModuleInterface::pointsAdded()).
+ * needs to be accessed (typically in IAnalysisDataModule::pointsAdded()).
*
* Methods in this class do not throw except where indicated.
*
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* \throws std::bad_alloc if out of memory.
*
- * Typically called from AnalysisDataModuleInterface::dataStarted().
+ * Typically called from IAnalysisDataModule::dataStarted().
*
* Must be called exactly once, before setting calling any other method
* in the class.
/*! \brief
* Accumulates data from a given point set into the average.
*
- * Typically called from AnalysisDataModuleInterface::pointsAdded().
+ * Typically called from IAnalysisDataModule::pointsAdded().
*
* Each call accumulates the values for those columns that are present
* in the point set. Can be called multiple times for a frame, and
* addPoints(). Currently, does nothing, but provided as a placeholder
* for more complex implementation.
*
- * Typically called from AnalysisDataModuleInterface::dataFinished().
+ * Typically called from IAnalysisDataModule::dataFinished().
*/
void finish();
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/oenv.h"
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/options/timeunitmanager.h"
#include "gromacs/selection/selectioncollection.h"
#include "gromacs/utility/exceptions.h"
void
-AnalysisDataPlotSettings::addOptions(Options *options)
+AnalysisDataPlotSettings::initOptions(IOptionsContainer *options)
{
options->addOption(StringOption("xvg").enumValue(g_plotFormats)
.defaultValue("xmgrace")
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
class AnalysisDataValue;
-class Options;
+class IOptionsContainer;
class SelectionCollection;
/*! \brief
*
* \param[in,out] options Options object to which options are added.
*/
- void addOptions(Options *options);
+ void initOptions(IOptionsContainer *options);
private:
const SelectionCollection *selections_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* used in its implementation: gmx::AbstractAnalysisData and
* gmx::AnalysisDataStorage.
* Most checking is done using gmx::test::AnalysisDataTestFixture and mock
- * modules that implement gmx::AnalysisDataModuleInterface.
+ * modules that implement gmx::IAnalysisDataModule.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_analysisdata
EXPECT_THROW_GMX(data.addModule(mod1), gmx::APIError);
MockAnalysisDataModulePointer mod2(
- new MockAnalysisDataModule(gmx::AnalysisDataModuleInterface::efAllowMulticolumn));
+ new MockAnalysisDataModule(gmx::IAnalysisDataModule::efAllowMulticolumn));
EXPECT_NO_THROW_GMX(data.addModule(mod2));
}
EXPECT_THROW_GMX(data.addModule(mod1), gmx::APIError);
MockAnalysisDataModulePointer mod2(
- new MockAnalysisDataModule(gmx::AnalysisDataModuleInterface::efAllowMultipoint));
+ new MockAnalysisDataModule(gmx::IAnalysisDataModule::efAllowMultipoint));
EXPECT_NO_THROW_GMX(data.addModule(mod2));
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* These tests check the functionality of gmx::AnalysisArrayData and its base
* class gmx::AbstractAnalysisArrayData.
* Checking is done using gmx::test::AnalysisDataTestFixture and mock
- * modules that implement gmx::AnalysisDataModuleInterface.
+ * modules that implement gmx::IAnalysisDataModule.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_analysisdata
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* \param source Data object to verify.
*
* Creates a mock module that verifies that the
- * AnalysisDataModuleInterface methods are called correctly by
+ * IAnalysisDataModule methods are called correctly by
* \p source. Parameters for the calls are verified against \p data.
* Adds the created module to \p source using \p data->addModule().
* Any exceptions from the called functions should be caught by the
* \param source Data object to verify.
*
* Creates a parallel mock module that verifies that the
- * AnalysisDataModuleInterface methods are called correctly by
+ * IAnalysisDataModule methods are called correctly by
* \p source. Parameters for the calls are verified against \p data.
* Adds the created module to \p source using \p data->addModule().
* Any exceptions from the called functions should be caught by the
* \param source Data object to verify.
*
* Creates a mock module that verifies that the
- * AnalysisDataModuleInterface methods are called correctly by
+ * IAnalysisDataModule methods are called correctly by
* \p source. Parameters for the calls are verified against \p data.
* Adds the created module to \p source using
* \p data->addColumnModule().
* Works like addStaticCheckerModule(), except that in addition, for
* each frame, the mock module also checks that previous frames can be
* accessed using AbstractAnalysisData::getDataFrame(). In the
- * AnalysisDataModuleInterface::dataStarted() callback, the mock module
+ * IAnalysisDataModule::dataStarted() callback, the mock module
* calls AbstractAnalysisData::requestStorage() with \p storageCount as
* the parameter.
*/
* \param[in] tolerance Tolerance to use for comparison.
*
* Creates a mock module that verifies that the
- * AnalysisDataModuleInterface methods are called correctly by
+ * IAnalysisDataModule methods are called correctly by
* \p source. Parameters for the calls are verified against reference
* data using a child compound \p id of \p checker.
* Adds the created module to \p source using \p data->addModule().
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* Functor for checking data frame header against static test input data.
*
* This functor is designed to be invoked as a handled for
- * AnalysisDataModuleInterface::frameStarted().
+ * IAnalysisDataModule::frameStarted().
*/
class StaticDataFrameHeaderChecker
{
* Functor for checking data frame points against static test input data.
*
* This functor is designed to be invoked as a handled for
- * AnalysisDataModuleInterface::pointsAdded().
+ * IAnalysisDataModule::pointsAdded().
*/
class StaticDataPointsChecker
{
* Functor for requesting data storage.
*
* This functor is designed to be invoked as a handled for
- * AnalysisDataModuleInterface::dataStarted().
+ * IAnalysisDataModule::dataStarted().
*/
class DataStorageRequester
{
* data.
*
* This functor is designed to be invoked as a handled for
- * AnalysisDataModuleInterface::pointsAdded().
+ * IAnalysisDataModule::pointsAdded().
*/
class StaticDataPointsStorageChecker
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
/*! \libinternal \file
* \brief
- * Declares mock implementation of gmx::AnalysisDataModuleInterface.
+ * Declares mock implementation of gmx::IAnalysisDataModule.
*
* Requires Google Mock.
*
class AnalysisDataTestInput;
class TestReferenceChecker;
-class MockAnalysisDataModule : public AnalysisDataModuleInterface
+class MockAnalysisDataModule : public IAnalysisDataModule
{
public:
explicit MockAnalysisDataModule(int flags);
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="InteractiveSession">
+ <pre>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="starts-with(@Name, 'Output')">
+ <xsl:value-of select="substring(.,2)"/>
+ </xsl:when>
+ <xsl:when test="string-length(.)=1">
+ <xsl:text>►</xsl:text>
+ <xsl:text>¶</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(substring(.,2), ' ')">
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="translate(substring(.,2), ' ', '⏎')"/>
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="substring(.,2)"/>
+ <xsl:text>¶</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:text>[EOF]</xsl:text>
+ </pre>
+</xsl:template>
+
</xsl:stylesheet>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* - Helper classes/functions for implementing the %main() function.
* See \ref page_usinglibrary for an overview of those available for user
* programs. These are declared in cmdlineinit.h
- * (gmx::CommandLineModuleInterface is declared in cmdlinemodule.h and
- * gmx::CommandLineOptionsInterface in cmdlineoptionsmodule.h).
+ * (gmx::ICommandLineModule is declared in cmdlinemodule.h and
+ * gmx::ICommandLineOptions in cmdlineoptionsmodule.h).
* \if libapi
*
* Additionally, for internal \Gromacs use, gmx::CommandLineModuleManager
{
public:
//! Creates the implementation class and the low-level context.
- Impl(File *file, HelpOutputFormat format, const HelpLinks *links)
- : writerContext_(file, format, links), moduleDisplayName_("gmx"),
+ Impl(TextOutputStream *stream, HelpOutputFormat format,
+ const HelpLinks *links)
+ : writerContext_(stream, format, links), moduleDisplayName_("gmx"),
completionWriter_(NULL), bHidden_(false)
{
}
};
CommandLineHelpContext::CommandLineHelpContext(
- File *file, HelpOutputFormat format, const HelpLinks *links,
- const std::string &programName)
- : impl_(new Impl(file, format, links))
+ TextOutputStream *stream, HelpOutputFormat format,
+ const HelpLinks *links, const std::string &programName)
+ : impl_(new Impl(stream, format, links))
{
impl_->writerContext_.setReplacement("[PROGRAM]", programName);
}
CommandLineHelpContext::CommandLineHelpContext(
ShellCompletionWriter *writer)
- : impl_(new Impl(writer->outputFile(), eHelpOutputFormat_Other, NULL))
+ : impl_(new Impl(&writer->outputStream(), eHelpOutputFormat_Other, NULL))
{
impl_->completionWriter_ = writer;
}
*
* Wraps the constructor of HelpWriterContext.
*/
- CommandLineHelpContext(File *file, HelpOutputFormat format,
- const HelpLinks *links,
+ CommandLineHelpContext(TextOutputStream *stream,
+ HelpOutputFormat format, const HelpLinks *links,
const std::string &programName);
//! Creates a context for a particular HelpWriterContext.
explicit CommandLineHelpContext(const HelpWriterContext &writerContext);
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/fileredirector.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/path.h"
#include "gromacs/utility/programcontext.h"
+#include "gromacs/utility/stringstream.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textreader.h"
+#include "gromacs/utility/textstream.h"
+#include "gromacs/utility/textwriter.h"
#include "shellcompletions.h"
namespace
{
-class HelpExportInterface;
+class IHelpExport;
class RootHelpTopic;
} // namespace
class CommandLineHelpModuleImpl
{
public:
- CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
+ CommandLineHelpModuleImpl(const IProgramContext &programContext,
const std::string &binaryName,
const CommandLineModuleMap &modules,
const CommandLineModuleGroupList &groups);
- void exportHelp(HelpExportInterface *exporter);
+ void exportHelp(IHelpExport *exporter);
boost::scoped_ptr<RootHelpTopic> rootTopic_;
- const ProgramContextInterface &programContext_;
+ const IProgramContext &programContext_;
std::string binaryName_;
const CommandLineModuleMap &modules_;
const CommandLineModuleGroupList &groups_;
CommandLineHelpContext *context_;
- const CommandLineModuleInterface *moduleOverride_;
+ const ICommandLineModule *moduleOverride_;
bool bHidden_;
- FileOutputRedirectorInterface *outputRedirector_;
+ IFileOutputRedirector *outputRedirector_;
GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
};
{
/********************************************************************
- * HelpExportInterface
+ * IHelpExport
*/
/*! \brief
*
* \ingroup module_commandline
*/
-class HelpExportInterface
+class IHelpExport
{
public:
//! Shorthand for a list of modules contained in a group.
typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
- virtual ~HelpExportInterface() {};
+ virtual ~IHelpExport() {};
/*! \brief
* Called once before exporting individual modules.
* \param[in] displayName Display name for the module (gmx something).
*/
virtual void exportModuleHelp(
- const CommandLineModuleInterface &module,
+ const ICommandLineModule &module,
const std::string &tag,
const std::string &displayName) = 0;
/*! \brief
*
* \param[in] topic Topic to export.
*/
- virtual void exportTopic(const HelpTopicInterface &topic) = 0;
+ virtual void exportTopic(const IHelpTopic &topic) = 0;
};
/********************************************************************
addSubTopic(move(topic));
}
//! Exports all the top-level topics with the given exporter.
- void exportHelp(HelpExportInterface *exporter);
+ void exportHelp(IHelpExport *exporter);
virtual void writeHelp(const HelpWriterContext &context) const;
GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
};
-void RootHelpTopic::exportHelp(HelpExportInterface *exporter)
+void RootHelpTopic::exportHelp(IHelpExport *exporter)
{
std::vector<std::string>::const_iterator topicName;
for (topicName = exportedTopics_.begin();
topicName != exportedTopics_.end();
++topicName)
{
- const HelpTopicInterface *topic = findSubTopic(topicName->c_str());
+ const IHelpTopic *topic = findSubTopic(topicName->c_str());
GMX_RELEASE_ASSERT(topic != NULL, "Exported help topic no longer found");
exporter->exportTopic(*topic);
}
}
cmdlineContext->setModuleDisplayName(helpModule_.binaryName_);
optionsHolder.initOptions();
- Options &options = *optionsHolder.options();
- options.setDescription(RootHelpText::text);
+ Options &options = *optionsHolder.options();
+ ConstArrayRef<const char *> helpText;
+ if (context.outputFormat() != eHelpOutputFormat_Console)
+ {
+ helpText = RootHelpText::text;
+ }
// TODO: Add <command> [<args>] into the synopsis.
CommandLineHelpWriter(options)
- .setShowDescriptions(context.outputFormat() != eHelpOutputFormat_Console)
+ .setHelpText(helpText)
.writeHelp(*cmdlineContext);
}
if (context.outputFormat() == eHelpOutputFormat_Console)
*
* \ingroup module_commandline
*/
-class CommandsHelpTopic : public HelpTopicInterface
+class CommandsHelpTopic : public IHelpTopic
{
public:
/*! \brief
virtual const char *name() const { return "commands"; }
virtual const char *title() const { return "List of available commands"; }
virtual bool hasSubTopics() const { return false; }
- virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
+ virtual const IHelpTopic *findSubTopic(const char * /*name*/) const
{
return NULL;
}
context.writeTextBlock(
"Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
"Available commands:");
- File &file = context.outputFile();
+ TextWriter &file = context.outputFile();
TextTableFormatter formatter;
formatter.addColumn(NULL, maxNameLength + 1, false);
formatter.addColumn(NULL, 72 - maxNameLength, true);
/*! \brief
* Help topic wrapper for a command-line module.
*
- * This class implements HelpTopicInterface such that it wraps a
- * CommandLineModuleInterface, allowing subcommand "help <command>"
+ * This class implements IHelpTopic such that it wraps a
+ * ICommandLineModule, allowing subcommand "help <command>"
* to produce the help for "<command>".
*
* \ingroup module_commandline
*/
-class ModuleHelpTopic : public HelpTopicInterface
+class ModuleHelpTopic : public IHelpTopic
{
public:
//! Constructs a help topic for a specific module.
- ModuleHelpTopic(const CommandLineModuleInterface &module,
+ ModuleHelpTopic(const ICommandLineModule &module,
const CommandLineHelpModuleImpl &helpModule)
: module_(module), helpModule_(helpModule)
{
virtual const char *name() const { return module_.name(); }
virtual const char *title() const { return NULL; }
virtual bool hasSubTopics() const { return false; }
- virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
+ virtual const IHelpTopic *findSubTopic(const char * /*name*/) const
{
return NULL;
}
virtual void writeHelp(const HelpWriterContext &context) const;
private:
- const CommandLineModuleInterface &module_;
+ const ICommandLineModule &module_;
const CommandLineHelpModuleImpl &helpModule_;
GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
*
* \ingroup module_commandline
*/
-class HelpExportReStructuredText : public HelpExportInterface
+class HelpExportReStructuredText : public IHelpExport
{
public:
//! Initializes reST exporter.
- explicit HelpExportReStructuredText(
- const CommandLineHelpModuleImpl &helpModule);
+ HelpExportReStructuredText(
+ const CommandLineHelpModuleImpl &helpModule,
+ IFileOutputRedirector *outputRedirector);
virtual void startModuleExport();
virtual void exportModuleHelp(
- const CommandLineModuleInterface &module,
+ const ICommandLineModule &module,
const std::string &tag,
const std::string &displayName);
virtual void finishModuleExport();
const ModuleGroupContents &modules);
virtual void finishModuleGroupExport();
- virtual void exportTopic(const HelpTopicInterface &topic);
+ virtual void exportTopic(const IHelpTopic &topic);
private:
- FileOutputRedirectorInterface *outputRedirector_;
+ IFileOutputRedirector *outputRedirector_;
const std::string &binaryName_;
HelpLinks links_;
- boost::scoped_ptr<File> indexFile_;
- boost::scoped_ptr<File> manPagesFile_;
+ boost::scoped_ptr<TextWriter> indexFile_;
+ boost::scoped_ptr<TextWriter> manPagesFile_;
};
HelpExportReStructuredText::HelpExportReStructuredText(
- const CommandLineHelpModuleImpl &helpModule)
- : outputRedirector_(helpModule.outputRedirector_),
+ const CommandLineHelpModuleImpl &helpModule,
+ IFileOutputRedirector *outputRedirector)
+ : outputRedirector_(outputRedirector),
binaryName_(helpModule.binaryName_),
links_(eHelpOutputFormat_Rst)
{
- File linksFile("links.dat", "r");
- std::string line;
- while (linksFile.readLine(&line))
+ TextReader linksFile("links.dat");
+ std::string line;
+ while (linksFile.readLineTrimmed(&line))
{
links_.addLink("[REF]." + line + "[ref]",
formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
void HelpExportReStructuredText::startModuleExport()
{
indexFile_.reset(
- new File(outputRedirector_->openFileForWriting("fragments/byname.rst")));
+ new TextWriter(
+ outputRedirector_->openTextOutputFile("fragments/byname.rst")));
indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
binaryName_.c_str(), binaryName_.c_str(),
RootHelpText::title));
manPagesFile_.reset(
- new File(outputRedirector_->openFileForWriting("conf-man.py")));
+ new TextWriter(
+ outputRedirector_->openTextOutputFile("conf-man.py")));
manPagesFile_->writeLine("man_pages = [");
}
void HelpExportReStructuredText::exportModuleHelp(
- const CommandLineModuleInterface &module,
+ const ICommandLineModule &module,
const std::string &tag,
const std::string &displayName)
{
- // TODO: Ideally, the file would only be touched if it really changes.
- // This would make Sphinx reruns much faster.
- File file(outputRedirector_->openFileForWriting("onlinehelp/" + tag + ".rst"));
- file.writeLine(formatString(".. _%s:", displayName.c_str()));
+ TextOutputStreamPointer file
+ = outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst");
+ TextWriter writer(file);
+ writer.writeLine(formatString(".. _%s:", displayName.c_str()));
if (0 == displayName.compare(binaryName_ + " mdrun"))
{
// Make an extra link target for the convenience of
// MPI-specific documentation
- file.writeLine(".. _mdrun_mpi:");
+ writer.writeLine(".. _mdrun_mpi:");
}
- file.writeLine();
+ writer.writeLine();
- CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_, binaryName_);
+ CommandLineHelpContext context(file.get(), eHelpOutputFormat_Rst, &links_, binaryName_);
context.enterSubSection(displayName);
context.setModuleDisplayName(displayName);
module.writeHelp(context);
- file.writeLine();
- file.writeLine(".. only:: man");
- file.writeLine();
- file.writeLine(" See also");
- file.writeLine(" --------");
- file.writeLine();
- file.writeLine(formatString(" :manpage:`%s(1)`", binaryName_.c_str()));
- file.writeLine();
- file.writeLine(" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
- file.close();
+ writer.writeLine();
+ writer.writeLine(".. only:: man");
+ writer.writeLine();
+ writer.writeLine(" See also");
+ writer.writeLine(" --------");
+ writer.writeLine();
+ writer.writeLine(formatString(" :manpage:`%s(1)`", binaryName_.c_str()));
+ writer.writeLine();
+ writer.writeLine(" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
+ file->close();
indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
displayName.c_str(), tag.c_str(),
void HelpExportReStructuredText::startModuleGroupExport()
{
indexFile_.reset(
- new File(outputRedirector_->openFileForWriting("fragments/bytopic.rst")));
+ new TextWriter(
+ outputRedirector_->openTextOutputFile("fragments/bytopic.rst")));
manPagesFile_.reset(
- new File(outputRedirector_->openFileForWriting("fragments/bytopic-man.rst")));
+ new TextWriter(
+ outputRedirector_->openTextOutputFile("fragments/bytopic-man.rst")));
}
void HelpExportReStructuredText::exportModuleGroup(
manPagesFile_.reset();
}
-void HelpExportReStructuredText::exportTopic(const HelpTopicInterface &topic)
+void HelpExportReStructuredText::exportTopic(const IHelpTopic &topic)
{
- const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst");
- File file(outputRedirector_->openFileForWriting(path));
- CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_,
- binaryName_);
- HelpManager manager(topic, context.writerContext());
+ const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst");
+ TextOutputStreamPointer file(outputRedirector_->openTextOutputFile(path));
+ CommandLineHelpContext context(file.get(), eHelpOutputFormat_Rst, &links_,
+ binaryName_);
+ HelpManager manager(topic, context.writerContext());
manager.writeCurrentTopic();
+ file->close();
}
/********************************************************************
*
* \ingroup module_commandline
*/
-class HelpExportCompletion : public HelpExportInterface
+class HelpExportCompletion : public IHelpExport
{
public:
//! Initializes completion exporter.
virtual void startModuleExport();
virtual void exportModuleHelp(
- const CommandLineModuleInterface &module,
+ const ICommandLineModule &module,
const std::string &tag,
const std::string &displayName);
virtual void finishModuleExport();
const ModuleGroupContents & /*modules*/) {}
virtual void finishModuleGroupExport() {}
- virtual void exportTopic(const HelpTopicInterface & /*topic*/) {}
+ virtual void exportTopic(const IHelpTopic & /*topic*/) {}
private:
ShellCompletionWriter bashWriter_;
}
void HelpExportCompletion::exportModuleHelp(
- const CommandLineModuleInterface &module,
+ const ICommandLineModule &module,
const std::string & /*tag*/,
const std::string & /*displayName*/)
{
*/
CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
- const ProgramContextInterface &programContext,
+ const IProgramContext &programContext,
const std::string &binaryName,
const CommandLineModuleMap &modules,
const CommandLineModuleGroupList &groups)
{
}
-void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter)
+void CommandLineHelpModuleImpl::exportHelp(IHelpExport *exporter)
{
// TODO: Would be nicer to have the file names supplied by the build system
// and/or export a list of files from here.
rootTopic_->exportHelp(exporter);
}
+namespace
+{
+
+/********************************************************************
+ * ModificationCheckingFileOutputStream
+ */
+
+class ModificationCheckingFileOutputStream : public TextOutputStream
+{
+ public:
+ ModificationCheckingFileOutputStream(
+ const char *path,
+ IFileOutputRedirector *redirector)
+ : path_(path), redirector_(redirector)
+ {
+ }
+
+ virtual void write(const char *str) { contents_.write(str); }
+ virtual void close()
+ {
+ const std::string &newContents = contents_.toString();
+ // TODO: Redirect these for unit tests.
+ if (File::exists(path_))
+ {
+ const std::string originalContents_
+ = TextReader::readFileToString(path_);
+ if (originalContents_ == newContents)
+ {
+ return;
+ }
+ }
+ TextWriter writer(redirector_->openTextOutputFile(path_));
+ writer.writeString(newContents);
+ }
+
+ private:
+ std::string path_;
+ StringOutputStream contents_;
+ IFileOutputRedirector *redirector_;
+};
+
+/********************************************************************
+ * ModificationCheckingFileOutputRedirector
+ */
+
+class ModificationCheckingFileOutputRedirector : public IFileOutputRedirector
+{
+ public:
+ explicit ModificationCheckingFileOutputRedirector(
+ IFileOutputRedirector *redirector)
+ : redirector_(redirector)
+ {
+ }
+
+ virtual TextOutputStream &standardOutput()
+ {
+ return redirector_->standardOutput();
+ }
+ virtual TextOutputStreamPointer openTextOutputFile(const char *filename)
+ {
+ return TextOutputStreamPointer(
+ new ModificationCheckingFileOutputStream(filename, redirector_));
+ }
+
+ private:
+ IFileOutputRedirector *redirector_;
+};
+
+} // namespace
+
/********************************************************************
* CommandLineHelpModule
*/
CommandLineHelpModule::CommandLineHelpModule(
- const ProgramContextInterface &programContext,
+ const IProgramContext &programContext,
const std::string &binaryName,
const CommandLineModuleMap &modules,
const CommandLineModuleGroupList &groups)
}
HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
- const CommandLineModuleInterface &module) const
+ const ICommandLineModule &module) const
{
return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
}
}
void CommandLineHelpModule::setModuleOverride(
- const CommandLineModuleInterface &module)
+ const ICommandLineModule &module)
{
impl_->moduleOverride_ = &module;
}
void CommandLineHelpModule::setOutputRedirector(
- FileOutputRedirectorInterface *output)
+ IFileOutputRedirector *output)
{
impl_->outputRedirector_ = output;
}
CommandLineParser(&options).parse(&argc, argv);
if (!exportFormat.empty())
{
- boost::scoped_ptr<HelpExportInterface> exporter;
+ ModificationCheckingFileOutputRedirector redirector(impl_->outputRedirector_);
+ boost::scoped_ptr<IHelpExport> exporter;
if (exportFormat == "rst")
{
- exporter.reset(new HelpExportReStructuredText(*impl_));
+ exporter.reset(new HelpExportReStructuredText(*impl_, &redirector));
}
else if (exportFormat == "completion")
{
return 0;
}
- File &outputFile = impl_->outputRedirector_->standardOutput();
+ TextOutputStream &outputFile = impl_->outputRedirector_->standardOutput();
HelpLinks links(eHelpOutputFormat_Console);
initProgramLinks(&links, *impl_);
CommandLineHelpContext context(&outputFile, eHelpOutputFormat_Console, &links,
#define GMX_COMMANDLINE_CMDLINEHELPMODULE_H
#include "gromacs/commandline/cmdlinemodule.h"
-#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
#include "gromacs/utility/classhelpers.h"
#include "cmdlinemodulemanager-impl.h"
{
class CommandLineHelpContext;
-class FileOutputRedirectorInterface;
-class ProgramContextInterface;
+class IFileOutputRedirector;
+class IProgramContext;
class CommandLineHelpModuleImpl;
*
* \ingroup module_commandline
*/
-class CommandLineHelpModule : public CommandLineModuleInterface
+class CommandLineHelpModule : public ICommandLineModule
{
public:
/*! \brief
* \param[in] groups List of module groups.
* \throws std::bad_alloc if out of memory.
*/
- CommandLineHelpModule(const ProgramContextInterface &programContext,
+ CommandLineHelpModule(const IProgramContext &programContext,
const std::string &binaryName,
const CommandLineModuleMap &modules,
const CommandLineModuleGroupList &groups);
* safety in CommandLineModuleManager::addModule().
*/
HelpTopicPointer
- createModuleHelpTopic(const CommandLineModuleInterface &module) const;
+ createModuleHelpTopic(const ICommandLineModule &module) const;
/*! \brief
* Adds a top-level help topic.
*
* If called, the help module directly prints the help for the given
* module when called, skipping any other processing.
*/
- void setModuleOverride(const CommandLineModuleInterface &module);
+ void setModuleOverride(const ICommandLineModule &module);
/*! \brief
* Sets a file redirector for writing help output.
* Used for unit testing; see
* CommandLineModuleManager::setOutputRedirector() for more details.
*/
- void setOutputRedirector(FileOutputRedirectorInterface *output);
+ void setOutputRedirector(IFileOutputRedirector *output);
virtual const char *name() const { return "help"; }
virtual const char *shortDescription() const
#include "gromacs/options/timeunitmanager.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "shellcompletions.h"
//! \{
/********************************************************************
- * DescriptionsFormatter
- */
-
-class DescriptionsFormatter : public OptionsVisitor
-{
- public:
- /*! \brief
- * Creates a new description formatter.
- *
- * \param[in] context Help context to use to write the help.
- */
- explicit DescriptionsFormatter(const HelpWriterContext &context)
- : context_(context), title_(NULL), bDidOutput_(false)
- {
- }
-
- //! Formats all section descriptions from a given options.
- void format(const Options &options, const char *title)
- {
- title_ = title;
- bDidOutput_ = false;
- visitSubSection(options);
- if (bDidOutput_)
- {
- context_.outputFile().writeLine();
- }
- }
-
- //! Formats the description for a single subsection and handles recursion.
- virtual void visitSubSection(const Options §ion);
- // This method is not used and never called.
- virtual void visitOption(const OptionInfo & /*option*/) {}
-
- private:
- const HelpWriterContext &context_;
- const char *title_;
- bool bDidOutput_;
-
- GMX_DISALLOW_COPY_AND_ASSIGN(DescriptionsFormatter);
-};
-
-void DescriptionsFormatter::visitSubSection(const Options §ion)
-{
- if (!section.description().empty())
- {
- if (bDidOutput_)
- {
- context_.outputFile().writeLine();
- }
- else if (title_ != NULL)
- {
- context_.writeTitle(title_);
- }
- // TODO: Print title for the section?
- context_.writeTextBlock(section.description());
- bDidOutput_ = true;
- }
-
- OptionsIterator iterator(section);
- iterator.acceptSubSections(this);
-}
-
-/********************************************************************
- * OptionsFormatterInterface
+ * IOptionsFormatter
*/
/*! \brief
*
* \see OptionsFilter
*/
-class OptionsFormatterInterface
+class IOptionsFormatter
{
public:
- virtual ~OptionsFormatterInterface() {}
+ virtual ~IOptionsFormatter() {}
//! Formats a single option option.
virtual void formatOption(const OptionInfo &option) = 0;
*
* Together with code in CommandLineHelpWriter::writeHelp(), this class
* implements the common logic for writing out the help.
- * An object implementing the OptionsFormatterInterface must be provided to the
+ * An object implementing the IOptionsFormatter must be provided to the
* constructor, and does the actual formatting that is specific to the output
* format.
*/
//! Formats selected options using the formatter.
void formatSelected(FilterType type,
- OptionsFormatterInterface *formatter,
+ IOptionsFormatter *formatter,
const Options &options);
virtual void visitSubSection(const Options §ion);
virtual void visitOption(const OptionInfo &option);
private:
- OptionsFormatterInterface *formatter_;
+ IOptionsFormatter *formatter_;
FilterType filterType_;
bool bShowHidden_;
};
void OptionsFilter::formatSelected(FilterType type,
- OptionsFormatterInterface *formatter,
+ IOptionsFormatter *formatter,
const Options &options)
{
formatter_ = formatter;
/*! \brief
* Formatter implementation for synopsis.
*/
-class SynopsisFormatter : public OptionsFormatterInterface
+class SynopsisFormatter : public IOptionsFormatter
{
public:
//! Creates a helper object for formatting the synopsis.
{
currentLength_ = std::strlen(name) + 1;
indent_ = std::min(currentLength_, 13);
- File &file = context_.outputFile();
+ TextWriter &file = context_.outputFile();
switch (context_.outputFormat())
{
case eHelpOutputFormat_Console:
void SynopsisFormatter::finish()
{
- File &file = context_.outputFile();
+ TextWriter &file = context_.outputFile();
file.writeLine();
file.writeLine();
}
}
fullOptionText.append(bFormatted_ ? "`]" : "]");
- File &file = context_.outputFile();
+ TextWriter &file = context_.outputFile();
currentLength_ += totalLength;
if (currentLength_ >= lineLength_)
{
/*! \brief
* Formatter implementation for help export.
*/
-class OptionsListFormatter : public OptionsFormatterInterface
+class OptionsListFormatter : public IOptionsFormatter
{
public:
//! Creates a helper object for formatting options.
//! Options object to use for generating help.
const Options &options_;
+ //! Help text.
+ std::string helpText_;
//! List of bugs/knows issues.
ConstArrayRef<const char *> bugs_;
//! Time unit to show in descriptions.
std::string timeUnit_;
- //! Whether to write descriptions to output.
- bool bShowDescriptions_;
};
CommandLineHelpWriter::Impl::Impl(const Options &options)
- : options_(options), timeUnit_(TimeUnitManager().timeUnitAsString()),
- bShowDescriptions_(false)
+ : options_(options), timeUnit_(TimeUnitManager().timeUnitAsString())
{
}
}
CommandLineHelpWriter &
-CommandLineHelpWriter::setShowDescriptions(bool bSet)
+CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
{
- impl_->bShowDescriptions_ = bSet;
+ impl_->timeUnit_ = timeUnit;
return *this;
}
CommandLineHelpWriter &
-CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
+CommandLineHelpWriter::setHelpText(const std::string &help)
{
- impl_->timeUnit_ = timeUnit;
+ impl_->helpText_ = help;
+ return *this;
+}
+
+CommandLineHelpWriter &
+CommandLineHelpWriter::setHelpText(const ConstArrayRef<const char *> &help)
+{
+ impl_->helpText_ = joinStrings(help, "\n");
return *this;
}
synopsisFormatter.finish();
}
- if (impl_->bShowDescriptions_)
+ if (!impl_->helpText_.empty())
{
- DescriptionsFormatter descriptionFormatter(writerContext);
- descriptionFormatter.format(impl_->options_, "Description");
+ writerContext.writeTitle("Description");
+ writerContext.writeTextBlock(impl_->helpText_);
+ writerContext.outputFile().writeLine();
}
CommonFormatterData common(impl_->timeUnit_.c_str());
OptionsListFormatter formatter(writerContext, common, "Options");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_COMMANDLINE_CMDLINEHELPWRITER_H
#define GMX_COMMANDLINE_CMDLINEHELPWRITER_H
+#include <string>
+
#include "gromacs/utility/classhelpers.h"
namespace gmx
template <typename T> class ConstArrayRef;
/*! \brief
- * Writes help information for Options in ascii format.
+ * Writes help information for Options.
*
* \inpublicapi
* \ingroup module_commandline
explicit CommandLineHelpWriter(const Options &options);
~CommandLineHelpWriter();
- /*! \brief
- * Sets whether long descriptions for sections are shown in the help.
- */
- CommandLineHelpWriter &setShowDescriptions(bool bShow);
/*! \brief
* Sets time unit to show in descriptions.
*
* If not called, uses a default "ps".
*/
CommandLineHelpWriter &setTimeUnitString(const char *timeUnit);
-
+ /*! \brief
+ * Sets the help text to print as description.
+ *
+ * \param[in] help Help text to show.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * If `help` is empty, or this method is not called, only a list of
+ * options is printed.
+ * Formatting for the help text is described on \ref page_onlinehelp.
+ */
+ CommandLineHelpWriter &setHelpText(const std::string &help);
+ //! \copydoc setHelpText(const std::string &)
+ CommandLineHelpWriter &
+ setHelpText(const ConstArrayRef<const char *> &help);
/*! \brief
* Sets the list of known bugs/limitations.
*
}
int runCommandLineModule(int argc, char *argv[],
- CommandLineModuleInterface *module)
+ ICommandLineModule *module)
{
return CommandLineModuleManager::runAsMainSingleModule(argc, argv, module);
}
int runCommandLineModule(int argc, char *argv[],
const char *name, const char *description,
- CommandLineOptionsModuleInterface *(*factory)())
+ ICommandLineOptionsModule *(*factory)())
{
- return CommandLineOptionsModuleInterface::runAsMain(
+ return ICommandLineOptionsModule::runAsMain(
argc, argv, name, description, factory);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class CommandLineModuleInterface;
-class CommandLineOptionsModuleInterface;
+class ICommandLineModule;
+class ICommandLineOptionsModule;
/*! \brief
* Initializes the \Gromacs library for command-line use.
* Does not throw. All exceptions are caught and handled internally.
*/
int runCommandLineModule(int argc, char *argv[],
- CommandLineModuleInterface *module);
+ ICommandLineModule *module);
/*! \brief
* Implements a main() method that runs a single module.
*
*
* Usage:
* \code
- class CustomCommandLineOptionsModule : public CommandLineOptionsModuleInterface
+ class CustomCommandLineOptionsModule : public ICommandLineOptionsModule
{
// <...>
};
- static CommandLineOptionsModuleInterface *create()
+ static ICommandLineOptionsModule *create()
{
return new CustomCommandLineOptionsModule();
}
*/
int runCommandLineModule(int argc, char *argv[],
const char *name, const char *description,
- CommandLineOptionsModuleInterface *(*factory)());
+ ICommandLineOptionsModule *(*factory)());
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
/*! \file
* \brief
- * Declares gmx::CommandLineModuleInterface and supporting classes.
+ * Declares gmx::ICommandLineModule and supporting classes.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inpublicapi
* \inpublicapi
* \ingroup module_commandline
*/
-class CommandLineModuleInterface
+class ICommandLineModule
{
public:
- virtual ~CommandLineModuleInterface() {}
+ virtual ~ICommandLineModule() {}
//! Returns the name of the module.
virtual const char *name() const = 0;
//! \cond libapi
/*! \libinternal \brief
- * Helper to implement CommandLineModuleInterface::writeHelp() with a C-like
+ * Helper to implement ICommandLineModule::writeHelp() with a C-like
* main() function that calls parse_common_args().
*
* \param[in] context Context object for writing the help.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
bool bVersion_;
bool bCopyright_;
int niceLevel_;
+ bool bNiceSet_;
bool bBackup_;
bool bFpexcept_;
int debugLevel_;
*/
/*! \brief
- * Implements a CommandLineModuleInterface, given a function with C/C++ main()
+ * Implements a ICommandLineModule, given a function with C/C++ main()
* signature.
*/
-class CMainCommandLineModule : public CommandLineModuleInterface
+class CMainCommandLineModule : public ICommandLineModule
{
public:
//! \copydoc gmx::CommandLineModuleManager::CMainFunction
CommandLineCommonOptionsHolder::CommandLineCommonOptionsHolder()
: options_(NULL, NULL), bHelp_(false), bHidden_(false),
bQuiet_(false), bVersion_(false), bCopyright_(true),
- niceLevel_(19), bBackup_(true), bFpexcept_(false), debugLevel_(0)
+ niceLevel_(19), bNiceSet_(false), bBackup_(true), bFpexcept_(false),
+ debugLevel_(0)
{
binaryInfoSettings_.copyright(true);
}
.description("Print extended version information and quit"));
options_.addOption(BooleanOption("copyright").store(&bCopyright_)
.description("Print copyright information on startup"));
- options_.addOption(IntegerOption("nice").store(&niceLevel_)
+ options_.addOption(IntegerOption("nice").store(&niceLevel_).storeIsSet(&bNiceSet_)
.description("Set the nicelevel (default depends on command)"));
options_.addOption(BooleanOption("backup").store(&bBackup_)
.description("Write backups if output files exist"));
void CommandLineCommonOptionsHolder::adjustFromSettings(
const CommandLineModuleSettings &settings)
{
- if (!options_.isSet("nice"))
+ if (!bNiceSet_)
{
niceLevel_ = settings.defaultNiceLevel();
}
* options). Also finds the module that should be run and the
* arguments that should be passed to it.
*/
- CommandLineModuleInterface *
+ ICommandLineModule *
processCommonOptions(CommandLineCommonOptionsHolder *optionsHolder,
int *argc, char ***argv);
*/
CommandLineHelpModule *helpModule_;
//! If non-NULL, run this module in single-module mode.
- CommandLineModuleInterface *singleModule_;
+ ICommandLineModule *singleModule_;
//! Stores the value set with setQuiet().
bool bQuiet_;
return modules_.find(name);
}
-CommandLineModuleInterface *
+ICommandLineModule *
CommandLineModuleManager::Impl::processCommonOptions(
CommandLineCommonOptionsHolder *optionsHolder, int *argc, char ***argv)
{
// Check if we are directly invoking a certain module.
- CommandLineModuleInterface *module = singleModule_;
+ ICommandLineModule *module = singleModule_;
// TODO: It would be nice to propagate at least the -quiet option to
// the modules so that they can also be quiet in response to this.
}
void CommandLineModuleManager::setOutputRedirector(
- FileOutputRedirectorInterface *output)
+ IFileOutputRedirector *output)
{
impl_->ensureHelpModuleExists();
impl_->helpModule_->setOutputRedirector(output);
}
-void CommandLineModuleManager::setSingleModule(CommandLineModuleInterface *module)
+void CommandLineModuleManager::setSingleModule(ICommandLineModule *module)
{
impl_->singleModule_ = module;
}
int CommandLineModuleManager::run(int argc, char *argv[])
{
- CommandLineModuleInterface *module;
+ ICommandLineModule *module;
const bool bMaster = (gmx_node_rank() == 0);
bool bQuiet = impl_->bQuiet_ || !bMaster;
CommandLineCommonOptionsHolder optionsHolder;
// static
int CommandLineModuleManager::runAsMainSingleModule(
- int argc, char *argv[], CommandLineModuleInterface *module)
+ int argc, char *argv[], ICommandLineModule *module)
{
CommandLineProgramContext &programContext = gmx::initForCommandLine(&argc, &argv);
try
#ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
#define GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
-#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/uniqueptr.h"
class CommandLineModuleGroup;
class CommandLineModuleGroupData;
-class CommandLineModuleInterface;
class CommandLineProgramContext;
-class FileOutputRedirectorInterface;
+class ICommandLineModule;
+class IFileOutputRedirector;
//! \addtogroup module_commandline
//! \{
-//! Smart pointer type for managing a CommandLineModuleInterface.
-typedef gmx_unique_ptr<CommandLineModuleInterface>::type
+//! Smart pointer type for managing a ICommandLineModule.
+typedef gmx_unique_ptr<ICommandLineModule>::type
CommandLineModulePointer;
/*! \libinternal \brief
* Does not throw. All exceptions are caught and handled internally.
*/
static int runAsMainSingleModule(int argc, char *argv[],
- CommandLineModuleInterface *module);
+ ICommandLineModule *module);
/*! \brief
* Implements a main() method that runs a given function.
*
* For tests, there should only be need to call this a single time,
* right after creating the manager.
*/
- void setOutputRedirector(FileOutputRedirectorInterface *output);
+ void setOutputRedirector(IFileOutputRedirector *output);
/*! \brief
* Makes the manager always run a single module.
* directly passes all command-line arguments to \p module.
* Help arguments are an exception: these are still recognized by the
* manager and translated into a call to
- * CommandLineModuleInterface::writeHelp().
+ * ICommandLineModule::writeHelp().
*
* This is public mainly for unit testing purposes; for other code,
* runAsMainSingleModule() typically provides the desired
*
* Does not throw.
*/
- void setSingleModule(CommandLineModuleInterface *module);
+ void setSingleModule(ICommandLineModule *module);
/*! \brief
* Adds a given module to this manager.
*
* \throws std::bad_alloc if out of memory.
*
* \p Module must be default-constructible and implement
- * CommandLineModuleInterface.
+ * ICommandLineModule.
*
* This method is provided as a convenient alternative to addModule()
* for cases where each module is implemented by a different type
*/
/*! \internal \file
* \brief
- * Implements supporting routines for gmx::CommandLineOptionsModuleInterface.
+ * Implements supporting routines for gmx::ICommandLineOptionsModule.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_commandline
#include "gromacs/commandline/cmdlineparser.h"
#include "gromacs/options/filenameoptionmanager.h"
#include "gromacs/options/options.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/stringutil.h"
namespace gmx
{
namespace
{
+/********************************************************************
+ * CommandLineOptionsModuleSettings
+ */
+
+class CommandLineOptionsModuleSettings : public ICommandLineOptionsModuleSettings
+{
+ public:
+ const std::string &helpText() const { return helpText_; }
+
+ virtual void setHelpText(const ConstArrayRef<const char *> &help)
+ {
+ helpText_ = joinStrings(help, "\n");
+ }
+
+ private:
+ std::string helpText_;
+};
+
/********************************************************************
* CommandLineOptionsModule
*/
-class CommandLineOptionsModule : public CommandLineModuleInterface
+class CommandLineOptionsModule : public ICommandLineModule
{
public:
//! Shorthand for the factory function pointer type.
- typedef CommandLineOptionsModuleInterface::FactoryMethod FactoryMethod;
+ typedef ICommandLineOptionsModule::FactoryMethod FactoryMethod;
CommandLineOptionsModule(const char *name, const char *description,
FactoryMethod factory)
{
}
CommandLineOptionsModule(const char *name, const char *description,
- CommandLineOptionsModuleInterface *module)
+ ICommandLineOptionsModule *module)
: name_(name), description_(description), factory_(NULL),
module_(module)
{
const char *name_;
const char *description_;
FactoryMethod factory_;
- boost::scoped_ptr<CommandLineOptionsModuleInterface> module_;
+ boost::scoped_ptr<ICommandLineOptionsModule> module_;
};
void CommandLineOptionsModule::init(CommandLineModuleSettings *settings)
void CommandLineOptionsModule::writeHelp(const CommandLineHelpContext &context) const
{
- boost::scoped_ptr<CommandLineOptionsModuleInterface> moduleGuard;
- CommandLineOptionsModuleInterface *module = module_.get();
+ boost::scoped_ptr<ICommandLineOptionsModule> moduleGuard;
+ ICommandLineOptionsModule *module = module_.get();
if (!module)
{
GMX_RELEASE_ASSERT(factory_ != NULL, "Neither factory nor module provided");
moduleGuard.reset(factory_());
module = moduleGuard.get();
}
- Options options(name(), shortDescription());
- module->initOptions(&options);
+ Options options(name(), shortDescription());
+ CommandLineOptionsModuleSettings settings;
+ module->initOptions(&options, &settings);
CommandLineHelpWriter(options)
- .setShowDescriptions(true)
+ .setHelpText(settings.helpText())
.writeHelp(context);
}
options.addManager(&fileoptManager);
- module_->initOptions(&options);
+ CommandLineOptionsModuleSettings settings;
+ module_->initOptions(&options, &settings);
{
CommandLineParser parser(&options);
parser.parse(&argc, argv);
options.finish();
}
- module_->optionsFinished(&options);
+ module_->optionsFinished();
}
} // namespace
/********************************************************************
- * CommandLineOptionsModuleInterface
+ * ICommandLineOptionsModuleSettings
+ */
+
+ICommandLineOptionsModuleSettings::~ICommandLineOptionsModuleSettings()
+{
+}
+
+/********************************************************************
+ * ICommandLineOptionsModule
*/
-CommandLineOptionsModuleInterface::~CommandLineOptionsModuleInterface()
+ICommandLineOptionsModule::~ICommandLineOptionsModule()
{
}
// static
-CommandLineModuleInterface *
-CommandLineOptionsModuleInterface::createModule(
+ICommandLineModule *
+ICommandLineOptionsModule::createModule(
const char *name, const char *description, FactoryMethod factory)
{
return new CommandLineOptionsModule(name, description, factory);
}
// static
-int CommandLineOptionsModuleInterface::runAsMain(
+int ICommandLineOptionsModule::runAsMain(
int argc, char *argv[], const char *name, const char *description,
FactoryMethod factory)
{
}
// static
-void CommandLineOptionsModuleInterface::registerModule(
+void ICommandLineOptionsModule::registerModule(
CommandLineModuleManager *manager, const char *name,
const char *description, FactoryMethod factory)
{
}
// static
-void CommandLineOptionsModuleInterface::registerModule(
+void ICommandLineOptionsModule::registerModule(
CommandLineModuleManager *manager, const char *name,
- const char *description, CommandLineOptionsModuleInterface *module)
+ const char *description, ICommandLineOptionsModule *module)
{
CommandLineModulePointer wrapperModule(
new CommandLineOptionsModule(name, description, module));
*/
/*! \file
* \brief
- * Declares gmx::CommandLineOptionsModuleInterface and supporting routines.
+ * Declares gmx::ICommandLineOptionsModule and supporting routines.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inpublicapi
namespace gmx
{
-class CommandLineModuleInterface;
+template <typename T> class ConstArrayRef;
+
class CommandLineModuleManager;
+class ICommandLineModule;
+class IOptionsContainer;
class Options;
+/*! \brief
+ * Settings to pass information between a CommandLineOptionsModule and generic
+ * code that runs it.
+ *
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+class ICommandLineOptionsModuleSettings
+{
+ public:
+ /*! \brief
+ * Sets the help text for the module from string array.
+ *
+ * \param[in] help String array to set as the description.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * Formatting for the help text is described on \ref page_onlinehelp.
+ *
+ * Example usage:
+ * \code
+ const char *const desc[] = {
+ "This is the description",
+ "for the options"
+ };
+
+ settings->setHelpText(desc);
+ \endcode
+ */
+ virtual void setHelpText(const ConstArrayRef<const char *> &help) = 0;
+
+ protected:
+ // Disallow deletion through the interface.
+ // (no need for the virtual, but some compilers warn otherwise)
+ virtual ~ICommandLineOptionsModuleSettings();
+};
+
/*! \brief
* Module that can be run from a command line and uses gmx::Options for
* argument processing.
*
* This class provides a higher-level interface on top of
- * gmx::CommandLineModuleInterface for cases where gmx::Options will be used
+ * gmx::ICommandLineModule for cases where gmx::Options will be used
* for declaring the command-line arguments. The module only needs to declare
* the options it uses, and the framework takes care of command-line parsing
* and help output. The module typically consists of the following parts:
* - init() allows for some interaction between the module and the framework
- * when running the module; see CommandLineModuleInterface::init(). If no
+ * when running the module; see ICommandLineModule::init(). If no
* such customization is necessary, an empty implementation is sufficient.
* - initOptions() is called both for running the module and for printing help
* for the module, and it should add the options that the module
* variables.
*
* registerModule(), runAsMain(), or createModule() can be used to use modules
- * of this type in all contexts where a gmx::CommandLineModuleInterface is
- * expected. These methods create a gmx::CommandLineModuleInterface
+ * of this type in all contexts where a gmx::ICommandLineModule is
+ * expected. These methods create a gmx::ICommandLineModule
* implementation that contains the common code needed to parse command-line
* options and write help, based on the information provided from the methods
* in this class.
* \inpublicapi
* \ingroup module_commandline
*/
-class CommandLineOptionsModuleInterface
+class ICommandLineOptionsModule
{
public:
/*! \brief
*
* The caller takes responsibility to `delete` the returned pointer.
*/
- typedef CommandLineOptionsModuleInterface *(*FactoryMethod)();
+ typedef ICommandLineOptionsModule *(*FactoryMethod)();
/*! \brief
- * Creates a CommandLineModuleInterface to run the specified module.
+ * Creates a ICommandLineModule to run the specified module.
*
* \param[in] name Name for the module.
* \param[in] description Short description for the module.
* \param[in] factory Factory that returns the module to run.
- * \returns CommandLineModuleInterface object that runs the module
+ * \returns ICommandLineModule object that runs the module
* returned by \p factory. Caller must `delete` the object.
* \throws std::bad_alloc if out of memory.
*
* This is mainly used by tests that want to bypass
* CommandLineModuleManager.
*/
- static CommandLineModuleInterface *
+ static ICommandLineModule *
createModule(const char *name, const char *description,
FactoryMethod factory);
/*! \brief
* \param[in] factory Factory that returns the module to register.
* \throws std::bad_alloc if out of memory.
*
- * This method internally creates a CommandLineModuleInterface module
+ * This method internally creates a ICommandLineModule module
* with the given \p name and \p description, and adds that to
* \p manager. When run or asked to write the help, the module calls
* \p factory to get the actual module, and forwards the necessary
* The method takes ownership (must have been allocated with `new`).
* \throws std::bad_alloc if out of memory.
*
- * This method internally creates a CommandLineModuleInterface module
+ * This method internally creates a ICommandLineModule module
* with the given \p name and \p description, and adds that to
* \p manager.
*
* This method is mainly used by tests that need to have a reference to
- * the CommandLineOptionsModuleInterface instance (e.g., for mocking).
+ * the ICommandLineOptionsModule instance (e.g., for mocking).
*/
static void
registerModule(CommandLineModuleManager *manager,
const char *name, const char *description,
- CommandLineOptionsModuleInterface *module);
+ ICommandLineOptionsModule *module);
- virtual ~CommandLineOptionsModuleInterface();
+ virtual ~ICommandLineOptionsModule();
- //! \copydoc gmx::CommandLineModuleInterface::init()
+ //! \copydoc gmx::ICommandLineModule::init()
virtual void init(CommandLineModuleSettings *settings) = 0;
/*! \brief
* Initializes command-line arguments understood by the module.
*
* \param[in,out] options Options object to add the options to.
+ * \param[in,out] settings Settings to communicate information
+ * to/from generic code running the module.
*
* When running the module, this method is called after init().
* When printing help, there is no call to init(), and this is the only
* the module to \p options. Output values from options should be
* stored in member variables.
*/
- virtual void initOptions(Options *options) = 0;
+ virtual void initOptions(IOptionsContainer *options,
+ ICommandLineOptionsModuleSettings *settings) = 0;
/*! \brief
* Called after all option values have been set.
*
- * \param[in,out] options Options object in which options are stored.
- *
* When running the module, this method is called after all
- * command-line arguments have been parsed, but while the Options
- * object still exists.
+ * command-line arguments have been parsed.
*
- * If the module needs to call, e.g., Options::isSet(), this is the
- * place to do that.
+ * \todo
+ * Remove if no real need materializes.
*/
- virtual void optionsFinished(Options *options) = 0;
+ virtual void optionsFinished() = 0;
/*! \brief
* Runs the module.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
: assigner_(options), bSkipUnknown_(false)
{
assigner_.setAcceptBooleanNoPrefix(true);
- assigner_.setNoStrictSectioning(true);
}
const char *CommandLineParser::Impl::toOptionName(const char *arg) const
#include <boost/scoped_ptr.hpp>
-#include "thread_mpi/mutex.h"
-
#include "buildinfo.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/mutex.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/stringutil.h"
}
/*! \brief
- * Default implementation for ExecutableEnvironmentInterface.
+ * Default implementation for IExecutableEnvironment.
*
- * Used if ExecutableEnvironmentInterface is not explicitly provided when
+ * Used if IExecutableEnvironment is not explicitly provided when
* constructing CommandLineProgramContext.
*/
-class DefaultExecutableEnvironment : public ExecutableEnvironmentInterface
+class DefaultExecutableEnvironment : public IExecutableEnvironment
{
public:
//! Allocates a default environment.
* If a binary with the given name cannot be located, \p invokedName is
* returned.
*/
-std::string findFullBinaryPath(const std::string &invokedName,
- const ExecutableEnvironmentInterface &env)
+std::string findFullBinaryPath(const std::string &invokedName,
+ const IExecutableEnvironment &env)
{
std::string searchName = invokedName;
// On Windows & Cygwin we need to add the .exe extension,
mutable std::string fullBinaryPath_;
mutable std::string installationPrefix_;
mutable bool bSourceLayout_;
- mutable tMPI::mutex binaryPathMutex_;
+ mutable Mutex binaryPathMutex_;
};
CommandLineProgramContext::Impl::Impl()
const char *CommandLineProgramContext::fullBinaryPath() const
{
- tMPI::lock_guard<tMPI::mutex> lock(impl_->binaryPathMutex_);
+ lock_guard<Mutex> lock(impl_->binaryPathMutex_);
impl_->findBinaryPath();
return impl_->fullBinaryPath_.c_str();
}
InstallationPrefixInfo CommandLineProgramContext::installationPrefix() const
{
- tMPI::lock_guard<tMPI::mutex> lock(impl_->binaryPathMutex_);
+ lock_guard<Mutex> lock(impl_->binaryPathMutex_);
if (impl_->installationPrefix_.empty())
{
impl_->findBinaryPath();
*
* \inlibraryapi
*/
-class ExecutableEnvironmentInterface
+class IExecutableEnvironment
{
public:
- virtual ~ExecutableEnvironmentInterface() {}
+ virtual ~IExecutableEnvironment() {}
/*! \brief
* Returns the working directory when the program was launched.
virtual std::vector<std::string> getExecutablePaths() const = 0;
};
-//! Shorthand for a smart pointer to ExecutableEnvironmentInterface.
-typedef boost::shared_ptr<ExecutableEnvironmentInterface>
+//! Shorthand for a smart pointer to IExecutableEnvironment.
+typedef boost::shared_ptr<IExecutableEnvironment>
ExecutableEnvironmentPointer;
/*! \libinternal \brief
*
* \inlibraryapi
*/
-class CommandLineProgramContext : public ProgramContextInterface
+class CommandLineProgramContext : public IProgramContext
{
public:
/*! \brief
* \param[in] env Customizes the way the binary name is handled.
*
* This overload allows one to customize the way the binary is located
- * by providing a custom ExecutableEnvironmentInterface implementation.
+ * by providing a custom IExecutableEnvironment implementation.
* This is mainly useful for testing purposes to make it possible to
* test different paths without setting environment variables, changing
* the working directory or doing other process-wide operations.
* It may also be useful for making Gromacs behave better when linked
* into a non-Gromacs executable (with possible extensions in
- * ExecutableEnvironmentInterface).
+ * IExecutableEnvironment).
*/
CommandLineProgramContext(int argc, const char *const argv[],
ExecutableEnvironmentPointer env);
try
{
- double tbegin = 0.0, tend = 0.0, tdelta = 0.0;
- bool bView = false;
- int xvgFormat = 0;
+ double tbegin = 0.0, tend = 0.0, tdelta = 0.0;
+ bool bBeginTimeSet = false, bEndTimeSet = false, bDtSet = false;
+ bool bView = false;
+ int xvgFormat = 0;
gmx::TimeUnitManager timeUnitManager;
gmx::OptionsAdapter adapter(*argc, argv);
gmx::Options options(NULL, NULL);
fileOptManager.disableInputOptionChecking(
FF(PCA_NOT_READ_NODE) || FF(PCA_DISABLE_INPUT_FILE_CHECKING));
options.addManager(&fileOptManager);
- options.setDescription(gmx::constArrayRefFromArray<const char *>(desc, ndesc));
if (FF(PCA_CAN_SET_DEFFNM))
{
if (FF(PCA_CAN_BEGIN))
{
options.addOption(
- gmx::DoubleOption("b").store(&tbegin).timeValue()
+ gmx::DoubleOption("b")
+ .store(&tbegin).storeIsSet(&bBeginTimeSet).timeValue()
.description("First frame (%t) to read from trajectory"));
}
if (FF(PCA_CAN_END))
{
options.addOption(
- gmx::DoubleOption("e").store(&tend).timeValue()
+ gmx::DoubleOption("e")
+ .store(&tend).storeIsSet(&bEndTimeSet).timeValue()
.description("Last frame (%t) to read from trajectory"));
}
if (FF(PCA_CAN_DT))
{
options.addOption(
- gmx::DoubleOption("dt").store(&tdelta).timeValue()
+ gmx::DoubleOption("dt")
+ .store(&tdelta).storeIsSet(&bDtSet).timeValue()
.description("Only use frame when t MOD dt = first time (%t)"));
}
if (FF(PCA_TIME_UNIT))
"Help output should be handled higher up and "
"only get called only on the master rank");
gmx::CommandLineHelpWriter(options)
- .setShowDescriptions(true)
+ .setHelpText(gmx::constArrayRefFromArray<const char *>(desc, ndesc))
.setTimeUnitString(timeUnitManager.timeUnitAsString())
.setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs))
.writeHelp(*context);
timeUnitManager.scaleTimeOptions(&options);
/* Extract Time info from arguments */
- // TODO: Use OptionInfo objects instead of string constants
- if (FF(PCA_CAN_BEGIN) && options.isSet("b"))
+ if (bBeginTimeSet)
{
setTimeValue(TBEGIN, tbegin);
}
- if (FF(PCA_CAN_END) && options.isSet("e"))
+ if (bEndTimeSet)
{
setTimeValue(TEND, tend);
}
- if (FF(PCA_CAN_DT) && options.isSet("dt"))
+ if (bDtSet)
{
setTimeValue(TDELTA, tdelta);
}
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
namespace gmx
{
class OptionCompletionWriter : public OptionsVisitor
{
public:
- explicit OptionCompletionWriter(File *out) : out_(*out) {}
+ explicit OptionCompletionWriter(TextWriter *out) : out_(*out) {}
virtual void visitSubSection(const Options §ion)
{
void writeOptionCompletion(const OptionInfo &option,
const std::string &completion);
- File &out_;
+ TextWriter &out_;
};
void OptionCompletionWriter::visitOption(const OptionInfo &option)
return formatString("_%s_%s_compl", binaryName_.c_str(), moduleName);
}
- std::string binaryName_;
- boost::scoped_ptr<File> file_;
+ std::string binaryName_;
+ boost::scoped_ptr<TextWriter> file_;
};
ShellCompletionWriter::ShellCompletionWriter(const std::string &binaryName,
{
}
-File *ShellCompletionWriter::outputFile()
+TextOutputStream &ShellCompletionWriter::outputStream()
{
- return impl_->file_.get();
+ return impl_->file_->stream();
}
void ShellCompletionWriter::startCompletions()
{
- impl_->file_.reset(new File(impl_->binaryName_ + "-completion.bash", "w"));
+ impl_->file_.reset(new TextWriter(impl_->binaryName_ + "-completion.bash"));
}
void ShellCompletionWriter::writeModuleCompletions(
const char *moduleName,
const Options &options)
{
- File &out = *impl_->file_;
+ TextWriter &out = *impl_->file_;
out.writeLine(formatString("%s() {", impl_->completionFunctionName(moduleName).c_str()));
out.writeLine("local IFS=$'\\n'");
out.writeLine("local c=${COMP_WORDS[COMP_CWORD]}");
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
class CommandLineHelpContext;
-class File;
class Options;
+class TextOutputStream;
//! \cond internal
//! \addtogroup module_commandline
ShellCompletionFormat format);
~ShellCompletionWriter();
- File *outputFile();
+ TextOutputStream &outputStream();
void startCompletions();
void writeModuleCompletions(const char *moduleName,
#include "gromacs/commandline/cmdlinemodulemanager.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/textwriter.h"
#include "gromacs/onlinehelp/tests/mock_helptopic.h"
#include "testutils/cmdlinetest.h"
};
CommandLine args(cmdline);
initManager(args, "test");
- redirectManagerOutput();
addModule("module", "First module");
addModule("other", "Second module");
addHelpTopic("topic", "Test topic");
int rc = 0;
ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv()));
ASSERT_EQ(0, rc);
- checkRedirectedOutputFiles();
+ checkRedirectedOutput();
}
TEST_F(CommandLineHelpModuleTest, PrintsHelpOnTopic)
};
CommandLine args(cmdline);
initManager(args, "test");
- redirectManagerOutput();
addModule("module", "First module");
MockHelpTopic &topic = addHelpTopic("topic", "Test topic");
topic.addSubTopic("sub1", "Subtopic 1", "");
int rc = 0;
ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv()));
ASSERT_EQ(0, rc);
- checkRedirectedOutputFiles();
+ checkRedirectedOutput();
}
/*! \brief
*
* \ingroup module_commandline
*/
-void initOptionsBasic(gmx::Options *options)
+void initOptionsBasic(gmx::IOptionsContainer *options,
+ gmx::ICommandLineOptionsModuleSettings *settings)
{
const char *const desc[] = {
"Sample description",
"for testing [THISMODULE]."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(gmx::IntegerOption("int"));
}
"test", "help", "-export", "rst"
};
// TODO: Find a more elegant solution, or get rid of the links.dat altogether.
- gmx::File::writeFileFromString("links.dat", "");
- CommandLine args(cmdline);
+ gmx::TextWriter::writeFileFromString("links.dat", "");
+ CommandLine args(cmdline);
initManager(args, "test");
- redirectManagerOutput();
MockOptionsModule &mod1 = addOptionsModule("module", "First module");
MockOptionsModule &mod2 = addOptionsModule("other", "Second module");
{
MockHelpTopic &topic2 = addHelpTopic("topic2", "Another topic");
using ::testing::_;
using ::testing::Invoke;
- EXPECT_CALL(mod1, initOptions(_)).WillOnce(Invoke(&initOptionsBasic));
- EXPECT_CALL(mod2, initOptions(_));
+ EXPECT_CALL(mod1, initOptions(_, _)).WillOnce(Invoke(&initOptionsBasic));
+ EXPECT_CALL(mod2, initOptions(_, _));
EXPECT_CALL(topic1, writeHelp(_));
EXPECT_CALL(sub1, writeHelp(_));
EXPECT_CALL(sub2, writeHelp(_));
int rc = 0;
ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv()));
ASSERT_EQ(0, rc);
- checkRedirectedOutputFiles();
+ checkRedirectedOutput();
std::remove("links.dat");
}
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
#include "gromacs/options/options.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/stringstream.h"
#include "testutils/stringtest.h"
-#include "testutils/testfilemanager.h"
namespace
{
void checkHelp(gmx::CommandLineHelpWriter *writer);
- gmx::test::TestFileManager tempFiles_;
bool bHidden_;
};
void CommandLineHelpWriterTest::checkHelp(gmx::CommandLineHelpWriter *writer)
{
- std::string filename = tempFiles_.getTemporaryFilePath("helptext.txt");
- gmx::File file(filename, "w");
- gmx::CommandLineHelpContext context(&file, gmx::eHelpOutputFormat_Console,
+ gmx::StringOutputStream stream;
+ gmx::CommandLineHelpContext context(&stream, gmx::eHelpOutputFormat_Console,
NULL, "test");
context.setShowHidden(bHidden_);
writer->writeHelp(context);
- file.close();
+ stream.close();
- checkFileContents(filename, "HelpText");
+ checkText(stream.toString(), "HelpText");
}
#endif
/*
- * Tests help printing for multiple sections.
+ * Tests help output with option groups.
*/
-TEST_F(CommandLineHelpWriterTest, HandlesMultipleSections)
+TEST_F(CommandLineHelpWriterTest, HandlesOptionGroups)
{
- using namespace gmx;
+ using gmx::IntegerOption;
- Options options("test", "Main Title");
- Options subSect1("subsect1", "Subsection 1 Title");
- Options subSect2("subsect2", "Subsection 2 Title");
- Options subSect3("subsect3", NULL);
- options.addSubSection(&subSect1);
- options.addSubSection(&subSect2);
- options.addSubSection(&subSect3);
- options.setDescription("Description for main section.");
- subSect1.setDescription("Description for subsection 1.");
- subSect2.setDescription("Description for subsection 2.");
- subSect3.setDescription("Description for subsection 3.");
- options.addOption(IntegerOption("main")
- .description("Option in main section"));
- subSect1.addOption(IntegerOption("sub1")
- .description("Option in subsection 1"));
- subSect2.addOption(IntegerOption("sub2")
- .description("Option in subsection 2"));
+ gmx::Options options(NULL, NULL);
+ gmx::IOptionsContainer &group1 = options.addGroup();
+ gmx::IOptionsContainer &group2 = options.addGroup();
+ group2.addOption(IntegerOption("sub2").description("Option in group 2"));
+ group1.addOption(IntegerOption("sub11").description("Option in group 1"));
+ options.addOption(IntegerOption("main").description("Option in root group"));
+ group1.addOption(IntegerOption("sub12").description("Option in group 1"));
- CommandLineHelpWriter writer(options);
- writer.setShowDescriptions(true);
+ gmx::CommandLineHelpWriter writer(options);
+ checkHelp(&writer);
+}
+
+/*
+ * Tests help output using a help text.
+ */
+TEST_F(CommandLineHelpWriterTest, HandlesHelpText)
+{
+ const char *const help[] = {
+ "Help text",
+ "for testing."
+ };
+ using gmx::IntegerOption;
+
+ gmx::Options options(NULL, NULL);
+ options.addOption(IntegerOption("int").description("Integer option")
+ .defaultValue(2));
+
+ gmx::CommandLineHelpWriter writer(options);
+ writer.setHelpText(help);
checkHelp(&writer);
}
#include "gromacs/onlinehelp/tests/mock_helptopic.h"
#include "testutils/cmdlinetest.h"
-#include "testutils/testfilemanager.h"
+#include "testutils/testfileredirector.h"
namespace gmx
{
class CommandLineModuleManagerTestBase::Impl
{
public:
+ TestFileOutputRedirector redirector_;
boost::scoped_ptr<CommandLineProgramContext> programContext_;
boost::scoped_ptr<CommandLineModuleManager> manager_;
- TestFileManager fileManager_;
};
CommandLineModuleManagerTestBase::CommandLineModuleManagerTestBase()
impl_->manager_.reset(new gmx::CommandLineModuleManager(
realBinaryName, impl_->programContext_.get()));
impl_->manager_->setQuiet(true);
+ impl_->manager_->setOutputRedirector(&impl_->redirector_);
}
MockModule &
CommandLineModuleManagerTestBase::addOptionsModule(const char *name, const char *description)
{
MockOptionsModule *module = new MockOptionsModule();
- gmx::CommandLineOptionsModuleInterface::registerModule(
+ gmx::ICommandLineOptionsModule::registerModule(
&manager(), name, description, module);
return *module;
}
return *impl_->manager_;
}
-void CommandLineModuleManagerTestBase::redirectManagerOutput()
+void CommandLineModuleManagerTestBase::checkRedirectedOutput()
{
- impl_->manager_->setOutputRedirector(&initOutputRedirector(&impl_->fileManager_));
+ impl_->redirector_.checkRedirectedFiles(&checker());
}
} // namespace test
class CommandLine;
class MockHelpTopic;
+class TestFileOutputRedirector;
/*! \internal \brief
- * Mock implementation of gmx::CommandLineModuleInterface.
+ * Mock implementation of gmx::ICommandLineModule.
*
* \ingroup module_commandline
*/
-class MockModule : public gmx::CommandLineModuleInterface
+class MockModule : public gmx::ICommandLineModule
{
public:
//! Creates a mock module with the given name and description.
};
/*! \internal \brief
- * Mock implementation of gmx::CommandLineOptionsModuleInterface.
+ * Mock implementation of gmx::ICommandLineOptionsModule.
*
* \ingroup module_commandline
*/
-class MockOptionsModule : public gmx::CommandLineOptionsModuleInterface
+class MockOptionsModule : public gmx::ICommandLineOptionsModule
{
public:
MockOptionsModule();
~MockOptionsModule();
MOCK_METHOD1(init, void(gmx::CommandLineModuleSettings *settings));
- MOCK_METHOD1(initOptions, void(gmx::Options *options));
- MOCK_METHOD1(optionsFinished, void(gmx::Options *options));
+ MOCK_METHOD2(initOptions, void(gmx::IOptionsContainer *options, gmx::ICommandLineOptionsModuleSettings *settings));
+ MOCK_METHOD0(optionsFinished, void());
MOCK_METHOD0(run, int());
};
CommandLineModuleManager &manager();
/*! \brief
- * Redirects all manager output to files.
+ * Checks all output from the manager using reference data.
*
- * Can be used to silence tests that would otherwise print out
- * something, and/or checkRedirectedFileContents() from the base class
- * can be used to check the output.
+ * Both output to `stdout` and to files is checked.
*
* The manager is put into quiet mode by default, so the manager will
* only print out information if, e.g., help is explicitly requested.
*/
- void redirectManagerOutput();
+ void checkRedirectedOutput();
private:
class Impl;
namespace
{
-class TestExecutableEnvironment : public gmx::ExecutableEnvironmentInterface
+class TestExecutableEnvironment : public gmx::IExecutableEnvironment
{
public:
TestExecutableEnvironment()
#include <gtest/gtest.h>
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "testutils/cmdlinetest.h"
#include "testutils/testasserts.h"
FileArgumentType type)
{
std::string filename(tempFiles_.getTemporaryFilePath(extension));
- gmx::File::writeFileFromString(filename, "Dummy file");
+ gmx::TextWriter::writeFileFromString(filename, "Dummy file");
if (name != NULL)
{
args_.append(name);
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
<ReferenceData>
- <String Name="fragments/byname.rst"><![CDATA[
-* :doc:`test </onlinehelp/test>` - molecular dynamics simulation suite
-* :doc:`test help </onlinehelp/test-help>` - Print help information
-* :doc:`test module </onlinehelp/test-module>` - First module
-* :doc:`test other </onlinehelp/test-other>` - Second module
-]]></String>
- <String Name="conf-man.py"><![CDATA[
-man_pages = [
- ('onlinehelp/test-help', 'test-help', "Print help information", '', 1),
- ('onlinehelp/test-module', 'test-module', "First module", '', 1),
- ('onlinehelp/test-other', 'test-other', "Second module", '', 1),
- ('onlinehelp/test', 'test', 'molecular dynamics simulation suite', '', 1)
-]
-]]></String>
<String Name="onlinehelp/test-help.rst"><![CDATA[
.. _test help:
:manpage:`test(1)`
More information about |Gromacs| is available at <http://www.gromacs.org/>.
+]]></String>
+ <String Name="fragments/byname.rst"><![CDATA[
+* :doc:`test </onlinehelp/test>` - molecular dynamics simulation suite
+* :doc:`test help </onlinehelp/test-help>` - Print help information
+* :doc:`test module </onlinehelp/test-module>` - First module
+* :doc:`test other </onlinehelp/test-other>` - Second module
+]]></String>
+ <String Name="conf-man.py"><![CDATA[
+man_pages = [
+ ('onlinehelp/test-help', 'test-help', "Print help information", '', 1),
+ ('onlinehelp/test-module', 'test-module', "First module", '', 1),
+ ('onlinehelp/test-other', 'test-other', "Second module", '', 1),
+ ('onlinehelp/test', 'test', 'molecular dynamics simulation suite', '', 1)
+]
]]></String>
<String Name="fragments/bytopic.rst"><![CDATA[
Group 1
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="HelpText"><![CDATA[
+SYNOPSIS
+
+gmx [-int <int>]
+
+DESCRIPTION
+
+Help text for testing.
+
+OPTIONS
+
+Other options:
+
+ -int <int> (2)
+ Integer option
+
+]]></String>
+</ReferenceData>
+++ /dev/null
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
-<ReferenceData>
- <String Name="HelpText"><![CDATA[
-SYNOPSIS
-
-gmx [-sub1 <int>] [-sub2 <int>] [-main <int>]
-
-DESCRIPTION
-
-Description for main section.
-
-Description for subsection 1.
-
-Description for subsection 2.
-
-Description for subsection 3.
-
-OPTIONS
-
-Other options:
-
- -sub1 <int>
- Option in subsection 1
- -sub2 <int>
- Option in subsection 2
- -main <int>
- Option in main section
-
-]]></String>
-</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="HelpText"><![CDATA[
+SYNOPSIS
+
+gmx [-main <int>] [-sub11 <int>] [-sub12 <int>] [-sub2 <int>]
+
+OPTIONS
+
+Other options:
+
+ -main <int>
+ Option in root group
+ -sub11 <int>
+ Option in group 1
+ -sub12 <int>
+ Option in group 1
+ -sub2 <int>
+ Option in group 2
+
+]]></String>
+</ReferenceData>
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014, by the GROMACS development team, led by
+# Copyright (c) 2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-file(GLOB GMXCORRFUNC_SOURCES *.c *.cpp)
+file(GLOB GMXCORRFUNC_SOURCES *.cpp)
file(GLOB LMFIT_SOURCES ${CMAKE_SOURCE_DIR}/src/external/lmfit/*.c)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXCORRFUNC_SOURCES} ${LMFIT_SOURCES} PARENT_SCOPE)
#include "autocorr.h"
-#include <math.h>
#include <stdio.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/correlationfunctions/expfit.h"
#include "gromacs/correlationfunctions/integrate.h"
#include "gromacs/correlationfunctions/manyautocorrelation.h"
int nCos)
{
int i = 0;
- int fftcode;
- real aver, *ans;
- aver = 0.0;
switch (nCos)
{
case enNorm:
for (i = 0; (i < nframes); i++)
{
- aver += c1[i];
cfour[i] = c1[i];
}
break;
gmx_fatal(FARGS, "nCos = %d, %s %d", nCos, __FILE__, __LINE__);
}
- fftcode = many_auto_correl(1, nframes, nfour, &cfour);
+ many_auto_correl(1, nframes, nfour, &cfour);
}
/*! \brief Routine to comput ACF without FFT. */
}
if (bFour)
{
- c0 = log((double)nframes)/log(2.0);
- k = c0;
+ c0 = std::log(static_cast<double>(nframes))/std::log(2.0);
+ k = static_cast<int>(c0);
if (k < c0)
{
k++;
* In this loop the actual correlation functions are computed, but without
* normalizing them.
*/
- k = max(1, pow(10, (int)(log(nitem)/log(100))));
- for (i = 0; i < nitem; i++)
+ for (int i = 0; i < nitem; i++)
{
- if (bVerbose && ((i%k == 0 || i == nitem-1)))
+ if (bVerbose && (((i % 100) == 0) || (i == nitem-1)))
{
fprintf(stderr, "\rThingie %d", i+1);
}
else
{
sum = print_and_integrate(fp, nout, dt, c1[0], NULL, 1);
- if (bVerbose)
- {
- printf("Correlation time (integral over corrfn): %g (ps)\n", sum);
- }
+ }
+ if (bVerbose)
+ {
+ printf("Correlation time (integral over corrfn): %g (ps)\n", sum);
}
}
else
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
nf_int = std::min(ncorr, (int)(tendfit/dt));
sum = print_and_integrate(debug, nf_int, dt, c1, NULL, 1);
- /* Estimate the correlation time for better fitting */
- ct_estimate = 0.5*c1[0];
- for (i = 1; (i < ncorr) && (c1[i] > 0); i++)
- {
- ct_estimate += c1[i];
- }
- ct_estimate *= dt/c1[0];
-
if (bPrint)
{
printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n",
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "manyautocorrelation.h"
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/fft/fft.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/utility/gmxomp.h"
#pragma omp parallel
{
typedef real complex[2];
- int i, t, j, fftcode;
+ int i, j;
gmx_fft_t fft1;
complex *in, *out;
int i0, i1;
// fprintf(stderr, "There are %d threads for correlation functions\n", nthreads);
}
i0 = thread_id*nfunc/nthreads;
- i1 = min(nfunc, (thread_id+1)*nfunc/nthreads);
+ i1 = std::min(nfunc, (thread_id+1)*nfunc/nthreads);
- fftcode = gmx_fft_init_1d(&fft1, nfft, GMX_FFT_FLAG_CONSERVATIVE);
+ gmx_fft_init_1d(&fft1, nfft, GMX_FFT_FLAG_CONSERVATIVE);
/* Allocate temporary arrays */
snew(in, nfft);
snew(out, nfft);
in[j][0] = in[j][1] = 0;
}
- fftcode = gmx_fft_1d(fft1, GMX_FFT_BACKWARD, (void *)in, (void *)out);
+ gmx_fft_1d(fft1, GMX_FFT_BACKWARD, (void *)in, (void *)out);
for (j = 0; j < nfft; j++)
{
in[j][0] = (out[j][0]*out[j][0] + out[j][1]*out[j][1])/nfft;
in[j][0] = in[j][1] = 0;
}
- fftcode = gmx_fft_1d(fft1, GMX_FFT_FORWARD, (void *)in, (void *)out);
+ gmx_fft_1d(fft1, GMX_FFT_FORWARD, (void *)in, (void *)out);
for (j = 0; (j < nfft); j++)
{
c[i][j] = out[j][0]/ndata;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 1991-2003 Erik Lindahl, David van der Spoel, University of Groningen.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* files like fft_fftw3.c or fft_mkl.c for that.
*/
-#ifndef GMX_FFT_FFTW3
+#if !GMX_FFT_FFTW3
struct gmx_many_fft {
int howmany;
FILE* debug = 0;
#endif
-#ifdef GMX_FFT_FFTW3
-#include "thread_mpi/mutex.h"
+#if GMX_FFT_FFTW3
#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/mutex.h"
/* none of the fftw3 calls, except execute(), are thread-safe, so
we need to serialize them with this mutex. */
-static tMPI::mutex big_fftw_mutex;
+static gmx::Mutex big_fftw_mutex;
#define FFTW_LOCK try { big_fftw_mutex.lock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
#define FFTW_UNLOCK try { big_fftw_mutex.unlock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
#endif /* GMX_FFT_FFTW3 */
fprintf(debug, "Running on %d threads\n", nthreads);
}
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
/* Don't add more stuff here! We have already had at least one bug because we are reimplementing
* the low-level FFT interface instead of using the Gromacs FFT module. If we need more
* generic functionality it is far better to extend the interface so we can use it for
}
}
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
}
#endif
if ((flags&FFT5D_ORDER_YZ)) /*plan->cart is in the order of transposes */
int s = 0, tstart, tend, bParallelDim;
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
if (plan->p3d)
{
if (thread == 0)
plan->oNout[s] = 0;
}
}
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
FFTW_LOCK;
#ifdef FFT5D_MPI_TRANSPOS
for (s = 0; s < 2; s++)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#endif
/*currently only special optimization for FFTE*/
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
#include <fftw3.h>
#endif
t_complex *lin;
t_complex *lout, *lout2, *lout3;
gmx_fft_t* p1d[3]; /*1D plans*/
-#ifdef GMX_FFT_FFTW3
+#if GMX_FFT_FFTW3
FFTW(plan) p2d; /*2D plan: used for 1D decomposition if FFT supports transposed output*/
FFTW(plan) p3d; /*3D plan: used for 0D decomposition if FFT supports transposed output*/
FFTW(plan) mpip[2];
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <fftw3.h>
-#include "thread_mpi/mutex.h"
-
#include "gromacs/fft/fft.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/mutex.h"
#ifdef GMX_DOUBLE
#define FFTWPREFIX(name) fftw_ ## name
/* none of the fftw3 calls, except execute(), are thread-safe, so
we need to serialize them with this mutex. */
-static tMPI::mutex big_fftw_mutex;
+static gmx::Mutex big_fftw_mutex;
#define FFTW_LOCK try { big_fftw_mutex.lock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
#define FFTW_UNLOCK try { big_fftw_mutex.unlock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
int i, j, k;
int fftw_flags;
-#ifdef GMX_DISABLE_FFTW_MEASURE
+#if GMX_DISABLE_FFTW_MEASURE
flags |= GMX_FFT_FLAG_CONSERVATIVE;
#endif
int i, j, k;
int fftw_flags;
-#ifdef GMX_DISABLE_FFTW_MEASURE
+#if GMX_DISABLE_FFTW_MEASURE
flags |= GMX_FFT_FLAG_CONSERVATIVE;
#endif
int i, j, k;
int fftw_flags;
-#ifdef GMX_DISABLE_FFTW_MEASURE
+#if GMX_DISABLE_FFTW_MEASURE
flags |= GMX_FFT_FLAG_CONSERVATIVE;
#endif
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
pdbio.h
tpxio.h
trajectory_writing.h
- trnio.h
+ trrio.h
trx.h
trxio.h
xdr_datatype.h
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "confio.h"
-
-#include <errno.h>
-#include <math.h>
-#include <stdio.h>
-
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trx.h"
-#include "gromacs/fileio/trxio.h"
-#include "gromacs/fileio/xdrf.h"
-#include "gromacs/legacyheaders/copyrite.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/pbcutil/pbc.h"
-#include "gromacs/topology/mtop_util.h"
-#include "gromacs/topology/symtab.h"
-#include "gromacs/topology/topology.h"
-#include "gromacs/utility/cstringutil.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-#define CHAR_SHIFT 24
-
-static int read_g96_pos(char line[], t_symtab *symtab,
- FILE *fp, const char *infile,
- t_trxframe *fr)
-{
- t_atoms *atoms;
- gmx_bool bEnd;
- int nwanted, natoms, atnr, resnr = 0, oldres, newres, shift;
- char anm[STRLEN], resnm[STRLEN];
- char c1, c2;
- double db1, db2, db3;
-
- nwanted = fr->natoms;
-
- atoms = fr->atoms;
-
- natoms = 0;
-
- if (fr->bX)
- {
- if (fr->bAtoms)
- {
- shift = CHAR_SHIFT;
- }
- else
- {
- shift = 0;
- }
- newres = -1;
- oldres = -666; /* Unlikely number for the first residue! */
- bEnd = FALSE;
- while (!bEnd && fgets2(line, STRLEN, fp))
- {
- bEnd = (strncmp(line, "END", 3) == 0);
- if (!bEnd && (line[0] != '#'))
- {
- if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
- {
- gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n",
- natoms+1, infile);
- }
- if ((nwanted != -1) && (natoms >= nwanted))
- {
- gmx_fatal(FARGS,
- "Found more coordinates (%d) in %s than expected %d\n",
- natoms, infile, nwanted);
- }
- if (atoms)
- {
- if (fr->bAtoms &&
- (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr)
- != 6))
- {
- if (oldres >= 0)
- {
- resnr = oldres;
- }
- else
- {
- resnr = 1;
- strncpy(resnm, "???", sizeof(resnm)-1);
- }
- strncpy(anm, "???", sizeof(anm)-1);
- }
- atoms->atomname[natoms] = put_symtab(symtab, anm);
- if (resnr != oldres)
- {
- oldres = resnr;
- newres++;
- if (newres >= atoms->nr)
- {
- gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
- infile, atoms->nr);
- }
- atoms->atom[natoms].resind = newres;
- if (newres+1 > atoms->nres)
- {
- atoms->nres = newres+1;
- }
- t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' ');
- }
- else
- {
- atoms->atom[natoms].resind = newres;
- }
- }
- if (fr->x)
- {
- fr->x[natoms][0] = db1;
- fr->x[natoms][1] = db2;
- fr->x[natoms][2] = db3;
- }
- natoms++;
- }
- }
- if ((nwanted != -1) && natoms != nwanted)
- {
- fprintf(stderr,
- "Warning: found less coordinates (%d) in %s than expected %d\n",
- natoms, infile, nwanted);
- }
- }
-
- fr->natoms = natoms;
-
- return natoms;
-}
-
-static int read_g96_vel(char line[], FILE *fp, const char *infile,
- t_trxframe *fr)
-{
- gmx_bool bEnd;
- int nwanted, natoms = -1, shift;
- double db1, db2, db3;
-
- nwanted = fr->natoms;
-
- if (fr->v && fr->bV)
- {
- if (strcmp(line, "VELOCITYRED") == 0)
- {
- shift = 0;
- }
- else
- {
- shift = CHAR_SHIFT;
- }
- natoms = 0;
- bEnd = FALSE;
- while (!bEnd && fgets2(line, STRLEN, fp))
- {
- bEnd = (strncmp(line, "END", 3) == 0);
- if (!bEnd && (line[0] != '#'))
- {
- if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
- {
- gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s",
- natoms+1, infile);
- }
- if ((nwanted != -1) && (natoms >= nwanted))
- {
- gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n",
- natoms, infile, nwanted);
- }
- if (fr->v)
- {
- fr->v[natoms][0] = db1;
- fr->v[natoms][1] = db2;
- fr->v[natoms][2] = db3;
- }
- natoms++;
- }
- }
- if ((nwanted != -1) && (natoms != nwanted))
- {
- fprintf(stderr,
- "Warning: found less velocities (%d) in %s than expected %d\n",
- natoms, infile, nwanted);
- }
- }
-
- return natoms;
-}
-
-int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line)
-{
- t_symtab *symtab = NULL;
- gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished;
- int natoms, nbp;
- double db1, db2, db3, db4, db5, db6, db7, db8, db9;
-
- bAtStart = (ftell(fp) == 0);
-
- clear_trxframe(fr, FALSE);
-
- if (!symtab)
- {
- snew(symtab, 1);
- open_symtab(symtab);
- }
-
- natoms = 0;
-
- if (bAtStart)
- {
- while (!fr->bTitle && fgets2(line, STRLEN, fp))
- {
- fr->bTitle = (strcmp(line, "TITLE") == 0);
- }
- if (fr->title == NULL)
- {
- fgets2(line, STRLEN, fp);
- fr->title = gmx_strdup(line);
- }
- bEnd = FALSE;
- while (!bEnd && fgets2(line, STRLEN, fp))
- {
- bEnd = (strcmp(line, "END") == 0);
- }
- fgets2(line, STRLEN, fp);
- }
-
- /* Do not get a line if we are not at the start of the file, *
- * because without a parameter file we don't know what is in *
- * the trajectory and we have already read the line in the *
- * previous call (VERY DIRTY). */
- bFinished = FALSE;
- do
- {
- bTime = (strcmp(line, "TIMESTEP") == 0);
- bAtoms = (strcmp(line, "POSITION") == 0);
- bPos = (bAtoms || (strcmp(line, "POSITIONRED") == 0));
- bVel = (strncmp(line, "VELOCITY", 8) == 0);
- bBox = (strcmp(line, "BOX") == 0);
- if (bTime)
- {
- if (!fr->bTime && !fr->bX)
- {
- fr->bStep = bTime;
- fr->bTime = bTime;
- do
- {
- bFinished = (fgets2(line, STRLEN, fp) == NULL);
- }
- while (!bFinished && (line[0] == '#'));
- sscanf(line, "%15d%15lf", &(fr->step), &db1);
- fr->time = db1;
- }
- else
- {
- bFinished = TRUE;
- }
- }
- if (bPos)
- {
- if (!fr->bX)
- {
- fr->bAtoms = bAtoms;
- fr->bX = bPos;
- natoms = read_g96_pos(line, symtab, fp, infile, fr);
- }
- else
- {
- bFinished = TRUE;
- }
- }
- if (fr->v && bVel)
- {
- fr->bV = bVel;
- natoms = read_g96_vel(line, fp, infile, fr);
- }
- if (bBox)
- {
- fr->bBox = bBox;
- clear_mat(fr->box);
- bEnd = FALSE;
- while (!bEnd && fgets2(line, STRLEN, fp))
- {
- bEnd = (strncmp(line, "END", 3) == 0);
- if (!bEnd && (line[0] != '#'))
- {
- nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
- &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9);
- if (nbp < 3)
- {
- gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
- }
- fr->box[XX][XX] = db1;
- fr->box[YY][YY] = db2;
- fr->box[ZZ][ZZ] = db3;
- if (nbp == 9)
- {
- fr->box[XX][YY] = db4;
- fr->box[XX][ZZ] = db5;
- fr->box[YY][XX] = db6;
- fr->box[YY][ZZ] = db7;
- fr->box[ZZ][XX] = db8;
- fr->box[ZZ][YY] = db9;
- }
- }
- }
- bFinished = TRUE;
- }
- }
- while (!bFinished && fgets2(line, STRLEN, fp));
-
- free_symtab(symtab);
-
- fr->natoms = natoms;
-
- return natoms;
-}
-
-void write_g96_conf(FILE *out, t_trxframe *fr,
- int nindex, const atom_id *index)
-{
- t_atoms *atoms;
- int nout, i, a;
-
- atoms = fr->atoms;
-
- if (index)
- {
- nout = nindex;
- }
- else
- {
- nout = fr->natoms;
- }
-
- if (fr->bTitle)
- {
- fprintf(out, "TITLE\n%s\nEND\n", fr->title);
- }
- if (fr->bStep || fr->bTime)
- {
- /* Officially the time format is %15.9, which is not enough for 10 ns */
- fprintf(out, "TIMESTEP\n%15d%15.6f\nEND\n", fr->step, fr->time);
- }
- if (fr->bX)
- {
- if (fr->bAtoms)
- {
- fprintf(out, "POSITION\n");
- for (i = 0; i < nout; i++)
- {
- if (index)
- {
- a = index[i];
- }
- else
- {
- a = i;
- }
- fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
- (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
- *atoms->resinfo[atoms->atom[a].resind].name,
- *atoms->atomname[a], (i+1) % 10000000,
- fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
- }
- }
- else
- {
- fprintf(out, "POSITIONRED\n");
- for (i = 0; i < nout; i++)
- {
- if (index)
- {
- a = index[i];
- }
- else
- {
- a = i;
- }
- fprintf(out, "%15.9f%15.9f%15.9f\n",
- fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
- }
- }
- fprintf(out, "END\n");
- }
- if (fr->bV)
- {
- if (fr->bAtoms)
- {
- fprintf(out, "VELOCITY\n");
- for (i = 0; i < nout; i++)
- {
- if (index)
- {
- a = index[i];
- }
- else
- {
- a = i;
- }
- fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
- (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
- *atoms->resinfo[atoms->atom[a].resind].name,
- *atoms->atomname[a], (i+1) % 10000000,
- fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
- }
- }
- else
- {
- fprintf(out, "VELOCITYRED\n");
- for (i = 0; i < nout; i++)
- {
- if (index)
- {
- a = index[i];
- }
- else
- {
- a = i;
- }
- fprintf(out, "%15.9f%15.9f%15.9f\n",
- fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
- }
- }
- fprintf(out, "END\n");
- }
- if (fr->bBox)
- {
- fprintf(out, "BOX\n");
- fprintf(out, "%15.9f%15.9f%15.9f",
- fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]);
- if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
- fr->box[YY][ZZ] || fr->box[ZZ][XX] || fr->box[ZZ][YY])
- {
- fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
- fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX],
- fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
- }
- fprintf(out, "\n");
- fprintf(out, "END\n");
- }
-}
-
-static int get_espresso_word(FILE *fp, char word[])
-{
- int ret, nc, i;
-
- ret = 0;
- nc = 0;
-
- do
- {
- i = fgetc(fp);
- if (i != EOF)
- {
- if (i == ' ' || i == '\n' || i == '\t')
- {
- if (nc > 0)
- {
- ret = 1;
- }
- }
- else if (i == '{')
- {
- if (nc == 0)
- {
- word[nc++] = '{';
- }
- ret = 2;
- }
- else if (i == '}')
- {
- if (nc == 0)
- {
- word[nc++] = '}';
- }
- ret = 3;
- }
- else
- {
- word[nc++] = (char)i;
- }
- }
- }
- while (i != EOF && ret == 0);
-
- word[nc] = '\0';
-
- /* printf("'%s'\n",word); */
-
- return ret;
-}
-
-static int check_open_parenthesis(FILE *fp, int r,
- const char *infile, const char *keyword)
-{
- int level_inc;
- char word[STRLEN];
-
- level_inc = 0;
- if (r == 2)
- {
- level_inc++;
- }
- else
- {
- r = get_espresso_word(fp, word);
- if (r == 2)
- {
- level_inc++;
- }
- else
- {
- gmx_fatal(FARGS, "Expected '{' after '%s' in file '%s'",
- keyword, infile);
- }
- }
-
- return level_inc;
-}
-
-static int check_close_parenthesis(FILE *fp, int r,
- const char *infile, const char *keyword)
-{
- int level_inc;
- char word[STRLEN];
-
- level_inc = 0;
- if (r == 3)
- {
- level_inc--;
- }
- else
- {
- r = get_espresso_word(fp, word);
- if (r == 3)
- {
- level_inc--;
- }
- else
- {
- gmx_fatal(FARGS, "Expected '}' after section '%s' in file '%s'",
- keyword, infile);
- }
- }
-
- return level_inc;
-}
-
-enum {
- espID, espPOS, espTYPE, espQ, espV, espF, espMOLECULE, espNR
-};
-const char *esp_prop[espNR] = {
- "id", "pos", "type", "q", "v", "f",
- "molecule"
-};
-
-static void read_espresso_conf(const char *infile,
- t_atoms *atoms, rvec x[], rvec *v, matrix box)
-{
- t_symtab *symtab = NULL;
- FILE *fp;
- char word[STRLEN], buf[STRLEN];
- int natoms, level, npar, r, nprop, p, i, m, molnr;
- int prop[32];
- double d;
- gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol;
-
- if (!symtab)
- {
- snew(symtab, 1);
- open_symtab(symtab);
- }
-
- clear_mat(box);
-
- fp = gmx_fio_fopen(infile, "r");
-
- bFoundParticles = FALSE;
- bFoundVariable = FALSE;
- bMol = FALSE;
- level = 0;
- while ((r = get_espresso_word(fp, word)))
- {
- if (level == 1 && strcmp(word, "particles") == 0 && !bFoundParticles)
- {
- bFoundParticles = TRUE;
- level += check_open_parenthesis(fp, r, infile, "particles");
- nprop = 0;
- while (level == 2 && (r = get_espresso_word(fp, word)))
- {
- bFoundProp = FALSE;
- for (p = 0; p < espNR; p++)
- {
- if (strcmp(word, esp_prop[p]) == 0)
- {
- bFoundProp = TRUE;
- prop[nprop++] = p;
- /* printf(" prop[%d] = %s\n",nprop-1,esp_prop[prop[nprop-1]]); */
- }
- }
- if (!bFoundProp && word[0] != '}')
- {
- gmx_fatal(FARGS, "Can not read Espresso files with particle property '%s'", word);
- }
- if (bFoundProp && p == espMOLECULE)
- {
- bMol = TRUE;
- }
- if (r == 3)
- {
- level--;
- }
- }
-
- i = 0;
- while (level > 0 && (r = get_espresso_word(fp, word)))
- {
- if (r == 2)
- {
- level++;
- }
- else if (r == 3)
- {
- level--;
- }
- if (level == 2)
- {
- for (p = 0; p < nprop; p++)
- {
- switch (prop[p])
- {
- case espID:
- r = get_espresso_word(fp, word);
- /* Not used */
- break;
- case espPOS:
- for (m = 0; m < 3; m++)
- {
- r = get_espresso_word(fp, word);
- sscanf(word, "%lf", &d);
- x[i][m] = d;
- }
- break;
- case espTYPE:
- r = get_espresso_word(fp, word);
- atoms->atom[i].type = strtol(word, NULL, 10);
- break;
- case espQ:
- r = get_espresso_word(fp, word);
- sscanf(word, "%lf", &d);
- atoms->atom[i].q = d;
- break;
- case espV:
- for (m = 0; m < 3; m++)
- {
- r = get_espresso_word(fp, word);
- sscanf(word, "%lf", &d);
- v[i][m] = d;
- }
- break;
- case espF:
- for (m = 0; m < 3; m++)
- {
- r = get_espresso_word(fp, word);
- /* not used */
- }
- break;
- case espMOLECULE:
- r = get_espresso_word(fp, word);
- molnr = strtol(word, NULL, 10);
- if (i == 0 ||
- atoms->resinfo[atoms->atom[i-1].resind].nr != molnr)
- {
- atoms->atom[i].resind =
- (i == 0 ? 0 : atoms->atom[i-1].resind+1);
- atoms->resinfo[atoms->atom[i].resind].nr = molnr;
- atoms->resinfo[atoms->atom[i].resind].ic = ' ';
- atoms->resinfo[atoms->atom[i].resind].chainid = ' ';
- atoms->resinfo[atoms->atom[i].resind].chainnum = molnr; /* Not sure if this is right? */
- }
- else
- {
- atoms->atom[i].resind = atoms->atom[i-1].resind;
- }
- break;
- }
- }
- /* Generate an atom name from the particle type */
- sprintf(buf, "T%d", atoms->atom[i].type);
- atoms->atomname[i] = put_symtab(symtab, buf);
- if (bMol)
- {
- if (i == 0 || atoms->atom[i].resind != atoms->atom[i-1].resind)
- {
- atoms->resinfo[atoms->atom[i].resind].name =
- put_symtab(symtab, "MOL");
- }
- }
- else
- {
- /* Residue number is the atom number */
- atoms->atom[i].resind = i;
- /* Generate an residue name from the particle type */
- if (atoms->atom[i].type < 26)
- {
- sprintf(buf, "T%c", 'A'+atoms->atom[i].type);
- }
- else
- {
- sprintf(buf, "T%c%c",
- 'A'+atoms->atom[i].type/26, 'A'+atoms->atom[i].type%26);
- }
- t_atoms_set_resinfo(atoms, i, symtab, buf, i, ' ', 0, ' ');
- }
-
- if (r == 3)
- {
- level--;
- }
- i++;
- }
- }
- atoms->nres = atoms->nr;
-
- if (i != atoms->nr)
- {
- gmx_fatal(FARGS, "Internal inconsistency in Espresso routines, read %d atoms, expected %d atoms", i, atoms->nr);
- }
- }
- else if (level == 1 && strcmp(word, "variable") == 0 && !bFoundVariable)
- {
- bFoundVariable = TRUE;
- level += check_open_parenthesis(fp, r, infile, "variable");
- while (level == 2 && (r = get_espresso_word(fp, word)))
- {
- if (level == 2 && strcmp(word, "box_l") == 0)
- {
- for (m = 0; m < 3; m++)
- {
- r = get_espresso_word(fp, word);
- sscanf(word, "%lf", &d);
- box[m][m] = d;
- }
- level += check_close_parenthesis(fp, r, infile, "box_l");
- }
- }
- }
- else if (r == 2)
- {
- level++;
- }
- else if (r == 3)
- {
- level--;
- }
- }
-
- if (!bFoundParticles)
- {
- fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n",
- infile);
- }
-
- gmx_fio_fclose(fp);
-}
-
-static int get_espresso_coordnum(const char *infile)
-{
- FILE *fp;
- char word[STRLEN];
- int natoms, level, r;
- gmx_bool bFoundParticles;
-
- natoms = 0;
-
- fp = gmx_fio_fopen(infile, "r");
-
- bFoundParticles = FALSE;
- level = 0;
- while ((r = get_espresso_word(fp, word)) && !bFoundParticles)
- {
- if (level == 1 && strcmp(word, "particles") == 0 && !bFoundParticles)
- {
- bFoundParticles = TRUE;
- level += check_open_parenthesis(fp, r, infile, "particles");
- while (level > 0 && (r = get_espresso_word(fp, word)))
- {
- if (r == 2)
- {
- level++;
- if (level == 2)
- {
- natoms++;
- }
- }
- else if (r == 3)
- {
- level--;
- }
- }
- }
- else if (r == 2)
- {
- level++;
- }
- else if (r == 3)
- {
- level--;
- }
- }
- if (!bFoundParticles)
- {
- fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n",
- infile);
- }
-
- gmx_fio_fclose(fp);
-
- return natoms;
-}
-
-static void write_espresso_conf_indexed(FILE *out, const char *title,
- t_atoms *atoms, int nx, atom_id *index,
- rvec *x, rvec *v, matrix box)
-{
- int i, j;
-
- fprintf(out, "# %s\n", title);
- if (TRICLINIC(box))
- {
- gmx_warning("The Espresso format does not support triclinic unit-cells");
- }
- fprintf(out, "{variable {box_l %f %f %f}}\n", box[0][0], box[1][1], box[2][2]);
-
- fprintf(out, "{particles {id pos type q%s}\n", v ? " v" : "");
- for (i = 0; i < nx; i++)
- {
- if (index)
- {
- j = index[i];
- }
- else
- {
- j = i;
- }
- fprintf(out, "\t{%d %f %f %f %d %g",
- j, x[j][XX], x[j][YY], x[j][ZZ],
- atoms->atom[j].type, atoms->atom[j].q);
- if (v)
- {
- fprintf(out, " %f %f %f", v[j][XX], v[j][YY], v[j][ZZ]);
- }
- fprintf(out, "}\n");
- }
- fprintf(out, "}\n");
-}
-
-static void get_coordnum_fp (FILE *in, char *title, int *natoms)
-{
- char line[STRLEN+1];
-
- fgets2 (title, STRLEN, in);
- fgets2 (line, STRLEN, in);
- if (sscanf (line, "%d", natoms) != 1)
- {
- gmx_fatal(FARGS, "gro file does not have the number of atoms on the second line");
- }
-}
-
-static void get_coordnum (const char *infile, int *natoms)
-{
- FILE *in;
- char title[STRLEN];
-
- in = gmx_fio_fopen(infile, "r");
- get_coordnum_fp(in, title, natoms);
- gmx_fio_fclose (in);
-}
-
-static gmx_bool get_w_conf(FILE *in, const char *infile, char *title,
- t_symtab *symtab, t_atoms *atoms, int *ndec,
- rvec x[], rvec *v, matrix box)
-{
- char name[6];
- char resname[6], oldresname[6];
- char line[STRLEN+1], *ptr;
- char buf[256];
- double x1, y1, z1, x2, y2, z2;
- rvec xmin, xmax;
- int natoms, i, m, resnr, newres, oldres, ddist, c;
- gmx_bool bFirst, bVel;
- char *p1, *p2, *p3;
-
- newres = -1;
- oldres = NOTSET; /* Unlikely number for the first residue! */
- ddist = 0;
-
- /* Read the title and number of atoms */
- get_coordnum_fp(in, title, &natoms);
-
- if (natoms > atoms->nr)
- {
- gmx_fatal(FARGS, "gro file contains more atoms (%d) than expected (%d)",
- natoms, atoms->nr);
- }
- else if (natoms < atoms->nr)
- {
- fprintf(stderr, "Warning: gro file contains less atoms (%d) than expected"
- " (%d)\n", natoms, atoms->nr);
- }
-
- bFirst = TRUE;
-
- bVel = FALSE;
-
- resname[0] = '\0';
- oldresname[0] = '\0';
-
- /* just pray the arrays are big enough */
- for (i = 0; (i < natoms); i++)
- {
- if ((fgets2 (line, STRLEN, in)) == NULL)
- {
- gmx_fatal(FARGS, "Unexpected end of file in file %s at line %d",
- infile, i+2);
- }
- if (strlen(line) < 39)
- {
- gmx_fatal(FARGS, "Invalid line in %s for atom %d:\n%s", infile, i+1, line);
- }
-
- /* determine read precision from distance between periods
- (decimal points) */
- if (bFirst)
- {
- bFirst = FALSE;
- p1 = strchr(line, '.');
- if (p1 == NULL)
- {
- gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
- }
- p2 = strchr(&p1[1], '.');
- if (p2 == NULL)
- {
- gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
- }
- ddist = p2 - p1;
- *ndec = ddist - 5;
-
- p3 = strchr(&p2[1], '.');
- if (p3 == NULL)
- {
- gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
- }
-
- if (p3 - p2 != ddist)
- {
- gmx_fatal(FARGS, "The spacing of the decimal points in file %s is not consistent for x, y and z", infile);
- }
- }
-
- /* residue number*/
- memcpy(name, line, 5);
- name[5] = '\0';
- sscanf(name, "%d", &resnr);
- sscanf(line+5, "%5s", resname);
-
- if (resnr != oldres || strncmp(resname, oldresname, sizeof(resname)))
- {
- oldres = resnr;
- newres++;
- if (newres >= natoms)
- {
- gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
- infile, natoms);
- }
- atoms->atom[i].resind = newres;
- t_atoms_set_resinfo(atoms, i, symtab, resname, resnr, ' ', 0, ' ');
- }
- else
- {
- atoms->atom[i].resind = newres;
- }
-
- /* atomname */
- memcpy(name, line+10, 5);
- atoms->atomname[i] = put_symtab(symtab, name);
-
- /* Copy resname to oldresname after we are done with the sanity check above */
- strncpy(oldresname, resname, sizeof(oldresname));
-
- /* eventueel controle atomnumber met i+1 */
-
- /* coordinates (start after residue data) */
- ptr = line + 20;
- /* Read fixed format */
- for (m = 0; m < DIM; m++)
- {
- for (c = 0; (c < ddist && ptr[0]); c++)
- {
- buf[c] = ptr[0];
- ptr++;
- }
- buf[c] = '\0';
- if (sscanf (buf, "%lf %lf", &x1, &x2) != 1)
- {
- gmx_fatal(FARGS, "Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)", infile);
- }
- else
- {
- x[i][m] = x1;
- }
- }
-
- /* velocities (start after residues and coordinates) */
- if (v)
- {
- /* Read fixed format */
- for (m = 0; m < DIM; m++)
- {
- for (c = 0; (c < ddist && ptr[0]); c++)
- {
- buf[c] = ptr[0];
- ptr++;
- }
- buf[c] = '\0';
- if (sscanf (buf, "%lf", &x1) != 1)
- {
- v[i][m] = 0;
- }
- else
- {
- v[i][m] = x1;
- bVel = TRUE;
- }
- }
- }
- }
- atoms->nres = newres + 1;
-
- /* box */
- fgets2 (line, STRLEN, in);
- if (sscanf (line, "%lf%lf%lf", &x1, &y1, &z1) != 3)
- {
- gmx_warning("Bad box in file %s", infile);
-
- /* Generate a cubic box */
- for (m = 0; (m < DIM); m++)
- {
- xmin[m] = xmax[m] = x[0][m];
- }
- for (i = 1; (i < atoms->nr); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- xmin[m] = min(xmin[m], x[i][m]);
- xmax[m] = max(xmax[m], x[i][m]);
- }
- }
- for (i = 0; i < DIM; i++)
- {
- for (m = 0; m < DIM; m++)
- {
- box[i][m] = 0.0;
- }
- }
- for (m = 0; (m < DIM); m++)
- {
- box[m][m] = (xmax[m]-xmin[m]);
- }
- fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n",
- box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
- }
- else
- {
- /* We found the first three values, the diagonal elements */
- box[XX][XX] = x1;
- box[YY][YY] = y1;
- box[ZZ][ZZ] = z1;
- if (sscanf (line, "%*f%*f%*f%lf%lf%lf%lf%lf%lf",
- &x1, &y1, &z1, &x2, &y2, &z2) != 6)
- {
- x1 = y1 = z1 = x2 = y2 = z2 = 0.0;
- }
- box[XX][YY] = x1;
- box[XX][ZZ] = y1;
- box[YY][XX] = z1;
- box[YY][ZZ] = x2;
- box[ZZ][XX] = y2;
- box[ZZ][YY] = z2;
- }
-
- return bVel;
-}
-
-static void read_whole_conf(const char *infile, char *title,
- t_atoms *atoms, rvec x[], rvec *v, matrix box)
-{
- FILE *in;
- int ndec;
- t_symtab symtab;
-
- /* open file */
- in = gmx_fio_fopen(infile, "r");
-
- open_symtab(&symtab);
- get_w_conf(in, infile, title, &symtab, atoms, &ndec, x, v, box);
- /* We can't free the symbols, as they are still used in atoms, so
- * the only choice is to leak them. */
- free_symtab(&symtab);
-
- gmx_fio_fclose(in);
-}
-
-static gmx_bool gmx_one_before_eof(FILE *fp)
-{
- char data[4];
- gmx_bool beof;
-
- if ((beof = fread(data, 1, 1, fp)) == 1)
- {
- gmx_fseek(fp, -1, SEEK_CUR);
- }
- return !beof;
-}
-
-gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr)
-{
- t_atoms atoms;
- t_symtab symtab;
- char title[STRLEN], *p;
- double tt;
- int ndec = 0, i;
-
- if (gmx_one_before_eof(status))
- {
- return FALSE;
- }
-
- open_symtab(&symtab);
- atoms.nr = fr->natoms;
- snew(atoms.atom, fr->natoms);
- atoms.nres = fr->natoms;
- snew(atoms.resinfo, fr->natoms);
- snew(atoms.atomname, fr->natoms);
-
- fr->bV = get_w_conf(status, title, title, &symtab, &atoms, &ndec, fr->x, fr->v, fr->box);
- fr->bPrec = TRUE;
- fr->prec = 1;
- /* prec = 10^ndec: */
- for (i = 0; i < ndec; i++)
- {
- fr->prec *= 10;
- }
- fr->title = title;
- fr->bTitle = TRUE;
- fr->bX = TRUE;
- fr->bBox = TRUE;
-
- sfree(atoms.atom);
- sfree(atoms.resinfo);
- sfree(atoms.atomname);
- done_symtab(&symtab);
-
- if ((p = strstr(title, "t=")) != NULL)
- {
- p += 2;
- if (sscanf(p, "%lf", &tt) == 1)
- {
- fr->time = tt;
- fr->bTime = TRUE;
- }
- else
- {
- fr->time = 0;
- fr->bTime = FALSE;
- }
- }
-
- if (atoms.nr != fr->natoms)
- {
- gmx_fatal(FARGS, "Number of atoms in gro frame (%d) doesn't match the number in the previous frame (%d)", atoms.nr, fr->natoms);
- }
-
- return TRUE;
-}
-
-int gro_first_x_or_v(FILE *status, t_trxframe *fr)
-{
- char title[STRLEN];
-
- frewind(status);
- fprintf(stderr, "Reading frames from gro file");
- get_coordnum_fp(status, title, &fr->natoms);
- frewind(status);
- fprintf(stderr, " '%s', %d atoms.\n", title, fr->natoms);
- fr->bTitle = TRUE;
- fr->title = title;
- if (fr->natoms == 0)
- {
- gmx_file("No coordinates in gro file");
- }
-
- snew(fr->x, fr->natoms);
- snew(fr->v, fr->natoms);
- gro_next_x_or_v(status, fr);
-
- return fr->natoms;
-}
-
-static void make_hconf_format(int pr, gmx_bool bVel, char format[])
-{
- int l, vpr;
-
- /* build format string for printing,
- something like "%8.3f" for x and "%8.4f" for v */
- if (pr < 0)
- {
- pr = 0;
- }
- if (pr > 30)
- {
- pr = 30;
- }
- l = pr+5;
- vpr = pr+1;
- if (bVel)
- {
- sprintf(format, "%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
- l, pr, l, pr, l, pr, l, vpr, l, vpr, l, vpr);
- }
- else
- {
- sprintf(format, "%%%d.%df%%%d.%df%%%d.%df\n", l, pr, l, pr, l, pr);
- }
-
-}
-
-static void write_hconf_box(FILE *out, int pr, matrix box)
-{
- char format[100];
- int l;
-
- if (pr < 5)
- {
- pr = 5;
- }
- l = pr+5;
-
- if (box[XX][YY] || box[XX][ZZ] || box[YY][XX] || box[YY][ZZ] ||
- box[ZZ][XX] || box[ZZ][YY])
- {
- sprintf(format, "%%%d.%df%%%d.%df%%%d.%df"
- "%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
- l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr);
- fprintf(out, format,
- box[XX][XX], box[YY][YY], box[ZZ][ZZ],
- box[XX][YY], box[XX][ZZ], box[YY][XX],
- box[YY][ZZ], box[ZZ][XX], box[ZZ][YY]);
- }
- else
- {
- sprintf(format, "%%%d.%df%%%d.%df%%%d.%df\n", l, pr, l, pr, l, pr);
- fprintf(out, format,
- box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
- }
-}
-
-void write_hconf_indexed_p(FILE *out, const char *title, t_atoms *atoms,
- int nx, const atom_id index[], int pr,
- rvec *x, rvec *v, matrix box)
-{
- char resnm[6], nm[6], format[100];
- int ai, i, resind, resnr;
-
- bromacs(format, 99);
- fprintf (out, "%s\n", (title && title[0]) ? title : format);
- fprintf (out, "%5d\n", nx);
-
- make_hconf_format(pr, v != NULL, format);
-
- for (i = 0; (i < nx); i++)
- {
- ai = index[i];
-
- resind = atoms->atom[ai].resind;
- strncpy(resnm, " ??? ", sizeof(resnm)-1);
- if (resind < atoms->nres)
- {
- strncpy(resnm, *atoms->resinfo[resind].name, sizeof(resnm)-1);
- resnr = atoms->resinfo[resind].nr;
- }
- else
- {
- strncpy(resnm, " ??? ", sizeof(resnm)-1);
- resnr = resind + 1;
- }
-
- if (atoms->atom)
- {
- strncpy(nm, *atoms->atomname[ai], sizeof(nm)-1);
- }
- else
- {
- strncpy(nm, " ??? ", sizeof(nm)-1);
- }
-
- fprintf(out, "%5d%-5.5s%5.5s%5d", resnr%100000, resnm, nm, (ai+1)%100000);
- /* next fprintf uses built format string */
- if (v)
- {
- fprintf(out, format,
- x[ai][XX], x[ai][YY], x[ai][ZZ], v[ai][XX], v[ai][YY], v[ai][ZZ]);
- }
- else
- {
- fprintf(out, format,
- x[ai][XX], x[ai][YY], x[ai][ZZ]);
- }
- }
-
- write_hconf_box(out, pr, box);
-
- fflush(out);
-}
-
-static void write_hconf_mtop(FILE *out, const char *title, gmx_mtop_t *mtop,
- int pr,
- rvec *x, rvec *v, matrix box)
-{
- char format[100];
- int i, resnr;
- gmx_mtop_atomloop_all_t aloop;
- t_atom *atom;
- char *atomname, *resname;
-
- bromacs(format, 99);
- fprintf (out, "%s\n", (title && title[0]) ? title : format);
- fprintf (out, "%5d\n", mtop->natoms);
-
- make_hconf_format(pr, v != NULL, format);
-
- aloop = gmx_mtop_atomloop_all_init(mtop);
- while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
- {
- gmx_mtop_atomloop_all_names(aloop, &atomname, &resnr, &resname);
-
- fprintf(out, "%5d%-5.5s%5.5s%5d",
- resnr%100000, resname, atomname, (i+1)%100000);
- /* next fprintf uses built format string */
- if (v)
- {
- fprintf(out, format,
- x[i][XX], x[i][YY], x[i][ZZ], v[i][XX], v[i][YY], v[i][ZZ]);
- }
- else
- {
- fprintf(out, format,
- x[i][XX], x[i][YY], x[i][ZZ]);
- }
- }
-
- write_hconf_box(out, pr, box);
-
- fflush(out);
-}
-
-void write_hconf_p(FILE *out, const char *title, t_atoms *atoms, int pr,
- rvec *x, rvec *v, matrix box)
-{
- atom_id *aa;
- int i;
-
- snew(aa, atoms->nr);
- for (i = 0; (i < atoms->nr); i++)
- {
- aa[i] = i;
- }
- write_hconf_indexed_p(out, title, atoms, atoms->nr, aa, pr, x, v, box);
- sfree(aa);
-}
-
-void write_conf_p(const char *outfile, const char *title,
- t_atoms *atoms, int pr,
- rvec *x, rvec *v, matrix box)
-{
- FILE *out;
-
- out = gmx_fio_fopen(outfile, "w");
- write_hconf_p(out, title, atoms, pr, x, v, box);
-
- gmx_fio_fclose (out);
-}
-
-static void write_conf(const char *outfile, const char *title, t_atoms *atoms,
- rvec *x, rvec *v, matrix box)
-{
- write_conf_p(outfile, title, atoms, 3, x, v, box);
-}
-
-void write_sto_conf_indexed(const char *outfile, const char *title,
- t_atoms *atoms,
- rvec x[], rvec *v, int ePBC, matrix box,
- atom_id nindex, atom_id index[])
-{
- FILE *out;
- int ftp;
- t_trxframe fr;
-
- ftp = fn2ftp(outfile);
- switch (ftp)
- {
- case efGRO:
- out = gmx_fio_fopen(outfile, "w");
- write_hconf_indexed_p(out, title, atoms, nindex, index, 3, x, v, box);
- gmx_fio_fclose(out);
- break;
- case efG96:
- clear_trxframe(&fr, TRUE);
- fr.bTitle = TRUE;
- fr.title = title;
- fr.natoms = atoms->nr;
- fr.bAtoms = TRUE;
- fr.atoms = atoms;
- fr.bX = TRUE;
- fr.x = x;
- if (v)
- {
- fr.bV = TRUE;
- fr.v = v;
- }
- fr.bBox = TRUE;
- copy_mat(box, fr.box);
- out = gmx_fio_fopen(outfile, "w");
- write_g96_conf(out, &fr, nindex, index);
- gmx_fio_fclose(out);
- break;
- case efPDB:
- case efBRK:
- case efENT:
- case efPQR:
- out = gmx_fio_fopen(outfile, "w");
- write_pdbfile_indexed(out, title, atoms, x, ePBC, box, ' ', -1, nindex, index, NULL, TRUE);
- gmx_fio_fclose(out);
- break;
- case efESP:
- out = gmx_fio_fopen(outfile, "w");
- write_espresso_conf_indexed(out, title, atoms, nindex, index, x, v, box);
- gmx_fio_fclose(out);
- break;
- case efTPR:
- gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile);
- break;
- default:
- gmx_incons("Not supported in write_sto_conf_indexed");
- }
-}
-
-void write_sto_conf(const char *outfile, const char *title, t_atoms *atoms,
- rvec x[], rvec *v, int ePBC, matrix box)
-{
- FILE *out;
- int ftp;
- t_trxframe fr;
-
- ftp = fn2ftp(outfile);
- switch (ftp)
- {
- case efGRO:
- write_conf(outfile, title, atoms, x, v, box);
- break;
- case efG96:
- clear_trxframe(&fr, TRUE);
- fr.bTitle = TRUE;
- fr.title = title;
- fr.natoms = atoms->nr;
- fr.bAtoms = TRUE;
- fr.atoms = atoms;
- fr.bX = TRUE;
- fr.x = x;
- if (v)
- {
- fr.bV = TRUE;
- fr.v = v;
- }
- fr.bBox = TRUE;
- copy_mat(box, fr.box);
- out = gmx_fio_fopen(outfile, "w");
- write_g96_conf(out, &fr, -1, NULL);
- gmx_fio_fclose(out);
- break;
- case efPDB:
- case efBRK:
- case efENT:
- out = gmx_fio_fopen(outfile, "w");
- write_pdbfile(out, title, atoms, x, ePBC, box, ' ', -1, NULL, TRUE);
- gmx_fio_fclose(out);
- break;
- case efESP:
- out = gmx_fio_fopen(outfile, "w");
- write_espresso_conf_indexed(out, title, atoms, atoms->nr, NULL, x, v, box);
- gmx_fio_fclose(out);
- break;
- case efTPR:
- gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile);
- break;
- default:
- gmx_incons("Not supported in write_sto_conf");
- }
-}
-
-void write_sto_conf_mtop(const char *outfile, const char *title,
- gmx_mtop_t *mtop,
- rvec x[], rvec *v, int ePBC, matrix box)
-{
- int ftp;
- FILE *out;
- t_atoms atoms;
-
- ftp = fn2ftp(outfile);
- switch (ftp)
- {
- case efGRO:
- out = gmx_fio_fopen(outfile, "w");
- write_hconf_mtop(out, title, mtop, 3, x, v, box);
- gmx_fio_fclose(out);
- break;
- default:
- /* This is a brute force approach which requires a lot of memory.
- * We should implement mtop versions of all writing routines.
- */
- atoms = gmx_mtop_global_atoms(mtop);
-
- write_sto_conf(outfile, title, &atoms, x, v, ePBC, box);
-
- done_atom(&atoms);
- break;
- }
-}
-
-void get_stx_coordnum(const char *infile, int *natoms)
-{
- FILE *in;
- int ftp, tpxver, tpxgen;
- t_trxframe fr;
- char g96_line[STRLEN+1];
-
- ftp = fn2ftp(infile);
- range_check(ftp, 0, efNR);
- switch (ftp)
- {
- case efGRO:
- get_coordnum(infile, natoms);
- break;
- case efG96:
- in = gmx_fio_fopen(infile, "r");
- fr.title = NULL;
- fr.natoms = -1;
- fr.atoms = NULL;
- fr.x = NULL;
- fr.v = NULL;
- fr.f = NULL;
- *natoms = read_g96_conf(in, infile, &fr, g96_line);
- gmx_fio_fclose(in);
- break;
- case efPDB:
- case efBRK:
- case efENT:
- in = gmx_fio_fopen(infile, "r");
- get_pdb_coordnum(in, natoms);
- gmx_fio_fclose(in);
- break;
- case efESP:
- *natoms = get_espresso_coordnum(infile);
- break;
- case efTPR:
- {
- t_tpxheader tpx;
-
- read_tpxheader(infile, &tpx, TRUE, &tpxver, &tpxgen);
- *natoms = tpx.natoms;
- break;
- }
- default:
- gmx_fatal(FARGS, "File type %s not supported in get_stx_coordnum",
- ftp2ext(ftp));
- }
-}
-
-void read_stx_conf(const char *infile, char *title, t_atoms *atoms,
- rvec x[], rvec *v, int *ePBC, matrix box)
-{
- FILE *in;
- char buf[256];
- gmx_mtop_t *mtop;
- t_topology top;
- t_trxframe fr;
- int i, ftp, natoms;
- real d;
- char g96_line[STRLEN+1];
-
- if (atoms->nr == 0)
- {
- fprintf(stderr, "Warning: Number of atoms in %s is 0\n", infile);
- }
- else if (atoms->atom == NULL)
- {
- gmx_mem("Uninitialized array atom");
- }
-
- if (ePBC)
- {
- *ePBC = -1;
- }
-
- ftp = fn2ftp(infile);
- switch (ftp)
- {
- case efGRO:
- read_whole_conf(infile, title, atoms, x, v, box);
- break;
- case efG96:
- fr.title = NULL;
- fr.natoms = atoms->nr;
- fr.atoms = atoms;
- fr.x = x;
- fr.v = v;
- fr.f = NULL;
- in = gmx_fio_fopen(infile, "r");
- read_g96_conf(in, infile, &fr, g96_line);
- gmx_fio_fclose(in);
- copy_mat(fr.box, box);
- strncpy(title, fr.title, STRLEN);
- break;
- case efPDB:
- case efBRK:
- case efENT:
- read_pdb_conf(infile, title, atoms, x, ePBC, box, TRUE, NULL);
- break;
- case efESP:
- read_espresso_conf(infile, atoms, x, v, box);
- break;
- case efTPR:
- snew(mtop, 1);
- i = read_tpx(infile, NULL, box, &natoms, x, v, NULL, mtop);
- if (ePBC)
- {
- *ePBC = i;
- }
-
- strcpy(title, *(mtop->name));
-
- /* Free possibly allocated memory */
- done_atom(atoms);
-
- *atoms = gmx_mtop_global_atoms(mtop);
- top = gmx_mtop_t_to_t_topology(mtop);
- tpx_make_chain_identifiers(atoms, &top.mols);
-
- sfree(mtop);
- /* The strings in the symtab are still in use in the returned t_atoms
- * structure, so we should not free them. But there is no place to put the
- * symbols; the only choice is to leak the memory...
- * So we clear the symbol table before freeing the topology structure. */
- free_symtab(&top.symtab);
- done_top(&top);
-
- break;
- default:
- gmx_incons("Not supported in read_stx_conf");
- }
-}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "confio.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include "gromacs/fileio/espio.h"
+#include "gromacs/fileio/filenm.h"
+#include "gromacs/fileio/g96io.h"
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/groio.h"
+#include "gromacs/fileio/pdbio.h"
+#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/trx.h"
+#include "gromacs/fileio/trxio.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/topology/atomprop.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/block.h"
+#include "gromacs/topology/mtop_util.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/topology/topology.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/smalloc.h"
+
+void write_sto_conf_indexed(const char *outfile, const char *title,
+ t_atoms *atoms,
+ rvec x[], rvec *v, int ePBC, matrix box,
+ atom_id nindex, atom_id index[])
+{
+ FILE *out;
+ int ftp;
+ t_trxframe fr;
+
+ ftp = fn2ftp(outfile);
+ switch (ftp)
+ {
+ case efGRO:
+ out = gmx_fio_fopen(outfile, "w");
+ write_hconf_indexed_p(out, title, atoms, nindex, index, 3, x, v, box);
+ gmx_fio_fclose(out);
+ break;
+ case efG96:
+ clear_trxframe(&fr, TRUE);
+ fr.bTitle = TRUE;
+ fr.title = title;
+ fr.natoms = atoms->nr;
+ fr.bAtoms = TRUE;
+ fr.atoms = atoms;
+ fr.bX = TRUE;
+ fr.x = x;
+ if (v)
+ {
+ fr.bV = TRUE;
+ fr.v = v;
+ }
+ fr.bBox = TRUE;
+ copy_mat(box, fr.box);
+ out = gmx_fio_fopen(outfile, "w");
+ write_g96_conf(out, &fr, nindex, index);
+ gmx_fio_fclose(out);
+ break;
+ case efPDB:
+ case efBRK:
+ case efENT:
+ case efPQR:
+ out = gmx_fio_fopen(outfile, "w");
+ write_pdbfile_indexed(out, title, atoms, x, ePBC, box, ' ', -1, nindex, index, NULL, TRUE);
+ gmx_fio_fclose(out);
+ break;
+ case efESP:
+ out = gmx_fio_fopen(outfile, "w");
+ write_espresso_conf_indexed(out, title, atoms, nindex, index, x, v, box);
+ gmx_fio_fclose(out);
+ break;
+ case efTPR:
+ gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile);
+ break;
+ default:
+ gmx_incons("Not supported in write_sto_conf_indexed");
+ }
+}
+
+void write_sto_conf(const char *outfile, const char *title, t_atoms *atoms,
+ rvec x[], rvec *v, int ePBC, matrix box)
+{
+ FILE *out;
+ int ftp;
+ t_trxframe fr;
+
+ ftp = fn2ftp(outfile);
+ switch (ftp)
+ {
+ case efGRO:
+ write_conf_p(outfile, title, atoms, 3, x, v, box);
+ break;
+ case efG96:
+ clear_trxframe(&fr, TRUE);
+ fr.bTitle = TRUE;
+ fr.title = title;
+ fr.natoms = atoms->nr;
+ fr.bAtoms = TRUE;
+ fr.atoms = atoms;
+ fr.bX = TRUE;
+ fr.x = x;
+ if (v)
+ {
+ fr.bV = TRUE;
+ fr.v = v;
+ }
+ fr.bBox = TRUE;
+ copy_mat(box, fr.box);
+ out = gmx_fio_fopen(outfile, "w");
+ write_g96_conf(out, &fr, -1, NULL);
+ gmx_fio_fclose(out);
+ break;
+ case efPDB:
+ case efBRK:
+ case efENT:
+ out = gmx_fio_fopen(outfile, "w");
+ write_pdbfile(out, title, atoms, x, ePBC, box, ' ', -1, NULL, TRUE);
+ gmx_fio_fclose(out);
+ break;
+ case efESP:
+ out = gmx_fio_fopen(outfile, "w");
+ write_espresso_conf_indexed(out, title, atoms, atoms->nr, NULL, x, v, box);
+ gmx_fio_fclose(out);
+ break;
+ case efTPR:
+ gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile);
+ break;
+ default:
+ gmx_incons("Not supported in write_sto_conf");
+ }
+}
+
+void write_sto_conf_mtop(const char *outfile, const char *title,
+ gmx_mtop_t *mtop,
+ rvec x[], rvec *v, int ePBC, matrix box)
+{
+ int ftp;
+ FILE *out;
+ t_atoms atoms;
+
+ ftp = fn2ftp(outfile);
+ switch (ftp)
+ {
+ case efGRO:
+ out = gmx_fio_fopen(outfile, "w");
+ write_hconf_mtop(out, title, mtop, 3, x, v, box);
+ gmx_fio_fclose(out);
+ break;
+ default:
+ /* This is a brute force approach which requires a lot of memory.
+ * We should implement mtop versions of all writing routines.
+ */
+ atoms = gmx_mtop_global_atoms(mtop);
+
+ write_sto_conf(outfile, title, &atoms, x, v, ePBC, box);
+
+ done_atom(&atoms);
+ break;
+ }
+}
+
+void get_stx_coordnum(const char *infile, int *natoms)
+{
+ FILE *in;
+ int ftp, tpxver, tpxgen;
+ t_trxframe fr;
+ char g96_line[STRLEN+1];
+
+ ftp = fn2ftp(infile);
+ range_check(ftp, 0, efNR);
+ switch (ftp)
+ {
+ case efGRO:
+ get_coordnum(infile, natoms);
+ break;
+ case efG96:
+ in = gmx_fio_fopen(infile, "r");
+ fr.title = NULL;
+ fr.natoms = -1;
+ fr.atoms = NULL;
+ fr.x = NULL;
+ fr.v = NULL;
+ fr.f = NULL;
+ *natoms = read_g96_conf(in, infile, &fr, g96_line);
+ gmx_fio_fclose(in);
+ break;
+ case efPDB:
+ case efBRK:
+ case efENT:
+ in = gmx_fio_fopen(infile, "r");
+ get_pdb_coordnum(in, natoms);
+ gmx_fio_fclose(in);
+ break;
+ case efESP:
+ *natoms = get_espresso_coordnum(infile);
+ break;
+ case efTPR:
+ {
+ t_tpxheader tpx;
+
+ read_tpxheader(infile, &tpx, TRUE, &tpxver, &tpxgen);
+ *natoms = tpx.natoms;
+ break;
+ }
+ default:
+ gmx_fatal(FARGS, "File type %s not supported in get_stx_coordnum",
+ ftp2ext(ftp));
+ }
+}
+
+static void tpx_make_chain_identifiers(t_atoms *atoms, t_block *mols)
+{
+ int m, a, a0, a1, r;
+ char c, chainid;
+ int chainnum;
+
+ /* We always assign a new chain number, but save the chain id characters
+ * for larger molecules.
+ */
+#define CHAIN_MIN_ATOMS 15
+
+ chainnum = 0;
+ chainid = 'A';
+ for (m = 0; m < mols->nr; m++)
+ {
+ a0 = mols->index[m];
+ a1 = mols->index[m+1];
+ if ((a1-a0 >= CHAIN_MIN_ATOMS) && (chainid <= 'Z'))
+ {
+ c = chainid;
+ chainid++;
+ }
+ else
+ {
+ c = ' ';
+ }
+ for (a = a0; a < a1; a++)
+ {
+ atoms->resinfo[atoms->atom[a].resind].chainnum = chainnum;
+ atoms->resinfo[atoms->atom[a].resind].chainid = c;
+ }
+ chainnum++;
+ }
+
+ /* Blank out the chain id if there was only one chain */
+ if (chainid == 'B')
+ {
+ for (r = 0; r < atoms->nres; r++)
+ {
+ atoms->resinfo[r].chainid = ' ';
+ }
+ }
+}
+
+void read_stx_conf(const char *infile, char *title, t_atoms *atoms,
+ rvec x[], rvec *v, int *ePBC, matrix box)
+{
+ FILE *in;
+ gmx_mtop_t *mtop;
+ t_topology top;
+ t_trxframe fr;
+ int i, ftp, natoms;
+ char g96_line[STRLEN+1];
+
+ if (atoms->nr == 0)
+ {
+ fprintf(stderr, "Warning: Number of atoms in %s is 0\n", infile);
+ }
+ else if (atoms->atom == NULL)
+ {
+ gmx_mem("Uninitialized array atom");
+ }
+
+ if (ePBC)
+ {
+ *ePBC = -1;
+ }
+
+ ftp = fn2ftp(infile);
+ switch (ftp)
+ {
+ case efGRO:
+ read_whole_conf(infile, title, atoms, x, v, box);
+ break;
+ case efG96:
+ fr.title = NULL;
+ fr.natoms = atoms->nr;
+ fr.atoms = atoms;
+ fr.x = x;
+ fr.v = v;
+ fr.f = NULL;
+ in = gmx_fio_fopen(infile, "r");
+ read_g96_conf(in, infile, &fr, g96_line);
+ gmx_fio_fclose(in);
+ copy_mat(fr.box, box);
+ std::strncpy(title, fr.title, STRLEN);
+ break;
+ case efPDB:
+ case efBRK:
+ case efENT:
+ read_pdb_conf(infile, title, atoms, x, ePBC, box, TRUE, NULL);
+ break;
+ case efESP:
+ read_espresso_conf(infile, title, atoms, x, v, box);
+ break;
+ case efTPR:
+ snew(mtop, 1);
+ i = read_tpx(infile, NULL, box, &natoms, x, v, NULL, mtop);
+ if (ePBC)
+ {
+ *ePBC = i;
+ }
+
+ strcpy(title, *(mtop->name));
+
+ /* Free possibly allocated memory */
+ done_atom(atoms);
+
+ *atoms = gmx_mtop_global_atoms(mtop);
+ top = gmx_mtop_t_to_t_topology(mtop);
+ tpx_make_chain_identifiers(atoms, &top.mols);
+
+ sfree(mtop);
+ /* The strings in the symtab are still in use in the returned t_atoms
+ * structure, so we should not free them. But there is no place to put the
+ * symbols; the only choice is to leak the memory...
+ * So we clear the symbol table before freeing the topology structure. */
+ free_symtab(&top.symtab);
+ done_top(&top);
+
+ break;
+ default:
+ gmx_incons("Not supported in read_stx_conf");
+ }
+}
+
+static void done_gmx_groups_t(gmx_groups_t *g)
+{
+ int i;
+
+ for (i = 0; (i < egcNR); i++)
+ {
+ if (NULL != g->grps[i].nm_ind)
+ {
+ sfree(g->grps[i].nm_ind);
+ g->grps[i].nm_ind = NULL;
+ }
+ if (NULL != g->grpnr[i])
+ {
+ sfree(g->grpnr[i]);
+ g->grpnr[i] = NULL;
+ }
+ }
+ /* The contents of this array is in symtab, don't free it here */
+ sfree(g->grpname);
+}
+
+gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *ePBC,
+ rvec **x, rvec **v, matrix box, gmx_bool bMass)
+{
+ t_tpxheader header;
+ int natoms, i, version, generation;
+ gmx_bool bTop, bXNULL = FALSE;
+ gmx_mtop_t *mtop;
+ gmx_atomprop_t aps;
+
+ bTop = fn2bTPX(infile);
+ *ePBC = -1;
+ if (bTop)
+ {
+ read_tpxheader(infile, &header, TRUE, &version, &generation);
+ if (x)
+ {
+ snew(*x, header.natoms);
+ }
+ if (v)
+ {
+ snew(*v, header.natoms);
+ }
+ snew(mtop, 1);
+ *ePBC = read_tpx(infile, NULL, box, &natoms,
+ (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, NULL, mtop);
+ *top = gmx_mtop_t_to_t_topology(mtop);
+ /* In this case we need to throw away the group data too */
+ done_gmx_groups_t(&mtop->groups);
+ sfree(mtop);
+ std::strcpy(title, *top->name);
+ tpx_make_chain_identifiers(&top->atoms, &top->mols);
+ }
+ else
+ {
+ get_stx_coordnum(infile, &natoms);
+ init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB));
+ if (x == NULL)
+ {
+ snew(x, 1);
+ bXNULL = TRUE;
+ }
+ snew(*x, natoms);
+ if (v)
+ {
+ snew(*v, natoms);
+ }
+ read_stx_conf(infile, title, &top->atoms, *x, (v == NULL) ? NULL : *v, ePBC, box);
+ if (bXNULL)
+ {
+ sfree(*x);
+ sfree(x);
+ }
+ if (bMass)
+ {
+ aps = gmx_atomprop_init();
+ for (i = 0; (i < natoms); i++)
+ {
+ if (!gmx_atomprop_query(aps, epropMass,
+ *top->atoms.resinfo[top->atoms.atom[i].resind].name,
+ *top->atoms.atomname[i],
+ &(top->atoms.atom[i].m)))
+ {
+ if (debug)
+ {
+ fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n",
+ *top->atoms.resinfo[top->atoms.atom[i].resind].name,
+ top->atoms.resinfo[top->atoms.atom[i].resind].nr,
+ *top->atoms.atomname[i]);
+ }
+ }
+ }
+ gmx_atomprop_destroy(aps);
+ }
+ top->idef.ntypes = -1;
+ }
+
+ return bTop;
+}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
#ifndef GMX_FILEIO_CONFIO_H
#define GMX_FILEIO_CONFIO_H
#include <stdio.h>
-#include "gromacs/fileio/trx.h"
#include "gromacs/legacyheaders/types/simple.h"
/* For reading coordinate files it is assumed that enough memory
struct gmx_mtop_t;
struct t_atoms;
-
-int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line);
-/* read a Gromos96 coordinate or trajectory file, *
- * returns the number of atoms *
- * sets what's in the frame in info *
- * read from fp, infile is only needed for error messages *
- * nwanted is the number of wanted coordinates, *
- * set this to -1 if you want to know the number of atoms in the file *
- * title, atoms, x, v can all be NULL, in which case they won't be read *
- * line holds the previous line for trajectory reading */
-
-void write_g96_conf(FILE *out, t_trxframe *fr, int nindex, const atom_id *index);
-/* write a Gromos96 coordinate file or trajectory frame *
- * index can be NULL */
-
-gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr);
-int gro_first_x_or_v(FILE *status, t_trxframe *fr);
-/* read first/next x and/or v frame from gro file */
-
-void write_hconf_indexed_p(FILE *out, const char *title, struct t_atoms *atoms,
- int nx, const atom_id index[], int ndec,
- rvec *x, rvec *v, matrix box);
-
-void write_hconf_p(FILE *out, const char *title, struct t_atoms *atoms, int ndec,
- rvec *x, rvec *v, matrix box);
-/* Write a Gromos file with precision ndec: number of decimal places in x,
- * v has one place more. */
+struct t_topology;
void write_sto_conf_indexed(const char *outfile, const char *title,
struct t_atoms *atoms,
* If ePBC!=NULL return the type of pbc in *ePBC or -1 if unknown.
*/
+gmx_bool read_tps_conf(const char *infile, char *title, struct t_topology *top,
+ int *ePBC, rvec **x, rvec **v, matrix box, gmx_bool bMass);
+/* Read title, top.atoms, x, v (if not NULL) and box from an STX file,
+ * memory for atoms, x and v will be allocated.
+ * Return TRUE if a complete topology was read.
+ * If infile is a TPX file read the whole top,
+ * else if bMass=TRUE, read the masses into top.atoms from the mass database.
+ */
+
#ifdef __cplusplus
}
#endif
-#endif /* GMX_FILEIO_CONFIO_H */
+#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "enxio.h"
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/fileio/xdrf.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
/* The source code in this file should be thread-safe.
XDR *xdr;
gmx_bool bRead = gmx_fio_getread(ef->fio);
int file_version;
- int i;
-
- gmx_fio_checktype(ef->fio);
xdr = gmx_fio_getxdr(ef->fio);
{
int magic = -7777777;
real first_real_to_check;
- int b, i, zero = 0, dum = 0;
+ int b, zero = 0, dum = 0;
gmx_bool bRead = gmx_fio_getread(ef->fio);
- int tempfix_nr = 0;
int ndisre = 0;
int startb = 0;
#ifndef GMX_DOUBLE
}
else
{
- fr->nsteps = max(1, fr->nsum);
+ fr->nsteps = std::max(1, fr->nsum);
}
if (*file_version >= 5)
{
((fr->nre > 0 && fr->nre != nre_test) ||
fr->nre < 0 || ndisre < 0 || fr->nblock < 0))
{
- *bWrongPrecision = TRUE;
+ if (bWrongPrecision)
+ {
+ *bWrongPrecision = TRUE;
+ }
return *bOK;
}
}
}
-static gmx_bool empty_file(const char *fn)
+/*!\brief Return TRUE if a file exists but is empty, otherwise FALSE.
+ *
+ * If the file exists but has length larger than zero, if it does not exist, or
+ * if there is a file system error, FALSE will be returned instead.
+ *
+ * \param fn File name to test
+ *
+ * \return TRUE if file could be open but is empty, otherwise FALSE.
+ */
+static gmx_bool
+empty_file(const char *fn)
{
FILE *fp;
char dum;
bEmpty = feof(fp);
gmx_fio_fclose(fp);
- return bEmpty;
+ // bEmpty==TRUE but ret!=0 would likely be some strange I/O error, but at
+ // least it's not a normal empty file, so we return FALSE in that case.
+ return (bEmpty && ret == 0);
}
ener_file_t open_enx(const char *fn, const char *mode)
{
- int nre, i;
+ int nre;
gmx_enxnm_t *nms = NULL;
int file_version = -1;
t_enxframe *fr;
if (mode[0] == 'r')
{
ef->fio = gmx_fio_open(fn, mode);
- gmx_fio_checktype(ef->fio);
gmx_fio_setprecision(ef->fio, FALSE);
do_enxnms(ef, &nre, &nms);
snew(fr, 1);
else
{
gmx_fio_rewind(ef->fio);
- gmx_fio_checktype(ef->fio);
gmx_fio_setprecision(ef->fio, TRUE);
do_enxnms(ef, &nre, &nms);
do_eheader(ef, &file_version, fr, nre, &bWrongPrecision, &bOK);
fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4;
/*d_size = fr->ndisre*(sizeof(real)*2);*/
}
- gmx_fio_checktype(ef->fio);
if (!do_eheader(ef, &file_version, fr, -1, NULL, &bOK))
{
{
fprintf(stderr, "\nWARNING: there may be something wrong with energy file %s\n",
gmx_fio_getname(ef->fio));
- fprintf(stderr, "Found: step=%"GMX_PRId64 ", nre=%d, nblock=%d, time=%g.\n"
+ fprintf(stderr, "Found: step=%" GMX_PRId64 ", nre=%d, nblock=%d, time=%g.\n"
"Trying to skip frame expect a crash though\n",
fr->step, fr->nre, fr->nblock, fr->t);
}
}
/* read/write data */
- bOK1 = TRUE;
switch (sub->type)
{
case xdr_datatype_float:
for (i = 0; i < nre; i++)
{
- if (strcmp(enm[i].name, name) == 0)
+ if (std::strcmp(enm[i].name, name) == 0)
{
return fr->ener[i].e;
}
"Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY"
};
- static const char *pcouplmu_nm[] = {
- "Pcoupl-Mu-XX", "Pcoupl-Mu-YY", "Pcoupl-Mu-ZZ",
- "Pcoupl-Mu-YX", "Pcoupl-Mu-ZX", "Pcoupl-Mu-ZY"
- };
static const char *baro_nm[] = {
"Barostat"
};
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_FILEIO_ENXIO_H
#define GMX_FILEIO_ENXIO_H
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/xdr_datatype.h"
#include "gromacs/legacyheaders/types/energy.h"
#include "gromacs/legacyheaders/types/inputrec.h"
#endif
struct gmx_groups_t;
+struct t_fileio;
/**************************************************************
* These are the base datatypes + functions for reading and
ener_file_t open_enx(const char *fn, const char *mode);
-t_fileio *enx_file_pointer(const ener_file_t ef);
+struct t_fileio *enx_file_pointer(const ener_file_t ef);
void close_enx(ener_file_t ef);
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2005, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "espio.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/smalloc.h"
+
+static int get_espresso_word(FILE *fp, char word[])
+{
+ int ret, nc, i;
+
+ ret = 0;
+ nc = 0;
+
+ do
+ {
+ i = fgetc(fp);
+ if (i != EOF)
+ {
+ if (i == ' ' || i == '\n' || i == '\t')
+ {
+ if (nc > 0)
+ {
+ ret = 1;
+ }
+ }
+ else if (i == '{')
+ {
+ if (nc == 0)
+ {
+ word[nc++] = '{';
+ }
+ ret = 2;
+ }
+ else if (i == '}')
+ {
+ if (nc == 0)
+ {
+ word[nc++] = '}';
+ }
+ ret = 3;
+ }
+ else
+ {
+ word[nc++] = (char)i;
+ }
+ }
+ }
+ while (i != EOF && ret == 0);
+
+ word[nc] = '\0';
+
+ return ret;
+}
+
+static int check_open_parenthesis(FILE *fp, int r,
+ const char *infile, const char *keyword)
+{
+ int level_inc;
+ char word[STRLEN];
+
+ level_inc = 0;
+ if (r == 2)
+ {
+ level_inc++;
+ }
+ else
+ {
+ r = get_espresso_word(fp, word);
+ if (r == 2)
+ {
+ level_inc++;
+ }
+ else
+ {
+ gmx_fatal(FARGS, "Expected '{' after '%s' in file '%s'",
+ keyword, infile);
+ }
+ }
+
+ return level_inc;
+}
+
+static int check_close_parenthesis(FILE *fp, int r,
+ const char *infile, const char *keyword)
+{
+ int level_inc;
+ char word[STRLEN];
+
+ level_inc = 0;
+ if (r == 3)
+ {
+ level_inc--;
+ }
+ else
+ {
+ r = get_espresso_word(fp, word);
+ if (r == 3)
+ {
+ level_inc--;
+ }
+ else
+ {
+ gmx_fatal(FARGS, "Expected '}' after section '%s' in file '%s'",
+ keyword, infile);
+ }
+ }
+
+ return level_inc;
+}
+
+enum {
+ espID, espPOS, espTYPE, espQ, espV, espF, espMOLECULE, espNR
+};
+static const char *const esp_prop[espNR] = {
+ "id", "pos", "type", "q", "v", "f",
+ "molecule"
+};
+
+void read_espresso_conf(const char *infile, char *title,
+ t_atoms *atoms, rvec x[], rvec *v, matrix box)
+{
+ t_symtab *symtab = NULL;
+ FILE *fp;
+ char word[STRLEN], buf[STRLEN];
+ int level, r, nprop, p, i, m, molnr;
+ int prop[32];
+ double d;
+ gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol;
+
+ if (!symtab)
+ {
+ snew(symtab, 1);
+ open_symtab(symtab);
+ }
+ // TODO: The code does not understand titles it writes...
+ title[0] = '\0';
+
+ clear_mat(box);
+
+ fp = gmx_fio_fopen(infile, "r");
+
+ bFoundParticles = FALSE;
+ bFoundVariable = FALSE;
+ bMol = FALSE;
+ level = 0;
+ while ((r = get_espresso_word(fp, word)))
+ {
+ if (level == 1 && std::strcmp(word, "particles") == 0 && !bFoundParticles)
+ {
+ bFoundParticles = TRUE;
+ level += check_open_parenthesis(fp, r, infile, "particles");
+ nprop = 0;
+ while (level == 2 && (r = get_espresso_word(fp, word)))
+ {
+ bFoundProp = FALSE;
+ for (p = 0; p < espNR; p++)
+ {
+ if (strcmp(word, esp_prop[p]) == 0)
+ {
+ bFoundProp = TRUE;
+ prop[nprop++] = p;
+ /* printf(" prop[%d] = %s\n",nprop-1,esp_prop[prop[nprop-1]]); */
+ }
+ }
+ if (!bFoundProp && word[0] != '}')
+ {
+ gmx_fatal(FARGS, "Can not read Espresso files with particle property '%s'", word);
+ }
+ if (bFoundProp && p == espMOLECULE)
+ {
+ bMol = TRUE;
+ }
+ if (r == 3)
+ {
+ level--;
+ }
+ }
+
+ i = 0;
+ while (level > 0 && (r = get_espresso_word(fp, word)))
+ {
+ if (r == 2)
+ {
+ level++;
+ }
+ else if (r == 3)
+ {
+ level--;
+ }
+ if (level == 2)
+ {
+ for (p = 0; p < nprop; p++)
+ {
+ switch (prop[p])
+ {
+ case espID:
+ r = get_espresso_word(fp, word);
+ /* Not used */
+ break;
+ case espPOS:
+ for (m = 0; m < 3; m++)
+ {
+ r = get_espresso_word(fp, word);
+ sscanf(word, "%lf", &d);
+ x[i][m] = d;
+ }
+ break;
+ case espTYPE:
+ r = get_espresso_word(fp, word);
+ atoms->atom[i].type = std::strtol(word, NULL, 10);
+ break;
+ case espQ:
+ r = get_espresso_word(fp, word);
+ sscanf(word, "%lf", &d);
+ atoms->atom[i].q = d;
+ break;
+ case espV:
+ for (m = 0; m < 3; m++)
+ {
+ r = get_espresso_word(fp, word);
+ sscanf(word, "%lf", &d);
+ v[i][m] = d;
+ }
+ break;
+ case espF:
+ for (m = 0; m < 3; m++)
+ {
+ r = get_espresso_word(fp, word);
+ /* not used */
+ }
+ break;
+ case espMOLECULE:
+ r = get_espresso_word(fp, word);
+ molnr = std::strtol(word, NULL, 10);
+ if (i == 0 ||
+ atoms->resinfo[atoms->atom[i-1].resind].nr != molnr)
+ {
+ atoms->atom[i].resind =
+ (i == 0 ? 0 : atoms->atom[i-1].resind+1);
+ atoms->resinfo[atoms->atom[i].resind].nr = molnr;
+ atoms->resinfo[atoms->atom[i].resind].ic = ' ';
+ atoms->resinfo[atoms->atom[i].resind].chainid = ' ';
+ atoms->resinfo[atoms->atom[i].resind].chainnum = molnr; /* Not sure if this is right? */
+ }
+ else
+ {
+ atoms->atom[i].resind = atoms->atom[i-1].resind;
+ }
+ break;
+ }
+ }
+ /* Generate an atom name from the particle type */
+ sprintf(buf, "T%d", atoms->atom[i].type);
+ atoms->atomname[i] = put_symtab(symtab, buf);
+ if (bMol)
+ {
+ if (i == 0 || atoms->atom[i].resind != atoms->atom[i-1].resind)
+ {
+ atoms->resinfo[atoms->atom[i].resind].name =
+ put_symtab(symtab, "MOL");
+ }
+ }
+ else
+ {
+ /* Residue number is the atom number */
+ atoms->atom[i].resind = i;
+ /* Generate an residue name from the particle type */
+ if (atoms->atom[i].type < 26)
+ {
+ sprintf(buf, "T%c", 'A'+atoms->atom[i].type);
+ }
+ else
+ {
+ sprintf(buf, "T%c%c",
+ 'A'+atoms->atom[i].type/26, 'A'+atoms->atom[i].type%26);
+ }
+ t_atoms_set_resinfo(atoms, i, symtab, buf, i, ' ', 0, ' ');
+ }
+
+ if (r == 3)
+ {
+ level--;
+ }
+ i++;
+ }
+ }
+ atoms->nres = atoms->nr;
+
+ if (i != atoms->nr)
+ {
+ gmx_fatal(FARGS, "Internal inconsistency in Espresso routines, read %d atoms, expected %d atoms", i, atoms->nr);
+ }
+ }
+ else if (level == 1 && std::strcmp(word, "variable") == 0 && !bFoundVariable)
+ {
+ bFoundVariable = TRUE;
+ level += check_open_parenthesis(fp, r, infile, "variable");
+ while (level == 2 && (r = get_espresso_word(fp, word)))
+ {
+ if (level == 2 && std::strcmp(word, "box_l") == 0)
+ {
+ for (m = 0; m < 3; m++)
+ {
+ r = get_espresso_word(fp, word);
+ sscanf(word, "%lf", &d);
+ box[m][m] = d;
+ }
+ level += check_close_parenthesis(fp, r, infile, "box_l");
+ }
+ }
+ }
+ else if (r == 2)
+ {
+ level++;
+ }
+ else if (r == 3)
+ {
+ level--;
+ }
+ }
+
+ if (!bFoundParticles)
+ {
+ fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n",
+ infile);
+ }
+
+ gmx_fio_fclose(fp);
+}
+
+int get_espresso_coordnum(const char *infile)
+{
+ FILE *fp;
+ char word[STRLEN];
+ int natoms, level, r;
+ gmx_bool bFoundParticles;
+
+ natoms = 0;
+
+ fp = gmx_fio_fopen(infile, "r");
+
+ bFoundParticles = FALSE;
+ level = 0;
+ while ((r = get_espresso_word(fp, word)) && !bFoundParticles)
+ {
+ if (level == 1 && strcmp(word, "particles") == 0 && !bFoundParticles)
+ {
+ bFoundParticles = TRUE;
+ level += check_open_parenthesis(fp, r, infile, "particles");
+ while (level > 0 && (r = get_espresso_word(fp, word)))
+ {
+ if (r == 2)
+ {
+ level++;
+ if (level == 2)
+ {
+ natoms++;
+ }
+ }
+ else if (r == 3)
+ {
+ level--;
+ }
+ }
+ }
+ else if (r == 2)
+ {
+ level++;
+ }
+ else if (r == 3)
+ {
+ level--;
+ }
+ }
+ if (!bFoundParticles)
+ {
+ fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n",
+ infile);
+ }
+
+ gmx_fio_fclose(fp);
+
+ return natoms;
+}
+
+void write_espresso_conf_indexed(FILE *out, const char *title,
+ t_atoms *atoms, int nx, atom_id *index,
+ rvec *x, rvec *v, matrix box)
+{
+ int i, j;
+
+ fprintf(out, "# %s\n", title);
+ if (TRICLINIC(box))
+ {
+ gmx_warning("The Espresso format does not support triclinic unit-cells");
+ }
+ fprintf(out, "{variable {box_l %f %f %f}}\n", box[0][0], box[1][1], box[2][2]);
+
+ fprintf(out, "{particles {id pos type q%s}\n", v ? " v" : "");
+ for (i = 0; i < nx; i++)
+ {
+ if (index)
+ {
+ j = index[i];
+ }
+ else
+ {
+ j = i;
+ }
+ fprintf(out, "\t{%d %f %f %f %d %g",
+ j, x[j][XX], x[j][YY], x[j][ZZ],
+ atoms->atom[j].type, atoms->atom[j].q);
+ if (v)
+ {
+ fprintf(out, " %f %f %f", v[j][XX], v[j][YY], v[j][ZZ]);
+ }
+ fprintf(out, "}\n");
+ }
+ fprintf(out, "}\n");
+}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2005, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifndef _genborn_sse_h
-#define _genborn_sse_h
+#ifndef GMX_FILEIO_ESPIO_H
+#define GMX_FILEIO_ESPIO_H
-#include "gromacs/legacyheaders/typedefs.h"
+#include <cstdio>
-float
-calc_gb_chainrule_sse2_single(int natoms, t_nblist *nl, float *dadx, float *dvda,
- float *xd, float *f, float *fshift, float *shift_vec,
- int gb_algorithm, gmx_genborn_t *born, t_mdatoms *md);
+#include "gromacs/legacyheaders/types/simple.h"
+#include "gromacs/math/vectypes.h"
-int
-calc_gb_rad_still_sse2_single(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
- float *x, t_nblist *nl, gmx_genborn_t *born);
+struct t_atoms;
-int
-calc_gb_rad_hct_obc_sse2_single(t_commrec *cr, t_forcerec * fr, int natoms, gmx_localtop_t *top,
- float *x, t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, int gb_algorithm);
+void read_espresso_conf(const char *infile, char *title,
+ t_atoms *atoms, rvec x[], rvec *v, matrix box);
-#endif /* _genborn_sse_h */
+int get_espresso_coordnum(const char *infile);
+
+void write_espresso_conf_indexed(FILE *out, const char *title,
+ t_atoms *atoms, int nx, atom_id *index,
+ rvec *x, rvec *v, matrix box);
+
+#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "filenm.h"
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/types/commrec.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
-/* XDR should be available on all platforms now,
- * but we keep the possibility of turning it off...
- */
-#define USE_XDR
-
/* Use bitflag ... */
#define IS_SET(fn) ((fn.flag & ffSET) != 0)
#define IS_OPT(fn) ((fn.flag & ffOPT) != 0)
enum
{
- eftASC, eftBIN, eftXDR, eftTNG, eftGEN, eftNR
+ eftASC, eftXDR, eftTNG, eftGEN, eftNR
};
/* To support multiple file types with one general (eg TRX) we have
*/
static const int trxs[] =
{
-#ifdef USE_XDR
efXTC, efTRR, efCPT,
-#endif
efGRO, efG96, efPDB, efTNG
};
#define NTRXS asize(trxs)
static const int trcompressed[] =
{
-#ifdef USE_XDR
efXTC,
-#endif
efTNG
};
#define NTRCOMPRESSED asize(trcompressed)
static const int tros[] =
{
-#ifdef USE_XDR
efXTC, efTRR,
-#endif
efGRO, efG96, efPDB, efTNG
};
#define NTROS asize(tros)
static const int trns[] =
{
-#ifdef USE_XDR
efTRR, efCPT,
-#endif
efTNG
};
#define NTRNS asize(trns)
static const int stxs[] =
{
- efGRO, efG96, efPDB, efBRK, efENT, efESP
-#ifdef USE_XDR
- , efTPR
-#endif
+ efGRO, efG96, efPDB, efBRK, efENT, efESP,
+ efTPR
};
#define NSTXS asize(stxs)
static const int tpss[] =
{
-#ifdef USE_XDR
efTPR,
-#endif
efGRO, efG96, efPDB, efBRK, efENT
};
#define NTPSS asize(tpss)
{ eftASC, "", "rundir", NULL, "Run directory" }
};
-#define NZEXT 2
-static const char *z_ext[NZEXT] =
-{ ".gz", ".Z" };
-
const char *ftp2ext(int ftp)
{
if ((0 <= ftp) && (ftp < efNR))
}
}
-const char *ftp2ftype(int ftp)
+gmx_bool ftp_is_text(int ftp)
{
if ((ftp >= 0) && (ftp < efNR))
{
- switch (deffile[ftp].ftype)
- {
- case eftASC:
- return "ASCII";
- case eftBIN:
- return "Binary";
- case eftXDR:
- return "XDR portable";
- case eftTNG:
- return "TNG";
- case eftGEN:
- return "";
- default:
- gmx_fatal(FARGS, "Unknown filetype %d in ftp2ftype", deffile[ftp].ftype);
- break;
- }
+ return deffile[ftp].ftype == eftASC;
+ }
+ return FALSE;
+}
+
+gmx_bool ftp_is_xdr(int ftp)
+{
+ if ((ftp >= 0) && (ftp < efNR))
+ {
+ return deffile[ftp].ftype == eftXDR;
}
- return "unknown";
+ return FALSE;
}
const char *ftp2defnm(int ftp)
return efNR;
}
- len = strlen(fn);
+ len = std::strlen(fn);
if ((len >= 4) && (fn[len - 4] == '.'))
{
feptr = &(fn[len - 4]);
for (i = 0; (i < nfile); i++)
{
- if (strcmp(opt, fnm[i].opt) == 0)
+ if (std::strcmp(opt, fnm[i].opt) == 0)
{
return fnm[i].fns[0];
}
for (i = 0; (i < nfile); i++)
{
- if (strcmp(opt, fnm[i].opt) == 0)
+ if (std::strcmp(opt, fnm[i].opt) == 0)
{
return (gmx_bool) IS_SET(fnm[i]);
}
for (i = 0; (i < nfile); i++)
{
- if (strcmp(opt, fnm[i].opt) == 0)
+ if (std::strcmp(opt, fnm[i].opt) == 0)
{
if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
{
int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix)
{
- int i, j, pos;
+ int i, j;
char buf[STRLEN], newname[STRLEN];
char *extpos;
for it, just in case... */
for (j = 0; j < fnm[i].nfiles; j++)
{
- strncpy(buf, fnm[i].fns[j], STRLEN - 1);
+ std::strncpy(buf, fnm[i].fns[j], STRLEN - 1);
extpos = strrchr(buf, '.');
*extpos = '\0';
sprintf(newname, "%s%s.%s", buf, suffix, extpos + 1);
extern "C" {
#endif
-/* this enum should correspond to the array deffile in gmxlib/filenm.c */
-enum {
+/* this enum should correspond to the array deffile in filenm.cpp */
+enum GromacsFileType {
efMDP,
efTRX, efTRO, efTRN, efTRR, efCOMPRESSED, efXTC, efTNG,
efEDR,
const char *ftp2defopt(int ftp);
/* Return default option name for file type */
-const char *ftp2ftype(int ftp);
-/* Return Binary or ASCII depending on file type */
+gmx_bool ftp_is_text(int ftp);
+gmx_bool ftp_is_xdr(int ftp);
const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[]);
/* Return the filename belonging to cmd-line option opt, or NULL when
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "g96io.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include "gromacs/fileio/trx.h"
+#include "gromacs/fileio/trxio.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/smalloc.h"
+
+#define CHAR_SHIFT 24
+
+static int read_g96_pos(char line[], t_symtab *symtab,
+ FILE *fp, const char *infile,
+ t_trxframe *fr)
+{
+ t_atoms *atoms;
+ gmx_bool bEnd;
+ int nwanted, natoms, atnr, resnr = 0, oldres, newres, shift;
+ char anm[STRLEN], resnm[STRLEN];
+ char c1, c2;
+ double db1, db2, db3;
+
+ nwanted = fr->natoms;
+
+ atoms = fr->atoms;
+
+ natoms = 0;
+
+ if (fr->bX)
+ {
+ if (fr->bAtoms)
+ {
+ shift = CHAR_SHIFT;
+ }
+ else
+ {
+ shift = 0;
+ }
+ newres = -1;
+ oldres = -666; /* Unlikely number for the first residue! */
+ bEnd = FALSE;
+ while (!bEnd && fgets2(line, STRLEN, fp))
+ {
+ bEnd = (std::strncmp(line, "END", 3) == 0);
+ if (!bEnd && (line[0] != '#'))
+ {
+ if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
+ {
+ gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n",
+ natoms+1, infile);
+ }
+ if ((nwanted != -1) && (natoms >= nwanted))
+ {
+ gmx_fatal(FARGS,
+ "Found more coordinates (%d) in %s than expected %d\n",
+ natoms, infile, nwanted);
+ }
+ if (atoms)
+ {
+ if (fr->bAtoms &&
+ (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr)
+ != 6))
+ {
+ if (oldres >= 0)
+ {
+ resnr = oldres;
+ }
+ else
+ {
+ resnr = 1;
+ strncpy(resnm, "???", sizeof(resnm)-1);
+ }
+ strncpy(anm, "???", sizeof(anm)-1);
+ }
+ atoms->atomname[natoms] = put_symtab(symtab, anm);
+ if (resnr != oldres)
+ {
+ oldres = resnr;
+ newres++;
+ if (newres >= atoms->nr)
+ {
+ gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
+ infile, atoms->nr);
+ }
+ atoms->atom[natoms].resind = newres;
+ if (newres+1 > atoms->nres)
+ {
+ atoms->nres = newres+1;
+ }
+ t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' ');
+ }
+ else
+ {
+ atoms->atom[natoms].resind = newres;
+ }
+ }
+ if (fr->x)
+ {
+ fr->x[natoms][0] = db1;
+ fr->x[natoms][1] = db2;
+ fr->x[natoms][2] = db3;
+ }
+ natoms++;
+ }
+ }
+ if ((nwanted != -1) && natoms != nwanted)
+ {
+ fprintf(stderr,
+ "Warning: found less coordinates (%d) in %s than expected %d\n",
+ natoms, infile, nwanted);
+ }
+ }
+
+ fr->natoms = natoms;
+
+ return natoms;
+}
+
+static int read_g96_vel(char line[], FILE *fp, const char *infile,
+ t_trxframe *fr)
+{
+ gmx_bool bEnd;
+ int nwanted, natoms = -1, shift;
+ double db1, db2, db3;
+
+ nwanted = fr->natoms;
+
+ if (fr->v && fr->bV)
+ {
+ if (strcmp(line, "VELOCITYRED") == 0)
+ {
+ shift = 0;
+ }
+ else
+ {
+ shift = CHAR_SHIFT;
+ }
+ natoms = 0;
+ bEnd = FALSE;
+ while (!bEnd && fgets2(line, STRLEN, fp))
+ {
+ bEnd = (strncmp(line, "END", 3) == 0);
+ if (!bEnd && (line[0] != '#'))
+ {
+ if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
+ {
+ gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s",
+ natoms+1, infile);
+ }
+ if ((nwanted != -1) && (natoms >= nwanted))
+ {
+ gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n",
+ natoms, infile, nwanted);
+ }
+ if (fr->v)
+ {
+ fr->v[natoms][0] = db1;
+ fr->v[natoms][1] = db2;
+ fr->v[natoms][2] = db3;
+ }
+ natoms++;
+ }
+ }
+ if ((nwanted != -1) && (natoms != nwanted))
+ {
+ fprintf(stderr,
+ "Warning: found less velocities (%d) in %s than expected %d\n",
+ natoms, infile, nwanted);
+ }
+ }
+
+ return natoms;
+}
+
+int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line)
+{
+ t_symtab *symtab = NULL;
+ gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished;
+ int natoms, nbp;
+ double db1, db2, db3, db4, db5, db6, db7, db8, db9;
+
+ bAtStart = (ftell(fp) == 0);
+
+ clear_trxframe(fr, FALSE);
+
+ if (!symtab)
+ {
+ snew(symtab, 1);
+ open_symtab(symtab);
+ }
+
+ natoms = 0;
+
+ if (bAtStart)
+ {
+ while (!fr->bTitle && fgets2(line, STRLEN, fp))
+ {
+ fr->bTitle = (std::strcmp(line, "TITLE") == 0);
+ }
+ if (fr->title == NULL)
+ {
+ fgets2(line, STRLEN, fp);
+ fr->title = gmx_strdup(line);
+ }
+ bEnd = FALSE;
+ while (!bEnd && fgets2(line, STRLEN, fp))
+ {
+ bEnd = (std::strcmp(line, "END") == 0);
+ }
+ fgets2(line, STRLEN, fp);
+ }
+
+ /* Do not get a line if we are not at the start of the file, *
+ * because without a parameter file we don't know what is in *
+ * the trajectory and we have already read the line in the *
+ * previous call (VERY DIRTY). */
+ bFinished = FALSE;
+ do
+ {
+ bTime = (std::strcmp(line, "TIMESTEP") == 0);
+ bAtoms = (std::strcmp(line, "POSITION") == 0);
+ bPos = (bAtoms || (strcmp(line, "POSITIONRED") == 0));
+ bVel = (std::strncmp(line, "VELOCITY", 8) == 0);
+ bBox = (std::strcmp(line, "BOX") == 0);
+ if (bTime)
+ {
+ if (!fr->bTime && !fr->bX)
+ {
+ fr->bStep = bTime;
+ fr->bTime = bTime;
+ do
+ {
+ bFinished = (fgets2(line, STRLEN, fp) == NULL);
+ }
+ while (!bFinished && (line[0] == '#'));
+ sscanf(line, "%15d%15lf", &(fr->step), &db1);
+ fr->time = db1;
+ }
+ else
+ {
+ bFinished = TRUE;
+ }
+ }
+ if (bPos)
+ {
+ if (!fr->bX)
+ {
+ fr->bAtoms = bAtoms;
+ fr->bX = bPos;
+ natoms = read_g96_pos(line, symtab, fp, infile, fr);
+ }
+ else
+ {
+ bFinished = TRUE;
+ }
+ }
+ if (fr->v && bVel)
+ {
+ fr->bV = bVel;
+ natoms = read_g96_vel(line, fp, infile, fr);
+ }
+ if (bBox)
+ {
+ fr->bBox = bBox;
+ clear_mat(fr->box);
+ bEnd = FALSE;
+ while (!bEnd && fgets2(line, STRLEN, fp))
+ {
+ bEnd = (strncmp(line, "END", 3) == 0);
+ if (!bEnd && (line[0] != '#'))
+ {
+ nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
+ &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9);
+ if (nbp < 3)
+ {
+ gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
+ }
+ fr->box[XX][XX] = db1;
+ fr->box[YY][YY] = db2;
+ fr->box[ZZ][ZZ] = db3;
+ if (nbp == 9)
+ {
+ fr->box[XX][YY] = db4;
+ fr->box[XX][ZZ] = db5;
+ fr->box[YY][XX] = db6;
+ fr->box[YY][ZZ] = db7;
+ fr->box[ZZ][XX] = db8;
+ fr->box[ZZ][YY] = db9;
+ }
+ }
+ }
+ bFinished = TRUE;
+ }
+ }
+ while (!bFinished && fgets2(line, STRLEN, fp));
+
+ free_symtab(symtab);
+
+ fr->natoms = natoms;
+
+ return natoms;
+}
+
+void write_g96_conf(FILE *out, t_trxframe *fr,
+ int nindex, const atom_id *index)
+{
+ t_atoms *atoms;
+ int nout, i, a;
+
+ atoms = fr->atoms;
+
+ if (index)
+ {
+ nout = nindex;
+ }
+ else
+ {
+ nout = fr->natoms;
+ }
+
+ if (fr->bTitle)
+ {
+ fprintf(out, "TITLE\n%s\nEND\n", fr->title);
+ }
+ if (fr->bStep || fr->bTime)
+ {
+ /* Officially the time format is %15.9, which is not enough for 10 ns */
+ fprintf(out, "TIMESTEP\n%15d%15.6f\nEND\n", fr->step, fr->time);
+ }
+ if (fr->bX)
+ {
+ if (fr->bAtoms)
+ {
+ fprintf(out, "POSITION\n");
+ for (i = 0; i < nout; i++)
+ {
+ if (index)
+ {
+ a = index[i];
+ }
+ else
+ {
+ a = i;
+ }
+ fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+ (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
+ *atoms->resinfo[atoms->atom[a].resind].name,
+ *atoms->atomname[a], (i+1) % 10000000,
+ fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
+ }
+ }
+ else
+ {
+ fprintf(out, "POSITIONRED\n");
+ for (i = 0; i < nout; i++)
+ {
+ if (index)
+ {
+ a = index[i];
+ }
+ else
+ {
+ a = i;
+ }
+ fprintf(out, "%15.9f%15.9f%15.9f\n",
+ fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
+ }
+ }
+ fprintf(out, "END\n");
+ }
+ if (fr->bV)
+ {
+ if (fr->bAtoms)
+ {
+ fprintf(out, "VELOCITY\n");
+ for (i = 0; i < nout; i++)
+ {
+ if (index)
+ {
+ a = index[i];
+ }
+ else
+ {
+ a = i;
+ }
+ fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+ (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
+ *atoms->resinfo[atoms->atom[a].resind].name,
+ *atoms->atomname[a], (i+1) % 10000000,
+ fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
+ }
+ }
+ else
+ {
+ fprintf(out, "VELOCITYRED\n");
+ for (i = 0; i < nout; i++)
+ {
+ if (index)
+ {
+ a = index[i];
+ }
+ else
+ {
+ a = i;
+ }
+ fprintf(out, "%15.9f%15.9f%15.9f\n",
+ fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
+ }
+ }
+ fprintf(out, "END\n");
+ }
+ if (fr->bBox)
+ {
+ fprintf(out, "BOX\n");
+ fprintf(out, "%15.9f%15.9f%15.9f",
+ fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]);
+ if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
+ fr->box[YY][ZZ] || fr->box[ZZ][XX] || fr->box[ZZ][YY])
+ {
+ fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
+ fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX],
+ fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
+ }
+ fprintf(out, "\n");
+ fprintf(out, "END\n");
+ }
+}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_FILEIO_G96IO_H
+#define GMX_FILEIO_G96IO_H
+
+#include <stdio.h>
+
+#include "gromacs/legacyheaders/types/simple.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct t_trxframe;
+
+int read_g96_conf(FILE *fp, const char *infile, struct t_trxframe *fr, char *line);
+/* read a Gromos96 coordinate or trajectory file, *
+ * returns the number of atoms *
+ * sets what's in the frame in info *
+ * read from fp, infile is only needed for error messages *
+ * nwanted is the number of wanted coordinates, *
+ * set this to -1 if you want to know the number of atoms in the file *
+ * title, atoms, x, v can all be NULL, in which case they won't be read *
+ * line holds the previous line for trajectory reading */
+
+void write_g96_conf(FILE *out, struct t_trxframe *fr, int nindex, const atom_id *index);
+/* write a Gromos96 coordinate file or trajectory frame *
+ * index can be NULL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
#include "config.h"
-#ifdef GMX_INTERNAL_XDR
+#if GMX_INTERNAL_XDR
-#include "gmx_system_xdr.h"
+#include "gmx_internal_xdr.h"
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
/* NB - THIS FILE IS ONLY USED ON MICROSOFT WINDOWS, since that
{
xdr_uint32_t y;
int i;
- char *px = (char *)&x;
- char *py = (char *)&y;
+ char *px = reinterpret_cast<char *>(&x);
+ char *py = reinterpret_cast<char *>(&y);
for (i = 0; i < 4; i++)
{
static xdr_uint32_t xdr_htonl(xdr_uint32_t x)
{
short s = 0x0F00;
- if (*((char *)&s) == (char)0x0F)
+ if (*(reinterpret_cast<char *>(&s)) == static_cast<char>(0x0F))
{
/* bigendian, do nothing */
return x;
static xdr_uint32_t xdr_ntohl(xdr_uint32_t x)
{
short s = 0x0F00;
- if (*((char *)&s) == (char)0x0F)
+ if (*(reinterpret_cast<char *>(&s)) == static_cast<char>(0x0F))
{
/* bigendian, do nothing */
return x;
switch (xdrs->x_op)
{
case XDR_ENCODE:
- l = (xdr_int32_t) (*ip);
+ l = static_cast<xdr_int32_t>(*ip);
return xdr_putint32 (xdrs, &l);
case XDR_DECODE:
{
return FALSE;
}
- *ip = (int) l;
+ *ip = static_cast<int>(l);
case XDR_FREE:
return TRUE;
switch (xdrs->x_op)
{
case XDR_ENCODE:
- l = (xdr_uint32_t) (*up);
+ l = static_cast<xdr_uint32_t>(*up);
return xdr_putuint32 (xdrs, &l);
case XDR_DECODE:
{
return FALSE;
}
- *up = (unsigned int) l;
+ *up = static_cast<unsigned int>(l);
case XDR_FREE:
return TRUE;
switch (xdrs->x_op)
{
case XDR_ENCODE:
- l = (xdr_int32_t) *sp;
+ l = static_cast<xdr_int32_t>(*sp);
return xdr_putint32 (xdrs, &l);
case XDR_DECODE:
{
return FALSE;
}
- *sp = (short) l;
+ *sp = static_cast<short>(l);
return TRUE;
case XDR_FREE:
switch (xdrs->x_op)
{
case XDR_ENCODE:
- l = (xdr_uint32_t) *usp;
+ l = static_cast<xdr_uint32_t>(*usp);
return xdr_putuint32 (xdrs, &l);
case XDR_DECODE:
{
return FALSE;
}
- *usp = (unsigned short) l;
+ *usp = static_cast<unsigned short>(l);
return TRUE;
case XDR_FREE:
{
return TRUE;
}
- return xdr_getbytes (xdrs, (char *)crud, rndup);
+ return xdr_getbytes (xdrs, crud, rndup);
case XDR_ENCODE:
if (!xdr_putbytes (xdrs, cp, cnt))
* storage is allocated. The last parameter is the max allowed length
* of the string as specified by a protocol.
*/
-bool_t
-xdr_string (xdrs, cpp, maxsize)
-XDR *xdrs;
-char **cpp;
-unsigned int maxsize;
+bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize)
{
char *sp = *cpp; /* sp is the actual string pointer */
unsigned int size = 0;
{
return FALSE;
}
- size = strlen (sp);
+ size = std::strlen (sp);
break;
case XDR_DECODE:
break;
}
if (sp == NULL)
{
- *cpp = sp = (char *) malloc (nodesize);
+ *cpp = sp = static_cast<char *>(std::malloc (nodesize));
}
if (sp == NULL)
{
/* Floating-point stuff */
-bool_t
-xdr_float(xdrs, fp)
-XDR *xdrs;
-float *fp;
+bool_t xdr_float(XDR * xdrs, float * fp)
{
xdr_int32_t tmp;
{
case XDR_ENCODE:
- tmp = *(xdr_int32_t *)fp;
+ tmp = *(reinterpret_cast<xdr_int32_t *>(fp));
return (xdr_putint32(xdrs, &tmp));
break;
case XDR_DECODE:
if (xdr_getint32(xdrs, &tmp))
{
- *(xdr_int32_t *)fp = tmp;
+ *(reinterpret_cast<xdr_int32_t *>(fp)) = tmp;
return (TRUE);
}
}
-bool_t
-xdr_double(xdrs, dp)
-XDR *xdrs;
-double *dp;
+bool_t xdr_double(XDR * xdrs, double * dp)
{
/* Windows and some other systems dont define double-precision
* B B 3f ef 9a dd 3c 0e 56 b8
*/
- unsigned char ix = *((char *)&x);
+ unsigned char ix = *(reinterpret_cast<char *>(&x));
if (ix == 0xdd || ix == 0x3f)
{
{
case XDR_ENCODE:
- ip = (int *)dp;
+ ip = reinterpret_cast<int *>(dp);
tmp[0] = ip[!LSW];
tmp[1] = ip[LSW];
return (xdr_putint32(xdrs, tmp) &&
break;
case XDR_DECODE:
- ip = (int *)dp;
+ ip = reinterpret_cast<int *>(dp);
if (xdr_getint32(xdrs, tmp+!LSW) &&
xdr_getint32(xdrs, tmp+LSW))
{
* > elemsize: size of each element
* > xdr_elem: routine to XDR each element
*/
-bool_t
-xdr_vector (xdrs, basep, nelem, elemsize, xdr_elem)
-XDR *xdrs;
-char *basep;
-unsigned int nelem;
-unsigned int elemsize;
-xdrproc_t xdr_elem;
+bool_t xdr_vector (XDR * xdrs, char * basep, unsigned int nelem,
+ unsigned int elemsize, xdrproc_t xdr_elem)
{
#define LASTUNSIGNED ((unsigned int)0-1)
unsigned int i;
static bool_t xdrstdio_getuint32 (XDR *, xdr_uint32_t *);
static bool_t xdrstdio_putuint32 (XDR *, xdr_uint32_t *);
-/*
- * Ops vector for stdio type XDR
- */
-static const struct xdr_ops xdrstdio_ops =
-{
- xdrstdio_getbytes, /* deserialize counted bytes */
- xdrstdio_putbytes, /* serialize counted bytes */
- xdrstdio_getpos, /* get offset in the stream */
- xdrstdio_setpos, /* set offset in the stream */
- xdrstdio_inline, /* prime stream for inline macros */
- xdrstdio_destroy, /* destroy stream */
- xdrstdio_getint32, /* deserialize a int */
- xdrstdio_putint32, /* serialize a int */
- xdrstdio_getuint32, /* deserialize a int */
- xdrstdio_putuint32 /* serialize a int */
-};
-
-/*
- * Initialize a stdio xdr stream.
- * Sets the xdr stream handle xdrs for use on the stream file.
- * Operation flag is set to op.
- */
-void
-xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op)
-{
- xdrs->x_op = op;
- /* We have to add the const since the `struct xdr_ops' in `struct XDR'
- is not `const'. */
- xdrs->x_ops = (struct xdr_ops *) &xdrstdio_ops;
- xdrs->x_private = (char *) file;
- xdrs->x_handy = 0;
- xdrs->x_base = 0;
-}
-
/*
* Destroy a stdio xdr stream.
* Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
static void
xdrstdio_destroy (XDR *xdrs)
{
- (void) fflush ((FILE *) xdrs->x_private);
+ fflush (reinterpret_cast<FILE *>(xdrs->x_private));
/* xx should we close the file ?? */
}
static bool_t
xdrstdio_getbytes (XDR *xdrs, char *addr, unsigned int len)
{
- if ((len != 0) && (fread (addr, (int) len, 1,
- (FILE *) xdrs->x_private) != 1))
+ if ((len != 0) && (fread (addr, static_cast<int>(len), 1,
+ reinterpret_cast<FILE *>(xdrs->x_private)) != 1))
{
return FALSE;
}
static bool_t
xdrstdio_putbytes (XDR *xdrs, char *addr, unsigned int len)
{
- if ((len != 0) && (fwrite (addr, (int) len, 1,
- (FILE *) xdrs->x_private) != 1))
+ if ((len != 0) && (fwrite (addr, static_cast<int>(len), 1,
+ reinterpret_cast<FILE *>(xdrs->x_private)) != 1))
{
return FALSE;
}
static unsigned int
xdrstdio_getpos (XDR *xdrs)
{
- return (unsigned int) ftell ((FILE *) xdrs->x_private);
+ return static_cast<int>(ftell (reinterpret_cast<FILE *>(xdrs->x_private)));
}
static bool_t
xdrstdio_setpos (XDR *xdrs, unsigned int pos)
{
- return fseek ((FILE *) xdrs->x_private, (xdr_int32_t) pos, 0) < 0 ? FALSE : TRUE;
+ return fseek (reinterpret_cast<FILE *>(xdrs->x_private), static_cast<xdr_int32_t>(pos), 0) < 0 ? FALSE : TRUE;
}
static xdr_int32_t *
{
xdr_int32_t mycopy;
- if (fread ((char *) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
+ if (fread (&mycopy, 4, 1, reinterpret_cast<FILE *>(xdrs->x_private)) != 1)
{
return FALSE;
}
xdr_int32_t mycopy = xdr_htonl (*ip);
ip = &mycopy;
- if (fwrite ((char *) ip, 4, 1, (FILE *) xdrs->x_private) != 1)
+ if (fwrite (ip, 4, 1, reinterpret_cast<FILE *>(xdrs->x_private)) != 1)
{
return FALSE;
}
{
xdr_uint32_t mycopy;
- if (fread ((char *) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
+ if (fread (&mycopy, 4, 1, reinterpret_cast<FILE *>(xdrs->x_private)) != 1)
{
return FALSE;
}
xdr_uint32_t mycopy = xdr_htonl (*ip);
ip = &mycopy;
- if (fwrite ((char *) ip, 4, 1, (FILE *) xdrs->x_private) != 1)
+ if (fwrite (ip, 4, 1, reinterpret_cast<FILE *>(xdrs->x_private)) != 1)
{
return FALSE;
}
return TRUE;
}
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct XDR::xdr_ops xdrstdio_ops =
+{
+ xdrstdio_getbytes, /* deserialize counted bytes */
+ xdrstdio_putbytes, /* serialize counted bytes */
+ xdrstdio_getpos, /* get offset in the stream */
+ xdrstdio_setpos, /* set offset in the stream */
+ xdrstdio_inline, /* prime stream for inline macros */
+ xdrstdio_destroy, /* destroy stream */
+ xdrstdio_getint32, /* deserialize a int */
+ xdrstdio_putint32, /* serialize a int */
+ xdrstdio_getuint32, /* deserialize a int */
+ xdrstdio_putuint32 /* serialize a int */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op)
+{
+ xdrs->x_op = op;
+ xdrs->x_ops = &xdrstdio_ops;
+ xdrs->x_private = reinterpret_cast<char *>(file);
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+}
+
#else
-int
- gmx_system_xdr_empty;
-#endif /* GMX_SYSTEM_XDR */
+int gmx_internal_xdr_empty;
+#endif /* GMX_INTERNAL_XDR */
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_FILEIO_GMX_SYSTEM_XDR_H
#define GMX_FILEIO_GMX_SYSTEM_XDR_H
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
+#include <climits>
+#include <cstdio>
+#include <cstdlib>
/*
* This header file is ONLY used on windows systems, since these do
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifndef GMX_FILEIO_GMXFIO_INT_H
-#define GMX_FILEIO_GMXFIO_INT_H
+/*! \internal \file
+ * \brief
+ * Internal definitions shared by gmxfio*.c files.
+ */
+#ifndef GMX_FILEIO_GMXFIO_IMPL_H
+#define GMX_FILEIO_GMXFIO_IMPL_H
/* This is the new improved and thread safe version of gmxfio. */
WARNING WARNING WARNING WARNING */
-
-/* XDR should be available on all platforms now,
- * but we keep the possibility of turning it off...
- */
-#define USE_XDR
-
#include "thread_mpi/lock.h"
#include "gromacs/fileio/xdrf.h"
-/* the reader/writer functions for t_iotype */
-typedef gmx_bool read_func (t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-typedef gmx_bool write_func (t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-
-
-/* these are pointers to the actual reading & writing functions */
-typedef struct
-{
- read_func *nread;
- write_func *nwrite;
-} t_iotype;
-
-
-
struct t_fileio
{
FILE *fp; /* the file pointer */
- const t_iotype *iotp; /* file type */
- gmx_bool bOpen, /* the file is open */
- bRead, /* the file is open for reading */
+ gmx_bool bRead, /* the file is open for reading */
bDouble, /* write doubles instead of floats */
- bDebug, /* the file ops should come with debug info */
- bStdio, /* the file is actually stdin or stdout */
bReadWrite; /* the file is open for reading and writing */
char *fn; /* the file name */
XDR *xdr; /* the xdr data pointer */
enum xdr_op xdrmode; /* the xdr mode */
int iFTP; /* the file type identifier */
- const char *comment; /* a comment string for debugging */
-
t_fileio *next, *prev; /* next and previous file pointers in the
linked list */
tMPI_Lock_t mtx; /* content locking mutex. This is a fast lock
a lock */
};
-
-
-extern const t_iotype asc_iotype;
-extern const t_iotype bin_iotype;
-extern const t_iotype xdr_iotype;
-extern const t_iotype dummy_iotype;
-
-extern const char *eioNames[eioNR];
-
-
-
-#define GMX_FIO_BUFLEN 256
-
-/* make a debug string if that is requested in the fio */
-const char *gmx_fio_dbgstr(t_fileio *fio, const char *desc, char *buf);
-/* check the number of items against the allowed number of items */
-void gmx_fio_check_nitem(int eio, int nitem, const char *file,
- int line);
-/* check the output type against allowed values */
-void gmx_fio_fe(t_fileio *fio, int eio, const char *desc, const char *srcfile,
- int line);
-
-/* lock/unlock the mutex associated with a fio */
+/** lock the mutex associated with a fio */
void gmx_fio_lock(t_fileio *fio);
+/** unlock the mutex associated with a fio */
void gmx_fio_unlock(t_fileio *fio);
#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "gmxfio-xdr.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/xdrf.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/smalloc.h"
+
+#include "gmxfio-impl.h"
+
+/* Enumerated for data types in files */
+enum {
+ eioREAL, eioFLOAT, eioDOUBLE, eioINT, eioINT64,
+ eioUCHAR, eioNUCHAR, eioUSHORT,
+ eioRVEC, eioNRVEC, eioIVEC, eioSTRING, eioNR
+};
+
+static const char *eioNames[eioNR] =
+{
+ "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
+ "IVEC", "STRING"
+};
+
+void gmx_fio_setprecision(t_fileio *fio, gmx_bool bDouble)
+{
+ gmx_fio_lock(fio);
+ fio->bDouble = bDouble;
+ gmx_fio_unlock(fio);
+}
+
+XDR *gmx_fio_getxdr(t_fileio *fio)
+{
+ XDR *ret = NULL;
+ gmx_fio_lock(fio);
+ GMX_RELEASE_ASSERT( fio->xdr != NULL, "Implementation error: NULL XDR pointers");
+ ret = fio->xdr;
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+/* check the number of items given against the type */
+static void gmx_fio_check_nitem(int eio, int nitem, const char *file, int line)
+{
+ if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR)))
+ {
+ gmx_fatal(FARGS,
+ "nitem (%d) may differ from 1 only for %s or %s, not for %s"
+ "(%s, %d)", nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC],
+ eioNames[eio], file, line);
+ }
+}
+
+/* output a data type error. */
+static void gmx_fio_fe(t_fileio *fio, int eio, const char *desc,
+ const char *srcfile, int line)
+{
+ gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d",
+ fio->bRead ? "read" : "write", desc, eio,
+ ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
+ srcfile, line);
+}
+
+/* This is the part that reads xdr files. */
+
+static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
+ const char *desc, const char *srcfile, int line)
+{
+ unsigned char ucdum, *ucptr;
+ bool_t res = 0;
+ float fvec[DIM];
+ double dvec[DIM];
+ int j, m, *iptr, idum;
+ gmx_int64_t sdum;
+ real *ptr;
+ unsigned short us;
+ double d = 0;
+ float f = 0;
+
+ GMX_RELEASE_ASSERT( fio->xdr != NULL, "Implementation error: NULL XDR pointers");
+ gmx_fio_check_nitem(eio, nitem, srcfile, line);
+ switch (eio)
+ {
+ case eioREAL:
+ if (fio->bDouble)
+ {
+ if (item && !fio->bRead)
+ {
+ d = *((real *) item);
+ }
+ res = xdr_double(fio->xdr, &d);
+ if (item)
+ {
+ *((real *) item) = d;
+ }
+ }
+ else
+ {
+ if (item && !fio->bRead)
+ {
+ f = *((real *) item);
+ }
+ res = xdr_float(fio->xdr, &f);
+ if (item)
+ {
+ *((real *) item) = f;
+ }
+ }
+ break;
+ case eioFLOAT:
+ if (item && !fio->bRead)
+ {
+ f = *((float *) item);
+ }
+ res = xdr_float(fio->xdr, &f);
+ if (item)
+ {
+ *((float *) item) = f;
+ }
+ break;
+ case eioDOUBLE:
+ if (item && !fio->bRead)
+ {
+ d = *((double *) item);
+ }
+ res = xdr_double(fio->xdr, &d);
+ if (item)
+ {
+ *((double *) item) = d;
+ }
+ break;
+ case eioINT:
+ if (item && !fio->bRead)
+ {
+ idum = *(int *) item;
+ }
+ res = xdr_int(fio->xdr, &idum);
+ if (item)
+ {
+ *(int *) item = idum;
+ }
+ break;
+ case eioINT64:
+ if (item && !fio->bRead)
+ {
+ sdum = *(gmx_int64_t *) item;
+ }
+ res = xdr_int64(fio->xdr, &sdum);
+ if (item)
+ {
+ *(gmx_int64_t *) item = sdum;
+ }
+ break;
+ case eioUCHAR:
+ if (item && !fio->bRead)
+ {
+ ucdum = *(unsigned char *) item;
+ }
+ res = xdr_u_char(fio->xdr, &ucdum);
+ if (item)
+ {
+ *(unsigned char *) item = ucdum;
+ }
+ break;
+ case eioNUCHAR:
+ ucptr = (unsigned char *) item;
+ res = 1;
+ for (j = 0; (j < nitem) && res; j++)
+ {
+ res = xdr_u_char(fio->xdr, &(ucptr[j]));
+ }
+ break;
+ case eioUSHORT:
+ if (item && !fio->bRead)
+ {
+ us = *(unsigned short *) item;
+ }
+ res = xdr_u_short(fio->xdr, (unsigned short *) &us);
+ if (item)
+ {
+ *(unsigned short *) item = us;
+ }
+ break;
+ case eioRVEC:
+ if (fio->bDouble)
+ {
+ if (item && !fio->bRead)
+ {
+ for (m = 0; (m < DIM); m++)
+ {
+ dvec[m] = ((real *) item)[m];
+ }
+ }
+ res = xdr_vector(fio->xdr, (char *) dvec, DIM,
+ static_cast<unsigned int>(sizeof(double)),
+ (xdrproc_t) xdr_double);
+ if (item)
+ {
+ for (m = 0; (m < DIM); m++)
+ {
+ ((real *) item)[m] = dvec[m];
+ }
+ }
+ }
+ else
+ {
+ if (item && !fio->bRead)
+ {
+ for (m = 0; (m < DIM); m++)
+ {
+ fvec[m] = ((real *) item)[m];
+ }
+ }
+ res = xdr_vector(fio->xdr, (char *) fvec, DIM,
+ static_cast<unsigned int>(sizeof(float)),
+ (xdrproc_t) xdr_float);
+ if (item)
+ {
+ for (m = 0; (m < DIM); m++)
+ {
+ ((real *) item)[m] = fvec[m];
+ }
+ }
+ }
+ break;
+ case eioNRVEC:
+ ptr = NULL;
+ res = 1;
+ for (j = 0; (j < nitem) && res; j++)
+ {
+ if (item)
+ {
+ ptr = ((rvec *) item)[j];
+ }
+ res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
+ }
+ break;
+ case eioIVEC:
+ iptr = (int *) item;
+ res = 1;
+ for (m = 0; (m < DIM) && res; m++)
+ {
+ if (item && !fio->bRead)
+ {
+ idum = iptr[m];
+ }
+ res = xdr_int(fio->xdr, &idum);
+ if (item)
+ {
+ iptr[m] = idum;
+ }
+ }
+ break;
+ case eioSTRING:
+ {
+ char *cptr;
+ int slen;
+
+ if (item)
+ {
+ if (!fio->bRead)
+ {
+ slen = strlen((char *) item) + 1;
+ }
+ else
+ {
+ slen = 0;
+ }
+ }
+ else
+ {
+ slen = 0;
+ }
+
+ if (xdr_int(fio->xdr, &slen) <= 0)
+ {
+ gmx_fatal(FARGS, "wrong string length %d for string %s"
+ " (source %s, line %d)", slen, desc, srcfile, line);
+ }
+ if (!item && fio->bRead)
+ {
+ snew(cptr, slen);
+ }
+ else
+ {
+ cptr = (char *)item;
+ }
+ if (cptr)
+ {
+ res = xdr_string(fio->xdr, &cptr, slen);
+ }
+ else
+ {
+ res = 1;
+ }
+ if (!item && fio->bRead)
+ {
+ sfree(cptr);
+ }
+ break;
+ }
+ default:
+ gmx_fio_fe(fio, eio, desc, srcfile, line);
+ }
+
+ return (res != 0);
+}
+
+/*******************************************************************
+ *
+ * READ/WRITE FUNCTIONS
+ *
+ *******************************************************************/
+
+gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ void *it = (void*)item; /* ugh.. */
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+
+}
+
+gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioFLOAT, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioDOUBLE, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+
+ gmx_fio_lock(fio);
+ if (fio->bRead)
+ {
+ int itmp = 0;
+ ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
+ *item = itmp;
+ }
+ else
+ {
+ int itmp = *item;
+ ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioINT, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_int64(t_fileio *fio, gmx_int64_t *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioINT64, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioUCHAR, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioUSHORT, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioRVEC, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioIVEC, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret;
+ gmx_fio_lock(fio);
+ ret = do_xdr(fio, item, 1, eioSTRING, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+/* Array reading & writing */
+
+gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ if (fio->bRead)
+ {
+ int itmp = 0;
+ ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
+ item[i] = itmp;
+ }
+ else
+ {
+ int itmp = item[i];
+ ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
+ }
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, gmx_int64_t *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ gmx_fio_lock(fio);
+ ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc,
+ srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ gmx_fio_lock(fio);
+ ret = ret && do_xdr(fio, item, n, eioNRVEC, desc, srcfile, line);
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
+
+
+
+gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
+ const char *desc, const char *srcfile, int line)
+{
+ gmx_bool ret = TRUE;
+ int i;
+ gmx_fio_lock(fio);
+ for (i = 0; i < n; i++)
+ {
+ ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc,
+ srcfile, line);
+ }
+ gmx_fio_unlock(fio);
+ return ret;
+}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_FILEIO_GMXFIO_XDR_H
+#define GMX_FILEIO_GMXFIO_XDR_H
+
+#include "gromacs/fileio/xdrf.h"
+#include "gromacs/math/vectypes.h"
+#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/real.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct t_fileio;
+
+void gmx_fio_setprecision(struct t_fileio *fio, gmx_bool bDouble);
+/* Select the floating point precision for reading and writing files */
+
+XDR *gmx_fio_getxdr(struct t_fileio *fio);
+/* Return the file pointer itself */
+
+gmx_bool gmx_fio_writee_string(struct t_fileio *fio, const char *item,
+ const char *desc, const char *srcfile, int line);
+
+/* reading or writing, depending on the file's opening mode string */
+gmx_bool gmx_fio_doe_real(struct t_fileio *fio, real *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_float(struct t_fileio *fio, float *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_double(struct t_fileio *fio, double *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_gmx_bool(struct t_fileio *fio, gmx_bool *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_int(struct t_fileio *fio, int *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_int64(struct t_fileio *fio, gmx_int64_t *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_uchar(struct t_fileio *fio, unsigned char *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_ushort(struct t_fileio *fio, unsigned short *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_rvec(struct t_fileio *fio, rvec *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_ivec(struct t_fileio *fio, ivec *item,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_doe_string(struct t_fileio *fio, char *item,
+ const char *desc, const char *srcfile, int line);
+
+/* array reading & writing */
+gmx_bool gmx_fio_ndoe_real(struct t_fileio *fio, real *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_float(struct t_fileio *fio, float *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_double(struct t_fileio *fio, double *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_gmx_bool(struct t_fileio *fio, gmx_bool *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_int(struct t_fileio *fio, int *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_int64(struct t_fileio *fio, gmx_int64_t *item, int n,
+ const char *desc, const char *srcfile,
+ int line);
+gmx_bool gmx_fio_ndoe_uchar(struct t_fileio *fio, unsigned char *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_ushort(struct t_fileio *fio, unsigned short *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_rvec(struct t_fileio *fio, rvec *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_ivec(struct t_fileio *fio, ivec *item, int n,
+ const char *desc, const char *srcfile, int line);
+gmx_bool gmx_fio_ndoe_string(struct t_fileio *fio, char *item[], int n,
+ const char *desc, const char *srcfile, int line);
+
+
+
+/* convenience macros */
+#define gmx_fio_write_string(fio, item) gmx_fio_writee_string(fio, item, (#item), __FILE__, __LINE__)
+
+#define gmx_fio_do_real(fio, item) gmx_fio_doe_real(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_float(fio, item) gmx_fio_doe_float(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_double(fio, item) gmx_fio_doe_double(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_gmx_bool(fio, item) gmx_fio_doe_gmx_bool(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_int(fio, item) gmx_fio_doe_int(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_int64(fio, item) gmx_fio_doe_int64(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_uchar(fio, item) gmx_fio_doe_uchar(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_ushort(fio, item) gmx_fio_doe_ushort(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_rvec(fio, item) gmx_fio_doe_rvec(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_ivec(fio, item) gmx_fio_doe_ivec(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_string(fio, item) gmx_fio_doe_string(fio, item, (#item), __FILE__, __LINE__)
+
+
+#define gmx_fio_ndo_real(fio, item, n) gmx_fio_ndoe_real(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_float(fio, item, n) gmx_fio_ndoe_float(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_double(fio, item, n) gmx_fio_ndoe_double(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_gmx_bool(fio, item, n) gmx_fio_ndoe_gmx_bool(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_int(fio, item, n) gmx_fio_ndoe_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_int64(fio, item, n) gmx_fio_ndoe_int64(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_uchar(fio, item, n) gmx_fio_ndoe_uchar(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_ushort(fio, item, n) gmx_fio_ndoe_ushort(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_rvec(fio, item, n) gmx_fio_ndoe_rvec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_ivec(fio, item, n) gmx_fio_ndoe_ivec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_string(fio, item, n) gmx_fio_ndoe_string(fio, item, n, (#item), __FILE__, __LINE__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
#include "config.h"
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
#ifdef HAVE_IO_H
#include <io.h>
#include "thread_mpi/threads.h"
#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio_int.h"
#include "gromacs/fileio/md5.h"
-#include "gromacs/legacyheaders/macros.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/snprintf.h"
+
+#include "gmxfio-impl.h"
/* This is the new improved and thread safe version of gmxfio. */
during the simulation. */
static tMPI_Thread_mutex_t open_file_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
-
-/* These simple lists define the I/O type for these files */
-static const int ftpXDR[] =
-{ efTPR, efTRR, efEDR, efXTC, efTNG, efMTX, efCPT };
-static const int ftpASC[] =
-{ efGRO, efPDB, efG96 };
-static const int ftpBIN[] =
-{ efTNG };
-#ifdef HAVE_XML
-static const int ftpXML[] =
-{ efXML};
-#endif
-
-const char *eioNames[eioNR] =
-{
- "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
- "IVEC", "STRING"
-};
-
/******************************************************************
*
* Internal functions:
{
rc = fflush(fio->fp);
}
- else if (fio->xdr)
- {
- rc = fflush((FILE *) fio->xdr->x_private);
- }
return rc;
}
-/* returns TRUE if the file type ftp is in the set set */
-static gmx_bool in_ftpset(int ftp, int nset, const int set[])
-{
- int i;
- gmx_bool bResult;
-
- bResult = FALSE;
- for (i = 0; (i < nset); i++)
- {
- if (ftp == set[i])
- {
- bResult = TRUE;
- }
- }
-
- return bResult;
-}
-
-
-
-extern void gmx_fio_set_comment(t_fileio *fio, const char *comment)
-{
- fio->comment = comment;
-}
-
-extern void gmx_fio_unset_comment(t_fileio *fio)
-{
- fio->comment = NULL;
-}
-
-
-const char *gmx_fio_dbgstr(t_fileio *fio, const char *desc, char *buf)
-{
- if (!fio->bDebug)
- {
- /* set to empty string */
- buf[0] = 0;
- }
- else
- {
- snprintf(buf, GMX_FIO_BUFLEN, " ; %s %s", fio->comment ? fio->comment : "", desc);
- }
- return buf;
-}
-
-
-/* check the number of items given against the type */
-void gmx_fio_check_nitem(int eio, int nitem, const char *file, int line)
-{
- if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR)))
- {
- gmx_fatal(FARGS,
- "nitem (%d) may differ from 1 only for %s or %s, not for %s"
- "(%s, %d)", nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC],
- eioNames[eio], file, line);
- }
-}
-
-
-/* output a data type error. */
-void gmx_fio_fe(t_fileio *fio, int eio, const char *desc,
- const char *srcfile, int line)
-{
-
- gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d",
- fio->bRead ? "read" : "write", desc, eio,
- ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
- srcfile, line);
-}
-
-
-/* set the reader/writer functions based on the file type */
-static void gmx_fio_set_iotype(t_fileio *fio)
-{
- if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
- {
-#ifdef USE_XDR
- fio->iotp = &xdr_iotype;
-#else
- gmx_fatal(FARGS, "Sorry, no XDR");
-#endif
- }
- else if (in_ftpset(fio->iFTP, asize(ftpASC), ftpASC))
- {
- fio->iotp = &asc_iotype;
- }
- else if (in_ftpset(fio->iFTP, asize(ftpBIN), ftpBIN))
- {
- fio->iotp = &bin_iotype;
- }
-#ifdef HAVE_XMl
- else if (in_ftpset(fio->iFTP, asize(ftpXML), ftpXML))
- {
- fio->iotp = &dummy_iotype;
- }
-#endif
- else
- {
- fio->iotp = &dummy_iotype;
- }
-}
-
-
/* lock the mutex associated with this fio. This needs to be done for every
type of access to the fio's elements. */
void gmx_fio_lock(t_fileio *fio)
NOTE: We also assume that the open_file_mutex has been locked */
static void gmx_fio_remove(t_fileio *fio)
{
- t_fileio *prev;
-
/* lock prev, because we're changing it */
gmx_fio_lock(fio->prev);
t_fileio *gmx_fio_open(const char *fn, const char *mode)
{
t_fileio *fio = NULL;
- int i;
char newmode[5];
gmx_bool bRead, bReadWrite;
- int xdrid;
/* sanitize the mode string */
- if (strncmp(mode, "r+", 2) == 0)
+ if (std::strncmp(mode, "r+", 2) == 0)
{
- strcpy(newmode, "r+");
+ std::strcpy(newmode, "r+");
}
else if (mode[0] == 'r')
{
- strcpy(newmode, "r");
+ std::strcpy(newmode, "r");
}
else if (strncmp(mode, "w+", 2) == 0)
{
- strcpy(newmode, "w+");
+ std::strcpy(newmode, "w+");
}
else if (mode[0] == 'w')
{
- strcpy(newmode, "w");
+ std::strcpy(newmode, "w");
}
else if (strncmp(mode, "a+", 2) == 0)
{
- strcpy(newmode, "a+");
+ std::strcpy(newmode, "a+");
}
else if (mode[0] == 'a')
{
- strcpy(newmode, "a");
+ std::strcpy(newmode, "a");
}
else
{
}
/* Check if it should be opened as a binary file */
- if (strncmp(ftp2ftype(fn2ftp(fn)), "ASCII", 5))
+ if (!ftp_is_text(fn2ftp(fn)))
{
- /* Not ascii, add b to file mode */
- if ((strchr(newmode, 'b') == NULL) && (strchr(newmode, 'B') == NULL))
- {
- strcat(newmode, "b");
- }
+ strcat(newmode, "b");
}
snew(fio, 1);
fio->xdr = NULL;
if (fn)
{
+ if (fn2ftp(fn) == efTNG)
+ {
+ gmx_incons("gmx_fio_open may not be used to open TNG files");
+ }
fio->iFTP = fn2ftp(fn);
fio->fn = gmx_strdup(fn);
- fio->bStdio = FALSE;
+ fio->fp = gmx_ffopen(fn, newmode);
/* If this file type is in the list of XDR files, open it like that */
- if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
+ if (ftp_is_xdr(fio->iFTP))
{
- /* First check whether we have to make a backup,
- * only for writing, not for read or append.
- */
- if (newmode[0] == 'w')
- {
-#ifndef GMX_FAHCORE
- /* only make backups for normal gromacs */
- make_backup(fn);
-#endif
- }
- else
- {
- /* Check whether file exists */
- if (!gmx_fexist(fn))
- {
- gmx_open(fn);
- }
- }
- if (fn2ftp(fn) == efTNG)
- {
- gmx_incons("gmx_fio_open may not be used to open TNG files");
- }
- /* Open the file */
- fio->fp = gmx_ffopen(fn, newmode);
-
/* determine the XDR direction */
if (newmode[0] == 'w' || newmode[0] == 'a')
{
{
fio->xdrmode = XDR_DECODE;
}
-
snew(fio->xdr, 1);
xdrstdio_create(fio->xdr, fio->fp, fio->xdrmode);
}
- else
- {
- /* If it is not, open it as a regular file */
- fio->fp = gmx_ffopen(fn, newmode);
- }
/* for appending seek to end of file to make sure ftell gives correct position
* important for checkpointing */
gmx_fseek(fio->fp, 0, SEEK_END);
}
}
+ else
+ {
+ gmx_fatal(FARGS, "Cannot open file with NULL filename string");
+ }
+
fio->bRead = bRead;
fio->bReadWrite = bReadWrite;
fio->bDouble = (sizeof(real) == sizeof(double));
- fio->bDebug = FALSE;
- fio->bOpen = TRUE;
-
- /* set the reader/writer functions */
- gmx_fio_set_iotype(fio);
/* and now insert this file into the list of open files. */
gmx_fio_insert(fio);
{
int rc = 0;
- if (!fio->bOpen)
- {
- gmx_fatal(FARGS, "File %s closed twice!\n", fio->fn);
- }
-
- if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
+ if (fio->xdr != NULL)
{
xdr_destroy(fio->xdr);
sfree(fio->xdr);
}
- /* Don't close stdin and stdout! */
- if (!fio->bStdio && fio->fp != NULL)
+ if (fio->fp != NULL)
{
rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
}
- fio->bOpen = FALSE;
return rc;
}
/* We don't want two processes operating on the list at the same time */
tMPI_Thread_mutex_lock(&open_file_mutex);
- if (fio->iFTP == efTNG)
- {
- gmx_incons("gmx_fio_close should not be called on a TNG file");
- }
gmx_fio_lock(fio);
/* first remove it from the list */
gmx_fio_remove(fio);
{
int rc = 0;
gmx_fio_lock(fio);
- if (!in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR) && !fio->bStdio)
+ if (fio->xdr == NULL)
{
rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
fio->fp = NULL;
FILE * gmx_fio_fopen(const char *fn, const char *mode)
{
- FILE *fp, *ret;
+ FILE *ret;
t_fileio *fio;
fio = gmx_fio_open(fn, mode);
int gmx_fio_fclose(FILE *fp)
{
t_fileio *cur;
- t_fileio *found = NULL;
int rc = -1;
cur = gmx_fio_get_first();
/* The fio_mutex should ALWAYS be locked when this function is called */
static int gmx_fio_int_get_file_position(t_fileio *fio, gmx_off_t *offset)
{
- char buf[STRLEN];
-
/* Flush the file, so we are sure it is written */
if (gmx_fio_int_flush(fio))
{
int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
int *p_nfiles)
{
- int i, nfiles, rc, nalloc;
- int pos_hi, pos_lo;
- long pos;
+ int nfiles, nalloc;
gmx_file_position_t * outputfiles;
- char buf[STRLEN];
t_fileio *cur;
nfiles = 0;
{
/* Skip the checkpoint files themselves, since they could be open when
we call this routine... */
- /* also skip debug files (shoud be the only iFTP==efNR) */
- if (cur->bOpen &&
- !cur->bRead &&
- !cur->bStdio &&
- cur->iFTP != efCPT &&
- cur->iFTP != efNR)
+ if (!cur->bRead && cur->iFTP != efCPT)
{
- int ret;
/* This is an output file currently open for writing, add it */
if (nfiles == nalloc)
{
srenew(outputfiles, nalloc);
}
- strncpy(outputfiles[nfiles].filename, cur->fn, STRLEN - 1);
+ std::strncpy(outputfiles[nfiles].filename, cur->fn, STRLEN - 1);
/* Get the file position */
gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
}
-void gmx_fio_checktype(t_fileio *fio)
-{
- if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
- {
- return;
- }
- else if (in_ftpset(fio->iFTP, asize(ftpASC), ftpASC))
- {
- return;
- }
- else if (in_ftpset(fio->iFTP, asize(ftpBIN), ftpBIN))
- {
- return;
- }
-#ifdef HAVE_XMl
- else if (in_ftpset(fio->iFTP, asize(ftpXML), ftpXML))
- {
- return;
- }
-#endif
- else
- {
- gmx_fatal(FARGS, "Can not read/write topologies to file type %s",
- ftp2ext(fio->iFTP));
- }
-
-}
-
-
-void gmx_fio_setprecision(t_fileio *fio, gmx_bool bDouble)
-{
- gmx_fio_lock(fio);
- fio->bDouble = bDouble;
- gmx_fio_unlock(fio);
-}
-
-gmx_bool gmx_fio_getdebug(t_fileio *fio)
-{
- gmx_bool ret;
-
- gmx_fio_lock(fio);
- ret = fio->bDebug;
- gmx_fio_unlock(fio);
-
- return ret;
-}
-
-void gmx_fio_setdebug(t_fileio *fio, gmx_bool bDebug)
-{
- gmx_fio_lock(fio);
- fio->bDebug = bDebug;
- gmx_fio_unlock(fio);
-}
-
char *gmx_fio_getname(t_fileio *fio)
{
char *ret;
static int gmx_fio_int_fsync(t_fileio *fio)
{
int rc = 0;
- int filen = -1;
-
if (fio->fp)
{
rc = gmx_fsync(fio->fp);
}
- else if (fio->xdr) /* this should normally not happen */
- {
- rc = gmx_fsync((FILE*) fio->xdr->x_private);
- /* ^ is this actually OK? */
- }
-
return rc;
}
cur = gmx_fio_get_first();
while (cur)
{
- /* skip debug files (shoud be the only iFTP==efNR) */
- if (cur->bOpen &&
- !cur->bRead &&
- !cur->bStdio &&
- cur->iFTP != efNR)
+ if (!cur->bRead)
{
/* if any of them fails, return failure code */
int rc = gmx_fio_int_fsync(cur);
return ret;
}
-XDR *gmx_fio_getxdr(t_fileio* fio)
-{
- XDR *ret = NULL;
-
- gmx_fio_lock(fio);
- if (fio->xdr)
- {
- ret = fio->xdr;
- }
- gmx_fio_unlock(fio);
-
- return ret;
-}
-
gmx_bool gmx_fio_getread(t_fileio* fio)
{
gmx_bool ret;
return ret;
}
-int xtc_seek_frame(t_fileio *fio, int frame, int natoms)
-{
- int ret;
-
- gmx_fio_lock(fio);
- ret = xdr_xtc_seek_frame(frame, fio->fp, fio->xdr, natoms);
- gmx_fio_unlock(fio);
-
- return ret;
-}
-
int xtc_seek_time(t_fileio *fio, real time, int natoms, gmx_bool bSeekForwardOnly)
{
int ret;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifdef __cplusplus
extern "C" {
#endif
-/* types */
-
-
-/* Enumerated for different items in files */
-enum {
- eitemHEADER, eitemIR, eitemBOX,
- eitemTOP, eitemX, eitemV, eitemF, eitemNR
-};
-
-/* Enumerated for data types in files */
-enum {
- eioREAL, eioFLOAT, eioDOUBLE, eioINT, eioINT64,
- eioUCHAR, eioNUCHAR, eioUSHORT,
- eioRVEC, eioNRVEC, eioIVEC, eioSTRING, eioNR
-};
typedef struct t_fileio t_fileio;
* Change properties of the open file
********************************************************/
-void gmx_fio_setprecision(t_fileio *fio, gmx_bool bDouble);
-/* Select the floating point precision for reading and writing files */
-
char *gmx_fio_getname(t_fileio *fio);
/* Return the filename corresponding to the fio index */
was opened as a specific file type and changing that midway is most
likely an evil hack. */
-void gmx_fio_setdebug(t_fileio *fio, gmx_bool bDebug);
-/* Set the debug mode */
-
-gmx_bool gmx_fio_getdebug(t_fileio *fio);
-/* Return whether debug mode is on in fio */
-
gmx_bool gmx_fio_getread(t_fileio *fio);
/* Return whether read mode is on in fio */
-
-void gmx_fio_checktype(t_fileio *fio);
-/* Check whether the fio is of a sane type */
-
/***************************************************
* FILE Operations
***************************************************/
* If you do not have it on some other platform you do not have largefile
* support at all, and you can define it to int (or better, find out how to
* enable large files). */
-typedef struct
+typedef struct gmx_file_position_t
{
char filename[STRLEN];
gmx_off_t offset;
unsigned char digest[]);
-int xtc_seek_frame(t_fileio *fio, int frame, int natoms);
-
int xtc_seek_time(t_fileio *fio, real time, int natoms, gmx_bool bSeekForwardOnly);
-/* Add this to the comment string for debugging */
-void gmx_fio_set_comment(t_fileio *fio, const char *comment);
-
-/* Remove previously set comment */
-void gmx_fio_unset_comment(t_fileio *fio);
-
-
-
-
-/********************************************************
- * Read and write
- ********************************************************/
-
-
-/* basic reading & writing */
-gmx_bool gmx_fio_reade_real(t_fileio *fio, real *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_float(t_fileio *fio, float *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_double(t_fileio *fio, double *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_int(t_fileio *fio, int *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_int64(t_fileio *fio, gmx_int64_t *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_uchar(t_fileio *fio, unsigned char *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_ushort(t_fileio *fio, unsigned short *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_reade_string(t_fileio *fio, char *item,
- const char *desc, const char *srcfile, int line);
-
-gmx_bool gmx_fio_writee_real(t_fileio *fio, real item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_float(t_fileio *fio, float item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_double(t_fileio *fio, double item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_int(t_fileio *fio, int item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_int64(t_fileio *fio, gmx_int64_t item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_uchar(t_fileio *fio, unsigned char item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_ushort(t_fileio *fio, unsigned short item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item,
- const char *desc, const char *srcfile, int line);
-
-/* reading or writing, depending on the file's opening mode string */
-gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_int64(t_fileio *fio, gmx_int64_t *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item,
- const char *desc, const char *srcfile, int line);
-
-
-
-
-/* array reading & writing */
-gmx_bool gmx_fio_nreade_real(t_fileio *fio, real *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_float(t_fileio *fio, float *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_double(t_fileio *fio, double *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_int(t_fileio *fio, int *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_int64(t_fileio *fio, gmx_int64_t *item, int n,
- const char *desc, const char *srcfile,
- int line);
-gmx_bool gmx_fio_nreade_uchar(t_fileio *fio, unsigned char *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_ushort(t_fileio *fio, unsigned short *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_rvec(t_fileio *fio, rvec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_ivec(t_fileio *fio, ivec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nreade_string(t_fileio *fio, char *item[], int n,
- const char *desc, const char *srcfile, int line);
-
-gmx_bool gmx_fio_nwritee_real(t_fileio *fio, const real *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_float(t_fileio *fio, const float *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_double(t_fileio *fio, const double *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_int(t_fileio *fio, const int *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_int64(t_fileio *fio,
- const gmx_int64_t *item, int n,
- const char *desc, const char *srcfile,
- int line);
-gmx_bool gmx_fio_nwritee_uchar(t_fileio *fio, const unsigned char *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_ushort(t_fileio *fio, const unsigned short *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_rvec(t_fileio *fio, const rvec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_ivec(t_fileio *fio, const ivec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_nwritee_string(t_fileio *fio, const char *item[], int n,
- const char *desc, const char *srcfile, int line);
-
-gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, gmx_int64_t *item, int n,
- const char *desc, const char *srcfile,
- int line);
-gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
- const char *desc, const char *srcfile, int line);
-gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
- const char *desc, const char *srcfile, int line);
-
-
-
-/* convenience macros */
-#define gmx_fio_read_real(fio, item) gmx_fio_reade_real(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_float(fio, item) gmx_fio_reade_float(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_double(fio, item) gmx_fio_reade_double(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_int(fio, item) gmx_fio_reade_int(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_int64(fio, item) gmx_fio_reade_int64(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_uchar(fio, item) gmx_fio_reade_uchar(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_ushort(fio, item) gmx_fio_reade_ushort(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_rvec(fio, item) gmx_fio_reade_rvec(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_ivec(fio, item) gmx_fio_reade_ivec(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_read_string(fio, item) gmx_fio_reade_string(fio, item, (#item), __FILE__, __LINE__)
-
-#define gmx_fio_write_real(fio, item) gmx_fio_writee_real(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_float(fio, item) gmx_fio_writee_float(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_double(fio, item) gmx_fio_writee_double(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_int(fio, item) gmx_fio_writee_int(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_int64(fio, item) gmx_fio_writee_int64(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_uchar(fio, item) gmx_fio_writee_uchar(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_ushort(fio, item) gmx_fio_writee_ushort(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_rvec(fio, item) gmx_fio_writee_rvec(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_ivec(fio, item) gmx_fio_writee_ivec(fio, item, (#item), __FILE__, __LINE__)
-#define gmx_fio_write_string(fio, item) gmx_fio_writee_string(fio, item, (#item), __FILE__, __LINE__)
-
-#define gmx_fio_do_real(fio, item) gmx_fio_doe_real(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_float(fio, item) gmx_fio_doe_float(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_double(fio, item) gmx_fio_doe_double(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_gmx_bool(fio, item) gmx_fio_doe_gmx_bool(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_int(fio, item) gmx_fio_doe_int(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_int64(fio, item) gmx_fio_doe_int64(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_uchar(fio, item) gmx_fio_doe_uchar(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_ushort(fio, item) gmx_fio_doe_ushort(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_rvec(fio, item) gmx_fio_doe_rvec(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_ivec(fio, item) gmx_fio_doe_ivec(fio, &item, (#item), __FILE__, __LINE__)
-#define gmx_fio_do_string(fio, item) gmx_fio_doe_string(fio, item, (#item), __FILE__, __LINE__)
-
-
-
-
-#define gmx_fio_nread_real(fio, item, n) gmx_fio_nreade_real(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_float(fio, item, n) gmx_fio_nreade_float(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_double(fio, item, n) gmx_fio_nreade_double(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_int(fio, item, n) gmx_fio_nreade_int(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_int64(fio, item, n) gmx_fio_nreade_int64(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_uchar(fio, item, n) gmx_fio_nreade_uchar(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_ushort(fio, item, n) gmx_fio_nreade_ushort(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_rvec(fio, item, n) gmx_fio_nreade_rvec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_ivec(fio, item, n) gmx_fio_nreade_ivec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nread_string(fio, item, n) gmx_fio_nreade_string(fio, item, n, (#item), __FILE__, __LINE__)
-
-#define gmx_fio_nwrite_real(fio, item, n) gmx_fio_nwritee_real(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_float(fio, item, n) gmx_fio_nwritee_float(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_double(fio, item, n) gmx_fio_nwritee_double(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_int(fio, item, n) gmx_fio_nwritee_int(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_int64(fio, item, n) gmx_fio_nwritee_int64(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_uchar(fio, item, n) gmx_fio_nwritee_uchar(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_ushort(fio, item, n) gmx_fio_nwritee_ushort(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_rvec(fio, item, n) gmx_fio_nwritee_rvec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_ivec(fio, item, n) gmx_fio_nwritee_ivec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_nwrite_string(fio, item, n) gmx_fio_nwritee_string(fio, item, n, (#item), __FILE__, __LINE__)
-
-#define gmx_fio_ndo_real(fio, item, n) gmx_fio_ndoe_real(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_float(fio, item, n) gmx_fio_ndoe_float(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_double(fio, item, n) gmx_fio_ndoe_double(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_gmx_bool(fio, item, n) gmx_fio_ndoe_gmx_bool(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_int(fio, item, n) gmx_fio_ndoe_int(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_int64(fio, item, n) gmx_fio_ndoe_int64(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_uchar(fio, item, n) gmx_fio_ndoe_uchar(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_ushort(fio, item, n) gmx_fio_ndoe_ushort(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_rvec(fio, item, n) gmx_fio_ndoe_rvec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_ivec(fio, item, n) gmx_fio_ndoe_ivec(fio, item, n, (#item), __FILE__, __LINE__)
-#define gmx_fio_ndo_string(fio, item, n) gmx_fio_ndoe_string(fio, item, n, (#item), __FILE__, __LINE__)
-
#ifdef __cplusplus
}
#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "config.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/gmxfio_int.h"
-#include "gromacs/fileio/md5.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/utility/cstringutil.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-
-/* This is the part that reads dummy and ascii files. */
-
-
-
-
-/* file type functions */
-static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-static gmx_bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-static gmx_bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-
-
-const t_iotype asc_iotype = {do_ascread, do_ascwrite};
-const t_iotype dummy_iotype = {do_dummyread, do_dummywrite};
-
-
-
-
-
-
-static gmx_bool do_dummyread(t_fileio gmx_unused *fio, void gmx_unused *item, int gmx_unused nitem, int gmx_unused eio,
- const char gmx_unused *desc, const char gmx_unused *srcfile, int gmx_unused line)
-{
- gmx_fatal(FARGS, "File type not set!");
- return FALSE;
-}
-
-static gmx_bool do_dummywrite(t_fileio gmx_unused *fio, const void gmx_unused *item, int gmx_unused nitem, int gmx_unused eio,
- const char gmx_unused *desc, const char gmx_unused *srcfile, int gmx_unused line)
-{
- gmx_fatal(FARGS, "File type not set!");
- return FALSE;
-}
-
-
-
-static void encode_string(int maxlen, char dst[], const char src[])
-{
- int i;
-
- for (i = 0; (i < maxlen - 1) && (src[i] != '\0'); i++)
- {
- if ((src[i] == ' ') || (src[i] == '\t'))
- {
- dst[i] = '_';
- }
- else
- {
- dst[i] = src[i];
- }
- }
- dst[i] = '\0';
-
- if (i == maxlen)
- {
- fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
- }
-}
-
-static void decode_string(int maxlen, char dst[], const char src[])
-{
- int i;
-
- for (i = 0; (i < maxlen - 1) && (src[i] != '\0'); i++)
- {
- if (src[i] == '_')
- {
- dst[i] = ' ';
- }
- else
- {
- dst[i] = src[i];
- }
- }
- dst[i] = '\0';
-
- if (i == maxlen)
- {
- fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
- }
-}
-
-static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- int i;
- int res = 0, *iptr;
- real *ptr;
- char strbuf[256];
- char buf[GMX_FIO_BUFLEN];
- unsigned char *ucptr;
- FILE *fp = fio->fp;
-
- gmx_fio_check_nitem(eio, nitem, srcfile, line);
- switch (eio)
- {
- case eioREAL:
- case eioFLOAT:
- case eioDOUBLE:
- res = fprintf(fp, "%18.10e%s\n", *((real *) item),
- gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioINT:
- res = fprintf(fp, "%18d%s\n", *((int *) item), gmx_fio_dbgstr(fio,
- desc,
- buf));
- break;
- case eioINT64:
- sprintf(strbuf, "%s%s%s", "%", GMX_PRId64, "\n");
- res = fprintf(fp, strbuf, *((gmx_int64_t *) item),
- gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioUCHAR:
- res = fprintf(fp, "%4d%s\n", *((unsigned char *) item),
- gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioNUCHAR:
- ucptr = (unsigned char *) item;
- for (i = 0; (i < nitem); i++)
- {
- res = fprintf(fp, "%4d", (int) ucptr[i]);
- }
- fprintf(fio->fp, "%s\n", gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioUSHORT:
- res = fprintf(fp, "%18d%s\n", *((unsigned short *) item),
- gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioRVEC:
- ptr = (real *) item;
- res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
- ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioNRVEC:
- for (i = 0; (i < nitem); i++)
- {
- ptr = ((rvec *) item)[i];
- res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
- ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
- }
- break;
- case eioIVEC:
- iptr = (int *) item;
- res = fprintf(fp, "%18d%18d%18d%s\n", iptr[XX], iptr[YY],
- iptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
- break;
- case eioSTRING:
- encode_string(256, strbuf, (char *) item);
- res = fprintf(fp, "%-18s%s\n", strbuf, gmx_fio_dbgstr(fio, desc, buf));
- break;
- default:
- gmx_fio_fe(fio, eio, desc, srcfile, line);
- }
- if ((res <= 0) && fio->bDebug)
- {
- fprintf(stderr,
- "Error writing %s %s to file %s (source %s, line %d)\n",
- eioNames[eio], desc, fio->fn, srcfile, line);
- }
-
- return (res > 0);
-}
-
-
-static char *next_item(FILE *fp, char *buf, int buflen)
-{
- int rd;
- gmx_bool in_comment = FALSE;
- gmx_bool in_token = FALSE;
- int i = 0;
- /* This routine reads strings from the file fp, strips comment
- * and buffers. For thread-safety reasons, It reads through getc() */
-
- rd = getc(fp);
- if (rd == EOF)
- {
- gmx_file("End of file");
- }
- do
- {
- if (in_comment)
- {
- if (rd == '\n')
- {
- in_comment = FALSE;
- }
- }
- else if (in_token)
- {
- if (isspace(rd) || rd == ';')
- {
- break;
- }
- buf[i++] = (char) rd;
- }
- else
- {
- if (!isspace(rd))
- {
- if (rd == ';')
- {
- in_comment = TRUE;
- }
- else
- {
- in_token = TRUE;
- buf[i++] = (char) (rd);
- }
- }
- }
- if (i >= buflen - 2)
- {
- break;
- }
- }
- while ((rd = getc(fp)) != EOF);
-
- fprintf(stderr, "WARNING, ftpASC file type not tested!\n");
-
- buf[i] = 0;
-
- return buf;
-}
-
-static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- FILE *fp = fio->fp;
- int i, m, res = 0, *iptr, ix;
- gmx_int64_t s;
- double d, x;
- char c;
- real *ptr;
- unsigned char *ucptr;
- char *cptr;
-#define NEXT_ITEM_BUF_LEN 128
- char ni_buf[NEXT_ITEM_BUF_LEN];
-
- gmx_fio_check_nitem(eio, nitem, srcfile, line);
- switch (eio)
- {
- case eioREAL:
- case eioFLOAT:
- case eioDOUBLE:
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf", &d);
- if (item)
- {
- *((real *) item) = d;
- }
- break;
- case eioINT:
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
- if (item)
- {
- *((int *) item) = i;
- }
- break;
- case eioINT64:
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN),
- "%"GMX_SCNd64, &s);
- if (item)
- {
- *((gmx_int64_t *) item) = s;
- }
- break;
- case eioUCHAR:
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%c", &c);
- if (item)
- {
- *((unsigned char *) item) = (unsigned char)c;
- }
- break;
- case eioNUCHAR:
- ucptr = (unsigned char *) item;
- for (i = 0; (i < nitem); i++)
- {
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &ix);
- if (item)
- {
- ucptr[i] = ix;
- }
- }
- break;
- case eioUSHORT:
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
- if (item)
- {
- *((unsigned short *) item) = i;
- }
- break;
- case eioRVEC:
- ptr = (real *) item;
- for (m = 0; (m < DIM); m++)
- {
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n", &x);
- ptr[m] = x;
- }
- break;
- case eioNRVEC:
- assert(item);
- for (i = 0; (i < nitem); i++)
- {
- ptr = ((rvec *) item)[i];
- for (m = 0; (m < DIM); m++)
- {
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n",
- &x);
- ptr[m] = x;
- }
- }
- break;
- case eioIVEC:
- iptr = (int *) item;
- for (m = 0; (m < DIM); m++)
- {
- res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d\n", &ix);
- if (item)
- {
- iptr[m] = ix;
- }
- }
- break;
- case eioSTRING:
- cptr = next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN);
- if (item)
- {
- decode_string(strlen(cptr) + 1, (char *) item, cptr);
- /* res = sscanf(cptr,"%s",(char *)item);*/
- res = 1;
- }
- break;
- default:
- gmx_fio_fe(fio, eio, desc, srcfile, line);
- }
-
- if ((res <= 0) && fio->bDebug)
- {
- fprintf(stderr,
- "Error reading %s %s from file %s (source %s, line %d)\n",
- eioNames[eio], desc, fio->fn, srcfile, line);
- }
- return (res > 0);
-}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "config.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/gmxfio_int.h"
-#include "gromacs/fileio/md5.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-/* This is the part that reads dummy and ascii files. */
-
-
-static gmx_bool do_binread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-static gmx_bool do_binwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-
-
-const t_iotype bin_iotype = {do_binread, do_binwrite};
-
-
-static gmx_bool do_binwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- size_t size = 0, wsize;
- int ssize;
-
- gmx_fio_check_nitem(eio, nitem, srcfile, line);
- switch (eio)
- {
- case eioREAL:
- size = sizeof(real);
- break;
- case eioFLOAT:
- size = sizeof(float);
- break;
- case eioDOUBLE:
- size = sizeof(double);
- break;
- case eioINT:
- size = sizeof(int);
- break;
- case eioINT64:
- size = sizeof(gmx_int64_t);
- break;
- case eioUCHAR:
- size = sizeof(unsigned char);
- break;
- case eioNUCHAR:
- size = sizeof(unsigned char);
- break;
- case eioUSHORT:
- size = sizeof(unsigned short);
- break;
- case eioRVEC:
- size = sizeof(rvec);
- break;
- case eioNRVEC:
- size = sizeof(rvec);
- break;
- case eioIVEC:
- size = sizeof(ivec);
- break;
- case eioSTRING:
- size = ssize = strlen((char *) item) + 1;
- do_binwrite(fio, &ssize, 1, eioINT, desc, srcfile, line);
- break;
- default:
- gmx_fio_fe(fio, eio, desc, srcfile, line);
- }
-
- wsize = fwrite(item, size, nitem, fio->fp);
-
- if ((wsize != nitem) && fio->bDebug)
- {
- fprintf(stderr,
- "Error writing %s %s to file %s (source %s, line %d)\n",
- eioNames[eio], desc, fio->fn, srcfile, line);
- fprintf(stderr, "written size %u bytes, source size %u bytes\n",
- (unsigned int) wsize, (unsigned int) size);
- }
- return (wsize == nitem);
-}
-
-static gmx_bool do_binread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- size_t size = 0, rsize;
- int ssize;
-
- gmx_fio_check_nitem(eio, nitem, srcfile, line);
- switch (eio)
- {
- case eioREAL:
- if (fio->bDouble)
- {
- size = sizeof(double);
- }
- else
- {
- size = sizeof(float);
- }
- break;
- case eioFLOAT:
- size = sizeof(float);
- break;
- case eioDOUBLE:
- size = sizeof(double);
- break;
- case eioINT:
- size = sizeof(int);
- break;
- case eioINT64:
- size = sizeof(gmx_int64_t);
- break;
- case eioUCHAR:
- size = sizeof(unsigned char);
- break;
- case eioNUCHAR:
- size = sizeof(unsigned char);
- break;
- case eioUSHORT:
- size = sizeof(unsigned short);
- break;
- case eioRVEC:
- case eioNRVEC:
- if (fio->bDouble)
- {
- size = sizeof(double) * DIM;
- }
- else
- {
- size = sizeof(float) * DIM;
- }
- break;
- case eioIVEC:
- size = sizeof(ivec);
- break;
- case eioSTRING:
- do_binread(fio, &ssize, 1, eioINT, desc, srcfile, line);
- size = ssize;
- break;
- default:
- gmx_fio_fe(fio, eio, desc, srcfile, line);
- }
- if (item)
- {
- rsize = fread(item, size, nitem, fio->fp);
- }
- else
- {
- /* Skip over it if we have a NULL pointer here */
- gmx_fseek(fio->fp, (gmx_off_t)(size*nitem), SEEK_CUR);
- rsize = nitem;
- }
- if ((rsize != nitem) && (fio->bDebug))
- {
- fprintf(stderr,
- "Error reading %s %s from file %s (source %s, line %d)\n",
- eioNames[eio], desc, fio->fn, srcfile, line);
- }
-
- return (rsize == nitem);
-}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "config.h"
-
-#include <errno.h>
-#include <stdio.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/gmxfio_int.h"
-#include "gromacs/fileio/md5.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-
-/*******************************************************************
- *
- * READ/WRITE FUNCTIONS
- *
- *******************************************************************/
-
-gmx_bool gmx_fio_reade_real(t_fileio *fio, real *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioREAL, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_float(t_fileio *fio, float *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioFLOAT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_reade_double(t_fileio *fio, double *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioDOUBLE, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_int(t_fileio *fio, int *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioINT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_int64(t_fileio *fio, gmx_int64_t *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioINT64, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_uchar(t_fileio *fio, unsigned char *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioUCHAR, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_reade_ushort(t_fileio *fio, unsigned short *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioUSHORT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioRVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioIVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_reade_string(t_fileio *fio, char *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, 1, eioSTRING, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-/* Write */
-
-gmx_bool gmx_fio_writee_real(t_fileio *fio, real item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioREAL, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_float(t_fileio *fio, float item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioFLOAT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_double(t_fileio *fio, double item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioDOUBLE, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_writee_int(t_fileio *fio, int item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioINT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_int64(t_fileio *fio, gmx_int64_t item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioINT64, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_uchar(t_fileio *fio, unsigned char item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioUCHAR, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_ushort(t_fileio *fio, unsigned short item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, &item, 1, eioUSHORT, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, item, 1, eioRVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, item, 1, eioIVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, item, 1, eioSTRING, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-/* Read/write functions */
-
-gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioREAL, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioREAL, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-
-}
-
-gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioFLOAT, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioFLOAT, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioDOUBLE, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioDOUBLE, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- int itmp;
-
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, &itmp, 1, eioINT, desc, srcfile, line);
- *item = itmp;
- }
- else
- {
- itmp = *item;
- ret = fio->iotp->nwrite(fio, &itmp, 1, eioINT, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioINT, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioINT, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_int64(t_fileio *fio, gmx_int64_t *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioINT64, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioINT64, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioUCHAR, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioUCHAR, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioUSHORT, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioUSHORT, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioRVEC, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioRVEC, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioIVEC, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioIVEC, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = fio->iotp->nread(fio, item, 1, eioSTRING, desc, srcfile, line);
- }
- else
- {
- ret = fio->iotp->nwrite(fio, item, 1, eioSTRING, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-
-
-
-
-/* Array reading & writing */
-
-gmx_bool gmx_fio_nreade_real(t_fileio *fio, real *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioREAL, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_float(t_fileio *fio, float *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioFLOAT, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_nreade_double(t_fileio *fio, double *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioDOUBLE, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_int(t_fileio *fio, int *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_int64(t_fileio *fio, gmx_int64_t *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT64, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_nreade_uchar(t_fileio *fio, unsigned char *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, n, eioNUCHAR, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_ushort(t_fileio *fio, unsigned short *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioUSHORT, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_rvec(t_fileio *fio, rvec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nread(fio, item, n, eioNRVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_ivec(t_fileio *fio, ivec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, item[i], 1, eioIVEC, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nreade_string(t_fileio *fio, char *item[], int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nread(fio, item[i], 1, eioSTRING, desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-
-/* Array writing */
-
-gmx_bool gmx_fio_nwritee_real(t_fileio *fio, const real *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioREAL, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_float(t_fileio *fio, const float *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioFLOAT, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_double(t_fileio *fio, const double *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioDOUBLE, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_int(t_fileio *fio, const int *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT, desc, srcfile,
- line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_int64(t_fileio *fio,
- const gmx_int64_t *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT64,
- desc, srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_uchar(t_fileio *fio, const unsigned char *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, item, n, eioNUCHAR, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_ushort(t_fileio *fio, const unsigned short *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioUSHORT, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_nwritee_rvec(t_fileio *fio, const rvec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret;
- gmx_fio_lock(fio);
- ret = fio->iotp->nwrite(fio, item, n, eioNRVEC, desc, srcfile, line);
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_nwritee_ivec(t_fileio *fio, const ivec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioIVEC, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-gmx_bool gmx_fio_nwritee_string(t_fileio *fio, const char *item[], int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioSTRING, desc, srcfile,
- line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-/* array read/write functions */
-
-gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioREAL, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioREAL, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioFLOAT, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioFLOAT, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioDOUBLE, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioDOUBLE, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i, itmp;
-
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &itmp, 1, eioINT, desc,
- srcfile, line);
- item[i] = itmp;
- }
- else
- {
- itmp = item[i];
- ret = ret && fio->iotp->nwrite(fio, &itmp, 1, eioINT, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, gmx_int64_t *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT64, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT64, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, item, n, eioNUCHAR, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, item, n, eioNUCHAR, desc,
- srcfile, line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioUSHORT, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioUSHORT, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- gmx_fio_lock(fio);
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, item, n, eioNRVEC, desc, srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, item, n, eioNRVEC, desc, srcfile,
- line);
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioIVEC, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioIVEC, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
-
-
-
-gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
- const char *desc, const char *srcfile, int line)
-{
- gmx_bool ret = TRUE;
- int i;
- gmx_fio_lock(fio);
- for (i = 0; i < n; i++)
- {
- if (fio->bRead)
- {
- ret = ret && fio->iotp->nread(fio, &(item[i]), 1, eioSTRING, desc,
- srcfile, line);
- }
- else
- {
- ret = ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioSTRING, desc,
- srcfile, line);
- }
- }
- gmx_fio_unlock(fio);
- return ret;
-}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "config.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/gmxfio_int.h"
-#include "gromacs/fileio/md5.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-/* This is the part that reads xdr files. */
-
-
-/* file type functions */
-static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line);
-
-
-const t_iotype xdr_iotype = {do_xdrread, do_xdrwrite};
-
-
-#ifdef USE_XDR
-
-static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- unsigned char ucdum, *ucptr;
- bool_t res = 0;
- float fvec[DIM];
- double dvec[DIM];
- int j, m, *iptr, idum;
- gmx_int64_t sdum;
- real *ptr;
- unsigned short us;
- double d = 0;
- float f = 0;
-
- gmx_fio_check_nitem(eio, nitem, srcfile, line);
- switch (eio)
- {
- case eioREAL:
- if (fio->bDouble)
- {
- if (item && !fio->bRead)
- {
- d = *((real *) item);
- }
- res = xdr_double(fio->xdr, &d);
- if (item)
- {
- *((real *) item) = d;
- }
- }
- else
- {
- if (item && !fio->bRead)
- {
- f = *((real *) item);
- }
- res = xdr_float(fio->xdr, &f);
- if (item)
- {
- *((real *) item) = f;
- }
- }
- break;
- case eioFLOAT:
- if (item && !fio->bRead)
- {
- f = *((float *) item);
- }
- res = xdr_float(fio->xdr, &f);
- if (item)
- {
- *((float *) item) = f;
- }
- break;
- case eioDOUBLE:
- if (item && !fio->bRead)
- {
- d = *((double *) item);
- }
- res = xdr_double(fio->xdr, &d);
- if (item)
- {
- *((double *) item) = d;
- }
- break;
- case eioINT:
- if (item && !fio->bRead)
- {
- idum = *(int *) item;
- }
- res = xdr_int(fio->xdr, &idum);
- if (item)
- {
- *(int *) item = idum;
- }
- break;
- case eioINT64:
- if (item && !fio->bRead)
- {
- sdum = *(gmx_int64_t *) item;
- }
- res = xdr_int64(fio->xdr, &sdum);
- if (item)
- {
- *(gmx_int64_t *) item = sdum;
- }
- break;
- case eioUCHAR:
- if (item && !fio->bRead)
- {
- ucdum = *(unsigned char *) item;
- }
- res = xdr_u_char(fio->xdr, &ucdum);
- if (item)
- {
- *(unsigned char *) item = ucdum;
- }
- break;
- case eioNUCHAR:
- ucptr = (unsigned char *) item;
- res = 1;
- for (j = 0; (j < nitem) && res; j++)
- {
- res = xdr_u_char(fio->xdr, &(ucptr[j]));
- }
- break;
- case eioUSHORT:
- if (item && !fio->bRead)
- {
- us = *(unsigned short *) item;
- }
- res = xdr_u_short(fio->xdr, (unsigned short *) &us);
- if (item)
- {
- *(unsigned short *) item = us;
- }
- break;
- case eioRVEC:
- if (fio->bDouble)
- {
- if (item && !fio->bRead)
- {
- for (m = 0; (m < DIM); m++)
- {
- dvec[m] = ((real *) item)[m];
- }
- }
- res = xdr_vector(fio->xdr, (char *) dvec, DIM,
- (unsigned int) sizeof(double),
- (xdrproc_t) xdr_double);
- if (item)
- {
- for (m = 0; (m < DIM); m++)
- {
- ((real *) item)[m] = dvec[m];
- }
- }
- }
- else
- {
- if (item && !fio->bRead)
- {
- for (m = 0; (m < DIM); m++)
- {
- fvec[m] = ((real *) item)[m];
- }
- }
- res = xdr_vector(fio->xdr, (char *) fvec, DIM,
- (unsigned int) sizeof(float),
- (xdrproc_t) xdr_float);
- if (item)
- {
- for (m = 0; (m < DIM); m++)
- {
- ((real *) item)[m] = fvec[m];
- }
- }
- }
- break;
- case eioNRVEC:
- ptr = NULL;
- res = 1;
- for (j = 0; (j < nitem) && res; j++)
- {
- if (item)
- {
- ptr = ((rvec *) item)[j];
- }
- res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
- }
- break;
- case eioIVEC:
- iptr = (int *) item;
- res = 1;
- for (m = 0; (m < DIM) && res; m++)
- {
- if (item && !fio->bRead)
- {
- idum = iptr[m];
- }
- res = xdr_int(fio->xdr, &idum);
- if (item)
- {
- iptr[m] = idum;
- }
- }
- break;
- case eioSTRING:
- {
- char *cptr;
- int slen;
-
- if (item)
- {
- if (!fio->bRead)
- {
- slen = strlen((char *) item) + 1;
- }
- else
- {
- slen = 0;
- }
- }
- else
- {
- slen = 0;
- }
-
- if (xdr_int(fio->xdr, &slen) <= 0)
- {
- gmx_fatal(FARGS, "wrong string length %d for string %s"
- " (source %s, line %d)", slen, desc, srcfile, line);
- }
- if (!item && fio->bRead)
- {
- snew(cptr, slen);
- }
- else
- {
- cptr = (char *)item;
- }
- if (cptr)
- {
- res = xdr_string(fio->xdr, &cptr, slen);
- }
- else
- {
- res = 1;
- }
- if (!item && fio->bRead)
- {
- sfree(cptr);
- }
- break;
- }
- default:
- gmx_fio_fe(fio, eio, desc, srcfile, line);
- }
- if ((res == 0) && (fio->bDebug))
- {
- fprintf(stderr, "Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
- eioNames[eio], desc, fio->fn, srcfile, line);
- }
-
- return (res != 0);
-}
-
-
-static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
-}
-
-
-static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
- const char *desc, const char *srcfile, int line)
-{
- void *it = (void*)item; /* ugh.. */
- return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
-}
-
-#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "groio.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include <algorithm>
+
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/trx.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/mtop_util.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/topology/topology.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
+#include "gromacs/utility/smalloc.h"
+
+static void get_coordnum_fp(FILE *in, char *title, int *natoms)
+{
+ char line[STRLEN+1];
+
+ fgets2(title, STRLEN, in);
+ fgets2(line, STRLEN, in);
+ if (sscanf(line, "%d", natoms) != 1)
+ {
+ gmx_fatal(FARGS, "gro file does not have the number of atoms on the second line");
+ }
+}
+
+void get_coordnum(const char *infile, int *natoms)
+{
+ FILE *in;
+ char title[STRLEN];
+
+ in = gmx_fio_fopen(infile, "r");
+ get_coordnum_fp(in, title, natoms);
+ gmx_fio_fclose(in);
+}
+
+static gmx_bool get_w_conf(FILE *in, const char *infile, char *title,
+ t_symtab *symtab, t_atoms *atoms, int *ndec,
+ rvec x[], rvec *v, matrix box)
+{
+ char name[6];
+ char resname[6], oldresname[6];
+ char line[STRLEN+1], *ptr;
+ char buf[256];
+ double x1, y1, z1, x2, y2, z2;
+ rvec xmin, xmax;
+ int natoms, i, m, resnr, newres, oldres, ddist, c;
+ gmx_bool bFirst, bVel;
+ char *p1, *p2, *p3;
+
+ newres = -1;
+ oldres = -12345; /* Unlikely number for the first residue! */
+ ddist = 0;
+
+ /* Read the title and number of atoms */
+ get_coordnum_fp(in, title, &natoms);
+
+ if (natoms > atoms->nr)
+ {
+ gmx_fatal(FARGS, "gro file contains more atoms (%d) than expected (%d)",
+ natoms, atoms->nr);
+ }
+ else if (natoms < atoms->nr)
+ {
+ fprintf(stderr, "Warning: gro file contains less atoms (%d) than expected"
+ " (%d)\n", natoms, atoms->nr);
+ }
+
+ bFirst = TRUE;
+
+ bVel = FALSE;
+
+ resname[0] = '\0';
+ oldresname[0] = '\0';
+
+ /* just pray the arrays are big enough */
+ for (i = 0; (i < natoms); i++)
+ {
+ if ((fgets2(line, STRLEN, in)) == NULL)
+ {
+ gmx_fatal(FARGS, "Unexpected end of file in file %s at line %d",
+ infile, i+2);
+ }
+ if (strlen(line) < 39)
+ {
+ gmx_fatal(FARGS, "Invalid line in %s for atom %d:\n%s", infile, i+1, line);
+ }
+
+ /* determine read precision from distance between periods
+ (decimal points) */
+ if (bFirst)
+ {
+ bFirst = FALSE;
+ p1 = strchr(line, '.');
+ if (p1 == NULL)
+ {
+ gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
+ }
+ p2 = strchr(&p1[1], '.');
+ if (p2 == NULL)
+ {
+ gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
+ }
+ ddist = p2 - p1;
+ *ndec = ddist - 5;
+
+ p3 = strchr(&p2[1], '.');
+ if (p3 == NULL)
+ {
+ gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
+ }
+
+ if (p3 - p2 != ddist)
+ {
+ gmx_fatal(FARGS, "The spacing of the decimal points in file %s is not consistent for x, y and z", infile);
+ }
+ }
+
+ /* residue number*/
+ memcpy(name, line, 5);
+ name[5] = '\0';
+ sscanf(name, "%d", &resnr);
+ sscanf(line+5, "%5s", resname);
+
+ if (resnr != oldres || strncmp(resname, oldresname, sizeof(resname)))
+ {
+ oldres = resnr;
+ newres++;
+ if (newres >= natoms)
+ {
+ gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
+ infile, natoms);
+ }
+ atoms->atom[i].resind = newres;
+ t_atoms_set_resinfo(atoms, i, symtab, resname, resnr, ' ', 0, ' ');
+ }
+ else
+ {
+ atoms->atom[i].resind = newres;
+ }
+
+ /* atomname */
+ std::memcpy(name, line+10, 5);
+ atoms->atomname[i] = put_symtab(symtab, name);
+
+ /* Copy resname to oldresname after we are done with the sanity check above */
+ std::strncpy(oldresname, resname, sizeof(oldresname));
+
+ /* eventueel controle atomnumber met i+1 */
+
+ /* coordinates (start after residue data) */
+ ptr = line + 20;
+ /* Read fixed format */
+ for (m = 0; m < DIM; m++)
+ {
+ for (c = 0; (c < ddist && ptr[0]); c++)
+ {
+ buf[c] = ptr[0];
+ ptr++;
+ }
+ buf[c] = '\0';
+ if (sscanf(buf, "%lf %lf", &x1, &x2) != 1)
+ {
+ gmx_fatal(FARGS, "Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)", infile);
+ }
+ else
+ {
+ x[i][m] = x1;
+ }
+ }
+
+ /* velocities (start after residues and coordinates) */
+ if (v)
+ {
+ /* Read fixed format */
+ for (m = 0; m < DIM; m++)
+ {
+ for (c = 0; (c < ddist && ptr[0]); c++)
+ {
+ buf[c] = ptr[0];
+ ptr++;
+ }
+ buf[c] = '\0';
+ if (sscanf(buf, "%lf", &x1) != 1)
+ {
+ v[i][m] = 0;
+ }
+ else
+ {
+ v[i][m] = x1;
+ bVel = TRUE;
+ }
+ }
+ }
+ }
+ atoms->nres = newres + 1;
+
+ /* box */
+ fgets2(line, STRLEN, in);
+ if (sscanf(line, "%lf%lf%lf", &x1, &y1, &z1) != 3)
+ {
+ gmx_warning("Bad box in file %s", infile);
+
+ /* Generate a cubic box */
+ for (m = 0; (m < DIM); m++)
+ {
+ xmin[m] = xmax[m] = x[0][m];
+ }
+ for (i = 1; (i < atoms->nr); i++)
+ {
+ for (m = 0; (m < DIM); m++)
+ {
+ xmin[m] = std::min(xmin[m], x[i][m]);
+ xmax[m] = std::max(xmax[m], x[i][m]);
+ }
+ }
+ for (i = 0; i < DIM; i++)
+ {
+ for (m = 0; m < DIM; m++)
+ {
+ box[i][m] = 0.0;
+ }
+ }
+ for (m = 0; (m < DIM); m++)
+ {
+ box[m][m] = (xmax[m]-xmin[m]);
+ }
+ fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n",
+ box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
+ }
+ else
+ {
+ /* We found the first three values, the diagonal elements */
+ box[XX][XX] = x1;
+ box[YY][YY] = y1;
+ box[ZZ][ZZ] = z1;
+ if (sscanf (line, "%*f%*f%*f%lf%lf%lf%lf%lf%lf",
+ &x1, &y1, &z1, &x2, &y2, &z2) != 6)
+ {
+ x1 = y1 = z1 = x2 = y2 = z2 = 0.0;
+ }
+ box[XX][YY] = x1;
+ box[XX][ZZ] = y1;
+ box[YY][XX] = z1;
+ box[YY][ZZ] = x2;
+ box[ZZ][XX] = y2;
+ box[ZZ][YY] = z2;
+ }
+
+ return bVel;
+}
+
+void read_whole_conf(const char *infile, char *title,
+ t_atoms *atoms, rvec x[], rvec *v, matrix box)
+{
+ FILE *in;
+ int ndec;
+ t_symtab symtab;
+
+ /* open file */
+ in = gmx_fio_fopen(infile, "r");
+
+ open_symtab(&symtab);
+ get_w_conf(in, infile, title, &symtab, atoms, &ndec, x, v, box);
+ /* We can't free the symbols, as they are still used in atoms, so
+ * the only choice is to leak them. */
+ free_symtab(&symtab);
+
+ gmx_fio_fclose(in);
+}
+
+static gmx_bool gmx_one_before_eof(FILE *fp)
+{
+ char data[4];
+ gmx_bool beof;
+
+ if ((beof = fread(data, 1, 1, fp)) == 1)
+ {
+ gmx_fseek(fp, -1, SEEK_CUR);
+ }
+ return !beof;
+}
+
+gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr)
+{
+ t_atoms atoms;
+ t_symtab symtab;
+ char title[STRLEN], *p;
+ double tt;
+ int ndec = 0, i;
+
+ if (gmx_one_before_eof(status))
+ {
+ return FALSE;
+ }
+
+ open_symtab(&symtab);
+ atoms.nr = fr->natoms;
+ snew(atoms.atom, fr->natoms);
+ atoms.nres = fr->natoms;
+ snew(atoms.resinfo, fr->natoms);
+ snew(atoms.atomname, fr->natoms);
+
+ fr->bV = get_w_conf(status, title, title, &symtab, &atoms, &ndec, fr->x, fr->v, fr->box);
+ fr->bPrec = TRUE;
+ fr->prec = 1;
+ /* prec = 10^ndec: */
+ for (i = 0; i < ndec; i++)
+ {
+ fr->prec *= 10;
+ }
+ fr->title = title;
+ fr->bTitle = TRUE;
+ fr->bX = TRUE;
+ fr->bBox = TRUE;
+
+ sfree(atoms.atom);
+ sfree(atoms.resinfo);
+ sfree(atoms.atomname);
+ done_symtab(&symtab);
+
+ if ((p = strstr(title, "t=")) != NULL)
+ {
+ p += 2;
+ if (sscanf(p, "%lf", &tt) == 1)
+ {
+ fr->time = tt;
+ fr->bTime = TRUE;
+ }
+ else
+ {
+ fr->time = 0;
+ fr->bTime = FALSE;
+ }
+ }
+
+ if (atoms.nr != fr->natoms)
+ {
+ gmx_fatal(FARGS, "Number of atoms in gro frame (%d) doesn't match the number in the previous frame (%d)", atoms.nr, fr->natoms);
+ }
+
+ return TRUE;
+}
+
+int gro_first_x_or_v(FILE *status, t_trxframe *fr)
+{
+ char title[STRLEN];
+
+ frewind(status);
+ fprintf(stderr, "Reading frames from gro file");
+ get_coordnum_fp(status, title, &fr->natoms);
+ frewind(status);
+ fprintf(stderr, " '%s', %d atoms.\n", title, fr->natoms);
+ fr->bTitle = TRUE;
+ fr->title = title;
+ if (fr->natoms == 0)
+ {
+ gmx_file("No coordinates in gro file");
+ }
+
+ snew(fr->x, fr->natoms);
+ snew(fr->v, fr->natoms);
+ gro_next_x_or_v(status, fr);
+
+ return fr->natoms;
+}
+
+static void make_hconf_format(int pr, gmx_bool bVel, char format[])
+{
+ int l, vpr;
+
+ /* build format string for printing,
+ something like "%8.3f" for x and "%8.4f" for v */
+ if (pr < 0)
+ {
+ pr = 0;
+ }
+ if (pr > 30)
+ {
+ pr = 30;
+ }
+ l = pr+5;
+ vpr = pr+1;
+ if (bVel)
+ {
+ sprintf(format, "%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
+ l, pr, l, pr, l, pr, l, vpr, l, vpr, l, vpr);
+ }
+ else
+ {
+ sprintf(format, "%%%d.%df%%%d.%df%%%d.%df\n", l, pr, l, pr, l, pr);
+ }
+
+}
+
+static void write_hconf_box(FILE *out, int pr, matrix box)
+{
+ char format[100];
+ int l;
+
+ if (pr < 5)
+ {
+ pr = 5;
+ }
+ l = pr+5;
+
+ if (box[XX][YY] || box[XX][ZZ] || box[YY][XX] || box[YY][ZZ] ||
+ box[ZZ][XX] || box[ZZ][YY])
+ {
+ sprintf(format, "%%%d.%df%%%d.%df%%%d.%df"
+ "%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
+ l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr, l, pr);
+ fprintf(out, format,
+ box[XX][XX], box[YY][YY], box[ZZ][ZZ],
+ box[XX][YY], box[XX][ZZ], box[YY][XX],
+ box[YY][ZZ], box[ZZ][XX], box[ZZ][YY]);
+ }
+ else
+ {
+ sprintf(format, "%%%d.%df%%%d.%df%%%d.%df\n", l, pr, l, pr, l, pr);
+ fprintf(out, format,
+ box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
+ }
+}
+
+void write_hconf_indexed_p(FILE *out, const char *title, t_atoms *atoms,
+ int nx, const atom_id index[], int pr,
+ rvec *x, rvec *v, matrix box)
+{
+ char resnm[6], nm[6], format[100];
+ int ai, i, resind, resnr;
+
+ bromacs(format, 99);
+ fprintf(out, "%s\n", (title && title[0]) ? title : format);
+ fprintf(out, "%5d\n", nx);
+
+ make_hconf_format(pr, v != NULL, format);
+
+ for (i = 0; (i < nx); i++)
+ {
+ ai = index[i];
+
+ resind = atoms->atom[ai].resind;
+ std::strncpy(resnm, " ??? ", sizeof(resnm)-1);
+ if (resind < atoms->nres)
+ {
+ std::strncpy(resnm, *atoms->resinfo[resind].name, sizeof(resnm)-1);
+ resnr = atoms->resinfo[resind].nr;
+ }
+ else
+ {
+ std::strncpy(resnm, " ??? ", sizeof(resnm)-1);
+ resnr = resind + 1;
+ }
+
+ if (atoms->atom)
+ {
+ std::strncpy(nm, *atoms->atomname[ai], sizeof(nm)-1);
+ }
+ else
+ {
+ std::strncpy(nm, " ??? ", sizeof(nm)-1);
+ }
+
+ fprintf(out, "%5d%-5.5s%5.5s%5d", resnr%100000, resnm, nm, (ai+1)%100000);
+ /* next fprintf uses built format string */
+ if (v)
+ {
+ fprintf(out, format,
+ x[ai][XX], x[ai][YY], x[ai][ZZ], v[ai][XX], v[ai][YY], v[ai][ZZ]);
+ }
+ else
+ {
+ fprintf(out, format,
+ x[ai][XX], x[ai][YY], x[ai][ZZ]);
+ }
+ }
+
+ write_hconf_box(out, pr, box);
+
+ fflush(out);
+}
+
+void write_hconf_mtop(FILE *out, const char *title, gmx_mtop_t *mtop, int pr,
+ rvec *x, rvec *v, matrix box)
+{
+ char format[100];
+ int i, resnr;
+ gmx_mtop_atomloop_all_t aloop;
+ t_atom *atom;
+ char *atomname, *resname;
+
+ bromacs(format, 99);
+ fprintf(out, "%s\n", (title && title[0]) ? title : format);
+ fprintf(out, "%5d\n", mtop->natoms);
+
+ make_hconf_format(pr, v != NULL, format);
+
+ aloop = gmx_mtop_atomloop_all_init(mtop);
+ while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
+ {
+ gmx_mtop_atomloop_all_names(aloop, &atomname, &resnr, &resname);
+
+ fprintf(out, "%5d%-5.5s%5.5s%5d",
+ resnr%100000, resname, atomname, (i+1)%100000);
+ /* next fprintf uses built format string */
+ if (v)
+ {
+ fprintf(out, format,
+ x[i][XX], x[i][YY], x[i][ZZ], v[i][XX], v[i][YY], v[i][ZZ]);
+ }
+ else
+ {
+ fprintf(out, format,
+ x[i][XX], x[i][YY], x[i][ZZ]);
+ }
+ }
+
+ write_hconf_box(out, pr, box);
+
+ fflush(out);
+}
+
+void write_hconf_p(FILE *out, const char *title, t_atoms *atoms, int pr,
+ rvec *x, rvec *v, matrix box)
+{
+ atom_id *aa;
+ int i;
+
+ snew(aa, atoms->nr);
+ for (i = 0; (i < atoms->nr); i++)
+ {
+ aa[i] = i;
+ }
+ write_hconf_indexed_p(out, title, atoms, atoms->nr, aa, pr, x, v, box);
+ sfree(aa);
+}
+
+void write_conf_p(const char *outfile, const char *title,
+ t_atoms *atoms, int pr,
+ rvec *x, rvec *v, matrix box)
+{
+ FILE *out;
+
+ out = gmx_fio_fopen(outfile, "w");
+ write_hconf_p(out, title, atoms, pr, x, v, box);
+ gmx_fio_fclose(out);
+}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_FILEIO_GROIO_H
+#define GMX_FILEIO_GROIO_H
+
+#include <stdio.h>
+
+#include "gromacs/legacyheaders/types/simple.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct gmx_mtop_t;
+struct t_atoms;
+struct t_topology;
+struct t_trxframe;
+
+void get_coordnum(const char *infile, int *natoms);
+void read_whole_conf(const char *infile, char *title,
+ struct t_atoms *atoms, rvec x[], rvec *v, matrix box);
+
+gmx_bool gro_next_x_or_v(FILE *status, struct t_trxframe *fr);
+int gro_first_x_or_v(FILE *status, struct t_trxframe *fr);
+/* read first/next x and/or v frame from gro file */
+
+void write_hconf_indexed_p(FILE *out, const char *title, struct t_atoms *atoms,
+ int nx, const atom_id index[], int ndec,
+ rvec *x, rvec *v, matrix box);
+
+void write_hconf_mtop(FILE *out, const char *title, struct gmx_mtop_t *mtop, int pr,
+ rvec *x, rvec *v, matrix box);
+
+void write_hconf_p(FILE *out, const char *title, struct t_atoms *atoms, int ndec,
+ rvec *x, rvec *v, matrix box);
+/* Write a Gromos file with precision ndec: number of decimal places in x,
+ * v has one place more. */
+
+void write_conf_p(const char *outfile, const char *title,
+ struct t_atoms *atoms, int pr,
+ rvec *x, rvec *v, matrix box);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include <limits.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <climits>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
#include "gromacs/fileio/xdr_datatype.h"
#include "gromacs/fileio/xdrf.h"
*/
#define MAXABS INT_MAX-2
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-#ifndef MAX
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-#endif
#ifndef SQR
#define SQR(x) ((x)*(x))
#endif
#define FIRSTIDX 9
/* note that magicints[FIRSTIDX-1] == 0 */
-#define LASTIDX (sizeof(magicints) / sizeof(*magicints))
+#define LASTIDX static_cast<int>((sizeof(magicints) / sizeof(*magicints)))
/*____________________________________________________________________________
int lastbits;
unsigned char * cbuf;
- cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
- cnt = (unsigned int) buf[0];
+ cbuf = (reinterpret_cast<unsigned char *>(buf)) + 3 * sizeof(*buf);
+ cnt = static_cast<unsigned int>(buf[0]);
lastbits = buf[1];
- lastbyte = (unsigned int) buf[2];
+ lastbyte = static_cast<unsigned int>(buf[2]);
while (num_of_bits >= 8)
{
lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
unsigned char * cbuf;
int mask = (1 << num_of_bits) -1;
- cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+ cbuf = reinterpret_cast<unsigned char *>(buf) + 3 * sizeof(*buf);
cnt = buf[0];
- lastbits = (unsigned int) buf[1];
- lastbyte = (unsigned int) buf[2];
+ lastbits = static_cast<unsigned int>(buf[1]);
+ lastbyte = static_cast<unsigned int>(buf[2]);
num = 0;
while (num_of_bits >= 8)
int tmp, *thiscoord, prevcoord[3];
unsigned int tmpcoord[30];
- int bufsize, xdrid, lsize;
+ int bufsize, lsize;
unsigned int bitsize;
float inv_precision;
int errval = 1;
bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
+ // The static analyzer warns about garbage values for thiscoord[] further
+ // down. It might be thrown off by all the reinterpret_casts, but we might
+ // as well make sure the small preallocated buffer is zero-initialized.
+ for (i = 0; i < static_cast<int>(prealloc_size); i++)
+ {
+ prealloc_ip[i] = 0;
+ }
+
if (!bRead)
{
/* xdrs is open for writing */
*/
if (*size <= 9)
{
- return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
- (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
+ return (xdr_vector(xdrs, reinterpret_cast<char *>(fp), static_cast<unsigned int>(size3),
+ static_cast<unsigned int>(sizeof(*fp)), (xdrproc_t)xdr_float));
}
if (xdr_float(xdrs, precision) == 0)
else
{
we_should_free = 1;
- bufsize = size3 * 1.2;
- ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
- buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
+ bufsize = static_cast<int>(size3 * 1.2);
+ ip = reinterpret_cast<int *>(malloc(size3 * sizeof(*ip)));
+ buf = reinterpret_cast<int *>(malloc(bufsize * sizeof(*buf)));
if (ip == NULL || buf == NULL)
{
fprintf(stderr, "malloc failed\n");
/* scaling would cause overflow */
errval = 0;
}
- lint1 = lf;
+ lint1 = static_cast<int>(lf);
if (lint1 < minint[0])
{
minint[0] = lint1;
/* scaling would cause overflow */
errval = 0;
}
- lint2 = lf;
+ lint2 = static_cast<int>(lf);
if (lint2 < minint[1])
{
minint[1] = lint2;
{
lf = *lfp * *precision - 0.5;
}
- if (fabs(lf) > MAXABS)
+ if (std::abs(lf) > MAXABS)
{
/* scaling would cause overflow */
errval = 0;
}
- lint3 = lf;
+ lint3 = static_cast<int>(lf);
if (lint3 < minint[2])
{
minint[2] = lint3;
}
*lip++ = lint3;
lfp++;
- diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
+ diff = std::abs(oldlint1-lint1)+std::abs(oldlint2-lint2)+std::abs(oldlint3-lint3);
if (diff < mindiff && lfp > fp + 3)
{
mindiff = diff;
{
bitsize = sizeofints(3, sizeint);
}
- lip = ip;
- luip = (unsigned int *) ip;
+ luip = reinterpret_cast<unsigned int *>(ip);
smallidx = FIRSTIDX;
while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
{
return 0;
}
- maxidx = MIN(LASTIDX, smallidx + 8);
+ maxidx = std::min(LASTIDX, smallidx + 8);
minidx = maxidx - 8; /* often this equal smallidx */
- smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
+ smaller = magicints[std::max(FIRSTIDX, smallidx-1)] / 2;
smallnum = magicints[smallidx] / 2;
sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
larger = magicints[maxidx] / 2;
while (i < *size)
{
is_small = 0;
- thiscoord = (int *)(luip) + i * 3;
+ thiscoord = reinterpret_cast<int *>(luip) + i * 3;
if (smallidx < maxidx && i >= 1 &&
- abs(thiscoord[0] - prevcoord[0]) < larger &&
- abs(thiscoord[1] - prevcoord[1]) < larger &&
- abs(thiscoord[2] - prevcoord[2]) < larger)
+ std::abs(thiscoord[0] - prevcoord[0]) < larger &&
+ std::abs(thiscoord[1] - prevcoord[1]) < larger &&
+ std::abs(thiscoord[2] - prevcoord[2]) < larger)
{
is_smaller = 1;
}
}
if (i + 1 < *size)
{
- if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
- abs(thiscoord[1] - thiscoord[4]) < smallnum &&
- abs(thiscoord[2] - thiscoord[5]) < smallnum)
+ if (std::abs(thiscoord[0] - thiscoord[3]) < smallnum &&
+ std::abs(thiscoord[1] - thiscoord[4]) < smallnum &&
+ std::abs(thiscoord[2] - thiscoord[5]) < smallnum)
{
/* interchange first with second atom for better
* compression of water molecules
}
- rc = errval * (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]));
+ rc = errval * (xdr_opaque(xdrs, reinterpret_cast<char *>(&(buf[3])), static_cast<unsigned int>(buf[0])));
if (we_should_free)
{
free(ip);
if (*size <= 9)
{
*precision = -1;
- return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
- (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
+ return (xdr_vector(xdrs, reinterpret_cast<char *>(fp), static_cast<unsigned int>(size3),
+ static_cast<unsigned int>(sizeof(*fp)), (xdrproc_t)xdr_float));
}
if (xdr_float(xdrs, precision) == 0)
{
else
{
we_should_free = 1;
- bufsize = size3 * 1.2;
- ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
- buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
+ bufsize = static_cast<int>(size3 * 1.2);
+ ip = reinterpret_cast<int *>(malloc(size3 * sizeof(*ip)));
+ buf = reinterpret_cast<int *>(malloc(bufsize * sizeof(*buf)));
if (ip == NULL || buf == NULL)
{
fprintf(stderr, "malloc failed\n");
return 0;
}
- maxidx = MIN(LASTIDX, smallidx + 8);
- minidx = maxidx - 8; /* often this equal smallidx */
- smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
+ smaller = magicints[std::max(FIRSTIDX, smallidx-1)] / 2;
smallnum = magicints[smallidx] / 2;
sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
- larger = magicints[maxidx];
/* buf[0] holds the length in bytes */
}
- if (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]) == 0)
+ if (xdr_opaque(xdrs, reinterpret_cast<char *>(&(buf[3])), static_cast<unsigned int>(buf[0])) == 0)
{
if (we_should_free)
{
lip = ip;
while (i < lsize)
{
- thiscoord = (int *)(lip) + i * 3;
+ thiscoord = reinterpret_cast<int *>(lip) + i * 3;
if (bitsize == 0)
{
static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms)
{
- int inp;
gmx_off_t res;
int ret;
int step;
gmx_bool bOK = FALSE;
gmx_off_t low = 0;
gmx_off_t high, offset, pos;
- int res;
int dt_sign = 0;
if (bSeekForwardOnly)
{
float time;
gmx_off_t off;
- int res;
*bOK = 1;
off = gmx_ftell(fp);
if (off < 0)
return -1;
}
- if ( (res = gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END)) != 0)
+ if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END) != 0)
{
*bOK = 0;
return -1;
return -1;
}
- if ( (res = gmx_fseek(fp, off, SEEK_SET)) != 0)
+ if (gmx_fseek(fp, off, SEEK_SET) != 0)
{
*bOK = 0;
return -1;
{
int frame;
gmx_off_t off;
- int res;
*bOK = 1;
if ((off = gmx_ftell(fp)) < 0)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "matio.h"
-#include <ctype.h>
-#include <stdio.h>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
#include <algorithm>
llmax = STRLEN;
while ((NULL != fgetline(&line_buf, llmax, &llalloc, in)) &&
- (strncmp(line_buf, "static", 6) != 0))
+ (std::strncmp(line_buf, "static", 6) != 0))
{
line = line_buf;
parsestring(line, "title", (mm->title));
m = 0;
while ((m < mm->nmap) && (NULL != fgetline(&line_buf, llmax, &llalloc, in)))
{
- line = strchr(line_buf, '\"');
+ line = std::strchr(line_buf, '\"');
if (line)
{
line++;
map[m].code.c2 = line[1];
}
line += nch;
- str = strchr(line, '#');
+ str = std::strchr(line, '#');
if (str)
{
str++;
col_len = 0;
- while (isxdigit(str[col_len]))
+ while (std::isxdigit(str[col_len]))
{
col_len++;
}
}
else
{
- str = strchr(line, 'c');
+ str = std::strchr(line, 'c');
if (str)
{
str += 2;
map[m].rgb.g = 1;
map[m].rgb.b = 1;
}
- line = strchr(line, '\"');
+ line = std::strchr(line, '\"');
line++;
line2string(&line);
map[m].desc = gmx_strdup(line);
bSetLine = TRUE;
if (strstr(line, "x-axis"))
{
- line = strstr(line, "x-axis");
+ line = std::strstr(line, "x-axis");
skipstr(line);
if (mm->axis_x == NULL)
{
skipstr(line);
}
}
- else if (strstr(line, "y-axis"))
+ else if (std::strstr(line, "y-axis"))
{
- line = strstr(line, "y-axis");
+ line = std::strstr(line, "y-axis");
skipstr(line);
if (mm->axis_y == NULL)
{
nmat = 0;
while (NULL != fgetline(&line, STRLEN, &llalloc, in))
{
- if (strstr(line, "/* XPM */"))
+ if (std::strstr(line, "/* XPM */"))
{
srenew(*mat, nmat+1);
read_xpm_entry(in, &(*mat)[nmat]);
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
mapper[i % NMAP],
(*nlevels <= NMAP) ? ' ' : mapper[i/NMAP],
- (unsigned int)round(255*r),
- (unsigned int)round(255*g),
- (unsigned int)round(255*b),
+ static_cast<unsigned int>(round(255*r)),
+ static_cast<unsigned int>(round(255*g)),
+ static_cast<unsigned int>(round(255*b)),
((nmid - i)*lo + i*mid)/clev_lo);
}
for (i = 0; (i < (*nlevels-nmid)); i++)
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
mapper[(i+nmid) % NMAP],
(*nlevels <= NMAP) ? ' ' : mapper[(i+nmid)/NMAP],
- (unsigned int)round(255*r),
- (unsigned int)round(255*g),
- (unsigned int)round(255*b),
+ static_cast<unsigned int>(round(255*r)),
+ static_cast<unsigned int>(round(255*g)),
+ static_cast<unsigned int>(round(255*b)),
((*nlevels - 1 - nmid - i)*mid + i*hi)/clev_hi);
}
}
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
mapper[(i+i0) % NMAP],
(nlevel <= NMAP) ? ' ' : mapper[(i+i0)/NMAP],
- (unsigned int)round(255*r),
- (unsigned int)round(255*g),
- (unsigned int)round(255*b),
+ static_cast<unsigned int>(round(255*r)),
+ static_cast<unsigned int>(round(255*g)),
+ static_cast<unsigned int>(round(255*b)),
lo+fac*(hi-lo));
}
}
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n",
mapper[(i+i0) % NMAP],
(n <= NMAP) ? ' ' : mapper[(i+i0)/NMAP],
- (unsigned int)round(255*rgbd[i].r),
- (unsigned int)round(255*rgbd[i].g),
- (unsigned int)round(255*rgbd[i].b),
+ static_cast<unsigned int>(round(255*rgbd[i].r)),
+ static_cast<unsigned int>(round(255*rgbd[i].g)),
+ static_cast<unsigned int>(round(255*rgbd[i].b)),
i);
}
}
b = (nlo*rlo.b+i*rhi.b)*invlevel;
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
mapper[i % NMAP], (*nlevels <= NMAP) ? ' ' : mapper[i/NMAP],
- (unsigned int)round(255*r),
- (unsigned int)round(255*g),
- (unsigned int)round(255*b),
+ static_cast<unsigned int>(round(255*r)),
+ static_cast<unsigned int>(round(255*g)),
+ static_cast<unsigned int>(round(255*b)),
(nlo*lo+i*hi)*invlevel);
}
}
fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n",
m.map[i].code.c1,
bOneChar ? ' ' : m.map[i].code.c2,
- (unsigned int)round(m.map[i].rgb.r*255),
- (unsigned int)round(m.map[i].rgb.g*255),
- (unsigned int)round(m.map[i].rgb.b*255), m.map[i].desc);
+ static_cast<unsigned int>(round(m.map[i].rgb.r*255)),
+ static_cast<unsigned int>(round(m.map[i].rgb.g*255)),
+ static_cast<unsigned int>(round(m.map[i].rgb.b*255)), m.map[i].desc);
}
write_xpm_axis(out, "x", m.flags & MAT_SPATIAL_X, m.nx, m.axis_x);
write_xpm_axis(out, "y", m.flags & MAT_SPATIAL_Y, m.ny, m.axis_y);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_INTEGER_BIG_ENDIAN
+#include <cstring>
+
+#if GMX_INTEGER_BIG_ENDIAN
#define ARCH_IS_BIG_ENDIAN 1
#else
#define ARCH_IS_BIG_ENDIAN 0
#include "md5.h"
-#include <string.h>
-
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
*/
static const int w = 1;
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+ if (*(reinterpret_cast<const md5_byte_t *>(&w))) /* dynamic little-endian */
#endif
-#if BYTE_ORDER <= 0 /* little-endian */
+#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
- if (!((data - (const md5_byte_t *)0) & 3))
+ if (!((data - reinterpret_cast<const md5_byte_t *>(0)) & 3))
{
/* data are properly aligned */
X = (const md5_word_t *)data;
else
{
/* not aligned */
- memcpy(xbuf, data, 64);
+ std::memcpy(xbuf, data, 64);
X = xbuf;
}
}
{
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
- memcpy(pms->buf + offset, p, copy);
+ std::memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
{
return;
#include "mdoutf.h"
#include "gromacs/domdec/domdec.h"
+#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/tngio.h"
#include "gromacs/fileio/trajectory_writing.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/checkpoint.h"
of->bExpanded = ir->bExpanded;
of->elamstats = ir->expandedvals->elamstats;
of->simulation_part = ir->simulation_part;
- of->x_compression_precision = ir->x_compression_precision;
+ of->x_compression_precision = static_cast<int>(ir->x_compression_precision);
of->wcycle = wcycle;
if (MASTER(cr))
{
case efTRR:
case efTRN:
- of->fp_trn = open_trn(filename, filemode);
+ of->fp_trn = gmx_trr_open(filename, filemode);
break;
case efTNG:
gmx_tng_open(filename, filemode[0], &of->tng);
{
if (of->fp_trn)
{
- fwrite_trn(of->fp_trn, step, t, state_local->lambda[efptFEP],
- state_local->box, top_global->natoms,
- (mdof_flags & MDOF_X) ? state_global->x : NULL,
- (mdof_flags & MDOF_V) ? global_v : NULL,
- (mdof_flags & MDOF_F) ? f_global : NULL);
+ gmx_trr_write_frame(of->fp_trn, step, t, state_local->lambda[efptFEP],
+ state_local->box, top_global->natoms,
+ (mdof_flags & MDOF_X) ? state_global->x : NULL,
+ (mdof_flags & MDOF_V) ? global_v : NULL,
+ (mdof_flags & MDOF_F) ? f_global : NULL);
if (gmx_fio_flush(of->fp_trn) != 0)
{
gmx_file("Cannot write trajectory; maybe you are out of disk space?");
}
gmx_fwrite_tng(of->tng, FALSE, step, t, state_local->lambda[efptFEP],
- (const rvec *) state_local->box,
+ state_local->box,
top_global->natoms,
- (mdof_flags & MDOF_X) ? (const rvec *) state_global->x : NULL,
- (mdof_flags & MDOF_V) ? (const rvec *) global_v : NULL,
- (mdof_flags & MDOF_F) ? (const rvec *) f_global : NULL);
+ (mdof_flags & MDOF_X) ? state_global->x : NULL,
+ (mdof_flags & MDOF_V) ? global_v : NULL,
+ (mdof_flags & MDOF_F) ? f_global : NULL);
}
if (mdof_flags & MDOF_X_COMPRESSED)
{
step,
t,
state_local->lambda[efptFEP],
- (const rvec *) state_local->box,
+ state_local->box,
of->natoms_x_compressed,
- (const rvec *) xxtc,
+ xxtc,
NULL,
NULL);
if (of->natoms_x_compressed != of->natoms_global)
}
if (of->fp_trn)
{
- close_trn(of->fp_trn);
+ gmx_trr_close(of->fp_trn);
}
if (of->fp_dhdl != NULL)
{
*/
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/xdrf.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/linearalgebra/sparsematrix.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/fatalerror.h"
gmx_sparsematrix_t * sparse_matrix)
{
t_fileio *fio;
- XDR * xd;
int i, j, prec;
- gmx_bool bDum = TRUE;
- gmx_bool bRead = FALSE;
size_t sz;
if (full_matrix != NULL && sparse_matrix != NULL)
}
fio = gmx_fio_open(filename, "w");
- gmx_fio_checktype(fio);
- xd = gmx_fio_getxdr(fio);
/* Write magic number */
i = GMX_MTXIO_MAGIC_NUMBER;
i = GMX_MTXIO_FULL_MATRIX;
gmx_fio_do_int(fio, i);
sz = nrow*ncol;
- bDum = gmx_fio_ndo_real(fio, full_matrix, sz);
+ gmx_fio_ndo_real(fio, full_matrix, sz);
}
else
{
{
gmx_fatal(FARGS, "Internal inconsistency in sparse matrix.\n");
}
- bDum = gmx_fio_ndo_int(fio, sparse_matrix->ndata, sparse_matrix->nrow);
+ gmx_fio_ndo_int(fio, sparse_matrix->ndata, sparse_matrix->nrow);
for (i = 0; i < sparse_matrix->nrow; i++)
{
for (j = 0; j < sparse_matrix->ndata[i]; j++)
gmx_sparsematrix_t ** sparse_matrix)
{
t_fileio *fio;
- XDR * xd;
int i, j, prec;
- gmx_bool bDum = TRUE;
- gmx_bool bRead = TRUE;
char gmxver[256];
size_t sz;
fio = gmx_fio_open(filename, "r");
- gmx_fio_checktype(fio);
- xd = gmx_fio_getxdr(fio);
/* Read and check magic number */
i = GMX_MTXIO_MAGIC_NUMBER;
sz = (*nrow) * (*ncol);
snew((*full_matrix), sz);
- bDum = gmx_fio_ndo_real(fio, (*full_matrix), sz);
+ gmx_fio_ndo_real(fio, (*full_matrix), sz);
}
else if (NULL != sparse_matrix)
{
snew((*sparse_matrix)->ndata, (*sparse_matrix)->nrow);
snew((*sparse_matrix)->nalloc, (*sparse_matrix)->nrow);
snew((*sparse_matrix)->data, (*sparse_matrix)->nrow);
- bDum = gmx_fio_ndo_int(fio, (*sparse_matrix)->ndata,
- (*sparse_matrix)->nrow);
+ gmx_fio_ndo_int(fio, (*sparse_matrix)->ndata,
+ (*sparse_matrix)->nrow);
for (i = 0; i < (*sparse_matrix)->nrow; i++)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "pdbio.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cctype>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/copyrite.h"
int i, length;
char temp;
- length = strlen(name);
- if (length > 3 && isdigit(name[0]))
+ length = std::strlen(name);
+ if (length > 3 && std::isdigit(name[0]))
{
temp = name[0];
for (i = 1; i < length; i++)
int i, length;
char temp;
- length = strlen(name);
- if (length > 3 && isdigit(name[length-1]))
+ length = std::strlen(name);
+ if (length > 3 && std::isdigit(name[length-1]))
{
temp = name[length-1];
for (i = length-1; i > 0; --i)
if (norm2(box[YY])*norm2(box[ZZ]) != 0)
{
- alpha = RAD2DEG*acos(cos_angle_no_table(box[YY], box[ZZ]));
+ alpha = RAD2DEG*std::acos(cos_angle_no_table(box[YY], box[ZZ]));
}
else
{
}
if (norm2(box[XX])*norm2(box[ZZ]) != 0)
{
- beta = RAD2DEG*acos(cos_angle_no_table(box[XX], box[ZZ]));
+ beta = RAD2DEG*std::acos(cos_angle_no_table(box[XX], box[ZZ]));
}
else
{
}
if (norm2(box[XX])*norm2(box[YY]) != 0)
{
- gamma = RAD2DEG*acos(cos_angle_no_table(box[XX], box[YY]));
+ gamma = RAD2DEG*std::acos(cos_angle_no_table(box[XX], box[YY]));
}
else
{
{
if (alpha != 90.0)
{
- cosa = cos(alpha*DEG2RAD);
+ cosa = std::cos(alpha*DEG2RAD);
}
else
{
}
if (beta != 90.0)
{
- cosb = cos(beta*DEG2RAD);
+ cosb = std::cos(beta*DEG2RAD);
}
else
{
}
if (gamma != 90.0)
{
- cosg = cos(gamma*DEG2RAD);
- sing = sin(gamma*DEG2RAD);
+ cosg = std::cos(gamma*DEG2RAD);
+ sing = std::sin(gamma*DEG2RAD);
}
else
{
box[YY][YY] = fb*sing;
box[ZZ][XX] = fc*cosb;
box[ZZ][YY] = fc*(cosa - cosb*cosg)/sing;
- box[ZZ][ZZ] = sqrt(fc*fc
- - box[ZZ][XX]*box[ZZ][XX] - box[ZZ][YY]*box[ZZ][YY]);
+ box[ZZ][ZZ] = std::sqrt(fc*fc
+ - box[ZZ][XX]*box[ZZ][XX] - box[ZZ][YY]*box[ZZ][YY]);
}
else
{
char altloc;
real occup, bfac;
gmx_bool bOccup;
- int nlongname = 0;
int chainnum, lastchainnum;
- int lastresind, lastchainresind;
gmx_residuetype_t*rt;
const char *p_restype;
const char *p_lastrestype;
fprintf(out, "MODEL %8d\n", model_nr > 0 ? model_nr : 1);
- lastchainresind = -1;
lastchainnum = -1;
- resind = -1;
p_restype = NULL;
for (ii = 0; ii < nindex; ii++)
{
i = index[ii];
- lastresind = resind;
resind = atoms->atom[i].resind;
chainnum = atoms->resinfo[resind].chainnum;
p_lastrestype = p_restype;
fprintf(out, "TER\n");
}
lastchainnum = chainnum;
- lastchainresind = lastresind;
}
strncpy(resnm, *atoms->resinfo[resind].name, sizeof(resnm)-1);
}
if (atoms->pdbinfo)
{
- type = (enum PDB_record)(atoms->pdbinfo[i].type);
+ type = static_cast<enum PDB_record>(atoms->pdbinfo[i].type);
altloc = atoms->pdbinfo[i].altloc;
if (!isalnum(altloc))
{
for (k = 0; (k < epdbNR); k++)
{
- if (strncmp(type, pdbtp[k], strlen(pdbtp[k])) == 0)
+ if (std::strncmp(type, pdbtp[k], strlen(pdbtp[k])) == 0)
{
break;
}
trim(anm);
/* Search backwards for number and name only */
- atomnr = strtol(anr, NULL, 10);
+ atomnr = std::strtol(anr, NULL, 10);
for (i = natom-1; (i >= 0); i--)
{
- if ((strcmp(anm, *(atoms->atomname[i])) == 0) &&
+ if ((std::strcmp(anm, *(atoms->atomname[i])) == 0) &&
(atomnr == atoms->pdbinfo[i].atomnr))
{
break;
}
for (i = 0; (i < atoms->nr); i++)
{
- strcpy(anm, atoms->pdbinfo[i].atomnm);
- strcpy(anm_copy, atoms->pdbinfo[i].atomnm);
+ std::strcpy(anm, atoms->pdbinfo[i].atomnm);
+ std::strcpy(anm_copy, atoms->pdbinfo[i].atomnm);
len = strlen(anm);
atomnumber = NOTSET;
- if ((anm[0] != ' ') && ((len <= 2) || ((len > 2) && !isdigit(anm[2]))))
+ if ((anm[0] != ' ') && ((len <= 2) || ((len > 2) && !std::isdigit(anm[2]))))
{
anm_copy[2] = nc;
if (gmx_atomprop_query(aps, epropElement, "???", anm_copy, &eval))
if (atomnumber == NOTSET)
{
k = 0;
- while ((k < strlen(anm)) && (isspace(anm[k]) || isdigit(anm[k])))
+ while ((k < std::strlen(anm)) && (std::isspace(anm[k]) || std::isdigit(anm[k])))
{
k++;
}
}
atoms->atom[i].atomnumber = atomnumber;
ptr = gmx_atomprop_element(aps, atomnumber);
- strncpy(atoms->atom[i].elem, ptr == NULL ? "" : ptr, 4);
+ std::strncpy(atoms->atom[i].elem, ptr == NULL ? "" : ptr, 4);
if (debug)
{
fprintf(debug, "Atomnumber for atom '%s' is %d\n", anm, atomnumber);
anm[k] = line[j];
}
anm[k] = nc;
- strcpy(anm_copy, anm);
+ std::strcpy(anm_copy, anm);
rtrim(anm_copy);
atomnumber = NOTSET;
trim(anm);
}
rnr[k] = nc;
trim(rnr);
- resnr = strtol(rnr, NULL, 10);
+ resnr = std::strtol(rnr, NULL, 10);
resic = line[j];
j += 4;
{
char buf[30];
- strcpy(buf, nm);
+ std::strcpy(buf, nm);
trim(buf);
if (buf[0] == 'H')
{
return TRUE;
}
- else if ((isdigit(buf[0])) && (buf[1] == 'H'))
+ else if ((std::isdigit(buf[0])) && (buf[1] == 'H'))
{
return TRUE;
}
{
char buf[30];
- strcpy(buf, nm);
+ std::strcpy(buf, nm);
trim(buf);
- if ((buf[0] == 'M') && isdigit(buf[strlen(buf)-1]))
+ if ((buf[0] == 'M') && std::isdigit(buf[strlen(buf)-1]))
{
return TRUE;
}
{
do
{
- strcat(form2, "%*s");
+ std::strcat(form2, "%*s");
sprintf(format, "%s%%d", form2);
n = sscanf(line, format, &aj);
if (n == 1)
snew(gc, 1);
- return (gmx_conect) gc;
+ return gc;
}
void gmx_conect_done(gmx_conect conect)
{
- gmx_conect_t *gc = (gmx_conect_t *)conect;
+ gmx_conect_t *gc = conect;
sfree(gc->conect);
}
gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj)
{
- gmx_conect_t *gc = (gmx_conect_t *)conect;
+ gmx_conect_t *gc = conect;
int i;
/* if (!gc->bSorted)
void gmx_conect_add(gmx_conect conect, int ai, int aj)
{
gmx_conect_t *gc = (gmx_conect_t *)conect;
- int i;
/* if (!gc->bSorted)
sort_conect(gc);*/
t_atoms *atoms, rvec x[], int *ePBC, matrix box, gmx_bool bChange,
gmx_conect conect)
{
- gmx_conect_t *gc = (gmx_conect_t *)conect;
+ gmx_conect_t *gc = conect;
t_symtab symtab;
gmx_bool bCOMPND;
gmx_bool bConnWarn = FALSE;
char line[STRLEN+1];
int line_type;
char *c, *d;
- int natom, chainnum, nres_ter_prev = 0;
- char chidmax = ' ';
+ int natom, chainnum;
gmx_bool bStop = FALSE;
if (ePBC)
case epdbTITLE:
case epdbHEADER:
- if (strlen(line) > 6)
+ if (std::strlen(line) > 6)
{
c = line+6;
/* skip HEADER or TITLE and spaces */
c++;
}
/* truncate after title */
- d = strstr(c, " ");
+ d = std::strstr(c, " ");
if (d)
{
d[0] = '\0';
}
- if (strlen(c) > 0)
+ if (std::strlen(c) > 0)
{
- strcpy(title, c);
+ std::strcpy(title, c);
}
}
break;
case epdbCOMPND:
- if ((!strstr(line, ": ")) || (strstr(line+6, "MOLECULE:")))
+ if ((!std::strstr(line, ": ")) || (std::strstr(line+6, "MOLECULE:")))
{
- if (!(c = strstr(line+6, "MOLECULE:")) )
+ if (!(c = std::strstr(line+6, "MOLECULE:")) )
{
c = line;
}
{
if (bCOMPND)
{
- strcat(title, "; ");
- strcat(title, c);
+ std::strcat(title, "; ");
+ std::strcat(title, c);
}
else
{
- strcpy(title, c);
+ std::strcpy(title, c);
}
}
bCOMPND = TRUE;
*natoms = 0;
while (fgets2(line, STRLEN, in))
{
- if (strncmp(line, "ENDMDL", 6) == 0)
+ if (std::strncmp(line, "ENDMDL", 6) == 0)
{
break;
}
- if ((strncmp(line, "ATOM ", 6) == 0) || (strncmp(line, "HETATM", 6) == 0))
+ if ((std::strncmp(line, "ATOM ", 6) == 0) || (std::strncmp(line, "HETATM", 6) == 0))
{
(*natoms)++;
}
/* If the atom name is an element name with two chars, it should start already in column 13.
* Otherwise it should start in column 14, unless the name length is 4 chars.
*/
- if ( (element != NULL) && (strlen(element) >= 2) && (gmx_strncasecmp(atom_name, element, 2) == 0) )
+ if ( (element != NULL) && (std::strlen(element) >= 2) && (gmx_strncasecmp(atom_name, element, 2) == 0) )
{
start_name_in_col13 = TRUE;
}
else
{
- start_name_in_col13 = (strlen(atom_name) >= 4);
+ start_name_in_col13 = (std::strlen(atom_name) >= 4);
}
sprintf(tmp_atomname, start_name_in_col13 ? "" : " ");
- strncat(tmp_atomname, atom_name, 4);
+ std::strncat(tmp_atomname, atom_name, 4);
tmp_atomname[5] = '\0';
}
else
}
/* Format residue name */
- strncpy(tmp_resname, (res_name != NULL) ? res_name : "", 4);
+ std::strncpy(tmp_resname, (res_name != NULL) ? res_name : "", 4);
/* Make sure the string is terminated if strlen was > 4 */
tmp_resname[4] = '\0';
/* String is properly terminated, so now we can use strcat. By adding a
* space we can write it right-justified, and if the original name was
* three characters or less there will be a space added on the right side.
*/
- strcat(tmp_resname, " ");
+ std::strcat(tmp_resname, " ");
/* Truncate integers so they fit */
atom_seq_number = atom_seq_number % 100000;
#include "strdb.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
sfree(line0);
return FALSE;
}
- dum = strchr(line0, '\n');
+ dum = std::strchr(line0, '\n');
if (dum)
{
dum[0] = '\0';
}
- else if (strlen(line0) == n)
+ else if (static_cast<int>(std::strlen(line0)) == n)
{
fprintf(stderr, "Warning: line length exceeds buffer length (%d), data might be corrupted\n", n);
line0[n-1] = '\0';
fprintf(stderr, "Warning: file does not end with a newline, last line:\n%s\n",
line0);
}
- dum = strchr(line0, ';');
+ dum = std::strchr(line0, ';');
if (dum)
{
dum[0] = '\0';
}
- strncpy(line, line0, n);
+ std::strncpy(line, line0, n);
dum = line0;
ltrim(dum);
}
{
char temp[STRLEN], *dum;
- strcpy(temp, line);
- dum = strchr(temp, '[');
+ std::strcpy(temp, line);
+ dum = std::strchr(temp, '[');
if (dum == NULL)
{
return FALSE;
}
dum[0] = ' ';
- dum = strchr(temp, ']');
+ dum = std::strchr(temp, ']');
if (dum == NULL)
{
gmx_fatal(FARGS, "header is not terminated on line:\n'%s'\n", line);
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-if(GMX_USE_TNG)
- gmx_add_unit_test(FileIOTests fileio-test
- tngio.cpp)
+set(test_sources
+ confio.cpp
+ )
+if (GMX_USE_TNG)
+ list(APPEND test_sources tngio.cpp)
endif()
+gmx_add_unit_test(FileIOTests fileio-test ${test_sources})
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Tests for reading/writing different structure file formats.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_fileio
+ */
+#include "gmxpre.h"
+
+#include "gromacs/fileio/confio.h"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "gromacs/fileio/filenm.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/math/vectypes.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/topology/topology.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/smalloc.h"
+
+#include "testutils/stringtest.h"
+#include "testutils/testfilemanager.h"
+
+// TODO: These should really appear somewhere centralized.
+/*! \brief
+ * Google Test formatter for GromacsFileType values.
+ */
+void PrintTo(const GromacsFileType &ftp, std::ostream *os)
+{
+ *os << "'" << ftp2ext(ftp) << "'";
+}
+
+namespace
+{
+
+class StructureIORoundtripTest : public gmx::test::StringTestBase,
+ public ::testing::WithParamInterface<GromacsFileType>
+{
+ public:
+ StructureIORoundtripTest()
+ {
+ generateReferenceTopology();
+ generateReferenceCoordinates();
+ testTop_ = NULL;
+ testX_ = NULL;
+ clear_mat(testBox_);
+ referenceFilename_ =
+ fileManager_.getTemporaryFilePath(getFileSuffix("ref"));
+ testFilename_ =
+ fileManager_.getTemporaryFilePath(getFileSuffix("test"));
+ }
+ ~StructureIORoundtripTest()
+ {
+ if (testTop_ != NULL)
+ {
+ free_t_atoms(&testTop_->atoms, TRUE);
+ done_top(testTop_);
+ sfree(testTop_);
+ }
+ sfree(testX_);
+ done_top(refTop_);
+ sfree(refTop_);
+ }
+
+ void writeReferenceFile()
+ {
+ write_sto_conf(referenceFilename_.c_str(), *refTop_->name,
+ &refTop_->atoms, as_rvec_array(&refX_[0]), NULL, -1,
+ refBox_);
+ }
+
+ void readReferenceFileStx()
+ {
+ int natoms = -1;
+ get_stx_coordnum(referenceFilename_.c_str(), &natoms);
+ ASSERT_EQ(refTop_->atoms.nr, natoms)
+ << "get_stx_coordnum() returned unexpected number of atoms";
+ char title[STRLEN];
+ snew(testTop_, 1);
+ init_t_atoms(&testTop_->atoms, natoms, GetParam() == efPDB);
+ snew(testX_, natoms);
+ read_stx_conf(referenceFilename_.c_str(), title, &testTop_->atoms,
+ testX_, NULL, NULL, testBox_);
+ testTop_->name = put_symtab(&testTop_->symtab, title);
+ }
+
+ void readReferenceFileTps()
+ {
+ snew(testTop_, 1);
+ int ePBC = -2;
+ char title[STRLEN];
+ read_tps_conf(referenceFilename_.c_str(), title, testTop_,
+ &ePBC, &testX_, NULL, testBox_, FALSE);
+ testTop_->name = put_symtab(&testTop_->symtab, title);
+ }
+
+ void testTopologies()
+ {
+ // TODO: Compare the topologies.
+ }
+
+ void writeTestFileAndTest()
+ {
+ write_sto_conf(testFilename_.c_str(), *testTop_->name,
+ &testTop_->atoms, testX_, NULL, -1, testBox_);
+ testFilesEqual(referenceFilename_, testFilename_);
+ }
+
+ private:
+ std::string getFileSuffix(const char *type)
+ {
+ return std::string(type) + "." + ftp2ext(GetParam());
+ }
+
+ void generateReferenceTopology()
+ {
+ snew(refTop_, 1);
+ open_symtab(&refTop_->symtab);
+ if (GetParam() == efESP)
+ {
+ // Titles cannot be read from an .esp file...
+ refTop_->name = put_symtab(&refTop_->symtab, "");
+ }
+ else
+ {
+ refTop_->name = put_symtab(&refTop_->symtab, "Test title");
+ }
+ const int atomCount = 10;
+ init_t_atoms(&refTop_->atoms, atomCount, FALSE);
+ for (int i = 0; i < atomCount; ++i)
+ {
+ char name[3];
+ name[0] = 'A';
+ name[1] = 'A' + i%3;
+ name[2] = '\0';
+ refTop_->atoms.atomname[i] = put_symtab(&refTop_->symtab, name);
+ refTop_->atoms.atom[i].resind = i/3;
+ if (i%3 == 0)
+ {
+ char resname[3];
+ resname[0] = 'R';
+ resname[1] = 'A' + i/3;
+ resname[2] = '\0';
+ t_atoms_set_resinfo(&refTop_->atoms, i, &refTop_->symtab,
+ resname, i/3 + 1, ' ', 0, ' ');
+ }
+ }
+ refTop_->atoms.nres = 4;
+ close_symtab(&refTop_->symtab);
+ }
+
+ void generateReferenceCoordinates()
+ {
+ clear_mat(refBox_);
+ refBox_[XX][XX] = 1;
+ refBox_[YY][YY] = 2;
+ refBox_[ZZ][ZZ] = 3;
+ const int atomCount = refTop_->atoms.nr;
+ refX_.reserve(atomCount);
+ for (int i = 0; i < atomCount; ++i)
+ {
+ refX_.push_back(gmx::RVec(i%4, i/4, (i/2)%3));
+ }
+ }
+
+ gmx::test::TestFileManager fileManager_;
+ std::string referenceFilename_;
+ std::string testFilename_;
+ t_topology *refTop_;
+ std::vector<gmx::RVec> refX_;
+ matrix refBox_;
+ t_topology *testTop_;
+ rvec *testX_;
+ matrix testBox_;
+};
+
+TEST_P(StructureIORoundtripTest, ReadWriteStxConf)
+{
+ writeReferenceFile();
+ readReferenceFileStx();
+ testTopologies();
+ writeTestFileAndTest();
+}
+
+TEST_P(StructureIORoundtripTest, ReadWriteTpsConf)
+{
+ writeReferenceFile();
+ readReferenceFileTps();
+ testTopologies();
+ writeTestFileAndTest();
+}
+
+INSTANTIATE_TEST_CASE_P(WithDifferentFormats,
+ StructureIORoundtripTest,
+ ::testing::Values(efGRO, efG96, efPDB, efESP));
+
+} // namespace
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "tng/tng_io.h"
#endif
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/copyrite.h"
#include "gromacs/legacyheaders/types/ifunc.h"
#include "gromacs/math/units.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/sysinfo.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#include <math.h>
+#include <cmath>
#ifdef GMX_USE_TNG
#include "tng/tng_io.h"
frame->step,
frame->time,
0,
- (const rvec *) frame->box,
+ frame->box,
natoms,
- (const rvec *) frame->x,
- (const rvec *) frame->v,
- (const rvec *) frame->f);
+ frame->x,
+ frame->v,
+ frame->f);
#else
GMX_UNUSED_VALUE(output);
GMX_UNUSED_VALUE(frame);
{
for (j = 0; j < nValues; j++)
{
- to[i*nValues+j] = (real)((float *)from)[i*nValues+j] * fact;
+ to[i*nValues+j] = reinterpret_cast<float *>(from)[i*nValues+j] * fact;
}
}
}
{
for (j = 0; j < nValues; j++)
{
- to[i*nValues+j] = (real)((float *)from)[i*nValues+j] * fact;
+ to[i*nValues+j] = reinterpret_cast<float *>(from)[i*nValues+j] * fact;
}
}
}
{
for (j = 0; j < nValues; j++)
{
- to[i*nValues+j] = (real)((gmx_int64_t *)from)[i*nValues+j] * fact;
+ to[i*nValues+j] = reinterpret_cast<gmx_int64_t *>(from)[i*nValues+j] * fact;
}
}
break;
{
for (j = 0; j < nValues; j++)
{
- to[i*nValues+j] = (real)((double *)from)[i*nValues+j] * fact;
+ to[i*nValues+j] = reinterpret_cast<double *>(from)[i*nValues+j] * fact;
}
}
}
{
for (j = 0; j < nValues; j++)
{
- to[i*nValues+j] = (real)((double *)from)[i*nValues+j] * fact;
+ to[i*nValues+j] = reinterpret_cast<double *>(from)[i*nValues+j] * fact;
}
}
}
}
for (int i = 0; i < DIM; i++)
{
- convert_array_to_real_array((char *)(values) + size * i * DIM,
- (real *) fr->box[i],
+ convert_array_to_real_array(reinterpret_cast<char *>(values) + size * i * DIM,
+ reinterpret_cast<real *>(fr->box[i]),
getDistanceScaleFactor(input),
1,
DIM,
case TNG_TRAJ_POSITIONS:
srenew(fr->x, fr->natoms);
convert_array_to_real_array(values,
- (real *) fr->x,
+ reinterpret_cast<real *>(fr->x),
getDistanceScaleFactor(input),
fr->natoms,
DIM,
case TNG_TRAJ_FORCES:
srenew(fr->f, fr->natoms);
convert_array_to_real_array(values,
- (real *) fr->f,
+ reinterpret_cast<real *>(fr->f),
getDistanceScaleFactor(input),
fr->natoms,
DIM,
switch (datatype)
{
case TNG_FLOAT_DATA:
- fr->lambda = (*(float *)values);
+ fr->lambda = *(reinterpret_cast<float *>(values));
break;
case TNG_DOUBLE_DATA:
- fr->lambda = (*(double *)values);
+ fr->lambda = *(reinterpret_cast<double *>(values));
break;
default:
gmx_incons("Illegal datatype lambda value!");
* be reallocated if it is not NULL. */
}
- fr->step = (int) frameNumber;
+ fr->step = static_cast<int>(frameNumber);
fr->bStep = TRUE;
// Convert the time to ps
fr->time = frameTime / PICO;
#include "tpxio.h"
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
-#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/filenm.h"
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/legacyheaders/copyrite.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/names.h"
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/math/vec.h"
-#include "gromacs/topology/atomprop.h"
#include "gromacs/topology/block.h"
#include "gromacs/topology/mtop_util.h"
#include "gromacs/topology/symtab.h"
gmx_bool bRead,
int file_version)
{
- int i;
rvec tmp;
gmx_fio_do_int(fio, pgrp->nat);
static void do_pull_group(t_fileio *fio, t_pull_group *pgrp, gmx_bool bRead)
{
- int i;
-
gmx_fio_do_int(fio, pgrp->nat);
if (bRead)
{
static void do_pull_coord(t_fileio *fio, t_pull_coord *pcrd, int file_version,
int ePullOld, int eGeomOld, ivec dimOld)
{
- int i;
-
gmx_fio_do_int(fio, pcrd->group[0]);
gmx_fio_do_int(fio, pcrd->group[1]);
if (file_version >= tpxv_PullCoordTypeGeom)
static void do_expandedvals(t_fileio *fio, t_expanded *expand, t_lambda *fepvals, gmx_bool bRead, int file_version)
{
- /* i is used in the ndo_double macro*/
- int i;
- real fv;
- real rdum;
int n_lambda = fepvals->n_lambda;
/* reset the lambda calculation window */
static void do_fepvals(t_fileio *fio, t_lambda *fepvals, gmx_bool bRead, int file_version)
{
/* i is defined in the ndo_double macro; use g to iterate. */
- int i, g;
- real fv;
+ int g;
real rdum;
/* free energy values */
static void do_pull(t_fileio *fio, pull_params_t *pull, gmx_bool bRead,
int file_version, int ePullOld)
{
- int eGeomOld;
+ int eGeomOld = -1;
ivec dimOld;
int g;
for (g = 0; g < pull->ngroup; g++)
{
/* We read and ignore a pull coordinate for group 0 */
- do_pullgrp_tpx_pre95(fio, &pull->group[g], &pull->coord[max(g-1, 0)],
+ do_pullgrp_tpx_pre95(fio, &pull->group[g], &pull->coord[std::max(g-1, 0)],
bRead, file_version);
if (g > 0)
{
static void do_rotgrp(t_fileio *fio, t_rotgrp *rotg, gmx_bool bRead)
{
- int i;
-
gmx_fio_do_int(fio, rotg->eType);
gmx_fio_do_int(fio, rotg->bMassW);
gmx_fio_do_int(fio, rotg->nat);
static void do_swapcoords(t_fileio *fio, t_swapcoords *swap, gmx_bool bRead)
{
- int i, j;
-
+ int j;
gmx_fio_do_int(fio, swap->nat);
gmx_fio_do_int(fio, swap->nat_sol);
int idum;
real rdum;
- if (!bRead)
- {
- gmx_fio_set_comment(fio, interaction_function[ftype].name);
- }
switch (ftype)
{
case F_ANGLES:
gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d",
ftype, interaction_function[ftype].name, __FILE__, __LINE__);
}
- if (!bRead)
- {
- gmx_fio_unset_comment(fio);
- }
}
-static void do_ilist(t_fileio *fio, t_ilist *ilist, gmx_bool bRead, int file_version,
- int ftype)
+static void do_ilist(t_fileio *fio, t_ilist *ilist, gmx_bool bRead, int file_version)
{
- int i, k, idum;
+ int i, idum;
- if (!bRead)
- {
- gmx_fio_set_comment(fio, interaction_function[ftype].name);
- }
if (file_version < 44)
{
for (i = 0; i < MAXNODES; i++)
snew(ilist->iatoms, ilist->nr);
}
gmx_fio_ndo_int(fio, ilist->iatoms, ilist->nr);
- if (!bRead)
- {
- gmx_fio_unset_comment(fio);
- }
}
static void do_ffparams(t_fileio *fio, gmx_ffparams_t *ffparams,
gmx_bool bRead, int file_version)
{
- int idum, i, j;
+ int idum, i;
unsigned int k;
gmx_fio_do_int(fio, ffparams->atnr);
static void do_ilists(t_fileio *fio, t_ilist *ilist, gmx_bool bRead,
int file_version)
{
- int i, j, renum[F_NRE];
+ int j;
gmx_bool bClear;
unsigned int k;
}
else
{
- do_ilist(fio, &ilist[j], bRead, file_version, j);
+ do_ilist(fio, &ilist[j], bRead, file_version);
if (file_version < 78 && j == F_SETTLE && ilist[j].nr > 0)
{
add_settle_atoms(&ilist[j]);
int file_version, gmx_groups_t *groups, int atnr)
{
int i, myngrp;
- char * p_elem;
gmx_fio_do_real(fio, atom->m);
gmx_fio_do_real(fio, atom->q);
/* Set element string from atomic number if present.
* This routine returns an empty string if the name is not found.
*/
- strncpy(atom->elem, atomicnumber_to_element(atom->atomnumber), 4);
+ std::strncpy(atom->elem, atomicnumber_to_element(atom->atomnumber), 4);
/* avoid warnings about potentially unterminated string */
atom->elem[3] = '\0';
}
static void do_grps(t_fileio *fio, int ngrp, t_grps grps[], gmx_bool bRead,
int file_version)
{
- int i, j, myngrp;
+ int j, myngrp;
if (file_version < 23)
{
gmx_bool bRead, t_symtab *symtab,
int file_version)
{
- int g, n, i;
+ int g;
do_grps(fio, egcNR, groups->grps, bRead, file_version);
gmx_fio_do_int(fio, groups->ngrpname);
static void do_atomtypes(t_fileio *fio, t_atomtypes *atomtypes, gmx_bool bRead,
int file_version)
{
- int i, j;
+ int j;
if (file_version > 25)
{
}
-void tpx_make_chain_identifiers(t_atoms *atoms, t_block *mols)
-{
- int m, a, a0, a1, r;
- char c, chainid;
- int chainnum;
-
- /* We always assign a new chain number, but save the chain id characters
- * for larger molecules.
- */
-#define CHAIN_MIN_ATOMS 15
-
- chainnum = 0;
- chainid = 'A';
- for (m = 0; m < mols->nr; m++)
- {
- a0 = mols->index[m];
- a1 = mols->index[m+1];
- if ((a1-a0 >= CHAIN_MIN_ATOMS) && (chainid <= 'Z'))
- {
- c = chainid;
- chainid++;
- }
- else
- {
- c = ' ';
- }
- for (a = a0; a < a1; a++)
- {
- atoms->resinfo[atoms->atom[a].resind].chainnum = chainnum;
- atoms->resinfo[atoms->atom[a].resind].chainid = c;
- }
- chainnum++;
- }
-
- /* Blank out the chain id if there was only one chain */
- if (chainid == 'B')
- {
- for (r = 0; r < atoms->nres; r++)
- {
- atoms->resinfo[r].chainid = ' ';
- }
- }
-}
-
static void do_moltype(t_fileio *fio, gmx_moltype_t *molt, gmx_bool bRead,
t_symtab *symtab, int file_version,
gmx_groups_t *groups)
{
- int i;
-
if (file_version >= 57)
{
do_symstr(fio, &(molt->name), bRead, symtab);
static void do_molblock(t_fileio *fio, gmx_molblock_t *molb, gmx_bool bRead)
{
- int i;
-
gmx_fio_do_int(fio, molb->type);
gmx_fio_do_int(fio, molb->nmol);
gmx_fio_do_int(fio, molb->natoms_mol);
for (i = 0; i < il->nr; i += 2)
{
ip = &mtop->ffparams.iparams[il->iatoms[i]];
- am = max(am, il->iatoms[i+1]);
+ am = std::max(am, il->iatoms[i+1]);
if (ip->posres.pos0B[XX] != ip->posres.pos0A[XX] ||
ip->posres.pos0B[YY] != ip->posres.pos0A[YY] ||
ip->posres.pos0B[ZZ] != ip->posres.pos0A[ZZ])
{
for (i = 0; i < ilfb->nr; i += 2)
{
- ip = &mtop->ffparams.iparams[ilfb->iatoms[i]];
- am = max(am, ilfb->iatoms[i+1]);
+ am = std::max(am, ilfb->iatoms[i+1]);
}
}
/* Make the posres coordinate block end at a molecule end */
static void do_mtop(t_fileio *fio, gmx_mtop_t *mtop, gmx_bool bRead,
int file_version)
{
- int mt, mb, i;
+ int mt, mb;
t_blocka dumb;
if (bRead)
int idum = 0;
real rdum = 0;
- gmx_fio_checktype(fio);
- gmx_fio_setdebug(fio, bDebugMode());
-
/* XDR binary topology file */
precision = sizeof(real);
if (bRead)
{
gmx_fio_do_string(fio, buf);
- if (strncmp(buf, "VERSION", 7))
+ if (std::strncmp(buf, "VERSION", 7))
{
gmx_fatal(FARGS, "Can not read file %s,\n"
" this file is from a GROMACS version which is older than 2.0\n"
sprintf(file_tag, "%s", TPX_TAG_RELEASE);
}
- if (strcmp(file_tag, tpx_tag) != 0)
+ if (std::strcmp(file_tag, tpx_tag) != 0)
{
fprintf(stderr, "Note: file tpx tag '%s', software tpx tag '%s'\n",
file_tag, tpx_tag);
/* We only support reading tpx files with the same tag as the code
* or tpx files with the release tag and with lower version number.
*/
- if (strcmp(file_tag, TPX_TAG_RELEASE) != 0 && fver < tpx_version)
+ if (std::strcmp(file_tag, TPX_TAG_RELEASE) != 0 && fver < tpx_version)
{
gmx_fatal(FARGS, "tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' with program for tpx version %d, tag '%s'",
gmx_fio_getname(fio), fver, file_tag,
gmx_mtop_t dum_top;
gmx_bool TopOnlyOK;
int file_version, file_generation;
- int i;
rvec *xptr, *vptr;
int ePBC;
gmx_bool bPeriodicMols;
return ePBC;
}
-/************************************************************
- *
- * The following routines are the exported ones
- *
- ************************************************************/
-
-t_fileio *open_tpx(const char *fn, const char *mode)
+static t_fileio *open_tpx(const char *fn, const char *mode)
{
return gmx_fio_open(fn, mode);
}
-void close_tpx(t_fileio *fio)
+static void close_tpx(t_fileio *fio)
{
gmx_fio_close(fio);
}
+/************************************************************
+ *
+ * The following routines are the exported ones
+ *
+ ************************************************************/
+
void read_tpxheader(const char *fn, t_tpxheader *tpx, gmx_bool TopOnlyOK,
int *file_version, int *file_generation)
{
rvec *x, rvec *v, rvec *f, t_topology *top)
{
gmx_mtop_t mtop;
- t_topology *ltop;
int ePBC;
ePBC = read_tpx(fn, ir, box, natoms, x, v, f, &mtop);
{
return (efTPR == fn2ftp(file));
}
-
-static void done_gmx_groups_t(gmx_groups_t *g)
-{
- int i;
-
- for (i = 0; (i < egcNR); i++)
- {
- if (NULL != g->grps[i].nm_ind)
- {
- sfree(g->grps[i].nm_ind);
- g->grps[i].nm_ind = NULL;
- }
- if (NULL != g->grpnr[i])
- {
- sfree(g->grpnr[i]);
- g->grpnr[i] = NULL;
- }
- }
- /* The contents of this array is in symtab, don't free it here */
- sfree(g->grpname);
-}
-
-gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *ePBC,
- rvec **x, rvec **v, matrix box, gmx_bool bMass)
-{
- t_tpxheader header;
- int natoms, i, version, generation;
- gmx_bool bTop, bXNULL = FALSE;
- gmx_mtop_t *mtop;
- t_topology *topconv;
- gmx_atomprop_t aps;
-
- bTop = fn2bTPX(infile);
- *ePBC = -1;
- if (bTop)
- {
- read_tpxheader(infile, &header, TRUE, &version, &generation);
- if (x)
- {
- snew(*x, header.natoms);
- }
- if (v)
- {
- snew(*v, header.natoms);
- }
- snew(mtop, 1);
- *ePBC = read_tpx(infile, NULL, box, &natoms,
- (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, NULL, mtop);
- *top = gmx_mtop_t_to_t_topology(mtop);
- /* In this case we need to throw away the group data too */
- done_gmx_groups_t(&mtop->groups);
- sfree(mtop);
- strcpy(title, *top->name);
- tpx_make_chain_identifiers(&top->atoms, &top->mols);
- }
- else
- {
- get_stx_coordnum(infile, &natoms);
- init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB));
- if (x == NULL)
- {
- snew(x, 1);
- bXNULL = TRUE;
- }
- snew(*x, natoms);
- if (v)
- {
- snew(*v, natoms);
- }
- read_stx_conf(infile, title, &top->atoms, *x, (v == NULL) ? NULL : *v, ePBC, box);
- if (bXNULL)
- {
- sfree(*x);
- sfree(x);
- }
- if (bMass)
- {
- aps = gmx_atomprop_init();
- for (i = 0; (i < natoms); i++)
- {
- if (!gmx_atomprop_query(aps, epropMass,
- *top->atoms.resinfo[top->atoms.atom[i].resind].name,
- *top->atoms.atomname[i],
- &(top->atoms.atom[i].m)))
- {
- if (debug)
- {
- fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n",
- *top->atoms.resinfo[top->atoms.atom[i].resind].name,
- top->atoms.resinfo[top->atoms.atom[i].resind].nr,
- *top->atoms.atomname[i]);
- }
- }
- }
- gmx_atomprop_destroy(aps);
- }
- top->idef.ntypes = -1;
- }
-
- return bTop;
-}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* The routines in the corresponding c-file tpxio.c
* are based on the lower level routines in gmxfio.c
- * The integer file pointer returned from open_tpx
- * can also be used with the routines in gmxfio.h
*
**************************************************************/
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/types/inputrec.h"
#include "gromacs/legacyheaders/types/state.h"
* These routines handle reading and writing of preprocessed
* topology files in any of the following formats:
* TPR : topology in XDR format, portable accross platforms
- * TRR : trajectory in XDR format (non compressed)
*
* Files are written in the precision with which the source are compiled,
* but double and single precision can be read by either.
*/
-t_fileio *open_tpx(const char *fn, const char *mode);
-/* Return an file pointer corresponding to the file you have just opened */
-
-void close_tpx(t_fileio *fio);
-/* Close the file corresponding to fio */
-
void read_tpxheader(const char *fn, t_tpxheader *tpx, gmx_bool TopOnlyOK,
int *version, int *generation);
/* Read the header from a tpx file and then close it again.
gmx_bool fn2bTPX(const char *file);
/* return if *file is one of the TPX file types */
-gmx_bool read_tps_conf(const char *infile, char *title, struct t_topology *top,
- int *ePBC, rvec **x, rvec **v, matrix box, gmx_bool bMass);
-/* Read title, top.atoms, x, v (if not NULL) and box from an STX file,
- * memory for atoms, x and v will be allocated.
- * Return TRUE if a complete topology was read.
- * If infile is a TPX file read the whole top,
- * else if bMass=TRUE, read the masses into top.atoms from the mass database.
- */
-
-void tpx_make_chain_identifiers(struct t_atoms *atoms, struct t_block *mols);
-
#ifdef __cplusplus
}
#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-
-#ifndef GMX_FILEIO_TRNIO_H
-#define GMX_FILEIO_TRNIO_H
-
-/**************************************************************
- *
- * These routines handle trr (trajectory) I/O, they read and
- * write trr files. The routines should be able to read single
- * and double precision files without the user noting it.
- * The files are backward compatible, therefore the header holds
- * some unused variables.
- *
- * The routines in the corresponding c-file trnio.c
- * are based on the lower level routines in gmxfio.c
- * The integer file pointer returned from open_trn
- * can also be used with the routines in gmxfio.h
- *
- **************************************************************/
-
-#include "gromacs/fileio/gmxfio.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct /* This struct describes the order and the */
- /* sizes of the structs in a trjfile, sizes are given in bytes. */
-{
- gmx_bool bDouble; /* Double precision? */
- int ir_size; /* Backward compatibility */
- int e_size; /* Backward compatibility */
- int box_size; /* Non zero if a box is present */
- int vir_size; /* Backward compatibility */
- int pres_size; /* Backward compatibility */
- int top_size; /* Backward compatibility */
- int sym_size; /* Backward compatibility */
- int x_size; /* Non zero if coordinates are present */
- int v_size; /* Non zero if velocities are present */
- int f_size; /* Non zero if forces are present */
-
- int natoms; /* The total number of atoms */
- int step; /* Current step number */
- int nre; /* Backward compatibility */
- real t; /* Current time */
- real lambda; /* Current value of lambda */
- int fep_state; /* Current value of alchemical state */
-} t_trnheader;
-
-t_fileio *open_trn(const char *fn, const char *mode);
-/* Open a trr / trr file */
-
-void close_trn(t_fileio *fio);
-/* Close it */
-
-gmx_bool fread_trnheader(t_fileio *fio, t_trnheader *trn, gmx_bool *bOK);
-/* Read the header of a trn file. Return FALSE if there is no frame.
- * bOK will be FALSE when the header is incomplete.
- */
-
-void read_trnheader(const char *fn, t_trnheader *header);
-/* Read the header of a trn file from fn, and close the file afterwards.
- */
-
-void pr_trnheader(FILE *fp, int indent, char *title, t_trnheader *sh);
-/* Print the header of a trn file to fp */
-
-gmx_bool is_trn(FILE *fp);
-/* Return true when the file is a trn file. File will be rewound
- * afterwards.
- */
-
-void fwrite_trn(t_fileio *fio, int step, real t, real lambda,
- rvec *box, int natoms, rvec *x, rvec *v, rvec *f);
-/* Write a trn frame to file fp, box, x, v, f may be NULL */
-
-gmx_bool fread_htrn(t_fileio *fio, t_trnheader *sh,
- rvec *box, rvec *x, rvec *v, rvec *f);
-/* Extern read a frame except the header (that should be pre-read,
- * using routine read_trnheader, see above) from a trn file.
- * Return FALSE on error
- */
-
-gmx_bool fread_trn(t_fileio *fio, int *step, real *t, real *lambda,
- rvec *box, int *natoms, rvec *x, rvec *v, rvec *f);
-/* Read a trn frame, including the header from fp. box, x, v, f may
- * be NULL, in which case the data will be skipped over.
- * return FALSE on error
- */
-
-void write_trn(const char *fn, int step, real t, real lambda,
- rvec *box, int natoms, rvec *x, rvec *v, rvec *f);
-/* Write a single trn frame to file fn, which is closed afterwards */
-
-void read_trn(const char *fn, int *step, real *t, real *lambda,
- rvec *box, int *natoms, rvec *x, rvec *v, rvec *f);
-/* Read a single trn frame from file fn, which is closed afterwards
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "trnio.h"
+#include "trrio.h"
-#include <string.h>
+#include <cstring>
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/legacyheaders/names.h"
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/utility/fatalerror.h"
#define BUFSIZE 128
#define GROMACS_MAGIC 1993
-static int nFloatSize(t_trnheader *sh)
+static int nFloatSize(gmx_trr_header_t *sh)
{
int nflsize = 0;
}
else
{
- gmx_file("Can not determine precision of trn file");
+ gmx_file("Can not determine precision of trr file");
}
if (((nflsize != sizeof(float)) && (nflsize != sizeof(double))))
return nflsize;
}
-static gmx_bool do_trnheader(t_fileio *fio, gmx_bool bRead, t_trnheader *sh, gmx_bool *bOK)
+static gmx_bool
+do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *bOK)
{
int magic = GROMACS_MAGIC;
static gmx_bool bFirst = TRUE;
*bOK = TRUE;
- gmx_fio_checktype(fio);
-
if (!gmx_fio_do_int(fio, magic) || magic != GROMACS_MAGIC)
{
return FALSE;
*bOK = *bOK && gmx_fio_do_string(fio, buf);
if (bFirst)
{
- fprintf(stderr, "trn version: %s ", buf);
+ fprintf(stderr, "trr version: %s ", buf);
}
}
else
return *bOK;
}
-void pr_trnheader(FILE *fp, int indent, char *title, t_trnheader *sh)
-{
- if (sh)
- {
- indent = pr_title(fp, indent, title);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "box_size = %d\n", sh->box_size);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "x_size = %d\n", sh->x_size);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "v_size = %d\n", sh->v_size);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "f_size = %d\n", sh->f_size);
-
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "natoms = %d\n", sh->natoms);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "step = %d\n", sh->step);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "t = %e\n", sh->t);
- (void) pr_indent(fp, indent);
- (void) fprintf(fp, "lambda = %e\n", sh->lambda);
- }
-}
-
-static gmx_bool do_htrn(t_fileio *fio, t_trnheader *sh,
- rvec *box, rvec *x, rvec *v, rvec *f)
+static gmx_bool
+do_trr_frame_data(t_fileio *fio, gmx_trr_header_t *sh,
+ rvec *box, rvec *x, rvec *v, rvec *f)
{
matrix pv;
gmx_bool bOK;
return bOK;
}
-static gmx_bool do_trn(t_fileio *fio, gmx_bool bRead, int *step, real *t, real *lambda,
- rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
+static gmx_bool
+do_trr_frame(t_fileio *fio, bool bRead, int *step, real *t, real *lambda,
+ rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
{
- t_trnheader *sh;
- gmx_bool bOK;
+ gmx_trr_header_t *sh;
+ gmx_bool bOK;
snew(sh, 1);
if (!bRead)
sh->t = *t;
sh->lambda = *lambda;
}
- if (!do_trnheader(fio, bRead, sh, &bOK))
+ if (!do_trr_frame_header(fio, bRead, sh, &bOK))
{
return FALSE;
}
*lambda = sh->lambda;
if (sh->ir_size)
{
- gmx_file("inputrec in trn file");
+ gmx_file("inputrec in trr file");
}
if (sh->e_size)
{
- gmx_file("energies in trn file");
+ gmx_file("energies in trr file");
}
if (sh->top_size)
{
- gmx_file("topology in trn file");
+ gmx_file("topology in trr file");
}
if (sh->sym_size)
{
- gmx_file("symbol table in trn file");
+ gmx_file("symbol table in trr file");
}
}
- bOK = do_htrn(fio, sh, box, x, v, f);
+ bOK = do_trr_frame_data(fio, sh, box, x, v, f);
sfree(sh);
*
************************************************************/
-void read_trnheader(const char *fn, t_trnheader *trn)
+void gmx_trr_read_single_header(const char *fn, gmx_trr_header_t *header)
{
- t_fileio *fio;
+ t_fileio *fio = gmx_trr_open(fn, "r");
gmx_bool bOK;
-
- fio = open_trn(fn, "r");
- if (!do_trnheader(fio, TRUE, trn, &bOK))
+ if (!do_trr_frame_header(fio, true, header, &bOK))
{
gmx_fatal(FARGS, "Empty file %s", fn);
}
- close_trn(fio);
+ gmx_trr_close(fio);
}
-gmx_bool fread_trnheader(t_fileio *fio, t_trnheader *trn, gmx_bool *bOK)
+gmx_bool gmx_trr_read_frame_header(t_fileio *fio, gmx_trr_header_t *header, gmx_bool *bOK)
{
- return do_trnheader(fio, TRUE, trn, bOK);
+ return do_trr_frame_header(fio, true, header, bOK);
}
-void write_trn(const char *fn, int step, real t, real lambda,
- rvec *box, int natoms, rvec *x, rvec *v, rvec *f)
+void gmx_trr_write_single_frame(const char *fn, int step, real t, real lambda,
+ rvec *box, int natoms, rvec *x, rvec *v, rvec *f)
{
- t_fileio *fio;
-
- fio = open_trn(fn, "w");
- do_trn(fio, FALSE, &step, &t, &lambda, box, &natoms, x, v, f);
- close_trn(fio);
+ t_fileio *fio = gmx_trr_open(fn, "w");
+ do_trr_frame(fio, false, &step, &t, &lambda, box, &natoms, x, v, f);
+ gmx_trr_close(fio);
}
-void read_trn(const char *fn, int *step, real *t, real *lambda,
- rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
+void gmx_trr_read_single_frame(const char *fn, int *step, real *t, real *lambda,
+ rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
{
- t_fileio *fio;
-
- fio = open_trn(fn, "r");
- (void) do_trn(fio, TRUE, step, t, lambda, box, natoms, x, v, f);
- close_trn(fio);
+ t_fileio *fio = gmx_trr_open(fn, "r");
+ do_trr_frame(fio, true, step, t, lambda, box, natoms, x, v, f);
+ gmx_trr_close(fio);
}
-void fwrite_trn(t_fileio *fio, int step, real t, real lambda,
- rvec *box, int natoms, rvec *x, rvec *v, rvec *f)
+void gmx_trr_write_frame(t_fileio *fio, int step, real t, real lambda,
+ rvec *box, int natoms, rvec *x, rvec *v, rvec *f)
{
- if (do_trn(fio, FALSE, &step, &t, &lambda, box, &natoms, x, v, f) == FALSE)
+ if (!do_trr_frame(fio, false, &step, &t, &lambda, box, &natoms, x, v, f))
{
gmx_file("Cannot write trajectory frame; maybe you are out of disk space?");
}
}
-gmx_bool fread_trn(t_fileio *fio, int *step, real *t, real *lambda,
- rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
+gmx_bool gmx_trr_read_frame(t_fileio *fio, int *step, real *t, real *lambda,
+ rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
{
- return do_trn(fio, TRUE, step, t, lambda, box, natoms, x, v, f);
+ return do_trr_frame(fio, true, step, t, lambda, box, natoms, x, v, f);
}
-gmx_bool fread_htrn(t_fileio *fio, t_trnheader *trn, rvec *box, rvec *x, rvec *v,
- rvec *f)
+gmx_bool gmx_trr_read_frame_data(t_fileio *fio, gmx_trr_header_t *header,
+ rvec *box, rvec *x, rvec *v, rvec *f)
{
- return do_htrn(fio, trn, box, x, v, f);
+ return do_trr_frame_data(fio, header, box, x, v, f);
}
-t_fileio *open_trn(const char *fn, const char *mode)
+t_fileio *gmx_trr_open(const char *fn, const char *mode)
{
return gmx_fio_open(fn, mode);
}
-void close_trn(t_fileio *fio)
+void gmx_trr_close(t_fileio *fio)
{
gmx_fio_close(fio);
}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_FILEIO_TRRIO_H
+#define GMX_FILEIO_TRRIO_H
+
+#include "gromacs/math/vectypes.h"
+#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/real.h"
+
+/**************************************************************
+ *
+ * These routines handle trr (trajectory) I/O, they read and
+ * write trr files. The routines should be able to read single
+ * and double precision files without the user noting it.
+ * The files are backward compatible, therefore the header holds
+ * some unused variables.
+ *
+ * The routines in the corresponding c-file trrio.cpp
+ * are based on the lower level routines in gmxfio.cpp
+ * The file handle returned from gmx_trr_open()
+ * can also be used with the routines in gmxfio.h
+ *
+ **************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct t_fileio;
+
+/* This struct describes the order and the */
+/* sizes of the structs in a trr file, sizes are given in bytes. */
+typedef struct gmx_trr_header_t
+{
+ gmx_bool bDouble; /* Double precision? */
+ int ir_size; /* Backward compatibility */
+ int e_size; /* Backward compatibility */
+ int box_size; /* Non zero if a box is present */
+ int vir_size; /* Backward compatibility */
+ int pres_size; /* Backward compatibility */
+ int top_size; /* Backward compatibility */
+ int sym_size; /* Backward compatibility */
+ int x_size; /* Non zero if coordinates are present */
+ int v_size; /* Non zero if velocities are present */
+ int f_size; /* Non zero if forces are present */
+
+ int natoms; /* The total number of atoms */
+ int step; /* Current step number */
+ int nre; /* Backward compatibility */
+ real t; /* Current time */
+ real lambda; /* Current value of lambda */
+ int fep_state; /* Current value of alchemical state */
+} gmx_trr_header_t;
+
+struct t_fileio *gmx_trr_open(const char *fn, const char *mode);
+/* Open a trr file */
+
+void gmx_trr_close(struct t_fileio *fio);
+/* Close it */
+
+gmx_bool gmx_trr_read_frame_header(struct t_fileio *fio, gmx_trr_header_t *header, gmx_bool *bOK);
+/* Read the header of a trr file. Return FALSE if there is no frame.
+ * bOK will be FALSE when the header is incomplete.
+ */
+
+gmx_bool gmx_trr_read_frame_data(struct t_fileio *fio, gmx_trr_header_t *sh,
+ rvec *box, rvec *x, rvec *v, rvec *f);
+/* Extern read a frame except the header (that should be pre-read,
+ * using routine gmx_trr_read_frame_header(), see above) from a trr file.
+ * Return FALSE on error
+ */
+
+gmx_bool gmx_trr_read_frame(struct t_fileio *fio, int *step, real *t, real *lambda,
+ rvec *box, int *natoms, rvec *x, rvec *v, rvec *f);
+/* Read a trr frame, including the header from fp. box, x, v, f may
+ * be NULL, in which case the data will be skipped over.
+ * return FALSE on error
+ */
+
+void gmx_trr_write_frame(struct t_fileio *fio, int step, real t, real lambda,
+ rvec *box, int natoms, rvec *x, rvec *v, rvec *f);
+/* Write a trr frame to file fp, box, x, v, f may be NULL */
+
+void gmx_trr_read_single_header(const char *fn, gmx_trr_header_t *header);
+/* Read the header of a trr file from fn, and close the file afterwards.
+ */
+
+void gmx_trr_read_single_frame(const char *fn, int *step, real *t, real *lambda,
+ rvec *box, int *natoms, rvec *x, rvec *v, rvec *f);
+/* Read a single trr frame from file fn, which is closed afterwards
+ */
+
+void gmx_trr_write_single_frame(const char *fn, int step, real t, real lambda,
+ rvec *box, int natoms, rvec *x, rvec *v, rvec *f);
+/* Write a single trr frame to file fn, which is closed afterwards */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
#include "config.h"
-#include <assert.h>
-#include <math.h>
+#include <cassert>
+#include <cmath>
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/g96io.h"
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
+#include "gromacs/fileio/groio.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/fileio/timecontrol.h"
#include "gromacs/fileio/tngio.h"
#include "gromacs/fileio/tngio_for_tools.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/trx.h"
#include "gromacs/fileio/xdrf.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#ifdef GMX_USE_PLUGINS
write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec);
break;
case efTRR:
- fwrite_trn(status->fio, nframes_read(status),
- fr->time, fr->step, fr->box, nind, xout, vout, fout);
+ gmx_trr_write_frame(status->fio, nframes_read(status),
+ fr->time, fr->step, fr->box, nind, xout, vout, fout);
break;
case efGRO:
case efPDB:
write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
break;
case efTRR:
- fwrite_trn(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
- fr->bX ? fr->x : NULL, fr->bV ? fr->v : NULL, fr->bF ? fr->f : NULL);
+ gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
+ fr->bX ? fr->x : NULL, fr->bV ? fr->v : NULL, fr->bF ? fr->f : NULL);
break;
case efGRO:
case efPDB:
static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr)
{
- t_trnheader sh;
- gmx_bool bOK, bRet;
+ gmx_trr_header_t sh;
+ gmx_bool bOK, bRet;
bRet = FALSE;
- if (fread_trnheader(status->fio, &sh, &bOK))
+ if (gmx_trr_read_frame_header(status->fio, &sh, &bOK))
{
fr->bDouble = sh.bDouble;
fr->natoms = sh.natoms;
}
fr->bF = sh.f_size > 0;
}
- if (fread_htrn(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
+ if (gmx_trr_read_frame_data(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
{
bRet = TRUE;
}
real pt;
int ct;
gmx_bool bOK, bRet, bMissingData = FALSE, bSkip = FALSE;
- int dummy = 0;
int ftp;
bRet = FALSE;
{
t_fileio *fio;
gmx_bool bFirst, bOK;
- int dummy = 0;
int ftp = fn2ftp(fn);
- gmx_int64_t *tng_ids;
clear_trxframe(fr, TRUE);
fr->flags = flags;
{
snew(fr->v, fr->natoms);
}
- fio = (*status)->fio = gmx_fio_open(fn, "r");
+ (*status)->fio = gmx_fio_open(fn, "r");
break;
case efXTC:
if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x,
&fr->prec, &bOK) == 0)
{
- assert(!bOK);
+ GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
fr->not_ok = DATA_NOT_OK;
}
if (fr->not_ok)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_FILEIO_TRXIO_H
#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/legacyheaders/oenv.h"
#include "gromacs/legacyheaders/readinp.h"
struct gmx_mtop_t;
struct t_atoms;
+struct t_fileio;
struct t_topology;
struct t_trxframe;
t_trxstatus *open_trx(const char *outfile, const char *filemode);
/* Open a TRX file and return an allocated status pointer */
-t_fileio *trx_get_fileio(t_trxstatus *status);
+struct t_fileio *trx_get_fileio(t_trxstatus *status);
/* get a fileio from a trxstatus */
float trx_get_time_of_final_frame(t_trxstatus *status);
static int load_vmd_library(const char *fn, t_gmxvmdplugin *vmdplugin)
{
- char pathname[GMX_PATH_MAX], filename[GMX_PATH_MAX];
+ char pathname[GMX_PATH_MAX];
const char *pathenv;
const char *err;
- int i;
int ret = 0;
char pathenv_buffer[GMX_PATH_MAX];
#ifndef GMX_NATIVE_WINDOWS
"The architecture (e.g. 32bit versus 64bit) of GROMACS and VMD has to match.\n");
return 0;
}
- for (i = 0; i < globbuf.gl_pathc && vmdplugin->api == NULL; i++)
+ for (size_t i = 0; i < globbuf.gl_pathc && vmdplugin->api == NULL; i++)
{
/* FIXME: Undefined which plugin is chosen if more than one plugin
can read a certain file ending. Requires some additional command
}
do
{
+ char filename[GMX_PATH_MAX];
sprintf(filename, "%s\\%s", pathenv, ffd.cFileName);
ret |= load_sharedlibrary_plugins(filename, vmdplugin);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "writeps.h"
-#include <stdio.h>
+#include <cstdio>
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/utility/fatalerror.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
sfree(ffp);
return ret;
#else
- return xdr3dfcoord(xdrs, (float *)fp, size, (float *)precision);
+ return xdr3dfcoord(xdrs, reinterpret_cast<float *>(fp), size, reinterpret_cast<float *>(precision));
#endif
}
imaj64 = ((*i)>>32) & two_p32_m1;
imin64 = (*i) & two_p32_m1;
- imaj = (int)imaj64;
- imin = (int)imin64;
+ imaj = static_cast<int>(imaj64);
+ imin = static_cast<int>(imin64);
ret = xdr_int(xdrs, &imaj);
ret |= xdr_int(xdrs, &imin);
- *i = (((gmx_int64_t)imaj << 32) | ((gmx_int64_t)imin & two_p32_m1));
+ *i = ((static_cast<gmx_int64_t>(imaj) << 32) | (static_cast<gmx_int64_t>(imin) & two_p32_m1));
return ret;
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_INTERNAL_XDR
-#include "gromacs/fileio/gmx_system_xdr.h"
+#if GMX_INTERNAL_XDR
+#include "gromacs/fileio/gmx_internal_xdr.h"
#else
#include <rpc/rpc.h>
#include <rpc/xdr.h>
extern "C" {
#endif
-struct t_fileio;
-
/* Read or write reduced precision *float* coordinates */
int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision);
int xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK);
-
-/* Defined in gmxfio.c.
- * TODO: It would be nice to decouple this header from t_fileio completely,
- * and not need the XDR struct in gmxfio.h, but that would require some
- * extra code that is not warranted for this single function.
- * Can be reconsidered if the file I/O gets refactored in the future.
- */
-XDR *gmx_fio_getxdr(struct t_fileio *fio);
-/* Return the file pointer itself */
-
#ifdef __cplusplus
}
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "xtcio.h"
-#include <string.h>
+#include <cstring>
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/fileio/xdrf.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/fatalerror.h"
}
}
-int xtc_check(const char *str, gmx_bool bResult, const char *file, int line)
+static int xtc_check(const char *str, gmx_bool bResult, const char *file, int line)
{
if (!bResult)
{
return 1;
}
-void xtc_check_fat_err(const char *str, gmx_bool bResult, const char *file, int line)
-{
- if (!bResult)
- {
- gmx_fatal(FARGS, "XTC read/write of %s failed, "
- "source file %s, line %d\n", str, file, line);
- }
-}
+#define XTC_CHECK(s, b) xtc_check(s, b, __FILE__, __LINE__)
static int xtc_header(XDR *xd, int *magic, int *natoms, int *step, real *time,
gmx_bool bRead, gmx_bool *bOK)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_FILEIO_XTCIO_H
#define GMX_FILEIO_XTCIO_H
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
extern "C" {
#endif
+struct t_fileio;
+
/* All functions return 1 if successful, 0 otherwise
* bOK tells if a frame is not corrupted
*/
-t_fileio *open_xtc(const char *filename, const char *mode);
+struct t_fileio *open_xtc(const char *filename, const char *mode);
/* Open a file for xdr I/O */
-void close_xtc(t_fileio *fio);
+void close_xtc(struct t_fileio *fio);
/* Close the file for xdr I/O */
-int read_first_xtc(t_fileio *fio,
+int read_first_xtc(struct t_fileio *fio,
int *natoms, int *step, real *time,
matrix box, rvec **x, real *prec, gmx_bool *bOK);
/* Open xtc file, read xtc file first time, allocate memory for x */
-int read_next_xtc(t_fileio *fio,
+int read_next_xtc(struct t_fileio *fio,
int natoms, int *step, real *time,
matrix box, rvec *x, real *prec, gmx_bool *bOK);
/* Read subsequent frames */
-int write_xtc(t_fileio *fio,
+int write_xtc(struct t_fileio *fio,
int natoms, int step, real time,
matrix box, rvec *x, real prec);
/* Write a frame to xtc file */
-int xtc_check(const char *str, gmx_bool bResult, const char *file, int line);
-#define XTC_CHECK(s, b) xtc_check(s, b, __FILE__, __LINE__)
-
-void xtc_check_fat_err(const char *str, gmx_bool bResult, const char *file, int line);
-#define XTC_CHECK_FAT_ERR(s, b) xtc_check_fat_err(s, b, __FILE__, __LINE__)
-
#ifdef __cplusplus
}
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "xvgr.h"
-#include <ctype.h>
-#include <string.h>
+#include <cctype>
+#include <cstring>
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/copyrite.h"
break;
}
g++;
- b = strlen(buf);
+ b = std::strlen(buf);
}
else
{
/* Check for special symbol */
i = 0;
while (sym[i] != NULL &&
- gmx_strncasecmp(sym[i], gmx+g, strlen(sym[i])) != 0)
+ gmx_strncasecmp(sym[i], gmx+g, std::strlen(sym[i])) != 0)
{
i++;
}
if (sym[i] != NULL)
{
c = symc[i];
- if (isupper(gmx[g]))
+ if (std::isupper(gmx[g]))
{
- c = toupper(c);
+ c = std::toupper(c);
}
switch (xvgf)
{
sprintf(buf+b, "%s%c%s", "\\8", c, "\\4");
break;
default:
- strncat(buf+b, gmx+g, strlen(sym[i]));
- b += strlen(sym[i]);
- if (gmx[g+strlen(sym[i])] != ' ')
+ std::strncat(buf+b, gmx+g, std::strlen(sym[i]));
+ b += std::strlen(sym[i]);
+ if (gmx[g+std::strlen(sym[i])] != ' ')
{
buf[b++] = ' ';
}
buf[b] = '\0';
break;
}
- g += strlen(sym[i]);
- b = strlen(buf);
+ g += std::strlen(sym[i]);
+ b = std::strlen(buf);
}
else
{
curp += len_remaining-1; /* overwrite the nul char in next iteration */
len_remaining = 1;
}
- while ((strchr(*ptr, '\n') == NULL) && (!feof(fp)));
+ while ((std::strchr(*ptr, '\n') == NULL) && (!feof(fp)));
if (*len + STRLEN >= maxlen)
{
}
{
/* now remove newline */
- int slen = strlen(*ptr);
+ int slen = std::strlen(*ptr);
if ((*ptr)[slen-1] == '\n')
{
(*ptr)[slen-1] = '\0';
{
for (i = 0; (ptr[i] != '\0'); i++)
{
- is[cur] = isspace(ptr[i]);
+ is[cur] = std::isspace(ptr[i]);
if ((0 == i) && !is[cur])
{
n++;
const char *ptr0, *ptr1;
char *str;
- ptr0 = strchr(line, '"');
+ ptr0 = std::strchr(line, '"');
if (ptr0 != NULL)
{
ptr0++;
- ptr1 = strchr(ptr0, '"');
+ ptr1 = std::strchr(ptr0, '"');
if (ptr1 != NULL)
{
str = gmx_strdup(ptr0);
ptr++;
trim(ptr);
set = -1;
- if (strncmp(ptr, "subtitle", 8) == 0)
+ if (std::strncmp(ptr, "subtitle", 8) == 0)
{
ptr += 8;
if (subtitle != NULL)
*subtitle = read_xvgr_string(ptr);
}
}
- else if (strncmp(ptr, "legend string", 13) == 0)
+ else if (std::strncmp(ptr, "legend string", 13) == 0)
{
ptr += 13;
sscanf(ptr, "%d%n", &set, &nchar);
sscanf(ptr, "%d%n", &set, &nchar);
ptr += nchar;
trim(ptr);
- if (strncmp(ptr, "legend", 6) == 0)
+ if (std::strncmp(ptr, "legend", 6) == 0)
{
ptr += 6;
}
/* fprintf(stderr,"ptr='%s'\n",ptr);*/
for (k = 0; (k < nny); k++)
{
- strcpy(fmt, base);
- strcat(fmt, "%lf");
+ std::strcpy(fmt, base);
+ std::strcat(fmt, "%lf");
rval = sscanf(ptr, fmt, &lf);
/* fprintf(stderr,"rval = %d\n",rval);*/
if ((rval == EOF) || (rval == 0))
yy[k][nx] = lf;
srenew(fmt, 3*(nny+1)+1);
srenew(base, 3*nny+1);
- strcat(base, "%*s");
+ std::strcat(base, "%*s");
}
if (k != nny)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "eigio.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
int *nvec, int **eignr,
rvec ***eigvec, real **eigval)
{
- t_trnheader head;
- int i, snew_size;
- t_fileio *status;
- rvec *x;
- matrix box;
- gmx_bool bOK;
+ gmx_trr_header_t head;
+ int i, snew_size;
+ struct t_fileio *status;
+ rvec *x;
+ matrix box;
+ gmx_bool bOK;
*bDMR = FALSE;
/* read (reference (t=-1) and) average (t=0) structure */
- status = open_trn(file, "r");
- fread_trnheader(status, &head, &bOK);
+ status = gmx_trr_open(file, "r");
+ gmx_trr_read_frame_header(status, &head, &bOK);
*natoms = head.natoms;
snew(*xav, *natoms);
- fread_htrn(status, &head, box, *xav, NULL, NULL);
+ gmx_trr_read_frame_data(status, &head, box, *xav, NULL, NULL);
if ((head.t >= -1.1) && (head.t <= -0.9))
{
sfree(*xref);
*xref = NULL;
}
- fread_trnheader(status, &head, &bOK);
- fread_htrn(status, &head, box, *xav, NULL, NULL);
+ gmx_trr_read_frame_header(status, &head, &bOK);
+ gmx_trr_read_frame_data(status, &head, box, *xav, NULL, NULL);
}
else
{
snew(*eigvec, snew_size);
*nvec = 0;
- while (fread_trnheader(status, &head, &bOK))
+ while (gmx_trr_read_frame_header(status, &head, &bOK))
{
- fread_htrn(status, &head, box, x, NULL, NULL);
+ gmx_trr_read_frame_data(status, &head, box, x, NULL, NULL);
if (*nvec >= snew_size)
{
snew_size += 10;
(*nvec)++;
}
sfree(x);
+ gmx_trr_close(status);
fprintf(stderr, "Read %d eigenvectors (for %d atoms)\n\n", *nvec, *natoms);
}
-void write_eigenvectors(const char *trnname, int natoms, real mat[],
+void write_eigenvectors(const char *trrname, int natoms, real mat[],
gmx_bool bReverse, int begin, int end,
int WriteXref, rvec *xref, gmx_bool bDMR,
rvec xav[], gmx_bool bDMA, real eigval[])
{
- t_fileio *trnout;
- int ndim, i, j, d, vec;
- matrix zerobox;
- rvec *x;
+ struct t_fileio *trrout;
+ int ndim, i, j, d, vec;
+ matrix zerobox;
+ rvec *x;
ndim = natoms*DIM;
clear_mat(zerobox);
fprintf (stderr,
"\nWriting %saverage structure & eigenvectors %d--%d to %s\n",
(WriteXref == eWXR_YES) ? "reference, " : "",
- begin, end, trnname);
+ begin, end, trrname);
- trnout = open_tpx(trnname, "w");
+ trrout = gmx_trr_open(trrname, "w");
if (WriteXref == eWXR_YES)
{
/* misuse lambda: 0/1 mass weighted fit no/yes */
- fwrite_trn(trnout, -1, -1, bDMR ? 1.0 : 0.0, zerobox, natoms, xref, NULL, NULL);
+ gmx_trr_write_frame(trrout, -1, -1, bDMR ? 1.0 : 0.0, zerobox, natoms, xref, NULL, NULL);
}
else if (WriteXref == eWXR_NOFIT)
{
/* misuse lambda: -1 no fit */
- fwrite_trn(trnout, -1, -1, -1.0, zerobox, natoms, x, NULL, NULL);
+ gmx_trr_write_frame(trrout, -1, -1, -1.0, zerobox, natoms, x, NULL, NULL);
}
/* misuse lambda: 0/1 mass weighted analysis no/yes */
- fwrite_trn(trnout, 0, 0, bDMA ? 1.0 : 0.0, zerobox, natoms, xav, NULL, NULL);
+ gmx_trr_write_frame(trrout, 0, 0, bDMA ? 1.0 : 0.0, zerobox, natoms, xav, NULL, NULL);
for (i = 0; i <= (end-begin); i++)
{
}
/* Store the eigenvalue in the time field */
- fwrite_trn(trnout, begin+i, eigval[vec], 0, zerobox, natoms, x, NULL, NULL);
+ gmx_trr_write_frame(trrout, begin+i, eigval[vec], 0, zerobox, natoms, x, NULL, NULL);
}
- close_trn(trnout);
+ gmx_trr_close(trrout);
sfree(x);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/* xav is the average/minimum structure is written (t=0). */
/* bDMA indicates mass weighted analysis/eigenvectors. */
-extern void write_eigenvectors(const char *trnname, int natoms, real mat[],
+extern void write_eigenvectors(const char *trrname, int natoms, real mat[],
gmx_bool bReverse, int begin, int end,
int WriteXref, rvec *xref, gmx_bool bDMR,
rvec xav[], gmx_bool bDMA, real *eigval);
-/* Write eigenvectors in mat to a TRN file. */
+/* Write eigenvectors in mat to a TRR file. */
/* The reference structure is written (t=-1) when WriteXref=eWXR_YES. */
/* When WriteXref==eWXR_NOFIT a zero frame is written (t=-1), */
/* with lambda=-1. */
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/correlationfunctions/autocorr.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/gmxana/gstat.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
-static void dump_dih_trn(int nframes, int nangles, real **dih, const char *fn,
+static void dump_dih_trr(int nframes, int nangles, real **dih, const char *fn,
real *time)
{
- int i, j, k, l, m, na;
- t_fileio *trn;
- rvec *x;
- matrix box = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}};
+ int i, j, k, l, m, na;
+ struct t_fileio *fio;
+ rvec *x;
+ matrix box = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}};
na = (nangles*2);
if ((na % 3) != 0)
printf("There are %d dihedrals. Will fill %d atom positions with cos/sin\n",
nangles, na);
snew(x, na);
- trn = open_trn(fn, "w");
+ fio = gmx_trr_open(fn, "w");
for (i = 0; (i < nframes); i++)
{
k = l = 0;
}
}
}
- fwrite_trn(trn, i, time[i], 0, box, na, x, NULL, NULL);
+ gmx_trr_write_frame(fio, i, time[i], 0, box, na, x, NULL, NULL);
}
- close_trn(trn);
+ gmx_trr_close(fio);
sfree(x);
}
{
if (mult != 4)
{
- gmx_fatal(FARGS, "Can not combine angles with trn dump");
+ gmx_fatal(FARGS, "Can not combine angles with trr dump");
}
else
{
}
if (opt2bSet("-or", NFILE, fnm))
{
- dump_dih_trn(nframes, nangles, dih, opt2fn("-or", NFILE, fnm), time);
+ dump_dih_trr(nframes, nangles, dih, opt2fn("-or", NFILE, fnm), time);
}
if (bFrac)
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/gmxana/gstat.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/residuetypes.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/cmat.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/index.h"
#include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/filenm.h"
+#include "gromacs/fileio/groio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/eigio.h"
#include <stdlib.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/statistics/statistics.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/gmxana/gstat.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/correlationfunctions/autocorr.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/matio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/random/random.h"
#include "gromacs/statistics/statistics.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/topology/index.h"
#include "gromacs/topology/mtop_util.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
typedef struct {
#include <stdlib.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/fileio/strdb.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gstat.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
static int strip_dssp(char *dsspfile, int nres,
#include "gromacs/correlationfunctions/integrate.h"
#include "gromacs/fft/fft.h"
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/index.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
int gmx_dyecoupl(int argc, char *argv[])
if (bDatout)
{
- datfp = fopen(out_datfile, "w");
+ datfp = gmx_ffopen(out_datfile, "w");
}
if (bRKout)
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/atomprop.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
typedef struct
#include "gromacs/legacyheaders/names.h"
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/correlationfunctions/autocorr.h"
#include "gromacs/fileio/enxio.h"
+#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/gmxana/princ.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/legacyheaders/force.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/correlationfunctions/autocorr.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/binsearch.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/eigio.h"
#include "gromacs/legacyheaders/macros.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/filenm.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/math/do_fit.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxana/eigio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/random/random.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxana/eigio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/cmat.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include <stdlib.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/cmat.h"
#include <math.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
#include "gromacs/fileio/strdb.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
int step, nre, natoms, i, g, m, teller = 0;
real t, lambda, *w_rls, *w_rms;
- t_tpxheader header;
t_inputrec ir;
t_topology top;
int ePBC;
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "config.h"
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/gmxomp.h"
#include <stdio.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/names.h"
#include "gmxpre.h"
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include <stdlib.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
static const double bohr = 0.529177249; /* conversion factor to compensate for VMD plugin conversion... */
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/fileio/tngio.h"
#include "gromacs/fileio/tngio_for_tools.h"
-#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/g96io.h"
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/groio.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/fileio/tngio_for_tools.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/fileio/xvgr.h"
strcat(out_file, ext);
}
-void check_trn(const char *fn)
+void check_trr(const char *fn)
{
if (fn2ftp(fn) != efTRR)
{
t_fileio *in;
FILE *fp;
gmx_bool bStop, bOK;
- t_trnheader sh;
+ gmx_trr_header_t sh;
gmx_off_t fpos;
char yesno[256];
int j;
}
/* Check whether this is a .trr file */
- check_trn(fn);
+ check_trr(fn);
- in = open_trn(fn, "r");
+ in = gmx_trr_open(fn, "r");
fp = gmx_fio_getfp(in);
if (fp == NULL)
{
fprintf(stderr, "Sorry, can not trunc %s, truncation of this filetype is not supported\n", fn);
- close_trn(in);
+ gmx_trr_close(in);
}
else
{
j = 0;
fpos = gmx_fio_ftell(in);
bStop = FALSE;
- while (!bStop && fread_trnheader(in, &sh, &bOK))
+ while (!bStop && gmx_trr_read_frame_header(in, &sh, &bOK))
{
- fread_htrn(in, &sh, NULL, NULL, NULL, NULL);
+ gmx_trr_read_frame_data(in, &sh, NULL, NULL, NULL, NULL);
fpos = gmx_ftell(fp);
t = sh.t;
if (t >= t0)
if (strcmp(yesno, "YES") == 0)
{
fprintf(stderr, "Once again, I'm gonna DO this...\n");
- close_trn(in);
+ gmx_trr_close(in);
if (0 != gmx_truncate(fn, fpos))
{
gmx_fatal(FARGS, "Error truncating file %s", fn);
else
{
fprintf(stderr, "Already at end of file (t=%g)...\n", t);
- close_trn(in);
+ gmx_trr_close(in);
}
}
}
#include <string.h>
#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
/* Enum for situations that can occur during log file parsing, the
#include <string.h>
#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/matio.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/random/random.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/gmxomp.h"
#include "gromacs/utility/smalloc.h"
{
printf("Executing command '%s'\n", Buffer);
}
-#ifdef HAVE_PIPES
+#if HAVE_PIPES
if ((pipe = popen(Buffer, "r")) == NULL)
{
gmx_fatal(FARGS, "Unable to open pipe to `%s'\n", Buffer);
//! Close file or pipe
void pdo_close_file(FILE *fp)
{
-#ifdef HAVE_PIPES
+#if HAVE_PIPES
pclose(fp);
#else
gmx_ffclose(fp);
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/legacyheaders/viewit.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/listed-forces/bonded.h"
#include "gromacs/pbcutil/rmpbc.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "sfactor.h"
-#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/strdb.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "buildinfo.h"
#include "gromacs/fileio/filenm.h"
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/gmxfio-xdr.h"
#include "gromacs/fileio/xdr_datatype.h"
#include "gromacs/fileio/xdrf.h"
#include "gromacs/legacyheaders/copyrite.h"
npmenodes = 0;
}
-#ifndef GMX_NO_RENAME
+#if !GMX_NO_RENAME
/* make the new temporary filename */
snew(fntemp, strlen(fn)+5+STEPSTRSIZE);
strcpy(fntemp, fn);
/* we don't move the checkpoint if the user specified they didn't want it,
or if the fsyncs failed */
-#ifndef GMX_NO_RENAME
+#if !GMX_NO_RENAME
if (!bNumberAndKeep && !ret)
{
if (gmx_fexist(fn))
#ifdef HAVE_LIBMKL
#include <mkl.h>
#endif
-#ifdef HAVE_EXTRAE
+#if HAVE_EXTRAE
#include <extrae_user_events.h>
#endif
#include <boost/version.hpp>
* but we dont call this routine often, and it avoids using
* a mutex for locking the variable...
*/
-#ifdef GMX_COOL_QUOTES
+#if GMX_COOL_QUOTES
return (getenv("GMX_NO_QUOTES") == NULL);
#else
/*be uncool*/
#else
fprintf(fp, "RDTSCP usage: disabled\n");
#endif
-#ifdef GMX_CXX11
+#if GMX_CXX11
fprintf(fp, "C++11 compilation: enabled\n");
#else
fprintf(fp, "C++11 compilation: disabled\n");
#else
fprintf(fp, "TNG support: disabled\n");
#endif
-#ifdef HAVE_EXTRAE
+#if HAVE_EXTRAE
unsigned major, minor, revision;
Extrae_get_version(&major, &minor, &revision);
fprintf(fp, "Tracing support: enabled. Using Extrae-%d.%d.%d\n", major, minor, revision);
{
}
-void printBinaryInformation(FILE *fp,
- const ProgramContextInterface &programContext)
+void printBinaryInformation(FILE *fp,
+ const IProgramContext &programContext)
{
printBinaryInformation(fp, programContext, BinaryInformationSettings());
}
void printBinaryInformation(FILE *fp,
- const ProgramContextInterface &programContext,
+ const IProgramContext &programContext,
const BinaryInformationSettings &settings)
{
const char *prefix = settings.prefix_;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
struct output_env
{
- explicit output_env(const gmx::ProgramContextInterface &context)
+ explicit output_env(const gmx::IProgramContext &context)
: programContext(context)
{
time_unit = time_ps;
verbosity = 0;
}
- const gmx::ProgramContextInterface &programContext;
+ const gmx::IProgramContext &programContext;
/* the time unit, enum defined in oenv.h */
time_unit_t time_unit;
/***** OUTPUT_ENV MEMBER FUNCTIONS ******/
void output_env_init(output_env_t *oenvp,
- const gmx::ProgramContextInterface &context,
+ const gmx::IProgramContext &context,
time_unit_t tmu, gmx_bool view, xvg_format_t xvg_format,
int verbosity)
{
return displayName;
}
-const gmx::ProgramContextInterface &
+const gmx::IProgramContext &
output_env_get_program_context(const output_env_t oenv)
{
return oenv->programContext;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
abort();
}
break;
-#ifdef HAVE_SIGUSR1
+#if HAVE_SIGUSR1
case SIGUSR1:
usr_condition = 1;
break;
}
gmx_signal(SIGINT);
}
-#ifdef HAVE_SIGUSR1
+#if HAVE_SIGUSR1
if (getenv("GMX_NO_USR1") == NULL)
{
if (debug)
gmx_bool gmx_got_usr_signal(void)
{
-#ifdef HAVE_SIGUSR1
+#if HAVE_SIGUSR1
gmx_bool ret = (gmx_bool)usr_condition;
usr_condition = 0;
return ret;
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/legacyheaders/types/commrec.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2011,2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2011,2013,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-file(GLOB GMXPREPROCESS_SOURCES *.c *.cpp)
+file(GLOB GMXPREPROCESS_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXPREPROCESS_SOURCES} PARENT_SCOPE)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
+#include <algorithm>
+
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/gmxpreprocess/hackblock.h"
#include "gromacs/gmxpreprocess/toputil.h"
int search_jtype(t_restp *rtp, char *name, gmx_bool bNterm)
{
- int niter, iter, j, k, kmax, jmax, minstrlen;
- char *rtpname, searchname[12];
+ int niter, iter, j, jmax;
+ size_t k, kmax, minstrlen;
+ char *rtpname, searchname[12];
strcpy(searchname, name);
}
if (iter == niter - 1)
{
- minstrlen = min(strlen(searchname), strlen(rtpname));
+ minstrlen = std::min(strlen(searchname), strlen(rtpname));
for (k = 0; k < minstrlen; k++)
{
if (searchname[k] != rtpname[k])
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/pdb2top.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
void add_param(t_params *ps, int ai, int aj, real *c, char *s);
void add_imp_param(t_params *ps, int ai, int aj, int ak, int al,
int search_jtype(t_restp *rp, char *name, gmx_bool bFirstRes);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "calch.h"
+#include <cmath>
+
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/math/units.h"
#include "gromacs/math/utilities.h"
#undef BB
#undef CC
int m;
- rvec kkk;
/* This was copied from Gromos */
for (m = 0; (m < DIM); m++)
real s6, rij, ra, rb, xd;
int d;
- s6 = 0.5*sqrt(3.e0);
+ s6 = 0.5*std::sqrt(3.e0);
/* common work for constructing one, two or three dihedral hydrogens */
switch (nht)
sb[d] = xd-xAK[d];
rij += sqr(sij[d]);
}
- rij = sqrt(rij);
+ rij = std::sqrt(rij);
sa[XX] = sij[YY]*sb[ZZ]-sij[ZZ]*sb[YY];
sa[YY] = sij[ZZ]*sb[XX]-sij[XX]*sb[ZZ];
sa[ZZ] = sij[XX]*sb[YY]-sij[YY]*sb[XX];
sij[d] = sij[d]/rij;
ra += sqr(sa[d]);
}
- ra = sqrt(ra);
+ ra = std::sqrt(ra);
for (d = 0; (d < DIM); d++)
{
sa[d] = sa[d]/ra;
rij += sqr(sij[d]);
rb += sqr(sb[d]);
}
- rij = sqrt(rij);
- rb = sqrt(rb);
+ rij = std::sqrt(rij);
+ rb = std::sqrt(rb);
ra = 0.e0;
for (d = 0; (d < DIM); d++)
{
sa[d] = sij[d]/rij+sb[d]/rb;
ra += sqr(sa[d]);
}
- ra = sqrt(ra);
+ ra = std::sqrt(ra);
for (d = 0; (d < DIM); d++)
{
xH1[d] = xAI[d]+distH*sa[d]/ra;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l);
/*
* w.f. van gunsteren, groningen, july 1981
* l : dynamically changed index
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "convparm.h"
-#include <math.h>
#include <string.h>
+#include <cmath>
+
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/gmxpreprocess/topio.h"
#include "gromacs/gmxpreprocess/toputil.h"
return i;
}
-static void set_ljparams(int comb, double reppow, real v, real w,
+static void set_ljparams(int comb, double reppow, double v, double w,
real *c6, real *c12)
{
if (comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS)
{
if (v >= 0)
{
- *c6 = 4*w*pow(v, 6.0);
- *c12 = 4*w*pow(v, reppow);
+ *c6 = 4*w*std::pow(v, 6.0);
+ *c12 = 4*w*std::pow(v, reppow);
}
else
{
/* Interpret negative sigma as c6=0 and c12 with -sigma */
*c6 = 0;
- *c12 = 4*w*pow(-v, reppow);
+ *c12 = 4*w*std::pow(-v, reppow);
}
}
else
real old[MAXFORCEPARAM], int comb, double reppow)
{
int i, j;
- real tmp;
gmx_bool all_param_zero = TRUE;
/* Set to zero */
newparam->thole.alpha2 = old[2];
if ((old[1] > 0) && (old[2] > 0))
{
- newparam->thole.rfac = old[0]*pow(old[1]*old[2], -1.0/6.0);
+ newparam->thole.rfac = old[0]*std::pow(old[1]*old[2], static_cast<real>(-1.0/6.0));
}
else
{
newparam->vsiten.a = old[1];
break;
case F_CMAP:
- newparam->cmap.cmapA = old[0];
- newparam->cmap.cmapB = old[1];
+ newparam->cmap.cmapA = static_cast<int>(old[0]);
+ newparam->cmap.cmapB = static_cast<int>(old[1]);
break;
case F_GB12:
case F_GB13:
int comb, double reppow, real fudgeQQ,
gmx_mtop_t *mtop)
{
- int i, j, maxtypes, mt;
+ int i, maxtypes, mt;
unsigned long flags;
gmx_ffparams_t *ffp;
gmx_moltype_t *molt;
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void convert_params(int atnr, t_params nbtypes[],
t_molinfo *mi,
t_molinfo *intermolecular_interactions,
int comb, double reppow, real fudgeQQ,
gmx_mtop_t *mtop);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "gromacs/utility/directoryenumerator.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/smalloc.h"
#include <stdio.h>
-#include "gromacs/utility/basedefinitions.h"
-
-#ifdef __cplusplus
#include <vector>
+#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/datafilefinder.h"
/*! \brief
*/
std::vector<gmx::DataFileInfo> fflib_enumerate_forcefields();
-extern "C" {
-#endif
-
const char *fflib_forcefield_dir_ext();
/* Returns the name of the force field directory extension */
* either absolute or relative to the current dir.
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "gen_ad.h"
#include <ctype.h>
-#include <math.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/fileio/confio.h"
#include "gromacs/gmxpreprocess/gpp_nextnb.h"
#include "gromacs/gmxpreprocess/pgutil.h"
static int get_impropers(t_atoms *atoms, t_hackblock hb[], t_param **improper,
gmx_bool bAllowMissing)
{
- char *a0;
t_rbondeds *impropers;
- t_rbonded *hbimproper;
- int nimproper, i, j, k, r, start, ninc, nalloc;
+ int nimproper, i, j, k, start, ninc, nalloc;
atom_id ai[MAXATOMLIST];
gmx_bool bStop;
void clean_excls(t_nextnb *nnb, int nrexcl, t_excls excls[])
{
- int i, j, j1, k, k1, l, l1, m, n, e;
+ int i, j, j1, k, k1, l, l1, e;
t_excls *excl;
if (nrexcl >= 1)
void generate_excls(t_nextnb *nnb, int nrexcl, t_excls excls[])
{
- int i, j, j1, k, k1, l, l1, m, n, e, N;
+ int i, j, n, N;
t_excls *excl;
- for (N = 1; (N < min(nrexcl, nnb->nrex)); N++)
+ for (N = 1; (N < std::min(nrexcl, nnb->nrex)); N++)
{
/* extract all i-j-k-l neighbours from nnb struct */
for (i = 0; (i < nnb->nr); i++)
maxres = minres;
for (m = 1; m < 3; m++)
{
- minres = min(minres, atoms->atom[ang[nang].a[m]].resind);
- maxres = max(maxres, atoms->atom[ang[nang].a[m]].resind);
+ minres = std::min(minres, atoms->atom[ang[nang].a[m]].resind);
+ maxres = std::max(maxres, atoms->atom[ang[nang].a[m]].resind);
}
res = 2*minres-maxres;
do
maxres = minres;
for (m = 1; m < 4; m++)
{
- minres = min(minres, atoms->atom[dih[ndih].a[m]].resind);
- maxres = max(maxres, atoms->atom[dih[ndih].a[m]].resind);
+ minres = std::min(minres, atoms->atom[dih[ndih].a[m]].resind);
+ maxres = std::max(maxres, atoms->atom[dih[ndih].a[m]].resind);
}
res = 2*minres-maxres;
do
}
if (nbd == 3)
{
- i1 = min(i, l1);
- i2 = max(i, l1);
+ i1 = std::min(i, l1);
+ i2 = std::max(i, l1);
bExcl = FALSE;
for (m = 0; m < excls[i1].nr; m++)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void generate_excls(t_nextnb *nnb, int nrexcl, t_excls excls[]);
void clean_excls(t_nextnb *nnb, int nrexcl, t_excls excls[]);
t_params plist[], t_excls excls[], t_hackblock hb[],
gmx_bool bAllowMissing);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gen_maxwell_velocities.h"
-#include <math.h>
+#include <cmath>
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/math/units.h"
mass = atom->m;
if (mass > 0)
{
- sd = sqrt(boltz/mass);
+ sd = std::sqrt(boltz/mass);
for (m = 0; (m < DIM); m++)
{
v[i][m] = sd*gmx_rng_gaussian_real(rng);
temp = (2.0*ekin)/(nrdf*BOLTZ);
if (temp > 0)
{
- scal = sqrt(tempi/temp);
+ scal = std::sqrt(tempi/temp);
for (i = 0; (i < mtop->natoms); i++)
{
for (m = 0; (m < DIM); m++)
void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t *mtop, rvec v[])
{
- atom_id *dummy;
- int i;
gmx_rng_t rng;
if (seed == 0)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*! \brief
* Generate Maxwellian velocities.
*
*/
void stop_cm(FILE *log, int natoms, real mass[], rvec x[], rvec v[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gen_vsite.h"
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
#include "gromacs/gmxpreprocess/add_par.h"
#include "gromacs/gmxpreprocess/fflibutil.h"
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
FILE *ddb;
char dirstr[STRLEN];
char pline[STRLEN];
- int i, j, n, k, nvsite, ntop, curdir, prevdir;
+ int i, n, k, nvsite, ntop, curdir;
t_vsiteconf *vsiteconflist;
t_vsitetop *vsitetoplist;
char *ch;
int Heavy, int nrHatoms, int Hatoms[],
int nrheavies, int heavies[])
{
- int i, j, ftype, other, moreheavy, bb;
+ int i, j, ftype, other, moreheavy;
gmx_bool bSwapParity;
for (i = 0; i < nrHatoms; i++)
int i, nvsite;
real a, b, dCGCE, tmp1, tmp2, mtot, mG, mrest;
- real xCG, yCG, xCE1, yCE1, xCE2, yCE2;
+ real xCG;
/* CG, CE1 and CE2 stay and each get a part of the total mass,
* so the c-o-m stays the same.
*/
}
/* constraints between CG, CE1 and CE2: */
- dCGCE = sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
+ dCGCE = std::sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE1], dCGCE);
my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE2], dCGCE);
my_add_param(&(plist[F_CONSTRNC]), ats[atCE1], ats[atCE2], dCGCE);
* the CE1-CE2 bond and y=0 at the line from CG to the middle of CE1-CE2 bond.
*/
xCG = -bond_cc+bond_cc*cos(ANGLE_6RING);
- yCG = 0;
- xCE1 = 0;
- yCE1 = bond_cc*sin(0.5*ANGLE_6RING);
- xCE2 = 0;
- yCE2 = -bond_cc*sin(0.5*ANGLE_6RING);
mG = at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = xcom*mtot/xCG;
mrest = mtot-mG;
atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2,
atCZ, atHZ, atNR
};
- real x[atNR], y[atNR];
+ real x[atNR];
/* Aromatic rings have 6-fold symmetry, so we only need one bond length.
* (angle is always 120 degrees).
*/
bond_ch = get_ddb_bond(vsitetop, nvsitetop, "PHE", "CD1", "HD1");
x[atCG] = -bond_cc+bond_cc*cos(ANGLE_6RING);
- y[atCG] = 0;
x[atCD1] = -bond_cc;
- y[atCD1] = bond_cc*sin(0.5*ANGLE_6RING);
x[atHD1] = x[atCD1]+bond_ch*cos(ANGLE_6RING);
- y[atHD1] = y[atCD1]+bond_ch*sin(ANGLE_6RING);
x[atCE1] = 0;
- y[atCE1] = y[atCD1];
x[atHE1] = x[atCE1]-bond_ch*cos(ANGLE_6RING);
- y[atHE1] = y[atCE1]+bond_ch*sin(ANGLE_6RING);
x[atCD2] = x[atCD1];
- y[atCD2] = -y[atCD1];
x[atHD2] = x[atHD1];
- y[atHD2] = -y[atHD1];
x[atCE2] = x[atCE1];
- y[atCE2] = -y[atCE1];
x[atHE2] = x[atHE1];
- y[atHE2] = -y[atHE1];
x[atCZ] = bond_cc*cos(0.5*ANGLE_6RING);
- y[atCZ] = 0;
x[atHZ] = x[atCZ]+bond_ch;
- y[atHZ] = 0;
xcom = mtot = 0;
for (i = 0; i < atNR; i++)
* virtual site coordinates here.
*/
real dx_ij, dx_ik, dy_ij, dy_ik;
- real b_ij, b_ik;
dx_ij = xj-xi;
dy_ij = yj-yi;
dx_ik = xk-xi;
dy_ik = yk-yi;
- b_ij = sqrt(dx_ij*dx_ij+dy_ij*dy_ij);
- b_ik = sqrt(dx_ik*dx_ik+dy_ik*dy_ik);
*a = ( (xd-xi)*dy_ik - dx_ik*(yd-yi) ) / (dx_ij*dy_ik - dx_ik*dy_ij);
*b = ( yd - yi - (*a)*dy_ij ) / dy_ik;
};
real xi[atNR], yi[atNR];
- real xcom[NMASS], ycom[NMASS], I, alpha;
- real lineA, lineB, dist;
+ real xcom[NMASS], ycom[NMASS], alpha;
real b_CD2_CE2, b_NE1_CE2, b_CG_CD2, b_CH2_HH2, b_CE2_CZ2;
real b_NE1_HE1, b_CD2_CE3, b_CE3_CZ3, b_CB_CG;
real b_CZ2_CH2, b_CZ2_HZ2, b_CD1_HD1, b_CE3_HE3;
real b_CG_CD1, b_CZ3_HZ3;
real a_NE1_CE2_CD2, a_CE2_CD2_CG, a_CB_CG_CD2, a_CE2_CD2_CE3;
- real a_CB_CG_CD1, a_CD2_CG_CD1, a_CE2_CZ2_HZ2, a_CZ2_CH2_HH2;
+ real a_CD2_CG_CD1, a_CE2_CZ2_HZ2, a_CZ2_CH2_HH2;
real a_CD2_CE2_CZ2, a_CD2_CE3_CZ3, a_CE3_CZ3_HZ3, a_CG_CD1_HD1;
real a_CE2_CZ2_CH2, a_HE1_NE1_CE2, a_CD2_CE3_HE3;
- real xM[NMASS];
int atM[NMASS], tpM, i, i0, j, nvsite;
- real mwtot, mtot, mM[NMASS], dCBM1, dCBM2, dM1M2;
- real a, b, c[MAXFORCEPARAM];
+ real mM[NMASS], dCBM1, dCBM2, dM1M2;
+ real a, b;
rvec r_ij, r_ik, t1, t2;
char name[10];
a_CE2_CD2_CG = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CD2", "CG");
a_CB_CG_CD2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CB", "CG", "CD2");
a_CD2_CG_CD1 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CG", "CD1");
- a_CB_CG_CD1 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CB", "CG", "CD1");
+ /*a_CB_CG_CD1 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CB", "CG", "CD1"); unused */
a_CE2_CD2_CE3 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CD2", "CE3");
a_CD2_CE2_CZ2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CE2", "CZ2");
xi[atHH2] = xi[atCH2]+b_CH2_HH2*sin(alpha);
yi[atHH2] = yi[atCH2]-b_CH2_HH2*cos(alpha);
- /* Determine coeff. for the line CB-CG */
- lineA = (yi[atCB]-yi[atCG])/(xi[atCB]-xi[atCG]);
- lineB = yi[atCG]-lineA*xi[atCG];
-
/* Calculate masses for each ring and put it on the dummy masses */
for (j = 0; j < NMASS; j++)
{
/* constraints between CB, M1 and M2 */
/* 'add_shift' says which atoms won't be renumbered afterwards */
- dCBM1 = sqrt( sqr(xcom[0]-xi[atCB]) + sqr(ycom[0]-yi[atCB]) );
- dM1M2 = sqrt( sqr(xcom[0]-xcom[1]) + sqr(ycom[0]-ycom[1]) );
- dCBM2 = sqrt( sqr(xcom[1]-xi[atCB]) + sqr(ycom[1]-yi[atCB]) );
+ dCBM1 = std::sqrt( sqr(xcom[0]-xi[atCB]) + sqr(ycom[0]-yi[atCB]) );
+ dM1M2 = std::sqrt( sqr(xcom[0]-xcom[1]) + sqr(ycom[0]-ycom[1]) );
+ dCBM2 = std::sqrt( sqr(xcom[1]-xi[atCB]) + sqr(ycom[1]-yi[atCB]) );
my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift+atM[0], dCBM1);
my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift+atM[1], dCBM2);
my_add_param(&(plist[F_CONSTRNC]), add_shift+atM[0], add_shift+atM[1], dM1M2);
real dCGCE, dCEOH, dCGM, tmp1, a, b;
real bond_cc, bond_ch, bond_co, bond_oh, angle_coh;
real xcom, mtot;
- real vmass, vdist, mM;
+ real vdist, mM;
rvec r1;
char name[10];
atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2,
atCZ, atOH, atHH, atNR
};
- real xi[atNR], yi[atNR];
+ real xi[atNR];
/* CG, CE1, CE2 (as in general 6-ring) and OH and HH stay,
rest gets virtualized.
Now we have two linked triangles with one improper keeping them flat */
angle_coh = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TYR", "CZ", "OH", "HH");
xi[atCG] = -bond_cc+bond_cc*cos(ANGLE_6RING);
- yi[atCG] = 0;
xi[atCD1] = -bond_cc;
- yi[atCD1] = bond_cc*sin(0.5*ANGLE_6RING);
xi[atHD1] = xi[atCD1]+bond_ch*cos(ANGLE_6RING);
- yi[atHD1] = yi[atCD1]+bond_ch*sin(ANGLE_6RING);
xi[atCE1] = 0;
- yi[atCE1] = yi[atCD1];
xi[atHE1] = xi[atCE1]-bond_ch*cos(ANGLE_6RING);
- yi[atHE1] = yi[atCE1]+bond_ch*sin(ANGLE_6RING);
xi[atCD2] = xi[atCD1];
- yi[atCD2] = -yi[atCD1];
xi[atHD2] = xi[atHD1];
- yi[atHD2] = -yi[atHD1];
xi[atCE2] = xi[atCE1];
- yi[atCE2] = -yi[atCE1];
xi[atHE2] = xi[atHE1];
- yi[atHE2] = -yi[atHE1];
xi[atCZ] = bond_cc*cos(0.5*ANGLE_6RING);
- yi[atCZ] = 0;
xi[atOH] = xi[atCZ]+bond_co;
- yi[atOH] = 0;
xcom = mtot = 0;
for (i = 0; i < atOH; i++)
at->atom[ats[atCZ]].m = at->atom[ats[atCZ]].mB = 0;
/* constraints between CE1, CE2 and OH */
- dCGCE = sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
- dCEOH = sqrt( cosrule(bond_cc, bond_co, ANGLE_6RING) );
+ dCGCE = std::sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
+ dCEOH = std::sqrt( cosrule(bond_cc, bond_co, ANGLE_6RING) );
my_add_param(&(plist[F_CONSTRNC]), ats[atCE1], ats[atOH], dCEOH);
my_add_param(&(plist[F_CONSTRNC]), ats[atCE2], ats[atOH], dCEOH);
nvsite++;
/* assume we also want the COH angle constrained: */
tmp1 = bond_cc*cos(0.5*ANGLE_6RING) + dCGCE*sin(ANGLE_6RING*0.5) + bond_co;
- dCGM = sqrt( cosrule(tmp1, vdist, angle_coh) );
+ dCGM = std::sqrt( cosrule(tmp1, vdist, angle_coh) );
my_add_param(&(plist[F_CONSTRNC]), ats[atCG], add_shift+atM, dCGM);
my_add_param(&(plist[F_CONSTRNC]), ats[atOH], add_shift+atM, vdist);
}
/* constraints between CG, CE1 and NE1 */
- dCGCE1 = sqrt( cosrule(b_CG_ND1, b_ND1_CE1, a_CG_ND1_CE1) );
- dCGNE2 = sqrt( cosrule(b_CG_CD2, b_CD2_NE2, a_CG_CD2_NE2) );
+ dCGCE1 = std::sqrt( cosrule(b_CG_ND1, b_ND1_CE1, a_CG_ND1_CE1) );
+ dCGNE2 = std::sqrt( cosrule(b_CG_CD2, b_CD2_NE2, a_CG_CD2_NE2) );
my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE1], dCGCE1);
my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atNE2], dCGNE2);
y[atCE1] = cosalpha*dCGCE1;
x[atNE2] = 0;
y[atNE2] = y[atCE1]-b_CE1_NE2;
- sinalpha = sqrt(1-cosalpha*cosalpha);
+ sinalpha = std::sqrt(1-cosalpha*cosalpha);
x[atCG] = -sinalpha*dCGCE1;
y[atCG] = 0;
x[atHE1] = x[atHE2] = x[atHD1] = x[atHD2] = 0;
int i, j, k, m, i0, ni0, whatres, resind, add_shift, ftype, nvsite, nadd;
int ai, aj, ak, al;
int nrfound = 0, needed, nrbonds, nrHatoms, Heavy, nrheavies, tpM, tpHeavy;
- int Hatoms[4], heavies[4], bb;
+ int Hatoms[4], heavies[4];
gmx_bool bWARNING, bAddVsiteParam, bFirstWater;
matrix tmpmat;
gmx_bool *bResProcessed;
mHtot *= mHmult;
}
fact2 = mHtot/mtot;
- fact = sqrt(fact2);
+ fact = std::sqrt(fact2);
/* generate vectors parallel and perpendicular to rotational axis:
* rpar = Heavy -> Hcom
* rperp = Hcom -> H1 */
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/hackblock.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
/* stuff for pdb2gmx */
void do_vsites(int nrtp, t_restp rtp[], gpp_atomtype_t atype,
void do_h_mass(t_params *psb, int vsite_type[], t_atoms *at, real mHmult,
gmx_bool bDeuterate);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/random/random.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_GENCONF_H
#define GMX_GMXPREPROCESS_GENCONF_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
int gmx_genconf(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static void expand_hackblocks_one(t_hackblock *hbr, char *atomname,
int *nabi, t_hack **abi, gmx_bool bN, gmx_bool bC)
{
- int j, k, l, d;
+ int j, k, l;
gmx_bool bIgnore;
/* we'll recursively add atoms to atoms */
static int check_atoms_present(t_atoms *pdba, int nab[], t_hack *ab[])
{
- int i, j, k, d, rnr, nadd;
+ int i, j, k, rnr, nadd;
nadd = 0;
for (i = 0; i < pdba->nr; i++)
{
t_atoms *newpdba = NULL, *pdba = NULL;
int nadd;
- int i, newi, j, d, natoms, nalreadypresent;
+ int i, newi, j, natoms, nalreadypresent;
int *nab = NULL;
t_hack **ab = NULL;
t_hackblock *hb;
}
*pdbaptr = newpdba;
}
- else
- {
- nadd = newi-natoms;
- }
sfree(*xptr);
*xptr = xn;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/fileio/pdbio.h"
#include "gromacs/gmxpreprocess/hackblock.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
int add_h(t_atoms **pdbaptr, rvec *xptr[],
int nah, t_hackblock ah[],
int nterpairs,
* removed
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include <ctype.h>
#include <errno.h>
#include <limits.h>
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include <sys/types.h>
#include "gromacs/legacyheaders/macros.h"
int cpp_open_file(const char *filenm, gmx_cpp_t *handle, char **cppopts)
{
gmx_cpp_t cpp;
- char *buf, *pdum;
+ char *buf;
char *ptr, *ptr2;
int i;
- unsigned int i1;
/* First process options, they might be necessary for opening files
(especially include statements). */
/* Make a linked list of open files and move on to the include file */
handle->child->parent = handle;
*handlep = handle->child;
- handle = *handlep;
return eCPP_OK;
}
}
if (nn > 0)
{
- len = strlen(buf) + nn*max(4, 4+strlen(defs[i].def)-strlen(defs[i].name));
+ size_t four = 4;
+
+ len = strlen(buf) + nn*std::max(four, four+strlen(defs[i].def)-strlen(defs[i].name));
snew(name, len);
ptr = buf;
while ((ptr2 = strstrw(ptr, defs[i].name)) != NULL)
/* Close the file! Return integer status. */
int cpp_close_file(gmx_cpp_t *handlep)
{
- int i;
gmx_cpp_t handle = (gmx_cpp_t)*handlep;
if (!handle)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_GMXCPP_H
#define GMX_GMXPREPROCESS_GMXCPP_H
+
typedef struct gmx_cpp *gmx_cpp_t;
/* The possible return codes for these functions */
NOT THREAD SAFE
*/
char *cpp_error(gmx_cpp_t *handlep, int status);
+
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gpp_atomtype.h"
-#include <math.h>
#include <string.h>
+#include <cmath>
+
#include "gromacs/gmxpreprocess/topdirs.h"
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/legacyheaders/txtdump.h"
int add_atomtype(gpp_atomtype_t ga, t_symtab *tab,
t_atom *a, const char *name, t_param *nb,
int bondatomtype,
- real radius, real vol, real surftens, real atomnumber,
+ real radius, real vol, real surftens, int atomnumber,
real gb_radius, real S_hct)
{
int i;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct gpp_atomtype *gpp_atomtype_t;
int get_atomtype_type(const char *str, gpp_atomtype_t at);
int add_atomtype(gpp_atomtype_t at, struct t_symtab *tab,
t_atom *a, const char *name, t_param *nb,
int bondatomtype,
- real radius, real vol, real surftens, real atomnumber,
+ real radius, real vol, real surftens, int atomnumber,
real gb_radius, real S_hct);
/* Add a complete new atom type to an existing atomtype structure. Returns
the number of the atom type. */
void copy_atomtype_atomtypes(gpp_atomtype_t atype, t_atomtypes *atypes);
/* Copy from one structure to another */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct gpp_bondatomtype *t_bond_atomtype;
int get_bond_atomtype_type(char *str, t_bond_atomtype at);
char *name);
/* Add a complete new atom type to an existing atomtype structure */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
void generate_excl (int nrexcl, int nratoms, t_params plist[], t_nextnb *nnb, t_blocka *excl)
{
- int i, j, k;
-
if (nrexcl < 0)
{
gmx_fatal(FARGS, "Can't have %d exclusions...", nrexcl);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
int nr; /* nr atoms (0 <= i < nr) (atoms->nr) */
int nrex; /* with nrex lists of neighbours */
* plist.
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define MAXSLEN 32
typedef struct {
* non-bonded parameter combinations, which will be copied to t_params.
*/
-#ifndef __cplusplus
/*
* With the macros below you don't
* have to use an index if you don't wan't to. You can eg. use
#define C0 c[0]
#define C1 c[1]
#define C2 c[2]
-#endif
typedef struct {
atom_id a[MAXATOMLIST]; /* The atom list (eg. bonds: particle */
d_none
} directive;
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "grompp.h"
-#include <assert.h>
#include <errno.h>
#include <limits.h>
-#include <math.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include <sys/types.h>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/enxio.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/gmxpreprocess/add_par.h"
#include "gromacs/gmxpreprocess/convparm.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/snprintf.h"
maxsize = 0;
for (cg = 0; cg < cgs->nr; cg++)
{
- maxsize = max(maxsize, cgs->index[cg+1]-cgs->index[cg]);
+ maxsize = std::max(maxsize, cgs->index[cg+1]-cgs->index[cg]);
}
if (maxsize > MAX_CHARGEGROUP_SIZE)
if (debug)
{
fprintf(debug, "fc %g m1 %g m2 %g period %g\n",
- fc, m1, m2, sqrt(period2));
+ fc, m1, m2, std::sqrt(period2));
}
if (period2 < limit2)
{
*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,
+ std::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.");
rvec com,
warninp_t wi)
{
- gmx_bool bFirst = TRUE, *hadAtom;
+ gmx_bool *hadAtom;
rvec *x, *v, *xp;
dvec sum;
double totmass;
get_stx_coordnum(fn, &natoms);
if (natoms != mtop->natoms)
{
- sprintf(warn_buf, "The number of atoms in %s (%d) does not match the number of atoms in the topology (%d). Will assume that the first %d atoms in the topology and %s match.", fn, natoms, mtop->natoms, min(mtop->natoms, natoms), fn);
+ sprintf(warn_buf, "The number of atoms in %s (%d) does not match the number of atoms in the topology (%d). Will assume that the first %d atoms in the topology and %s match.", fn, natoms, mtop->natoms, std::min(mtop->natoms, natoms), fn);
warning(wi, warn_buf);
}
snew(x, natoms);
if (rc_scaling != erscNO)
{
- assert(npbcdim <= DIM);
+ GMX_ASSERT(npbcdim <= DIM, "Only DIM dimensions can have PBC");
for (mb = 0; mb < mtop->nmolblock; mb++)
{
rvec com, rvec comB,
warninp_t wi)
{
- int i, j;
-
read_posres (mtop, mi, FALSE, fnA, rc_scaling, ePBC, com, wi);
/* It is safer to simply read the b-state posres rather than trying
* to be smart and copy the positions.
int ix;
double a, b;
- ix = (x-xmin)/dx;
+ ix = static_cast<int>((x-xmin)/dx);
a = (xmin+(ix+1)*dx-x)/dx;
b = (x-xmin-ix*dx)/dx;
void init_cmap_grid(gmx_cmap_t *cmap_grid, int ngrid, int grid_spacing)
{
- int i, k, nelem;
+ int i, nelem;
cmap_grid->ngrid = ngrid;
cmap_grid->grid_spacing = grid_spacing;
const t_inputrec *ir,
rvec *v)
{
- double sum_mv2;
gmx_mtop_atomloop_all_t aloop;
t_atom *atom;
int a;
- int nrdf, g;
-
- sum_mv2 = 0;
+ double sum_mv2 = 0;
aloop = gmx_mtop_atomloop_all_init(mtop);
while (gmx_mtop_atomloop_all_next(aloop, &a, &atom))
{
sum_mv2 += atom->m*norm2(v[a]);
}
- nrdf = 0;
- for (g = 0; g < ir->opts.ngtc; g++)
+ double nrdf = 0;
+ for (int g = 0; g < ir->opts.ngtc; g++)
{
nrdf += ir->opts.nrdf[g];
}
}
else
{
- ref_t = max(ref_t, ir->opts.ref_t[i]);
+ ref_t = std::max(ref_t, ir->opts.ref_t[i]);
}
}
matrix box,
warninp_t wi)
{
- int i;
verletbuf_list_setup_t ls;
real rlist_1x1;
int n_nonlin_vsite;
}
printf("Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm\n",
- 1, 1, rlist_1x1, rlist_1x1-max(ir->rvdw, ir->rcoulomb));
+ 1, 1, rlist_1x1, rlist_1x1-std::max(ir->rvdw, ir->rcoulomb));
ir->rlistlong = ir->rlist;
printf("Set rlist, assuming %dx%d atom pair-list, to %.3f nm, buffer size %.3f nm\n",
ls.cluster_size_i, ls.cluster_size_j,
- ir->rlist, ir->rlist-max(ir->rvdw, ir->rcoulomb));
+ ir->rlist, ir->rlist-std::max(ir->rvdw, ir->rcoulomb));
printf("Note that mdrun will redetermine rlist based on the actual pair-list setup\n");
if (sqr(ir->rlistlong) >= max_cutoff2(ir->ePBC, box))
{
- gmx_fatal(FARGS, "The pair-list cut-off (%g nm) is longer than half the shortest box vector or longer than the smallest box diagonal element (%g nm). Increase the box size or decrease nstlist or increase verlet-buffer-tolerance.", ir->rlistlong, sqrt(max_cutoff2(ir->ePBC, box)));
+ gmx_fatal(FARGS, "The pair-list cut-off (%g nm) is longer than half the shortest box vector or longer than the smallest box diagonal element (%g nm). Increase the box size or decrease nstlist or increase verlet-buffer-tolerance.", ir->rlistlong, std::sqrt(max_cutoff2(ir->ePBC, box)));
}
}
t_molinfo *mi, *intermolecular_interactions;
gpp_atomtype_t atype;
t_inputrec *ir;
- int natoms, nvsite, comb, mt;
+ int nvsite, comb, mt;
t_params *plist;
t_state *state;
matrix box;
- real max_spacing, fudgeQQ;
+ real fudgeQQ;
double reppow;
char fn[STRLEN], fnB[STRLEN];
const char *mdparin;
int ntype;
gmx_bool bNeedVel, bGenVel;
gmx_bool have_atomnumber;
- int n12, n13, n14;
- t_params *gb_plist = NULL;
- gmx_genborn_t *born = NULL;
output_env_t oenv;
gmx_bool bVerbose = FALSE;
warninp_t wi;
char warn_buf[STRLEN];
- unsigned int useed;
- t_atoms IMDatoms; /* Atoms to be operated on interactively (IMD) */
t_filenm fnm[] = {
{ efMDP, NULL, NULL, ffREAD },
if (ir->ld_seed == -1)
{
ir->ld_seed = (gmx_int64_t)gmx_rng_make_seed();
- fprintf(stderr, "Setting the LD random seed to %"GMX_PRId64 "\n", ir->ld_seed);
+ fprintf(stderr, "Setting the LD random seed to %" GMX_PRId64 "\n", ir->ld_seed);
}
if (ir->expandedvals->lmc_seed == -1)
if (bRenum)
{
renum_atype(plist, sys, ir->wall_atomtype, atype, bVerbose);
- ntype = get_atomtype_ntypes(atype);
+ get_atomtype_ntypes(atype);
}
if (ir->implicit_solvent != eisNO)
}
do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm),
sys, bVerbose, ir,
- bGenVel ? state->v : NULL,
wi);
if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 &&
set_warning_line(wi, mdparin, -1);
warning_error(wi, "Some of the Fourier grid sizes are set, but all of them need to be set.");
}
- max_spacing = calc_grid(stdout, box, ir->fourier_spacing,
- &(ir->nkx), &(ir->nky), &(ir->nkz));
+ calc_grid(stdout, box, ir->fourier_spacing,
+ &(ir->nkx), &(ir->nky), &(ir->nkz));
}
/* MRS: eventually figure out better logic for initializing the fep
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_GROMPP_H
#define GMX_GMXPREPROCESS_GROMPP_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
int gmx_grompp(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <stdlib.h>
#include <string.h>
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/gmxpreprocess/fflibutil.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/utility/cstringutil.h"
}
gmx_ffclose(in);
- /* Sort the list (necessary to be able to use bsearch */
- qsort(aah, nah, (size_t)sizeof(**ah), compaddh);
+ if (nah > 0)
+ {
+ /* Sort the list (necessary to be able to use bsearch */
+ qsort(aah, nah, (size_t)sizeof(**ah), compaddh);
+ }
/*
if (debug)
int nhdbf, f;
char **hdbf;
int nah;
- FILE *fp;
/* Read the hydrogen database file(s).
* Do not generate an error when no files are found.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/hackblock.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* functions for the h-database */
void read_ab(char *line, const char *fn, t_hack *ab);
t_hackblock *search_h_db(int nh, t_hackblock ah[], char *key);
/* Search for an entry in the database */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/topology/symtab.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Used for reading .rtp/.tdb */
/* ebtsBONDS must be the first, new types can be added to the end */
/* these *MUST* correspond to the arrays in hackblock.c */
void init_t_protonate(t_protonate *protonate);
/* initialize t_protein struct */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <stdio.h>
#include <string.h>
+#include <cmath>
+
#include "gromacs/fileio/pdbio.h"
#include "gromacs/gmxpreprocess/pdb2top.h"
#include "gromacs/gmxpreprocess/toputil.h"
pdba->resinfo[pdba->atom[i].resind].nr, *pdba->atomname[i],
*pdba->resinfo[pdba->atom[aj].resind].name,
pdba->resinfo[pdba->atom[aj].resind].nr, *pdba->atomname[aj],
- sqrt(d2), a);
+ std::sqrt(d2), a);
}
hbond[i] = TRUE;
bHB = TRUE;
#define NPD asize(prot_don)
gmx_bool *donor, *acceptor;
- gmx_bool *hbond, bHaveH = FALSE;
+ gmx_bool *hbond;
gmx_bool bHDd, bHEd;
rvec xh1, xh2;
int natom;
- int i, j, nd, na, aj, hisind, his0, type = -1;
+ int i, j, nd, na, hisind, type = -1;
int nd1, ne2, cg, cd2, ce1;
t_blocka *hb;
- real d;
char *atomnm;
natom = pdba->nr;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_HIZZIE_H
#define GMX_GMXPREPROCESS_HIZZIE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void set_histp(t_atoms *pdba, rvec *x, real angle, real distance);
/* calculate HIStidine protonation state */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/random/random.h"
#include "gromacs/selection/nbsearch.h"
namespace
{
-class InsertMolecules : public CommandLineOptionsModuleInterface
+class InsertMolecules : public ICommandLineOptionsModule
{
public:
InsertMolecules()
{
}
- virtual void initOptions(Options *options);
- virtual void optionsFinished(Options *options);
+ virtual void initOptions(IOptionsContainer *options,
+ ICommandLineOptionsModuleSettings *settings);
+ virtual void optionsFinished() {}
virtual int run();
int enumRot_;
};
-void InsertMolecules::initOptions(Options *options)
+void InsertMolecules::initOptions(IOptionsContainer *options,
+ ICommandLineOptionsModuleSettings *settings)
{
const char *const desc[] = {
"[THISMODULE] inserts [TT]-nmol[tt] copies of the system specified in",
"[TT]-try[tt] and [TT]-rot[tt] work as in the default mode (see above)."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
// TODO: Replace use of legacyType.
options->addOption(FileNameOption("f")
.description("Output configuration after insertion"));
options->addOption(RealOption("box").vector()
- .store(newBox_)
+ .store(newBox_).storeIsSet(&bBox_)
.description("Box size (in nm)"));
options->addOption(IntegerOption("nmol")
.store(&nmolIns_)
.description("Rotate inserted molecules randomly"));
}
-void InsertMolecules::optionsFinished(Options *options)
-{
- bBox_ = options->isSet("box");
-}
-
int InsertMolecules::run()
{
const bool bProt = !inputConfFile_.empty();
const char InsertMoleculesInfo::name[] = "insert-molecules";
const char InsertMoleculesInfo::shortDescription[] =
"Insert molecules into existing vacancies";
-CommandLineOptionsModuleInterface *InsertMoleculesInfo::create()
+ICommandLineOptionsModule *InsertMoleculesInfo::create()
{
return new InsertMolecules();
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class CommandLineOptionsModuleInterface;
+class ICommandLineOptionsModule;
class InsertMoleculesInfo
{
public:
static const char name[];
static const char shortDescription[];
- static CommandLineOptionsModuleInterface *create();
+ static ICommandLineOptionsModule *create();
};
} // namespace gmx
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
+#include <algorithm>
+
#include "gromacs/fileio/confio.h"
#include "gromacs/gmxpreprocess/fflibutil.h"
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
static void rd_nm2type_file(const char *fn, int *nnm, t_nm2type **nmp)
char format[128], f1[128];
char buf[1024], elem[16], type[16], nbbuf[16], **newbuf;
int i, nb, nnnm, line = 1;
- double qq, mm, *blen;
+ double qq, mm;
t_nm2type *nm2t = NULL;
fp = fflib_open(fn);
int cur = 0;
#define prev (1-cur)
int i, j, k, m, n, nresolved, nb, maxbond, ai, aj, best, im, nqual[2][ematchNR];
- int *bbb, *n_mask, *m_mask, **match, **quality;
+ int *bbb, *n_mask, *m_mask, **match;
char *aname_i, *aname_m, *aname_n, *type;
double qq, mm;
t_param *param;
maxbond = 0;
for (i = 0; (i < atoms->nr); i++)
{
- maxbond = max(maxbond, nbonds[i]);
+ maxbond = std::max(maxbond, nbonds[i]);
}
if (debug)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/topology/atoms.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
char *elem, *type;
double q, m;
* with help of the bond list
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#define RTP_MAXCHAR 5
int nrr, rtprename_t *rr, t_symtab *symtab,
gmx_bool bVerbose)
{
- int r, i, j;
+ int r, j;
gmx_bool bStart, bEnd;
char *nn;
gmx_bool bFFRTPTERRNM;
rvec **xnew;
int i, j;
t_restp *rptr;
- t_hackblock *hbr;
t_pdbindex *pdbi;
atom_id *a;
char *atomnm;
{
pdba->atom[j] = pdba->atom[j+1];
pdba->atomname[j] = pdba->atomname[j+1];
- pdba->pdbinfo[j] = pdba->pdbinfo[j+1];
+ if (pdba->pdbinfo)
+ {
+ pdba->pdbinfo[j] = pdba->pdbinfo[j+1];
+ }
copy_rvec(x[j+1], x[j]);
}
srenew(pdba->atom, pdba->nr);
}
-static void
-modify_chain_numbers(t_atoms * pdba,
- const char * chainsep)
+enum SplittingType
{
- int i;
- char old_prev_chainid;
- char old_this_chainid;
- int old_prev_chainnum;
- int old_this_chainnum;
- t_resinfo *ri;
- char select[STRLEN];
- int new_chainnum;
- int this_atomnum;
- int prev_atomnum;
- const char * prev_atomname;
- const char * this_atomname;
- const char * prev_resname;
- const char * this_resname;
- int prev_resnum;
- int this_resnum;
- char prev_chainid;
- char this_chainid;
- int prev_chainnumber;
- int this_chainnumber;
-
- enum
- {
- SPLIT_ID_OR_TER,
- SPLIT_ID_AND_TER,
- SPLIT_ID_ONLY,
- SPLIT_TER_ONLY,
- SPLIT_INTERACTIVE
- }
- splitting;
-
- splitting = SPLIT_TER_ONLY; /* keep compiler happy */
+ SPLIT_ID_OR_TER,
+ SPLIT_ID_AND_TER,
+ SPLIT_ID_ONLY,
+ SPLIT_TER_ONLY,
+ SPLIT_INTERACTIVE
+};
+
+static SplittingType getSplittingType(const char *chainsep)
+{
+ SplittingType splitting = SPLIT_TER_ONLY; /* keep compiler happy */
/* Be a bit flexible to catch typos */
if (!strncmp(chainsep, "id_o", 4))
{
gmx_fatal(FARGS, "Unidentified setting for chain separation: %s\n", chainsep);
}
+ return splitting;
+}
+
+static void
+modify_chain_numbers(t_atoms * pdba,
+ const char * chainsep)
+{
+ int i;
+ char old_prev_chainid;
+ char old_this_chainid;
+ int old_prev_chainnum;
+ int old_this_chainnum;
+ t_resinfo *ri;
+ char select[STRLEN];
+ int new_chainnum;
+ int this_atomnum;
+ int prev_atomnum;
+ const char * prev_atomname;
+ const char * this_atomname;
+ const char * prev_resname;
+ const char * this_resname;
+ int prev_resnum;
+ int this_resnum;
+ char prev_chainid;
+ char this_chainid;
+
+ SplittingType splitting = getSplittingType(chainsep);
/* The default chain enumeration is based on TER records only, which is reflected in chainnum below */
this_resname = NULL;
this_resnum = -1;
this_chainid = '?';
- this_chainnumber = -1;
for (i = 0; i < pdba->nres; i++)
{
prev_resname = this_resname;
prev_resnum = this_resnum;
prev_chainid = this_chainid;
- prev_chainnumber = this_chainnumber;
this_atomname = *(pdba->atomname[i]);
this_atomnum = (pdba->pdbinfo != NULL) ? pdba->pdbinfo[i].atomnr : i+1;
this_resname = *ri->name;
this_resnum = ri->nr;
this_chainid = ri->chainid;
- this_chainnumber = ri->chainnum;
switch (splitting)
{
const char *watres;
int nrtpf;
char **rtpf;
- char rtp[STRLEN];
int nrrn;
char **rrn;
- int nrtprename, naa;
+ int nrtprename;
rtprename_t *rtprename = NULL;
int nah, nNtdb, nCtdb, ntdblist;
t_hackblock *ntdb, *ctdb, **tdblist;
int nssbonds;
t_ssbond *ssbonds;
rvec *pdbx, *x;
- gmx_bool bVsites = FALSE, bWat, bPrevWat = FALSE, bITP, bVsiteAromatics = FALSE, bCheckMerge;
+ gmx_bool bVsites = FALSE, bWat, bPrevWat = FALSE, bITP, bVsiteAromatics = FALSE;
real mHmult = 0;
t_hackblock *hb_chain;
t_restp *restp_chain;
mHmult = 1.0;
}
+ /* parse_common_args ensures vsitestr has been selected, but
+ clang-static-analyzer needs clues to know that */
+ GMX_ASSERT(vsitestr[0], "-vsite default wasn't processed correctly");
switch (vsitestr[0][0])
{
case 'n': /* none */
sfree(rrn);
/* Add all alternative names from the residue renaming database to the list of recognized amino/nucleic acids. */
- naa = 0;
for (i = 0; i < nrtprename; i++)
{
rc = gmx_residuetype_get_type(rt, rtprename[i].gmx, &p_restype);
}
printf("Analyzing pdb file\n");
- nch = 0;
- maxch = 0;
nwaterchain = 0;
modify_chain_numbers(&pdba_all, chainsep[0]);
/* Keep the compiler happy */
prev_chainstart = 0;
- pdb_ch = NULL;
+ nch = 0;
+ maxch = 16;
+ snew(pdb_ch, maxch);
bMerged = FALSE;
for (i = 0; (i < natom); i++)
{
ri = &pdba_all.resinfo[pdba_all.atom[i].resind];
+ /* TODO this should live in a helper object, and consolidate
+ that with code in modify_chain_numbers */
prev_atomname = this_atomname;
prev_atomnum = this_atomnum;
prev_resname = this_resname;
ri->chainid);
}
}
+ // TODO This is too convoluted. Use a std::vector
if (nch == maxch)
{
maxch += 16;
nmol = 0;
incls = NULL;
mols = NULL;
- nres = 0;
for (chain = 0; (chain < nch); chain++)
{
cc = &(chains[chain]);
block = new_blocka();
snew(gnames, 1);
sort_pdbatoms(restp_chain, natom, &pdba, &x, block, &gnames);
- natom = remove_duplicate_atoms(pdba, x, bVerbose);
+ remove_duplicate_atoms(pdba, x, bVerbose);
if (ftp2bSet(efNDX, NFILE, fnm))
{
if (bRemoveH)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_PDB2GMX_H
#define GMX_GMXPREPROCESS_PDB2GMX_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
int gmx_pdb2gmx(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "pdb2top.h"
#include <ctype.h>
-#include <math.h>
#include <stdio.h>
#include <string.h>
+#include <cmath>
+
#include <algorithm>
#include <string>
#include <vector>
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/programcontext.h"
{
fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n",
- ai+1, aj+1, sqrt(dist2));
+ ai+1, aj+1, std::sqrt(dist2));
}
else if (dist2 < short_bond_dist2)
{
fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n",
- ai+1, aj+1, sqrt(dist2));
+ ai+1, aj+1, std::sqrt(dist2));
}
add_param(psb, ai, aj, NULL, hb[resind].rb[ebtsBONDS].b[j].s);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
/* this *MUST* correspond to array in pdb2top.c */
enum {
ehisA, ehisB, ehisH, ehis1, ehisNR
void print_sums(t_atoms *atoms, gmx_bool bSystem);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
/* Search an atom in array of pointers to strings, starting from start
* if type starts with '-' then searches backwards from start.
* bondtype is only used for printing the error/warning string,
void set_at(t_atom *at, real m, real q, int type, int resind);
-#ifdef __cplusplus
-}
-#endif
-
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/types/simple.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
struct gmx_atomprop;
struct t_atoms;
char *readConformation(const char *confin, struct t_atoms *atoms, rvec **x, rvec **v,
int *ePBC, matrix box, const char *statusTitle);
-#ifdef __cplusplus
-}
-#endif
-
#endif
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009 Christoph Junghans, Brad Lambeth.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <limits.h>
#include <stdlib.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/legacyheaders/chargegroup.h"
#include "gromacs/legacyheaders/inputrec.h"
}
else if (simtemp->eSimTempScale == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */
{
- simtemp->temperatures[i] = simtemp->simtemp_low * pow(simtemp->simtemp_high/simtemp->simtemp_low, (1.0*i)/(ntemps-1));
+ simtemp->temperatures[i] = simtemp->simtemp_low * std::pow(simtemp->simtemp_high/simtemp->simtemp_low, static_cast<real>((1.0*i)/(ntemps-1)));
}
else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
{
-static void _low_check(gmx_bool b, char *s, warninp_t wi)
+static void _low_check(gmx_bool b, const char *s, warninp_t wi)
{
if (b)
{
#define CHECK(b) _low_check(b, err_buf, wi)
char err_buf[256], warn_buf[STRLEN];
int i, j;
- int ns_type = 0;
- real dt_coupl = 0;
real dt_pcoupl;
- int nstcmin;
t_lambda *fep = ir->fepvals;
t_expanded *expand = ir->expandedvals;
warning_note(wi, "With Verlet lists the optimal nstlist is >= 10, with GPUs >= 20. Note that with the Verlet scheme, nstlist has no effect on the accuracy of your simulation.");
}
- rc_max = max(ir->rvdw, ir->rcoulomb);
+ rc_max = std::max(ir->rvdw, ir->rcoulomb);
if (ir->verletbuf_tol <= 0)
{
sigma = 0.34;
/* Maximum estimate for A and B charges equal with lambda power 1 */
lambda = 0.5;
- r_sc = pow(lambda*fep->sc_alpha*pow(sigma/ir->rcoulomb, fep->sc_r_power) + 1.0, 1.0/fep->sc_r_power);
+ r_sc = std::pow(lambda*fep->sc_alpha*std::pow(sigma/ir->rcoulomb, fep->sc_r_power) + 1.0, 1.0/fep->sc_r_power);
sprintf(warn_buf, "With PME there is a minor soft core effect present at the cut-off, proportional to (LJsigma/rcoulomb)^%g. This could have a minor effect on energy conservation, but usually other effects dominate. With a common sigma value of %g nm the fraction of the particle-particle potential at the cut-off at lambda=%g is around %.1e, while ewald-rtol is %.1e.",
fep->sc_r_power,
sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
{
fep = ir->fepvals;
- expand = ir->expandedvals;
/* checking equilibration of weights inputs for validity */
sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!= 'no',mc_temperature must be set to a positive number");
if (expand->nstTij > 0)
{
+ sprintf(err_buf, "nstlog must be non-zero");
+ CHECK(ir->nstlog != 0);
sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
expand->nstTij, ir->nstlog);
- CHECK((mod(expand->nstTij, ir->nstlog) != 0));
+ CHECK((expand->nstTij % ir->nstlog) != 0);
}
}
}
}
- expand = ir->expandedvals;
/* now read in the weights */
parse_n_real(weights, &nweights, &(expand->init_lambda_weights));
if (nweights == 0)
void read_expandedparams(int *ninp_p, t_inpfile **inp_p,
t_expanded *expand, warninp_t wi)
{
- int ninp, nerror = 0;
+ int ninp;
t_inpfile *inp;
ninp = *ninp_p;
{
dumdub[0][i] = 0;
}
- m = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf",
- &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
- &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]));
+ sscanf(is->deform, "%lf %lf %lf %lf %lf %lf",
+ &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
+ &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]));
for (i = 0; i < 3; i++)
{
ir->deform[i][i] = dumdub[0][i];
{
imin = 2;
}
- imin = min(imin, nrdf2[ai]);
- jmin = min(jmin, nrdf2[aj]);
+ imin = std::min(imin, nrdf2[ai]);
+ jmin = std::min(jmin, nrdf2[aj]);
nrdf2[ai] -= imin;
nrdf2[aj] -= jmin;
nrdf_tc [ggrpnr(groups, egcTC, ai)] -= 0.5*imin;
for (j = 0; j < 3; j++)
{
ai = as + ia[1+j];
- imin = min(2, nrdf2[ai]);
+ imin = std::min(2, nrdf2[ai]);
nrdf2[ai] -= imin;
nrdf_tc [ggrpnr(groups, egcTC, ai)] -= 0.5*imin;
nrdf_vcm[ggrpnr(groups, egcVCM, ai)] -= 0.5*imin;
n_sub = 6;
break;
default:
- n_sub = 0;
gmx_incons("Checking comm_mode");
}
void do_index(const char* mdparin, const char *ndx,
gmx_mtop_t *mtop,
gmx_bool bVerbose,
- t_inputrec *ir, rvec *v,
+ t_inputrec *ir,
warninp_t wi)
{
t_blocka *grps;
int nacg, nfreeze, nfrdim, nenergy, nvcm, nuser;
char *ptr1[MAXPTR], *ptr2[MAXPTR], *ptr3[MAXPTR];
int i, j, k, restnm;
- real SAtime;
gmx_bool bExcl, bTable, bSetTCpar, bAnneal, bRest;
- int nQMmethod, nQMbasis, nQMcharge, nQMmult, nbSH, nCASorb, nCASelec,
- nSAon, nSAoff, nSAsteps, nQMg, nbOPT, nbTS;
+ int nQMmethod, nQMbasis, nQMg;
char warn_buf[STRLEN];
if (bVerbose)
if (ir->opts.tau_t[i] >= 0)
{
- tau_min = min(tau_min, ir->opts.tau_t[i]);
+ tau_min = std::min(tau_min, ir->opts.tau_t[i]);
}
}
if (ir->etc != etcNO && ir->nsttcouple == -1)
{
if (ir->nstpcouple != ir->nsttcouple)
{
- int mincouple = min(ir->nstpcouple, ir->nsttcouple);
+ int mincouple = std::min(ir->nstpcouple, ir->nsttcouple);
ir->nstpcouple = ir->nsttcouple = mincouple;
sprintf(warn_buf, "for current Trotter decomposition methods with vv, nsttcouple and nstpcouple must be equal. Both have been reset to min(nsttcouple,nstpcouple) = %d", mincouple);
warning_note(wi, warn_buf);
/* Now we have filled the freeze struct, so we can calculate NRDF */
calc_nrdf(mtop, ir, gnames);
- if (v && NULL)
- {
- real fac, ntot = 0;
-
- /* Must check per group! */
- for (i = 0; (i < ir->opts.ngtc); i++)
- {
- ntot += ir->opts.nrdf[i];
- }
- if (ntot != (DIM*natoms))
- {
- fac = sqrt(ntot/(DIM*natoms));
- if (bVerbose)
- {
- fprintf(stderr, "Scaling velocities by a factor of %.3f to account for constraints\n"
- "and removal of center of mass motion\n", fac);
- }
- for (i = 0; (i < natoms); i++)
- {
- svmul(fac, v[i], v[i]);
- }
- }
- }
-
nuser = str_nelem(is->user1, MAXPTR, ptr1);
do_numbering(natoms, groups, nuser, ptr1, grps, gnames, egcUser1,
restnm, egrptpALL_GENREST, bVerbose, wi);
eQMbasis_names);
}
- nQMmult = str_nelem(is->QMmult, MAXPTR, ptr1);
- nQMcharge = str_nelem(is->QMcharge, MAXPTR, ptr2);
- nbSH = str_nelem(is->bSH, MAXPTR, ptr3);
+ str_nelem(is->QMmult, MAXPTR, ptr1);
+ str_nelem(is->QMcharge, MAXPTR, ptr2);
+ str_nelem(is->bSH, MAXPTR, ptr3);
snew(ir->opts.QMmult, nr);
snew(ir->opts.QMcharge, nr);
snew(ir->opts.bSH, nr);
ir->opts.bSH[i] = (gmx_strncasecmp(ptr3[i], "Y", 1) == 0);
}
- nCASelec = str_nelem(is->CASelectrons, MAXPTR, ptr1);
- nCASorb = str_nelem(is->CASorbitals, MAXPTR, ptr2);
+ str_nelem(is->CASelectrons, MAXPTR, ptr1);
+ str_nelem(is->CASorbitals, MAXPTR, ptr2);
snew(ir->opts.CASelectrons, nr);
snew(ir->opts.CASorbitals, nr);
for (i = 0; i < nr; i++)
}
/* special optimization options */
- nbOPT = str_nelem(is->bOPT, MAXPTR, ptr1);
- nbTS = str_nelem(is->bTS, MAXPTR, ptr2);
+ str_nelem(is->bOPT, MAXPTR, ptr1);
+ str_nelem(is->bTS, MAXPTR, ptr2);
snew(ir->opts.bOPT, nr);
snew(ir->opts.bTS, nr);
for (i = 0; i < nr; i++)
ir->opts.bOPT[i] = (gmx_strncasecmp(ptr1[i], "Y", 1) == 0);
ir->opts.bTS[i] = (gmx_strncasecmp(ptr2[i], "Y", 1) == 0);
}
- nSAon = str_nelem(is->SAon, MAXPTR, ptr1);
- nSAoff = str_nelem(is->SAoff, MAXPTR, ptr2);
- nSAsteps = str_nelem(is->SAsteps, MAXPTR, ptr3);
+ str_nelem(is->SAon, MAXPTR, ptr1);
+ str_nelem(is->SAoff, MAXPTR, ptr2);
+ str_nelem(is->SAsteps, MAXPTR, ptr3);
snew(ir->opts.SAon, nr);
snew(ir->opts.SAoff, nr);
snew(ir->opts.SAsteps, nr);
gmx_bool *bC6ParametersWorkWithLBRules,
gmx_bool *bLBRulesPossible)
{
- int ntypes, tpi, tpj, thisLBdiff, thisgeomdiff;
+ int ntypes, tpi, tpj;
int *typecount;
real tol;
- double geometricdiff, LBdiff;
double c6i, c6j, c12i, c12j;
double c6, c6_geometric, c6_LB;
double sigmai, sigmaj, epsi, epsj;
*bC6ParametersWorkWithLBRules = TRUE;
*bC6ParametersWorkWithGeometricRules = TRUE;
bCanDoLBRules = TRUE;
- bCanDoGeometricRules = TRUE;
ntypes = mtop->ffparams.atnr;
snew(typecount, ntypes);
gmx_mtop_count_atomtypes(mtop, state, typecount);
- geometricdiff = LBdiff = 0.0;
*bLBRulesPossible = TRUE;
for (tpi = 0; tpi < ntypes; ++tpi)
{
c6j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
c12j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
c6 = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
- c6_geometric = sqrt(c6i * c6j);
+ c6_geometric = std::sqrt(c6i * c6j);
if (!gmx_numzero(c6_geometric))
{
if (!gmx_numzero(c12i) && !gmx_numzero(c12j))
{
- sigmai = pow(c12i / c6i, 1.0/6.0);
- sigmaj = pow(c12j / c6j, 1.0/6.0);
+ sigmai = std::pow(c12i / c6i, 1.0/6.0);
+ sigmaj = std::pow(c12j / c6j, 1.0/6.0);
epsi = c6i * c6i /(4.0 * c12i);
epsj = c6j * c6j /(4.0 * c12j);
- c6_LB = 4.0 * pow(epsi * epsj, 1.0/2.0) * pow(0.5 * (sigmai + sigmaj), 6);
+ c6_LB = 4.0 * std::pow(epsi * epsj, 1.0/2.0) * std::pow(0.5 * (sigmai + sigmaj), 6);
}
else
{
check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop,
warninp_t wi)
{
- char err_buf[256];
gmx_bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
check_combination_rule_differences(mtop, 0,
warninp_t wi)
{
char err_buf[STRLEN];
- int i, m, c, nmol, npct;
+ int i, m, c, nmol;
gmx_bool bCharge, bAcc;
- real gdt_max, *mgrp, mt;
+ real *mgrp, mt;
rvec acc;
gmx_mtop_atomloop_block_t aloopb;
gmx_mtop_atomloop_all_t aloop;
tau = 0;
for (i = 0; i < ir->opts.ngtc; i++)
{
- T = max(T, ir->opts.ref_t[i]);
- tau = max(tau, ir->opts.tau_t[i]);
+ T = std::max(T, ir->opts.ref_t[i]);
+ tau = std::max(tau, ir->opts.tau_t[i]);
}
if (T > 0)
{
}
else
{
- min_size = min(box[XX][XX], min(box[YY][YY], box[ZZ][ZZ]));
+ min_size = std::min(box[XX][XX], std::min(box[YY][YY], box[ZZ][ZZ]));
if (2*ir->rlistlong >= min_size)
{
sprintf(warn_buf, "ERROR: One of the box lengths is smaller than twice the cut-off length. Increase the box size or decrease rlist.");
sprintf(warn_buf,
"The sum of the two largest charge group radii (%f) "
"is larger than rlist (%f)\n",
- max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
+ std::max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
warning(wi, warn_buf);
}
else
#include "gromacs/legacyheaders/readinp.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
enum {
eshNONE, eshHBONDS, eshALLBONDS, eshHANGLES, eshALLANGLES, eshNR
};
gmx_mtop_t *mtop,
gmx_bool bVerbose,
t_inputrec *ir,
- rvec *v,
warninp_t wi);
/* Read the index file and assign grp numbers to atoms.
- * If v is not NULL, the velocities will be scaled to the correct number
- * of degrees of freedom.
*/
/* Routines In readpull.c */
void set_reference_positions(t_rot *rot, rvec *x, matrix box,
const char *fn, gmx_bool bSet, warninp_t wi);
-#ifdef __cplusplus
-}
-#endif
-
#endif
const char *wbuf)
{
double d;
- int n, m;
+ int n;
pg->nweight = 0;
while (sscanf(wbuf, "%lf %n", &d, &n) == 1)
static void process_pull_dim(char *dim_buf, ivec dim)
{
- int ndim, d, nchar, c;
+ int ndim, d, nchar;
char *ptr, pulldim1[STRLEN];
- t_pull_coord *pcrd;
ptr = dim_buf;
ndim = 0;
pull_params_t *pull,
warninp_t wi)
{
- int ninp, i, nchar, nscan, m, idum;
+ int ninp, i, nscan, idum;
t_inpfile *inp;
const char *tmp;
char **grpbuf;
- char dummy[STRLEN], buf[STRLEN], groups[STRLEN], dim_buf[STRLEN];
- char init[STRLEN];
- const char *init_def1 = "0.0", *init_def3 = "0.0 0.0 0.0";
+ char buf[STRLEN], groups[STRLEN], dim_buf[STRLEN];
char wbuf[STRLEN], origin_buf[STRLEN], vec_buf[STRLEN];
t_pull_group *pgrp;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/gmxpreprocess/readir.h"
#include "gromacs/legacyheaders/names.h"
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
-static char *RotStr = {"Enforced rotation:"};
+static const char *RotStr = "Enforced rotation:";
static char s_vec[STRLEN];
t_rot *rot, rvec *x, matrix box,
const char *fn, gmx_bool bSet, warninp_t wi)
{
- int g, i, ii;
- t_rotgrp *rotg;
- t_trnheader header; /* Header information of reference file */
- char base[STRLEN], extension[STRLEN], reffile[STRLEN];
- char *extpos;
- rvec f_box[3]; /* Box from reference file */
+ int g, i, ii;
+ t_rotgrp *rotg;
+ gmx_trr_header_t header; /* Header information of reference file */
+ char base[STRLEN], extension[STRLEN], reffile[STRLEN];
+ char *extpos;
+ rvec f_box[3]; /* Box from reference file */
/* Base name and extension of the reference file: */
if (gmx_fexist(reffile))
{
fprintf(stderr, " Reading them from %s.\n", reffile);
- read_trnheader(reffile, &header);
+ gmx_trr_read_single_header(reffile, &header);
if (rotg->nat != header.natoms)
{
gmx_fatal(FARGS, "Number of atoms in file %s (%d) does not match the number of atoms in rotation group (%d)!\n",
reffile, header.natoms, rotg->nat);
}
- read_trn(reffile, &header.step, &header.t, &header.lambda, f_box, &header.natoms, rotg->x_ref, NULL, NULL);
+ gmx_trr_read_single_frame(reffile, &header.step, &header.t, &header.lambda, f_box, &header.natoms, rotg->x_ref, NULL, NULL);
/* Check whether the box is unchanged and output a warning if not: */
check_box_unchanged(f_box, box, reffile, wi);
ii = rotg->ind[i];
copy_rvec(x[ii], rotg->x_ref[i]);
}
- write_trn(reffile, g, 0.0, 0.0, box, rotg->nat, rotg->x_ref, NULL, NULL);
+ gmx_trr_write_single_frame(reffile, g, 0.0, 0.0, box, rotg->nat, rotg->x_ref, NULL, NULL);
}
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <stdlib.h>
#include <string.h>
+#include <algorithm>
+
#include "gromacs/fileio/strdb.h"
#include "gromacs/gmxpreprocess/fflibutil.h"
#include "gromacs/gmxpreprocess/pgutil.h"
if (sscanf(buf, "%s%lf", name, &m) == 2)
{
a->m = m;
- add_atomtype(at, tab, a, name, nb, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
+ add_atomtype(at, tab, a, name, nb, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0 );
fprintf(stderr, "\rAtomtype %d", ++nratt);
}
else
gmx_bool bAllowOverrideRTP)
{
FILE *in;
- char filebase[STRLEN], *ptr, line[STRLEN], header[STRLEN];
+ char filebase[STRLEN], line[STRLEN], header[STRLEN];
int i, nrtp, maxrtp, bt, nparam;
int dum1, dum2, dum3;
t_restp *rrtp, *header_settings;
l1 = (int)strlen(a1);
l2 = (int)strlen(a2);
- lm = min(l1, l2);
+ lm = std::min(l1, l2);
if (lm >= 1 &&
((l1 == l2+1 && is_sign(a1[l1-1])) ||
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/hackblock.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
char *search_rtp(const char *key, int nrtp, t_restp rtp[]);
/* Search for an entry in the rtp database, returns the rtp residue name.
* A mismatch of one character is allowed, if there is only one nearly
void print_resall(FILE *out, int nrtp, t_restp rtp[],
gpp_atomtype_t atype);
/* write rtp database */
-#ifdef __cplusplus
-}
-#endif
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_SOLVATE_H
#define GMX_GMXPREPROCESS_SOLVATE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
int gmx_solvate(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/random/random.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void randwater(int astart, int nwater, int nwatom,
rvec x[], rvec v[], gmx_rng_t rng);
/* Randomize the order of nwater molecules of length nwatom, the
/* Make compact subboxes
* IS NOT THREAD SAFE */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "specbond.h"
#include <ctype.h>
-#include <math.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/fileio/pdbio.h"
#include "gromacs/fileio/strdb.h"
#include "gromacs/gmxpreprocess/pdb2top.h"
for (j = 0; (j < nspec); j++)
{
aj = sgp[j];
- d[i][j] = sqrt(distance2(x[ai], x[aj]));
+ d[i][j] = std::sqrt(distance2(x[ai], x[aj]));
}
}
if (nspec > 1)
{
/* print resname/number column headings */
fprintf(stderr, "%8s%8s", "", "");
- e = min(b+MAXCOL, nspec-1);
+ e = std::min(b+MAXCOL, nspec-1);
for (i = b; (i < e); i++)
{
sprintf(buf, "%s%d", *pdba->resinfo[pdba->atom[sgp[i]].resind].name,
fprintf(stderr, "\n");
/* print atomname/number column headings */
fprintf(stderr, "%8s%8s", "", "");
- e = min(b+MAXCOL, nspec-1);
+ e = std::min(b+MAXCOL, nspec-1);
for (i = b; (i < e); i++)
{
sprintf(buf, "%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
}
fprintf(stderr, "\n");
/* print matrix */
- e = min(b+MAXCOL, nspec);
+ e = std::min(b+MAXCOL, nspec);
for (i = b+1; (i < nspec); i++)
{
sprintf(buf, "%s%d", *pdba->resinfo[pdba->atom[sgp[i]].resind].name,
fprintf(stderr, "%8s", buf);
sprintf(buf, "%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
fprintf(stderr, "%8s", buf);
- e2 = min(i, e);
+ e2 = std::min(i, e);
for (j = b; (j < e2); j++)
{
fprintf(stderr, " %7.3f", d[i][j]);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/pdb2top.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
int mk_specbonds(t_atoms *pdba, rvec x[], gmx_bool bInteractive,
t_ssbond **specbonds, gmx_bool bVerbose);
gmx_bool yesno(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
char **nname, t_atom *a, gpp_atomtype_t atype, int *cgnr)
{
int nr, i;
- char buf[5][30], type[12];
+ char buf[5][30];
double m, q;
/* This code is messy, because of support for different formats:
{
FILE *out;
int i, j, k, bt, nrepl, nadd, ndel;
- char buf[STRLEN], nname[STRLEN];
+ char buf[STRLEN];
sprintf(buf, "%s-%c.tdb", ff, C);
out = gmx_fio_fopen(buf, "w");
const char *rtpname,
int *nret)
{
+ // TODO Four years later, no force fields have ever used this, so decide status of this feature
/* Since some force fields (e.g. OPLS) needs different
* atomtypes for different residues there could be a lot
* of entries in the databases for specific residues
*/
t_restp * restp;
- int i, j, n, len, none_idx;
+ int i, j, n, none_idx;
gmx_bool found;
- char *rtpname_match, *s, *s2, *c;
+ char *rtpname_match, *s;
t_hackblock **list;
rtpname_match = search_rtp(rtpname, nrtp, rtp);
while (!found && s != NULL);
}
- /* All residue-specific termini have been added. See if there
- * are some generic ones by searching for the occurence of
+ /* All residue-specific termini have been added. We might have to fall
+ * back on generic termini, which are characterized by not having
* '-' in the name prior to the last position (which indicates charge).
* The [ None ] alternative is special since we don't want that
* to be the default, so we put it last in the list we return.
}
else
{
- c = strchr(s, '-');
- if (c == NULL || ((c-s+1) == strlen(s)))
+ /* Time to see if there's a generic terminus that matches.
+ Is there a hyphen? */
+ char *c = strchr(s, '-');
+
+ /* A conjunction hyphen normally indicates a residue-specific
+ terminus, which is named like "GLY-COOH". A generic terminus
+ won't have a hyphen. */
+ bool bFoundAnyHyphen = (c != NULL);
+ /* '-' as the last character indicates charge, so if that's
+ the only one found e.g. "COO-", then it was not a conjunction
+ hyphen, so this is a generic terminus */
+ bool bOnlyFoundChargeHyphen = (bFoundAnyHyphen &&
+ *(c+1) == '\0');
+ /* Thus, "GLY-COO-" is not recognized as a generic terminus. */
+ bool bFoundGenericTerminus = !bFoundAnyHyphen || bOnlyFoundChargeHyphen;
+ if (bFoundGenericTerminus)
{
/* Check that we haven't already added a residue-specific version
* of this terminus.
printf("%s\n", title);
for (i = 0; (i < nb); i++)
{
- char *advice_string = "";
- if (0 == gmx_wcmatch("*ZWITTERION*", (*tb[i]).name))
- {
- advice_string = " (only use with zwitterions containing exactly one residue)";
- }
- printf("%2d: %s%s\n", i, (*tb[i]).name, advice_string);
+ bool bIsZwitterion = (0 == gmx_wcmatch("*ZWITTERION*", (*tb[i]).name));
+ printf("%2d: %s%s\n", i, (*tb[i]).name,
+ bIsZwitterion ? " (only use with zwitterions containing exactly one residue)" : "");
}
do
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/gmxpreprocess/hackblock.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
int read_ter_db(const char *ffdir, char ter,
t_hackblock **tbptr, gpp_atomtype_t atype);
t_hackblock *choose_ter(int nb, t_hackblock **tb, const char *title);
/* Interactively select one.. */
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "tomorse.h"
#include <ctype.h>
-#include <math.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/gmxpreprocess/toputil.h"
bRemoveHarm[j] = TRUE;
b0 = mols[i].plist[bb].param[j].c[0];
kb = mols[i].plist[bb].param[j].c[1];
- beta = sqrt(kb/(2*edis));
+ beta = std::sqrt(kb/(2*edis));
mols[i].plist[F_MORSE].param[nrmorse].a[0] = ni;
mols[i].plist[F_MORSE].param[nrmorse].a[1] = nj;
mols[i].plist[F_MORSE].param[nrmorse].c[0] = b0;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void convert_harmonics(int nrmols, t_molinfo mols[], gpp_atomtype_t atype);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/grompp-impl.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct tagDirStack {
directive d;
struct tagDirStack *prev;
int DS_Check_Order (DirStack *DS, directive d);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "topio.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
#include <sys/types.h>
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#define OPENDIR '[' /* starting sign for directive */
int i, j, ntp, nrfp, nrfpA, nrfpB, nnn;
real scaling;
ntp = nbs->nr;
- nnn = sqrt(ntp);
+ nnn = static_cast<int>(std::sqrt(static_cast<double>(ntp)));
+ GMX_ASSERT(nnn * nnn == ntp, "Number of pairs of generated non-bonded parameters should be a perfect square");
nrfp = NRFP(F_LJ);
nrfpA = interaction_function[F_LJ14].nrfpA;
nrfpB = interaction_function[F_LJ14].nrfpB;
if (status1 == 0 && status2 == 0)
{
/* cosine theorem to get r13 */
- *length = sqrt(r12*r12+r23*r23-(2*r12*r23*cos(a123/RAD2DEG)));
+ *length = std::sqrt(r12*r12+r23*r23-(2*r12*r23*cos(a123/RAD2DEG)));
found = 1;
}
}
int
generate_gb_exclusion_interactions(t_molinfo *mi, gpp_atomtype_t atype, t_nextnb *nnb)
{
- int i, j, k, n, ai, aj, ti, tj;
- int n12, n13, n14;
+ int j, n, ai, aj, ti, tj;
int ftype;
t_param param;
t_params * plist;
warninp_t wi)
{
FILE *out;
- int i, sl, nb_funct, comb;
+ int i, sl, nb_funct;
char *pline = NULL, **title = NULL;
char line[STRLEN], errbuf[256], comb_str[256], nb_str[256];
char genpairs[32];
int nrcopies, nmol, nmolb = 0, nscan, ncombs, ncopy;
double fLJ, fQQ, fPOW;
gmx_molblock_t *molb = NULL;
- t_topology *block = NULL;
t_molinfo *mi0 = NULL;
DirStack *DS;
directive d, newd;
t_nbparam **nbparam, **pair;
- gmx_bool bIntermolecularInteractions;
t_block2 *block2;
real fudgeLJ = -1; /* Multiplication factor to generate 1-4 from LJ */
gmx_bool bReadDefaults, bReadMolType, bGenPairs, bWarn_copy_A_B;
push_vsitesn(d, mi0->plist, &(mi0->atoms), pline, wi);
break;
case d_exclusions:
- assert(block2);
+ GMX_ASSERT(block2, "block2 must always be allocated so exclusions can be processed");
if (!block2[nmol-1].nr)
{
init_block2(&(block2[nmol-1]), mi0->atoms.nr);
j = 0;
while (j < molt->ilist[i].nr)
{
- bexcl = FALSE;
switch (nratoms)
{
case 2:
break;
default:
gmx_fatal(FARGS, "no such bonded interactions with %d atoms\n", nratoms);
+ bexcl = FALSE;
}
if (bexcl)
{
#include "gromacs/gmxpreprocess/readir.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
double check_mol(gmx_mtop_t *mtop, warninp_t wi);
/* Check mass and charge */
/* This routine expects sys->molt[m].ilist to be of size F_NRE and ordered. */
void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp_t wi);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "toppush.h"
-#include <assert.h>
#include <ctype.h>
-#include <math.h>
#include <stdlib.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/gmxpreprocess/gpp_bond_atomtype.h"
#include "gromacs/gmxpreprocess/readir.h"
#include "gromacs/topology/symtab.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
void generate_nbparams(int comb, int ftype, t_params *plist, gpp_atomtype_t atype,
{
ci = get_atomtype_nbparam(i, nf, atype);
cj = get_atomtype_nbparam(j, nf, atype);
- c = sqrt(ci * cj);
+ c = std::sqrt(ci * cj);
plist->param[k].c[nf] = c;
}
}
{
plist->param[k].c[0] *= -1;
}
- plist->param[k].c[1] = sqrt(ci1*cj1);
+ plist->param[k].c[1] = std::sqrt(ci1*cj1);
}
}
cj0 = get_atomtype_nbparam(j, 0, atype);
ci1 = get_atomtype_nbparam(i, 1, atype);
cj1 = get_atomtype_nbparam(j, 1, atype);
- plist->param[k].c[0] = sqrt(fabs(ci0*cj0));
+ plist->param[k].c[0] = std::sqrt(fabs(ci0*cj0));
/* Negative sigma signals that c6 should be set to zero later,
* so we need to propagate that through the combination rules.
*/
{
plist->param[k].c[0] *= -1;
}
- plist->param[k].c[1] = sqrt(ci1*cj1);
+ plist->param[k].c[1] = std::sqrt(ci1*cj1);
}
}
cj2 = get_atomtype_nbparam(j, 2, atype);
bi = get_atomtype_nbparam(i, 1, atype);
bj = get_atomtype_nbparam(j, 1, atype);
- plist->param[k].c[0] = sqrt(ci0 * cj0);
+ plist->param[k].c[0] = std::sqrt(ci0 * cj0);
if ((bi == 0) || (bj == 0))
{
plist->param[k].c[1] = 0;
{
plist->param[k].c[1] = 2.0/(1/bi+1/bj);
}
- plist->param[k].c[2] = sqrt(ci2 * cj2);
+ plist->param[k].c[2] = std::sqrt(ci2 * cj2);
}
}
gmx_fatal(FARGS, "Replacing atomtype %s failed", type);
}
}
- else if ((nr = add_atomtype(at, symtab, atom, type, param,
- batype_nr, radius, vol,
- surftens, atomnr, gb_radius, S_hct)) == NOTSET)
+ else if ((add_atomtype(at, symtab, atom, type, param,
+ batype_nr, radius, vol,
+ surftens, atomnr, gb_radius, S_hct)) == NOTSET)
{
gmx_fatal(FARGS, "Adding atomtype %s failed", type);
}
"%*s%*s%*s%*s%*s%*s%*s"
};
const char *formlf = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
- int i, ft, ftype, nn, nrfp, nrfpA, nrfpB;
+ int i, ft, ftype, nn, nrfp, nrfpA;
char f1[STRLEN];
char alc[MAXATOMLIST+1][20];
/* One force parameter more, so we can check if we read too many */
ftype = ifunc_index(d, ft);
nrfp = NRFP(ftype);
nrfpA = interaction_function[ftype].nrfpA;
- nrfpB = interaction_function[ftype].nrfpB;
strcpy(f1, formnl[nral]);
strcat(f1, formlf);
if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12]))
"%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
"%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
};
- int i, ft, ftype, nn, nrfp, nrfpA, nrfpB, nral;
+ int i, ft, ftype, nn, nrfp, nrfpA, nral;
char f1[STRLEN];
char alc[MAXATOMLIST+1][20];
double c[MAXFORCEPARAM];
ftype = ifunc_index(d, ft);
nrfp = NRFP(ftype);
nrfpA = interaction_function[ftype].nrfpA;
- nrfpB = interaction_function[ftype].nrfpB;
strcpy(f1, formnl[nral]);
strcat(f1, formlf[nrfp-1]);
warninp_t wi)
{
/* swap the atoms */
- const char *form2 = "%*s%*s%*s%lf%lf";
const char *form3 = "%*s%*s%*s%lf%lf%lf";
const char *form4 = "%*s%*s%*s%lf%lf%lf%lf";
const char *form5 = "%*s%*s%*s%lf%lf%lf%lf%lf";
char a0[80], a1[80];
- int i, f, n, ftype, atnr, nrfp;
+ int i, f, n, ftype, nrfp;
double c[4], dum;
- real cr[4], sig6;
+ real cr[4];
atom_id ai, aj;
t_nbparam *nbp;
gmx_bool bId;
/* When the B topology parameters are not set,
* copy them from topology A
*/
- assert(nrfp <= 4);
+ GMX_ASSERT(nrfp <= 4, "LJ-14 cannot have more than 4 parameters");
for (i = n; i < nrfp; i++)
{
c[i] = c[i-2];
{
gmx_fatal(FARGS, "Atomtype %s not found", a1);
}
- nbp = &(nbt[max(ai, aj)][min(ai, aj)]);
+ nbp = &(nbt[std::max(ai, aj)][std::min(ai, aj)]);
if (nbp->bSet)
{
push_gb_params (gpp_atomtype_t at, char *line,
warninp_t wi)
{
- int nfield;
int atype;
double radius, vol, surftens, gb_radius, S_hct;
char atypename[STRLEN];
char errbuf[STRLEN];
- if ( (nfield = sscanf(line, "%s%lf%lf%lf%lf%lf", atypename, &radius, &vol, &surftens, &gb_radius, &S_hct)) != 6)
+ if ( (sscanf(line, "%s%lf%lf%lf%lf%lf", atypename, &radius, &vol, &surftens, &gb_radius, &S_hct)) != 6)
{
sprintf(errbuf, "Too few gb parameters for type %s\n", atypename);
warning(wi, errbuf);
{
const char *formal = "%s%s%s%s%s%s%s%s";
- int i, j, ft, ftype, nn, nrfp, nrfpA, nrfpB;
+ int i, ft, ftype, nn, nrfp, nrfpA, nrfpB;
int start;
int nxcmap, nycmap, ncmap, read_cmap, sl, nct;
char s[20], alc[MAXATOMLIST+2][20];
t_param p;
- gmx_bool bAllowRepeat;
char errbuf[256];
/* Keep the compiler happy */
/* First test the generated-pair position to save
* time when we have 1000*1000 entries for e.g. OPLS...
*/
- ntype = sqrt(nr);
+ ntype = static_cast<int>(std::sqrt(static_cast<double>(nr)));
+ GMX_ASSERT(ntype * ntype == nr, "Number of pairs of generated non-bonded parameters should be a perfect square");
if (bB)
{
ti = at->atom[p->a[0]].typeB;
t_param *p, gmx_bool bB,
int *cmap_type, int *nparam_def)
{
- int i, j, nparam_found;
+ int i, nparam_found;
int ct;
gmx_bool bFound = FALSE;
/* One force parameter more, so we can check if we read too many */
double cc[MAXFORCEPARAM+1];
int aa[MAXATOMLIST+1];
- t_param param, paramB, *param_defA, *param_defB;
+ t_param param, *param_defA, *param_defB;
gmx_bool bFoundA = FALSE, bFoundB = FALSE, bDef, bPert, bSwapParity = FALSE;
int nparam_defA, nparam_defB;
char errbuf[256];
if (bFoundA)
{
/* Copy the A-state and B-state default parameters. */
- assert(NRFPA(ftype)+NRFPB(ftype) <= MAXFORCEPARAM);
+ GMX_ASSERT(NRFPA(ftype)+NRFPB(ftype) <= MAXFORCEPARAM, "Bonded interactions may have at most 12 parameters");
for (j = 0; (j < NRFPA(ftype)+NRFPB(ftype)); j++)
{
param.c[j] = param_defA->c[j];
"%d%d%d%d%d%d%d"
};
- int i, j, nr, ftype, nral, nread, ncmap_params;
+ int i, j, ftype, nral, nread, ncmap_params;
int cmap_type;
int aa[MAXATOMLIST+1];
char errbuf[256];
gmx_bool bFound;
- t_param param, paramB, *param_defA, *param_defB;
+ t_param param;
ftype = ifunc_index(d, 1);
nral = NRAL(ftype);
- nr = bondtype[ftype].nr;
ncmap_params = 0;
nread = sscanf(line, aaformat[nral-1],
param.a[0] = a - 1;
- ret = sscanf(ptr, "%d%n", &type, &n);
+ sscanf(ptr, "%d%n", &type, &n);
ptr += n;
ftype = ifunc_index(d, type);
n = mol->atoms.nr;
atom = mol->atoms.atom;
- ntype = sqrt(nbp->nr);
+ ntype = static_cast<int>(std::sqrt(static_cast<double>(nbp->nr)));
+ GMX_ASSERT(ntype * ntype == nbp->nr, "Number of pairs of generated non-bonded parameters should be a perfect square");
for (i = 0; i < MAXATOMLIST; i++)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/legacyheaders/warninp.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
int nr; /* The number of entries in the list */
int nra2; /* The total number of entries in a */
* of the system, but full interaction with itself.
*/
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "topshake.h"
#include <ctype.h>
-#include <math.h>
+
+#include <cmath>
#include "gromacs/gmxpreprocess/readir.h"
#include "gromacs/gmxpreprocess/topdirs.h"
t_params *bonds;
t_param p, *bond, *ang;
real b_ij, b_jk;
- int nb, b, i, j, ftype, ftype_a;
+ int i, j, ftype, ftype_a;
gmx_bool bFound;
if (nshake != eshNONE)
if (bFound)
{
/* apply law of cosines */
- p.C0 = sqrt( b_ij*b_ij + b_jk*b_jk -
- 2.0*b_ij*b_jk*cos(DEG2RAD*ang->C0) );
+ p.C0 = std::sqrt( b_ij*b_ij + b_jk*b_jk -
+ 2.0*b_ij*b_jk*cos(DEG2RAD*ang->C0) );
p.C1 = p.C0;
#ifdef DEBUG
printf("p: %d, q: %d, dist: %12.5e\n", p.AI, p.AJ, p.C0);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/topio.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void make_shake (t_params plist[], t_atoms *atoms, int nshake);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "toputil.h"
-#include <assert.h>
-#include <math.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/gmxpreprocess/topdirs.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/topology/block.h"
#include "gromacs/topology/symtab.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
/* UTILITIES */
{
return;
}
- assert(!((pr->nr == 0) && (pr->param != NULL)));
+ GMX_ASSERT(pr->nr != 0 || pr->param == NULL, "Invalid t_params object");
if (pr->nr+extra > pr->maxnr)
{
- pr->maxnr = max(1.2*pr->maxnr, pr->maxnr + extra);
+ pr->maxnr = std::max(static_cast<int>(1.2*pr->maxnr), pr->maxnr + extra);
srenew(pr->param, pr->maxnr);
for (i = pr->nr; (i < pr->maxnr); i++)
{
gmx_fatal(FARGS, "tpA = %d, i= %d in print_atoms", tpA, i);
}
+ /* This is true by construction, but static analysers don't know */
+ GMX_ASSERT(!bRTPresname || at->resinfo[at->atom[i].resind].rtp, "-rtpres did not have residue name available");
fprintf(out, "%6d %10s %6d%c %5s %6s %6d %10g %10g",
i+1, tpnmA,
at->resinfo[ri].nr,
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/gmxpreprocess/grompp-impl.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* UTILITIES */
int name2index(char *str, char ***typenames, int ntypes);
void print_excl(FILE *out, int natoms, t_excls excls[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "vsite_parm.h"
-#include <assert.h>
-#include <math.h>
#include <stdio.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/gmxpreprocess/add_par.h"
#include "gromacs/gmxpreprocess/resall.h"
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
typedef struct {
bError = bError || (bjk != bjl);
/* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */
- aN = max(param->AK, param->AL)+1;
+ aN = std::max(param->AK, param->AL)+1;
/* get common bonds */
bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
/* calculate common things */
rM = 0.5*bMM;
- dM = sqrt( sqr(bCM) - sqr(rM) );
+ dM = std::sqrt( sqr(bCM) - sqr(rM) );
/* are we dealing with the X atom? */
if (param->AI == aN)
bError = bError || (bjk != bjl);
/* the X atom (C or N) in the XH3 group is the first after the masses: */
- aN = max(param->AK, param->AL)+1;
+ aN = std::max(param->AK, param->AL)+1;
/* get all bondlengths and angles: */
bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
rHx = rH*cos(DEG2RAD*30);
rHy = rH*sin(DEG2RAD*30);
rM = 0.5*bMM;
- dM = sqrt( sqr(bCM) - sqr(rM) );
+ dM = std::sqrt( sqr(bCM) - sqr(rM) );
a = 0.5*( (dH/dM) - (rHy/rM) );
b = 0.5*( (dH/dM) + (rHy/rM) );
c = rHx / (2*dM*rM);
pijl = cos(aijl)*bij;
a = ( pijk + (pijk*cos(akjl)-pijl) * cos(akjl) / sqr(sin(akjl)) ) / bjk;
b = ( pijl + (pijl*cos(akjl)-pijk) * cos(akjl) / sqr(sin(akjl)) ) / bjl;
- c = -sqrt( sqr(bij) -
- ( sqr(pijk) - 2*pijk*pijl*cos(akjl) + sqr(pijl) )
- / sqr(sin(akjl)) )
+ c = -std::sqrt( sqr(bij) -
+ ( sqr(pijk) - 2*pijk*pijl*cos(akjl) + sqr(pijl) )
+ / sqr(sin(akjl)) )
/ ( bjk*bjl*sin(akjl) );
}
gmx_fatal(FARGS, "invalid construction in calc_vsite4fd for atom %d: "
"cosakl=%f, cosakm=%f\n", param->AI+1, cosakl, cosakm);
}
- sinakl = sqrt(1-sqr(cosakl));
- sinakm = sqrt(1-sqr(cosakm));
+ sinakl = std::sqrt(1-sqr(cosakl));
+ sinakm = std::sqrt(1-sqr(cosakm));
/* note: there is a '+' because of the way the sines are calculated */
cl = -pk / ( pl*cosakl - pk + pl*sinakl*(pm*cosakm-pk)/(pm*sinakm) );
t_mybonded *idihs;
bFirst = TRUE;
- bERROR = TRUE;
nvsite = 0;
if (debug)
{
"for %s atom %d",
interaction_function[ftype].longname,
plist[ftype].param[i].AI+1);
+ bERROR = TRUE;
} /* switch */
if (bERROR)
{
static void clean_vsite_bonds(t_params *plist, t_pindex pindex[],
int cftype, int vsite_type[])
{
- int ftype, i, j, parnr, k, l, m, n, nvsite, nOut, kept_i, vsitetype;
+ int ftype, i, j, k, m, n, nvsite, nOut, kept_i;
int nconverted, nremoved;
atom_id atom, oatom, at1, at2;
gmx_bool bKeep, bRemove, bUsed, bPresent, bThisFD, bThisOUT, bAllFD, bFirstTwo;
}
else
{
- assert(vsnral != 0);
- assert(first_atoms != NULL);
+ GMX_ASSERT(vsnral != 0, "nvsite > 1 must have vsnral != 0");
+ GMX_ASSERT(first_atoms != NULL, "nvsite > 1 must have first_atoms != NULL");
/* if it is not the first then
check if this vsite is constructed from the same atoms */
if (vsnral == NRAL(pindex[atom].ftype)-1)
bUsed = FALSE;
for (m = 0; (m < vsnral) && !bUsed; m++)
{
- assert(first_atoms != NULL);
+ GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
if (atom == first_atoms[m])
{
int cftype, int vsite_type[],
at2vsitecon_t *at2vc)
{
- int i, j, parnr, k, l, m, n, nvsite, kept_i, vsitetype;
+ int i, j, k, m, n, nvsite, kept_i;
atom_id atom, at1, at2;
gmx_bool bKeep, bUsed, bPresent, bAll3FAD, bFirstTwo;
t_params *ps;
}
else
{
- assert(vsnral != 0);
- assert(first_atoms != NULL);
+ GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
+ GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
/* check if this vsite is constructed from the same atoms */
if (vsnral == NRAL(pindex[atom].ftype)-1)
{
bUsed = FALSE;
for (m = 0; (m < vsnral) && !bUsed; m++)
{
- assert(first_atoms != NULL);
+ GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
if (atom == first_atoms[m])
{
kept_i = 0;
for (i = 0; (i < ps->nr); i++) /* for all dihedrals in the plist */
{
- int ftype, parnr, k, l, m, n, nvsite;
+ int k, m, n, nvsite;
int vsnral = 0;
const atom_id *first_atoms = NULL;
atom_id atom;
}
else
{
- assert(vsnral != 0);
- assert(first_atoms != NULL);
-
+ GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
+ GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
/* check if this vsite is constructed from the same atoms */
if (vsnral == NRAL(pindex[atom].ftype)-1)
{
construction of virtual sites. If so, keep it, if not throw away: */
for (k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */
{
- assert(vsnral != 0);
- assert(first_atoms != NULL);
-
+ GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
+ GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
atom = ps->param[i].a[k];
if (vsite_type[atom] == NOTSET && vsite_type[atom] != F_VSITEN)
{
#include "gromacs/gmxpreprocess/grompp-impl.h"
#include "gromacs/legacyheaders/typedefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
int set_vsites(gmx_bool bVerbose, t_atoms *atoms, gpp_atomtype_t atype,
t_params plist[]);
/* set parameters for virtual sites, return number of virtual sites */
* Throw away all constraints. */
void clean_vsite_bondeds(t_params *ps, int natoms, gmx_bool bRmVSiteBds);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "x2top.h"
-#include <assert.h>
+#include <cmath>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/topology/symtab.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
char atp[7] = "HCNOSX";
dx2 = iprod(dx, dx);
if (is_bond(nnm, nmt, *atoms->atomname[i], *atoms->atomname[j],
- sqrt(dx2)))
+ std::sqrt(dx2)))
{
b.AI = i;
b.AJ = j;
- b.C0 = sqrt(dx2);
+ b.C0 = std::sqrt(dx2);
add_param_to_list (bond, &b);
nbond[i]++;
nbond[j]++;
{
int i, n = 1;
int *cgnr;
- double qt = 0, mt = 0;
+ double qt = 0;
*qtot = *mtot = 0;
snew(cgnr, atoms->nr);
c[0] += 180;
}
}
- assert(nrfp <= MAXFORCEPARAM/2);
+ GMX_ASSERT(nrfp <= MAXFORCEPARAM/2, "Only 6 parameters may be used for an interaction");
for (j = 0; (j < nrfp); j++)
{
plist->param[i].c[j] = c[j];
void set_force_const(t_params plist[], real kb, real kt, real kp, gmx_bool bRound,
gmx_bool bParam)
{
- int i;
real c[MAXFORCEPARAM];
c[0] = 0;
int bts[] = { 1, 1, 1, 2 };
matrix box; /* box length matrix */
int natoms; /* number of atoms in one molecule */
- int nres; /* number of molecules? */
- int i, j, k, l, m, ndih;
int epbc;
gmx_bool bRTP, bTOP, bOPLS;
t_symtab symtab;
- real cutoff, qtot, mtot;
+ real qtot, mtot;
char n2t[STRLEN];
output_env_t oenv;
{ efRTP, "-r", "out", ffOPTWR }
};
#define NFILE asize(fnm)
- static real scale = 1.1, kb = 4e5, kt = 400, kp = 5;
+ static real kb = 4e5, kt = 400, kp = 5;
static t_restp rtp_header_settings;
static gmx_bool bRemoveDihedralIfWithImproper = FALSE;
static gmx_bool bGenerateHH14Interactions = TRUE;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_X2TOP_H
#define GMX_GMXPREPROCESS_X2TOP_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
int gmx_x2top(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/gmxpreprocess/hackblock.h"
#include "gromacs/utility/basedefinitions.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
struct gmx_residuetype_t;
struct t_atoms;
struct t_symtab;
gmx_bool bResname, struct gmx_residuetype_t *rt, gmx_bool bReorderNum,
gmx_bool bVerbose);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#endif
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/imd/imdsocket.h"
#include "gromacs/legacyheaders/gmx_ga2la.h"
#ifndef _checkpoint_h
#define _checkpoint_h
-
#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/typedefs.h"
#ifdef __cplusplus
extern "C" {
#endif
+struct gmx_file_position_t;
+struct t_fileio;
+
/* the name of the environment variable to disable fsync failure checks with */
#define GMX_IGNORE_FSYNC_FAILURE_ENV "GMX_IGNORE_FSYNC_FAILURE"
gmx_int64_t *step, double *t, t_state *state);
/* Read everything that can be stored in t_trxframe from a checkpoint file */
-void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr);
+void read_checkpoint_trxframe(struct t_fileio *fp, t_trxframe *fr);
/* Print the complete contents of checkpoint file fn to out */
void list_checkpoint(const char *fn, FILE *out);
* \param[out] outputfiles Pointer to array of output file names from the previous run. Pointer is allocated in this function.
*/
void
-read_checkpoint_simulation_part_and_filenames(t_fileio *fp,
- int *simulation_part,
- int *nfiles,
- gmx_file_position_t **outputfiles);
+read_checkpoint_simulation_part_and_filenames(struct t_fileio *fp,
+ int *simulation_part,
+ int *nfiles,
+ struct gmx_file_position_t **outputfiles);
#ifdef __cplusplus
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class ProgramContextInterface;
+class IProgramContext;
/*! \brief
* Settings for printBinaryInformation().
//! Needed to read the members without otherwise unnecessary accessors.
friend void printBinaryInformation(
- FILE *fp, const ProgramContextInterface &programContext,
+ FILE *fp, const IProgramContext &programContext,
const BinaryInformationSettings &settings);
};
* \param[in] programContext Program information object to use.
*/
void printBinaryInformation(FILE *fp,
- const ProgramContextInterface &programContext);
+ const IProgramContext &programContext);
/*! \brief
* Print basic information about the executable with custom settings.
*
* \see BinaryInformationSettings
*/
void printBinaryInformation(FILE *fp,
- const ProgramContextInterface &programContext,
+ const IProgramContext &programContext,
const BinaryInformationSettings &settings);
} // namespace gmx;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class ProgramContextInterface;
+class IProgramContext;
} // namespace gmx
void output_env_init(output_env_t *oenvp,
- const gmx::ProgramContextInterface &context,
+ const gmx::IProgramContext &context,
time_unit_t tmu, gmx_bool view, xvg_format_t xvg_format,
int verbosity);
/* initialize an output_env structure, setting the command line,
the graph formatting type, the verbosity, and debug level */
/*! \brief
- * Returns gmx::ProgramContextInterface from an output_env structure.
+ * Returns gmx::IProgramContext from an output_env structure.
*/
-const gmx::ProgramContextInterface &
+const gmx::IProgramContext &
output_env_get_program_context(const output_env_t oenv);
#endif
/* Abstract type for PME that is defined only in the routine that use them. */
struct gmx_pme_t;
struct nonbonded_verlet_t;
+struct bonded_threading_t;
/* Structure describing the data in a single table */
typedef struct
/* Forward declaration of type for managing Ewald tables */
struct gmx_ewald_tab_t;
-typedef struct f_thread_t f_thread_t;
+typedef struct ewald_corr_thread_t ewald_corr_thread_t;
typedef struct {
interaction_const_t *ic;
real userreal3;
real userreal4;
- /* Thread local force and energy data */
- /* FIXME move to bonded_thread_data_t */
- int nthreads;
- int red_ashift;
- int red_nblock;
- f_thread_t *f_t;
+ /* Pointer to struct for managing threading of bonded force calculation */
+ struct bonded_threading_t *bonded_threading;
- /* Maximum thread count for uniform distribution of bondeds over threads */
- int bonded_max_nthread_uniform;
-
- /* Exclusion load distribution over the threads */
- int *excl_load;
+ /* Ewald correction thread local virial and energy data */
+ int nthread_ewc;
+ ewald_corr_thread_t *ewc_t;
+ /* Ewald charge correction load distribution over the threads */
+ int *excl_load;
} t_forcerec;
/* Important: Starting with Gromacs-4.6, the values of c6 and c12 in the nbfp array have
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/pbcutil/mshift.h"
-#include "gromacs/pbcutil/pbc-simd.h"
#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pbcutil/pbc-simd.h"
#include "gromacs/simd/simd.h"
#include "gromacs/simd/simd_math.h"
#include "gromacs/simd/vector_operations.h"
#include "gromacs/listed-forces/bonded.h"
#include "gromacs/listed-forces/position-restraints.h"
#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/forcerec-threading.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/simd/simd.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/utility/smalloc.h"
+#include "listed-internal.h"
#include "pairs.h"
namespace
t_fcdata *fcd, int *global_atom_index,
int force_flags)
{
- gmx_bool bCalcEnerVir;
- int i;
- real dvdl[efptNR]; /* The dummy array is to have a place to store the dhdl at other values
- of lambda, which will be thrown away in the end*/
- const t_pbc *pbc_null;
- int thread;
+ struct bonded_threading_t *bt;
+ gmx_bool bCalcEnerVir;
+ int i;
+ /* The dummy array is to have a place to store the dhdl at other values
+ of lambda, which will be thrown away in the end */
+ real dvdl[efptNR];
+ const t_pbc *pbc_null;
+ int thread;
+
+ bt = fr->bonded_threading;
- assert(fr->nthreads == idef->nthreads);
+ assert(bt->nthreads == idef->nthreads);
bCalcEnerVir = (force_flags & (GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY));
}
wallcycle_sub_start(wcycle, ewcsLISTED);
-#pragma omp parallel for num_threads(fr->nthreads) schedule(static)
- for (thread = 0; thread < fr->nthreads; thread++)
+#pragma omp parallel for num_threads(bt->nthreads) schedule(static)
+ for (thread = 0; thread < bt->nthreads; thread++)
{
int ftype;
real *epot, v;
}
else
{
- zero_thread_forces(&fr->f_t[thread], fr->natoms_force,
- fr->red_nblock, 1<<fr->red_ashift);
-
- ft = fr->f_t[thread].f;
- fshift = fr->f_t[thread].fshift;
- epot = fr->f_t[thread].ener;
- grpp = &fr->f_t[thread].grpp;
- dvdlt = fr->f_t[thread].dvdl;
+ zero_thread_forces(&bt->f_t[thread], fr->natoms_force,
+ bt->red_nblock, 1<<bt->red_ashift);
+
+ ft = bt->f_t[thread].f;
+ fshift = bt->f_t[thread].fshift;
+ epot = bt->f_t[thread].ener;
+ grpp = &bt->f_t[thread].grpp;
+ dvdlt = bt->f_t[thread].dvdl;
}
/* Loop over all bonded force types to calculate the bonded forces */
for (ftype = 0; (ftype < F_NRE); ftype++)
}
wallcycle_sub_stop(wcycle, ewcsLISTED);
- if (fr->nthreads > 1)
+ if (bt->nthreads > 1)
{
wallcycle_sub_start(wcycle, ewcsLISTED_BUF_OPS);
reduce_thread_forces(fr->natoms_force, f, fr->fshift,
enerd->term, &enerd->grpp, dvdl,
- fr->nthreads, fr->f_t,
- fr->red_nblock, 1<<fr->red_ashift,
+ bt->nthreads, bt->f_t,
+ bt->red_nblock, 1<<bt->red_ashift,
bCalcEnerVir,
force_flags & GMX_FORCE_DHDL);
wallcycle_sub_stop(wcycle, ewcsLISTED_BUF_OPS);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_LISTED_FORCES_LISTED_INTERNAL_H
#define GMX_LISTED_FORCES_LISTED_INTERNAL_H
+#include "gromacs/legacyheaders/types/forcerec.h"
+#include "gromacs/math/vectypes.h"
+#include "gromacs/topology/idef.h"
+#include "gromacs/utility/bitmask.h"
+
+/*! \internal \brief struct with output for bonded forces, used per thread */
+typedef struct
+{
+ rvec *f; /**< Force array */
+ int f_nalloc; /**< Allocation size of f */
+ gmx_bitmask_t red_mask; /**< Mask for marking which parts of f are filled */
+ rvec *fshift; /**< Shift force array, size SHIFTS */
+ real ener[F_NRE]; /**< Energy array */
+ gmx_grppairener_t grpp; /**< Group pair energy data for pairs */
+ real dvdl[efptNR]; /**< Free-energy dV/dl output */
+}
+f_thread_t;
+
+/*! \internal \brief struct contain all data for bonded force threading */
+struct bonded_threading_t
+{
+ /* Thread local force and energy data */
+ int nthreads; /**< Number of threads to be used for bondeds */
+ int red_ashift; /**< Size of force reduction blocks in bits */
+ int red_nblock; /**< The number of force blocks to reduce */
+ f_thread_t *f_t; /**< Force/enegry data per thread, size nthreads */
+
+ /* There are two different ways to distribute the bonded force calculation
+ * over the threads. We dedice which to use based on the number of threads.
+ */
+ int bonded_max_nthread_uniform; /**< Maximum thread count for uniform distribution of bondeds over threads */
+};
+
+
/*! \brief Returns the global topology atom number belonging to local
* atom index i.
*
#include "gromacs/legacyheaders/gmx_omp_nthreads.h"
#include "gromacs/listed-forces/listed-forces.h"
-#include "gromacs/mdlib/forcerec-threading.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
+#include "listed-internal.h"
+
/*! \brief struct for passing all data required for a function type */
typedef struct {
int ftype; /**< the function type index */
void setup_bonded_threading(t_forcerec *fr, t_idef *idef)
{
- int t;
- int ctot, c, b;
+ bonded_threading_t *bt;
+ int t;
+ int ctot, c, b;
+
+ bt = fr->bonded_threading;
- assert(fr->nthreads >= 1);
+ assert(bt->nthreads >= 1);
/* Divide the bonded interaction over the threads */
divide_bondeds_over_threads(idef,
- fr->nthreads,
- fr->bonded_max_nthread_uniform);
+ bt->nthreads,
+ bt->bonded_max_nthread_uniform);
- if (fr->nthreads == 1)
+ if (bt->nthreads == 1)
{
- fr->red_nblock = 0;
+ bt->red_nblock = 0;
return;
}
- fr->red_ashift = 6;
- while (fr->natoms_force > (int)(maxBlockBits*(1U<<fr->red_ashift)))
+ bt->red_ashift = 6;
+ while (fr->natoms_force > (int)(maxBlockBits*(1U<<bt->red_ashift)))
{
- fr->red_ashift++;
+ bt->red_ashift++;
}
if (debug)
{
fprintf(debug, "bonded force buffer block atom shift %d bits\n",
- fr->red_ashift);
+ bt->red_ashift);
}
/* Determine to which blocks each thread's bonded force calculation
* contributes. Store this is a mask for each thread.
*/
-#pragma omp parallel for num_threads(fr->nthreads) schedule(static)
- for (t = 1; t < fr->nthreads; t++)
+#pragma omp parallel for num_threads(bt->nthreads) schedule(static)
+ for (t = 1; t < bt->nthreads; t++)
{
- calc_bonded_reduction_mask(&fr->f_t[t].red_mask,
- idef, fr->red_ashift, t, fr->nthreads);
+ calc_bonded_reduction_mask(&bt->f_t[t].red_mask,
+ idef, bt->red_ashift, t, bt->nthreads);
}
/* Determine the maximum number of blocks we need to reduce over */
- fr->red_nblock = 0;
+ bt->red_nblock = 0;
ctot = 0;
- for (t = 0; t < fr->nthreads; t++)
+ for (t = 0; t < bt->nthreads; t++)
{
c = 0;
for (b = 0; b < maxBlockBits; b++)
{
- if (bitmask_is_set(fr->f_t[t].red_mask, b))
+ if (bitmask_is_set(bt->f_t[t].red_mask, b))
{
- fr->red_nblock = std::max(fr->red_nblock, b+1);
+ bt->red_nblock = std::max(bt->red_nblock, b+1);
c++;
}
}
if (debug)
{
#if BITMASK_SIZE <= 64 //move into bitmask when it is C++
- std::string flags = gmx::formatString("%x", fr->f_t[t].red_mask);
+ std::string flags = gmx::formatString("%x", bt->f_t[t].red_mask);
#else
- std::string flags = gmx::formatAndJoin(fr->f_t[t].red_mask,
- fr->f_t[t].red_mask+BITMASK_ALEN,
+ std::string flags = gmx::formatAndJoin(bt->f_t[t].red_mask,
+ bt->f_t[t].red_mask+BITMASK_ALEN,
"", gmx::StringFormatter("%x"));
#endif
fprintf(debug, "thread %d flags %s count %d\n",
if (debug)
{
fprintf(debug, "Number of blocks to reduce: %d of size %d\n",
- fr->red_nblock, 1<<fr->red_ashift);
+ bt->red_nblock, 1<<bt->red_ashift);
fprintf(debug, "Reduction density %.2f density/#thread %.2f\n",
- ctot*(1<<fr->red_ashift)/(double)fr->natoms_force,
- ctot*(1<<fr->red_ashift)/(double)(fr->natoms_force*fr->nthreads));
+ ctot*(1<<bt->red_ashift)/(double)fr->natoms_force,
+ ctot*(1<<bt->red_ashift)/(double)(fr->natoms_force*bt->nthreads));
}
}
-void init_bonded_threading(FILE *fplog, t_forcerec *fr, int nenergrp)
+void init_bonded_threading(FILE *fplog, int nenergrp,
+ struct bonded_threading_t **bt_ptr)
{
+ bonded_threading_t *bt;
+
+ snew(bt, 1);
+
/* These thread local data structures are used for bondeds only */
- fr->nthreads = gmx_omp_nthreads_get(emntBonded);
+ bt->nthreads = gmx_omp_nthreads_get(emntBonded);
- if (fr->nthreads > 1)
+ if (bt->nthreads > 1)
{
int t;
- snew(fr->f_t, fr->nthreads);
-#pragma omp parallel for num_threads(fr->nthreads) schedule(static)
- for (t = 0; t < fr->nthreads; t++)
+ snew(bt->f_t, bt->nthreads);
+#pragma omp parallel for num_threads(bt->nthreads) schedule(static)
+ for (t = 0; t < bt->nthreads; t++)
{
/* Thread 0 uses the global force and energy arrays */
if (t > 0)
{
int i;
- fr->f_t[t].f = NULL;
- fr->f_t[t].f_nalloc = 0;
- snew(fr->f_t[t].fshift, SHIFTS);
- fr->f_t[t].grpp.nener = nenergrp*nenergrp;
+ bt->f_t[t].f = NULL;
+ bt->f_t[t].f_nalloc = 0;
+ snew(bt->f_t[t].fshift, SHIFTS);
+ bt->f_t[t].grpp.nener = nenergrp*nenergrp;
for (i = 0; i < egNR; i++)
{
- snew(fr->f_t[t].grpp.ener[i], fr->f_t[t].grpp.nener);
+ snew(bt->f_t[t].grpp.ener[i], bt->f_t[t].grpp.nener);
}
}
}
if ((ptr = getenv("GMX_BONDED_NTHREAD_UNIFORM")) != NULL)
{
- sscanf(ptr, "%d", &fr->bonded_max_nthread_uniform);
+ sscanf(ptr, "%d", &bt->bonded_max_nthread_uniform);
if (fplog != NULL)
{
fprintf(fplog, "\nMax threads for uniform bonded distribution set to %d by env.var.\n",
- fr->bonded_max_nthread_uniform);
+ bt->bonded_max_nthread_uniform);
}
}
else
{
- fr->bonded_max_nthread_uniform = max_nthread_uniform;
+ bt->bonded_max_nthread_uniform = max_nthread_uniform;
}
}
+
+ *bt_ptr = bt;
}
*/
void setup_bonded_threading(t_forcerec *fr, t_idef *idef);
-/*! \brief Initialize the bonded threading data structures */
-void init_bonded_threading(FILE *fplog, t_forcerec *fr, int nenergrp);
+/*! \brief Initialize the bonded threading data structures
+ *
+ * Allocates and initializes a bonded threading data structure.
+ * A pointer to this struct is returned as \p *bb_ptr.
+ */
+void init_bonded_threading(FILE *fplog, int nenergrp,
+ struct bonded_threading_t **bt_ptr);
#ifdef __cplusplus
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
double gmx_erfd(double x)
{
-#ifdef GMX_FLOAT_FORMAT_IEEE754
+#if GMX_FLOAT_FORMAT_IEEE754
gmx_int32_t hx, ix, i;
double R, S, P, Q, s, y, z, r;
conv.d = x;
-#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
+#if GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
hx = conv.i[0];
#else
hx = conv.i[1];
conv.d = x;
-#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
+#if GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
conv.i[1] = 0;
#else
conv.i[0] = 0;
double gmx_erfcd(double x)
{
-#ifdef GMX_FLOAT_FORMAT_IEEE754
+#if GMX_FLOAT_FORMAT_IEEE754
gmx_int32_t hx, ix;
double R, S, P, Q, s, y, z, r;
conv.d = x;
-#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
+#if GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
hx = conv.i[0];
#else
hx = conv.i[1];
conv.d = x;
-#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
+#if GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
conv.i[1] = 0;
#else
conv.i[0] = 0;
int gmx_feenableexcept()
{
-#ifdef HAVE_FEENABLEEXCEPT
+#if HAVE_FEENABLEEXCEPT
return feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#elif (defined(__i386__) || defined(__x86_64__)) && defined(__APPLE__)
/* Author: David N. Williams
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
return a/b;
}
-static gmx_inline int _mod(int a, int b, char *file, int line)
+static gmx_inline int _mod(int a, int b, const char *file, int line)
{
if (b == 0)
{
#include <algorithm>
#include "gromacs/domdec/domdec.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/constr.h"
#include "gromacs/legacyheaders/copyrite.h"
#include "gromacs/legacyheaders/gmx_omp_nthreads.h"
#include "gromacs/legacyheaders/types/commrec.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
-#include "gromacs/pbcutil/pbc-simd.h"
#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pbcutil/pbc-simd.h"
#include "gromacs/simd/simd.h"
#include "gromacs/simd/simd_math.h"
#include "gromacs/simd/vector_operations.h"
#include "gromacs/topology/block.h"
#include "gromacs/topology/mtop_util.h"
#include "gromacs/utility/bitmask.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxomp.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
#include "gromacs/random/random.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/units.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/domdec/domdec.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/legacyheaders/calcmu.h"
#include "gromacs/legacyheaders/chargegroup.h"
#include "gromacs/pbcutil/mshift.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
}
}
-static void reduce_thread_forces(int n, rvec *f,
- tensor vir_q, tensor vir_lj,
- real *Vcorr_q, real *Vcorr_lj,
- real *dvdl_q, real *dvdl_lj,
- int nthreads, f_thread_t *f_t)
+static void reduce_thread_energies(tensor vir_q, tensor vir_lj,
+ real *Vcorr_q, real *Vcorr_lj,
+ real *dvdl_q, real *dvdl_lj,
+ int nthreads,
+ ewald_corr_thread_t *ewc_t)
{
- int t, i;
- int nthreads_loop gmx_unused;
+ int t;
- // cppcheck-suppress unreadVariable
- nthreads_loop = gmx_omp_nthreads_get(emntBonded);
- /* This reduction can run over any number of threads */
-#pragma omp parallel for num_threads(nthreads_loop) private(t) schedule(static)
- for (i = 0; i < n; i++)
- {
- for (t = 1; t < nthreads; t++)
- {
- rvec_inc(f[i], f_t[t].f[i]);
- }
- }
for (t = 1; t < nthreads; t++)
{
- *Vcorr_q += f_t[t].Vcorr_q;
- *Vcorr_lj += f_t[t].Vcorr_lj;
- *dvdl_q += f_t[t].dvdl[efptCOUL];
- *dvdl_lj += f_t[t].dvdl[efptVDW];
- m_add(vir_q, f_t[t].vir_q, vir_q);
- m_add(vir_lj, f_t[t].vir_lj, vir_lj);
+ *Vcorr_q += ewc_t[t].Vcorr_q;
+ *Vcorr_lj += ewc_t[t].Vcorr_lj;
+ *dvdl_q += ewc_t[t].dvdl[efptCOUL];
+ *dvdl_lj += ewc_t[t].dvdl[efptVDW];
+ m_add(vir_q, ewc_t[t].vir_q, vir_q);
+ m_add(vir_lj, ewc_t[t].vir_lj, vir_lj);
}
}
gmx_fatal(FARGS, "TPI with PME currently only works in a 3D geometry with tin-foil boundary conditions");
}
- nthreads = gmx_omp_nthreads_get(emntBonded);
+ nthreads = fr->nthread_ewc;
#pragma omp parallel for num_threads(nthreads) schedule(static)
for (t = 0; t < nthreads; t++)
{
- int i;
- rvec *fnv;
tensor *vir_q, *vir_lj;
real *Vcorrt_q, *Vcorrt_lj, *dvdlt_q, *dvdlt_lj;
if (t == 0)
{
- fnv = fr->f_novirsum;
vir_q = &fr->vir_el_recip;
vir_lj = &fr->vir_lj_recip;
Vcorrt_q = &Vcorr_q;
}
else
{
- fnv = fr->f_t[t].f;
- vir_q = &fr->f_t[t].vir_q;
- vir_lj = &fr->f_t[t].vir_lj;
- Vcorrt_q = &fr->f_t[t].Vcorr_q;
- Vcorrt_lj = &fr->f_t[t].Vcorr_lj;
- dvdlt_q = &fr->f_t[t].dvdl[efptCOUL];
- dvdlt_lj = &fr->f_t[t].dvdl[efptVDW];
- for (i = 0; i < fr->natoms_force; i++)
- {
- clear_rvec(fnv[i]);
- }
+ vir_q = &fr->ewc_t[t].vir_q;
+ vir_lj = &fr->ewc_t[t].vir_lj;
+ Vcorrt_q = &fr->ewc_t[t].Vcorr_q;
+ Vcorrt_lj = &fr->ewc_t[t].Vcorr_lj;
+ dvdlt_q = &fr->ewc_t[t].dvdl[efptCOUL];
+ dvdlt_lj = &fr->ewc_t[t].dvdl[efptVDW];
clear_mat(*vir_q);
clear_mat(*vir_lj);
}
*dvdlt_q = 0;
*dvdlt_lj = 0;
+ /* Threading is only supported with the Verlet cut-off
+ * scheme and then only single particle forces (no
+ * exclusion forces) are calculated, so we can store
+ * the forces in the normal, single fr->f_novirsum array.
+ */
ewald_LRcorrection(fr->excl_load[t], fr->excl_load[t+1],
cr, t, fr,
md->chargeA, md->chargeB,
excl, x, bSB ? boxs : box, mu_tot,
ir->ewald_geometry,
ir->epsilon_surface,
- fnv, *vir_q, *vir_lj,
+ fr->f_novirsum, *vir_q, *vir_lj,
Vcorrt_q, Vcorrt_lj,
lambda[efptCOUL], lambda[efptVDW],
dvdlt_q, dvdlt_lj);
}
if (nthreads > 1)
{
- reduce_thread_forces(fr->natoms_force, fr->f_novirsum,
- fr->vir_el_recip, fr->vir_lj_recip,
- &Vcorr_q, &Vcorr_lj,
- &dvdl_long_range_correction_q,
- &dvdl_long_range_correction_lj,
- nthreads, fr->f_t);
+ reduce_thread_energies(fr->vir_el_recip, fr->vir_lj_recip,
+ &Vcorr_q, &Vcorr_lj,
+ &dvdl_long_range_correction_q,
+ &dvdl_long_range_correction_lj,
+ nthreads, fr->ewc_t);
}
wallcycle_sub_stop(wcycle, ewcsEWALD_CORRECTION);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_MDLIB_FORCEREC_THREADING_H
#define GMX_MDLIB_FORCEREC_THREADING_H
-#include "gromacs/utility/bitmask.h"
-
#ifdef __cplusplus
extern "C" {
#endif
-struct f_thread_t {
- rvec *f;
- int f_nalloc;
- gmx_bitmask_t red_mask; /* Mask for marking which parts of f are filled */
- rvec *fshift;
- real ener[F_NRE];
- gmx_grppairener_t grpp;
+struct ewald_corr_thread_t {
real Vcorr_q;
real Vcorr_lj;
real dvdl[efptNR];
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/simd/simd.h"
#include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
}
/* Initialize the thread working data for bonded interactions */
- init_bonded_threading(fp, fr, mtop->groups.grps[egcENER].nr);
+ init_bonded_threading(fp, mtop->groups.grps[egcENER].nr,
+ &fr->bonded_threading);
- snew(fr->excl_load, fr->nthreads+1);
+ fr->nthread_ewc = gmx_omp_nthreads_get(emntBonded);
+ snew(fr->ewc_t, fr->nthread_ewc);
+ snew(fr->excl_load, fr->nthread_ewc + 1);
/* fr->ic is used both by verlet and group kernels (to some extent) now */
init_interaction_const(fp, &fr->ic, fr);
fr->excl_load[0] = 0;
n = 0;
i = 0;
- for (t = 1; t <= fr->nthreads; t++)
+ for (t = 1; t <= fr->nthread_ewc; t++)
{
- ntarget = (ntot*t)/fr->nthreads;
+ ntarget = (ntot*t)/fr->nthread_ewc;
while (i < top->excls.nr && n < ntarget)
{
for (j = ind[i]; j < ind[i+1]; j++)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/genborn.h"
-#include <math.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/domdec/domdec.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/legacyheaders/names.h"
#include "gromacs/legacyheaders/types/commrec.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/genborn_allvsall.h"
#include "gromacs/pbcutil/ishift.h"
#include "gromacs/pbcutil/mshift.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/utility/gmxmpi.h"
#include "gromacs/utility/smalloc.h"
-#ifdef GMX_SIMD_X86_SSE2_OR_HIGHER
-# ifdef GMX_DOUBLE
-# include "gromacs/mdlib/genborn_allvsall_sse2_double.h"
-# include "gromacs/mdlib/genborn_sse2_double.h"
-# else
-# include "gromacs/mdlib/genborn_allvsall_sse2_single.h"
-# include "gromacs/mdlib/genborn_sse2_single.h"
-# endif /* GMX_DOUBLE */
-#endif /* SSE or AVX present */
-
-#include "gromacs/mdlib/genborn_allvsall.h"
-
-/*#define DISABLE_SSE*/
typedef struct {
int shift;
gmx_genborn_t *born, int natoms)
{
- int i, j, i1, i2, k, m, nbond, nang, ia, ib, ic, id, nb, idx, idx2, at;
- int iam, ibm;
- int at0, at1;
- real length, angle;
- real r, ri, rj, ri2, ri3, rj2, r2, r3, r4, rk, ratio, term, h, doffset;
- real p1, p2, p3, factor, cosine, rab, rbc;
+ int i, j, m, ia, ib;
+ real r, ri, rj, ri2, rj2, r3, r4, ratio, term, h, doffset;
real *vsol;
real *gp;
snew(gp, natoms);
snew(born->gpol_still_work, natoms+3);
- at0 = 0;
- at1 = natoms;
-
doffset = born->gb_doffset;
for (i = 0; i < natoms; i++)
rj = atype->gb_radius[atoms->atom[ib].type];
ri2 = ri*ri;
- ri3 = ri2*ri;
rj2 = rj*rj;
ratio = (rj2-ri2-r*r)/(2*ri*r);
t_forcerec *fr, const t_inputrec *ir,
const gmx_mtop_t *mtop, int gb_algorithm)
{
- int i, j, m, ai, aj, jj, natoms, nalloc;
- real rai, sk, p, doffset;
+ int i, jj, natoms;
+ real rai, sk, doffset;
t_atoms atoms;
gmx_genborn_t *born;
rvec x[], t_nblist *nl,
gmx_genborn_t *born, t_mdatoms *md)
{
- int i, k, n, nj0, nj1, ai, aj, type;
+ int i, k, n, nj0, nj1, ai, aj;
int shift;
real shX, shY, shZ;
- real gpi, dr, dr2, dr4, idr4, rvdw, ratio, ccf, theta, term, rai, raj;
+ real gpi, dr2, idr4, rvdw, ratio, ccf, theta, term, rai, raj;
real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
real rinv, idr2, idr6, vaj, dccf, cosq, sinq, prod, gpi2;
real factor;
rvec x[], t_nblist *nl,
gmx_genborn_t *born, t_mdatoms *md)
{
- int i, k, n, ai, aj, nj0, nj1, at0, at1;
+ int i, k, n, ai, aj, nj0, nj1;
int shift;
real shX, shY, shZ;
- real rai, raj, gpi, dr2, dr, sk, sk_ai, sk2, sk2_ai, lij, uij, diff2, tmp, sum_ai;
+ real rai, raj, dr2, dr, sk, sk_ai, sk2, sk2_ai, lij, uij, diff2, tmp, sum_ai;
real rad, min_rad, rinv, rai_inv;
real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
real lij2, uij2, lij3, uij3, t1, t2, t3;
- real lij_inv, dlij, duij, sk2_rinv, prod, log_term;
+ real lij_inv, dlij, sk2_rinv, prod, log_term;
real doffset, raj_inv, dadx_val;
real *gb_radius;
/* Keep the compiler happy */
n = 0;
- prod = 0;
for (i = 0; i < nl->nri; i++)
{
sk2_rinv = sk2*rinv;
prod = 0.25*sk2_rinv;
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
prod*(-diff2);
/* log_term = table_log(uij*lij_inv,born->log_table,
LOG_TABLE_ACCURACY); */
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
prod*(-diff2);
min_rad = rai + doffset;
rad = 1.0/sum_ai;
- born->bRad[i] = rad > min_rad ? rad : min_rad;
+ born->bRad[i] = std::max(rad, min_rad);
fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
}
}
calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
rvec x[], t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md)
{
- int i, k, ai, aj, nj0, nj1, n, at0, at1;
+ int i, k, ai, aj, nj0, nj1, n;
int shift;
real shX, shY, shZ;
- real rai, raj, gpi, dr2, dr, sk, sk2, lij, uij, diff2, tmp, sum_ai;
- real rad, min_rad, sum_ai2, sum_ai3, tsum, tchain, rinv, rai_inv, lij_inv, rai_inv2;
+ real rai, raj, dr2, dr, sk, sk2, lij, uij, diff2, tmp, sum_ai;
+ real sum_ai2, sum_ai3, tsum, tchain, rinv, rai_inv, lij_inv, rai_inv2;
real log_term, prod, sk2_rinv, sk_ai, sk2_ai;
real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
- real lij2, uij2, lij3, uij3, dlij, duij, t1, t2, t3;
+ real lij2, uij2, lij3, uij3, dlij, t1, t2, t3;
real doffset, raj_inv, dadx_val;
real *gb_radius;
/* Keep the compiler happy */
n = 0;
- prod = 0;
- raj = 0;
doffset = born->gb_doffset;
gb_radius = born->gb_radius;
sk2_rinv = sk2*rinv;
prod = 0.25*sk2_rinv;
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
prod = 0.25 * sk2_rinv;
/* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir, gmx_localtop_t *top,
rvec x[], t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, t_nrnb *nrnb)
{
- real *p;
int cnt;
int ndadx;
if (ir->gb_algorithm == egbSTILL)
{
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- if (fr->use_simd_kernels)
- {
-# ifdef GMX_DOUBLE
- genborn_allvsall_calc_still_radii_sse2_double(fr, md, born, top, x[0], cr, &fr->AllvsAll_workgb);
-# else
- genborn_allvsall_calc_still_radii_sse2_single(fr, md, born, top, x[0], cr, &fr->AllvsAll_workgb);
-# endif
- }
- else
- {
- genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], cr, &fr->AllvsAll_workgb);
- }
-#else
genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], &fr->AllvsAll_workgb);
-#endif
/* 13 flops in outer loop, 47 flops in inner loop */
inc_nrnb(nrnb, eNR_BORN_AVA_RADII_STILL, md->homenr*13+cnt*47);
}
else if (ir->gb_algorithm == egbHCT || ir->gb_algorithm == egbOBC)
{
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- if (fr->use_simd_kernels)
- {
-# ifdef GMX_DOUBLE
- genborn_allvsall_calc_hct_obc_radii_sse2_double(fr, md, born, ir->gb_algorithm, top, x[0], cr, &fr->AllvsAll_workgb);
-# else
- genborn_allvsall_calc_hct_obc_radii_sse2_single(fr, md, born, ir->gb_algorithm, top, x[0], cr, &fr->AllvsAll_workgb);
-# endif
- }
- else
- {
- genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], cr, &fr->AllvsAll_workgb);
- }
-#else
genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], &fr->AllvsAll_workgb);
-#endif
/* 24 flops in outer loop, 183 in inner */
inc_nrnb(nrnb, eNR_BORN_AVA_RADII_HCT_OBC, md->homenr*24+cnt*183);
}
/* Switch for determining which algorithm to use for Born radii calculation */
#ifdef GMX_DOUBLE
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
- switch (ir->gb_algorithm)
- {
- case egbSTILL:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_still_sse2_double(cr, fr, born->nr, top, atype, x[0], nl, born);
- }
- else
- {
- calc_gb_rad_still(cr, fr, top, x, nl, born, md);
- }
- break;
- case egbHCT:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_hct_obc_sse2_double(cr, fr, born->nr, top, atype, x[0], nl, born, md, ir->gb_algorithm);
- }
- else
- {
- calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
- }
- break;
- case egbOBC:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_hct_obc_sse2_double(cr, fr, born->nr, top, atype, x[0], nl, born, md, ir->gb_algorithm);
- }
- else
- {
- calc_gb_rad_obc(cr, fr, born->nr, top, x, nl, born, md);
- }
- break;
-
- default:
- gmx_fatal(FARGS, "Unknown double precision sse-enabled algorithm for Born radii calculation: %d", ir->gb_algorithm);
- }
-#else
switch (ir->gb_algorithm)
{
case egbSTILL:
gmx_fatal(FARGS, "Unknown double precision algorithm for Born radii calculation: %d", ir->gb_algorithm);
}
-#endif
-
#else
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
- switch (ir->gb_algorithm)
- {
- case egbSTILL:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_still_sse2_single(cr, fr, born->nr, top, x[0], nl, born);
- }
- else
- {
- calc_gb_rad_still(cr, fr, top, x, nl, born, md);
- }
- break;
- case egbHCT:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_hct_obc_sse2_single(cr, fr, born->nr, top, x[0], nl, born, md, ir->gb_algorithm);
- }
- else
- {
- calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
- }
- break;
-
- case egbOBC:
- if (fr->use_simd_kernels)
- {
- calc_gb_rad_hct_obc_sse2_single(cr, fr, born->nr, top, x[0], nl, born, md, ir->gb_algorithm);
- }
- else
- {
- calc_gb_rad_obc(cr, fr, born->nr, top, x, nl, born, md);
- }
- break;
-
- default:
- gmx_fatal(FARGS, "Unknown sse-enabled algorithm for Born radii calculation: %d", ir->gb_algorithm);
- }
-
-#else
switch (ir->gb_algorithm)
{
case egbSTILL:
gmx_fatal(FARGS, "Unknown algorithm for Born radii calculation: %d", ir->gb_algorithm);
}
-#endif /* Single precision sse */
-
#endif /* Double or single precision */
if (fr->bAllvsAll == FALSE)
real *invsqrta, real *dvda, real *GBtab, t_idef *idef, real epsilon_r,
real gb_epsilon_solvent, real facel, const t_pbc *pbc, const t_graph *graph)
{
- int i, j, n0, m, nnn, type, ai, aj;
+ int i, j, n0, m, nnn, ai, aj;
int ki;
real isai, isaj;
real r, rsq11;
real rinv11, iq;
real isaprod, qq, gbscale, gbtabscale, Y, F, Geps, Heps2, Fp, VV, FF, rt, eps, eps2;
- real vgb, fgb, vcoul, fijC, dvdatmp, fscal, dvdaj;
+ real vgb, fgb, fijC, dvdatmp, fscal;
real vctot;
rvec dx;
gbscale = isaprod*gbtabscale;
r = rsq11*rinv11;
rt = r*gbscale;
- n0 = rt;
+ n0 = static_cast<int>(rt);
eps = rt-n0;
eps2 = eps*eps;
nnn = 4*n0;
real *dvda, t_mdatoms *md)
{
int ai, i, at0, at1;
- real e, es, rai, rbi, term, probe, tmp, factor;
+ real e, es, rai, term, probe, tmp, factor;
real rbi_inv, rbi_inv2;
- /* To keep the compiler happy */
- factor = 0;
-
if (DOMAINDECOMP(cr))
{
at0 = 0;
/* factor is the surface tension */
factor = born->sa_surface_tension;
- /*
-
- // The surface tension factor is 0.0049 for Still model, 0.0054 for HCT/OBC
- if(gb_algorithm==egbSTILL)
- {
- factor=0.0049*100*CAL2JOULE;
- }
- else
- {
- factor=0.0054*100*CAL2JOULE;
- }
- */
- /* if(gb_algorithm==egbHCT || gb_algorithm==egbOBC) */
es = 0;
probe = 0.14;
int i, k, n, ai, aj, nj0, nj1, n0, n1;
int shift;
real shX, shY, shZ;
- real fgb, fij, rb2, rbi, fix1, fiy1, fiz1;
- real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11, rsq11;
- real rinv11, tx, ty, tz, rbai, rbaj, fgb_ai;
+ real fgb, rbi, fix1, fiy1, fiz1;
+ real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
+ real tx, ty, tz, rbai, rbaj, fgb_ai;
real *rb;
- volatile int idx;
n = 0;
rb = born->work;
rvec x[], rvec f[], t_forcerec *fr, t_idef *idef, int gb_algorithm, int sa_algorithm, t_nrnb *nrnb,
const t_pbc *pbc, const t_graph *graph, gmx_enerdata_t *enerd)
{
- real v = 0;
int cnt;
- int i;
/* PBC or not? */
const t_pbc *pbc_null;
if (fr->bAllvsAll)
{
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- if (fr->use_simd_kernels)
- {
-# ifdef GMX_DOUBLE
- genborn_allvsall_calc_chainrule_sse2_double(fr, md, born, x[0], f[0], gb_algorithm, fr->AllvsAll_workgb);
-# else
- genborn_allvsall_calc_chainrule_sse2_single(fr, md, born, x[0], f[0], gb_algorithm, fr->AllvsAll_workgb);
-# endif
- }
- else
- {
- genborn_allvsall_calc_chainrule(fr, md, born, x[0], f[0], gb_algorithm, fr->AllvsAll_workgb);
- }
-#else
genborn_allvsall_calc_chainrule(fr, md, born, x[0], f[0], gb_algorithm, fr->AllvsAll_workgb);
-#endif
cnt = md->homenr*(md->nr/2+1);
/* 9 flops for outer loop, 15 for inner */
inc_nrnb(nrnb, eNR_BORN_AVA_CHAINRULE, md->homenr*9+cnt*15);
return;
}
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
- if (fr->use_simd_kernels)
- {
-# ifdef GMX_DOUBLE
- calc_gb_chainrule_sse2_double(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda, x[0],
- f[0], fr->fshift[0], fr->shift_vec[0], gb_algorithm, born, md);
-# else
- calc_gb_chainrule_sse2_single(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda, x[0],
- f[0], fr->fshift[0], fr->shift_vec[0], gb_algorithm, born, md);
-# endif
- }
- else
- {
- calc_gb_chainrule(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda,
- x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
- }
-#else
calc_gb_chainrule(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda,
x, f, fr->fshift, fr->shift_vec, gb_algorithm, born);
-#endif
if (!fr->bAllvsAll)
{
gmx_bool bMolPBC, t_pbc *pbc, t_graph *g, rvec *x,
struct gbtmpnbls *nls)
{
- int ind, j, ai, aj, shift, found;
+ int ind, j, ai, aj, found;
rvec dx;
ivec dt;
gbtmpnbl_t *list;
- shift = CENTRAL;
for (ind = 0; ind < il->nr; ind += 3)
{
ai = il->iatoms[ind+1];
aj = il->iatoms[ind+2];
- shift = CENTRAL;
+ int shift = CENTRAL;
if (g != NULL)
{
rvec_sub(x[ai], x[aj], dx);
rvec x[], matrix box,
t_forcerec *fr, t_idef *idef, t_graph *graph, gmx_genborn_t *born)
{
- int i, l, ii, j, k, n, nj0, nj1, ai, aj, at0, at1, found, shift, s;
- int apa;
+ int i, j, k, n, nj0, nj1, ai, shift, s;
t_nblist *nblist;
t_pbc pbc;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "genborn_allvsall.h"
-#include <math.h>
+#include <cmath>
+
+#include <algorithm>
#include "gromacs/legacyheaders/genborn.h"
#include "gromacs/legacyheaders/network.h"
gmx_bool bInclude13,
gmx_bool bInclude14)
{
- int i, j, k, tp;
+ int i, j, k;
int a1, a2;
- int nj0, nj1;
int max_offset;
int max_excl_offset;
- int nj;
/* This routine can appear to be a bit complex, but it is mostly book-keeping.
* To enable the fast all-vs-all kernel we need to be able to stream through all coordinates
}
if (k > 0 && k <= max_offset)
{
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
+ max_excl_offset = std::max(k, max_excl_offset);
}
}
}
}
if (k > 0 && k <= max_offset)
{
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
+ max_excl_offset = std::max(k, max_excl_offset);
}
}
}
}
if (k > 0 && k <= max_offset)
{
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
+ max_excl_offset = std::max(k, max_excl_offset);
}
}
}
- max_excl_offset = (max_offset < max_excl_offset) ? max_offset : max_excl_offset;
+ max_excl_offset = std::min(max_offset, max_excl_offset);
aadata->jindex_gb[3*i+1] = i+1+max_excl_offset;
gmx_bool bInclude13,
gmx_bool bInclude14)
{
- int i, j, idx;
gmx_allvsallgb2_data_t *aadata;
- real *p;
snew(aadata, 1);
*p_aadata = aadata;
ni1 = mdatoms->homenr;
n = 0;
- prod = 0;
- raj = 0;
doffset = born->gb_doffset;
aadata = *((gmx_allvsallgb2_data_t **)work);
sk2_rinv = sk2*rinv;
prod = 0.25*sk2_rinv;
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
/* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
prod = 0.25 * sk2_rinv;
/* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
sk2_rinv = sk2*rinv;
prod = 0.25*sk2_rinv;
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
/* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
prod = 0.25 * sk2_rinv;
/* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
- log_term = log(uij*lij_inv);
+ log_term = std::log(uij*lij_inv);
tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
min_rad = rai + born->gb_doffset;
rad = 1.0/sum_ai;
- born->bRad[i] = rad > min_rad ? rad : min_rad;
+ born->bRad[i] = std::max(rad, min_rad);
fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
}
}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include <math.h>
-
-#include "gromacs/legacyheaders/genborn.h"
-#include "gromacs/legacyheaders/network.h"
-#include "gromacs/legacyheaders/types/simple.h"
-#include "gromacs/math/units.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/genborn_allvsall.h"
-#include "gromacs/utility/smalloc.h"
-
-
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
-
-#include <gmx_sse2_double.h>
-
-
-#define SIMD_WIDTH 2
-#define UNROLLI 2
-#define UNROLLJ 2
-
-
-
-
-
-
-
-
-
-typedef struct
-{
- int * jindex_gb;
- int ** prologue_mask_gb;
- int ** epilogue_mask;
- int * imask;
- double * gb_radius;
- double * workparam;
- double * work;
- double * x_align;
- double * y_align;
- double * z_align;
- double * fx_align;
- double * fy_align;
- double * fz_align;
-}
-gmx_allvsallgb2_data_t;
-
-
-static int
-calc_maxoffset(int i, int natoms)
-{
- int maxoffset;
-
- if ((natoms % 2) == 1)
- {
- /* Odd number of atoms, easy */
- maxoffset = natoms/2;
- }
- else if ((natoms % 4) == 0)
- {
- /* Multiple of four is hard */
- if (i < natoms/2)
- {
- if ((i % 2) == 0)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
- else
- {
- if ((i % 2) == 1)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
- }
- else
- {
- /* natoms/2 = odd */
- if ((i % 2) == 0)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
-
- return maxoffset;
-}
-
-static void
-setup_gb_exclusions_and_indices(gmx_allvsallgb2_data_t * aadata,
- t_ilist * ilist,
- int start,
- int end,
- int natoms,
- gmx_bool bInclude12,
- gmx_bool bInclude13,
- gmx_bool bInclude14)
-{
- int i, j, k, tp;
- int a1, a2;
- int ni0, ni1, nj0, nj1, nj;
- int imin, imax, iexcl;
- int max_offset;
- int max_excl_offset;
- int firstinteraction;
- int ibase;
- int *pi;
-
- /* This routine can appear to be a bit complex, but it is mostly book-keeping.
- * To enable the fast all-vs-all kernel we need to be able to stream through all coordinates
- * whether they should interact or not.
- *
- * To avoid looping over the exclusions, we create a simple mask that is 1 if the interaction
- * should be present, otherwise 0. Since exclusions typically only occur when i & j are close,
- * we create a jindex array with three elements per i atom: the starting point, the point to
- * which we need to check exclusions, and the end point.
- * This way we only have to allocate a short exclusion mask per i atom.
- */
-
- ni0 = (start/UNROLLI)*UNROLLI;
- ni1 = ((end+UNROLLI-1)/UNROLLI)*UNROLLI;
-
- /* Set the interaction mask to only enable the i atoms we want to include */
- snew(pi, 2*(natoms+UNROLLI+2*SIMD_WIDTH));
- aadata->imask = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->imask[2*i] = (i >= start && i < end) ? 0xFFFFFFFF : 0;
- aadata->imask[2*i+1] = (i >= start && i < end) ? 0xFFFFFFFF : 0;
- }
-
- /* Allocate memory for our modified jindex array */
- snew(aadata->jindex_gb, 4*(natoms+UNROLLI));
- for (i = 0; i < 4*(natoms+UNROLLI); i++)
- {
- aadata->jindex_gb[i] = 0;
- }
-
- /* Create the exclusion masks for the prologue part */
- snew(aadata->prologue_mask_gb, natoms+UNROLLI); /* list of pointers */
-
- /* First zero everything to avoid uninitialized data */
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->prologue_mask_gb[i] = NULL;
- }
-
- /* Calculate the largest exclusion range we need for each UNROLLI-tuplet of i atoms. */
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- max_excl_offset = -1;
-
- /* First find maxoffset for the next 4 atoms (or fewer if we are close to end) */
- imax = ((ibase+UNROLLI) < end) ? (ibase+UNROLLI) : end;
-
- /* Which atom is the first we (might) interact with? */
- imin = natoms; /* Guaranteed to be overwritten by one of 'firstinteraction' */
- for (i = ibase; i < imax; i++)
- {
- /* Before exclusions, which atom is the first we (might) interact with? */
- firstinteraction = i+1;
- max_offset = calc_maxoffset(i, natoms);
-
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- imin = (firstinteraction < imin) ? firstinteraction : imin;
- }
- /* round down to j unrolling factor */
- imin = (imin/UNROLLJ)*UNROLLJ;
-
- for (i = ibase; i < imax; i++)
- {
- max_offset = calc_maxoffset(i, natoms);
-
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- }
-
- /* The offset specifies the last atom to be excluded, so add one unit to get an upper loop limit */
- max_excl_offset++;
- /* round up to j unrolling factor */
- max_excl_offset = (max_excl_offset/UNROLLJ+1)*UNROLLJ;
-
- /* Set all the prologue masks length to this value (even for i>end) */
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- aadata->jindex_gb[4*i] = imin;
- aadata->jindex_gb[4*i+1] = imin+max_excl_offset;
- }
- }
-
- /* Now the hard part, loop over it all again to calculate the actual contents of the prologue masks */
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- nj = aadata->jindex_gb[4*i+1] - aadata->jindex_gb[4*i];
- imin = aadata->jindex_gb[4*i];
-
- /* Allocate aligned memory */
- snew(pi, 2*(nj+2*SIMD_WIDTH));
- aadata->prologue_mask_gb[i] = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
-
- max_offset = calc_maxoffset(i, natoms);
-
- /* Include interactions i+1 <= j < i+maxoffset */
- for (k = 0; k < nj; k++)
- {
- j = imin + k;
-
- if ( (j > i) && (j <= i+max_offset) )
- {
- aadata->prologue_mask_gb[i][2*k] = 0xFFFFFFFF;
- aadata->prologue_mask_gb[i][2*k+1] = 0xFFFFFFFF;
- }
- else
- {
- aadata->prologue_mask_gb[i][2*k] = 0;
- aadata->prologue_mask_gb[i][2*k+1] = 0;
- }
- }
-
- /* Clear out the explicit exclusions */
- if (i < end)
- {
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][2*k] = 0;
- aadata->prologue_mask_gb[i][2*k+1] = 0;
- }
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][2*k] = 0;
- aadata->prologue_mask_gb[i][2*k+1] = 0;
- }
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][2*k] = 0;
- aadata->prologue_mask_gb[i][2*k+1] = 0;
- }
- }
- }
- }
- }
- }
-
- /* Construct the epilogue mask - this just contains the check for maxoffset */
- snew(aadata->epilogue_mask, natoms+UNROLLI);
-
- /* First zero everything to avoid uninitialized data */
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->jindex_gb[4*i+2] = aadata->jindex_gb[4*i+1];
- aadata->jindex_gb[4*i+3] = aadata->jindex_gb[4*i+1];
- aadata->epilogue_mask[i] = NULL;
- }
-
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- /* Find the lowest index for which we need to use the epilogue */
- imin = ibase;
- max_offset = calc_maxoffset(imin, natoms);
-
- imin = imin + 1 + max_offset;
-
- /* Find largest index for which we need to use the epilogue */
- imax = ibase + UNROLLI-1;
- imax = (imax < end) ? imax : end;
-
- max_offset = calc_maxoffset(imax, natoms);
- imax = imax + 1 + max_offset + UNROLLJ - 1;
-
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- /* Start of epilogue - round down to j tile limit */
- aadata->jindex_gb[4*i+2] = (imin/UNROLLJ)*UNROLLJ;
- /* Make sure we dont overlap - for small systems everything is done in the prologue */
- aadata->jindex_gb[4*i+2] = (aadata->jindex_gb[4*i+1] > aadata->jindex_gb[4*i+2]) ? aadata->jindex_gb[4*i+1] : aadata->jindex_gb[4*i+2];
- /* Round upwards to j tile limit */
- aadata->jindex_gb[4*i+3] = (imax/UNROLLJ)*UNROLLJ;
- /* Make sure we dont have a negative range for the epilogue */
- aadata->jindex_gb[4*i+3] = (aadata->jindex_gb[4*i+2] > aadata->jindex_gb[4*i+3]) ? aadata->jindex_gb[4*i+2] : aadata->jindex_gb[4*i+3];
- }
- }
-
- /* And fill it with data... */
-
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
-
- nj = aadata->jindex_gb[4*i+3] - aadata->jindex_gb[4*i+2];
-
- /* Allocate aligned memory */
- snew(pi, 2*(nj+2*SIMD_WIDTH));
- aadata->epilogue_mask[i] = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
-
- max_offset = calc_maxoffset(i, natoms);
-
- for (k = 0; k < nj; k++)
- {
- j = aadata->jindex_gb[4*i+2] + k;
- aadata->epilogue_mask[i][2*k] = (j <= i+max_offset) ? 0xFFFFFFFF : 0;
- aadata->epilogue_mask[i][2*k+1] = (j <= i+max_offset) ? 0xFFFFFFFF : 0;
- }
- }
- }
-}
-
-
-static void
-genborn_allvsall_setup(gmx_allvsallgb2_data_t ** p_aadata,
- gmx_localtop_t * top,
- gmx_genborn_t * born,
- t_mdatoms * mdatoms,
- double radius_offset,
- int gb_algorithm,
- gmx_bool bInclude12,
- gmx_bool bInclude13,
- gmx_bool bInclude14)
-{
- int i, j, idx;
- int natoms;
- gmx_allvsallgb2_data_t *aadata;
- double *p;
-
- natoms = mdatoms->nr;
-
- snew(aadata, 1);
- *p_aadata = aadata;
-
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->x_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->y_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->z_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fx_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fy_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fz_align = (double *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->gb_radius = (double *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->workparam = (double *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->work = (double *) (((size_t) p + 16) & (~((size_t) 15)));
-
- for (i = 0; i < mdatoms->nr; i++)
- {
- aadata->gb_radius[i] = top->atomtypes.gb_radius[mdatoms->typeA[i]] - radius_offset;
- if (gb_algorithm == egbSTILL)
- {
- aadata->workparam[i] = born->vsolv[i];
- }
- else if (gb_algorithm == egbOBC)
- {
- aadata->workparam[i] = born->param[i];
- }
- aadata->work[i] = 0.0;
- }
- for (i = 0; i < mdatoms->nr; i++)
- {
- aadata->gb_radius[natoms+i] = aadata->gb_radius[i];
- aadata->workparam[natoms+i] = aadata->workparam[i];
- aadata->work[natoms+i] = aadata->work[i];
- }
-
- for (i = 0; i < 2*natoms+SIMD_WIDTH; i++)
- {
- aadata->x_align[i] = 0.0;
- aadata->y_align[i] = 0.0;
- aadata->z_align[i] = 0.0;
- aadata->fx_align[i] = 0.0;
- aadata->fy_align[i] = 0.0;
- aadata->fz_align[i] = 0.0;
- }
-
- setup_gb_exclusions_and_indices(aadata, top->idef.il, 0, mdatoms->homenr, mdatoms->nr,
- bInclude12, bInclude13, bInclude14);
-}
-
-
-/*
- * This routine apparently hits a compiler bug visual studio has had 'forever'.
- * It is present both in VS2005 and VS2008, and the only way around it is to
- * decrease optimization. We do that with at pragma, and only for MSVC, so it
- * will not hurt any of the well-behaving and supported compilers out there.
- * MS: Fix your compiler, it sucks like a black hole!
- */
-#ifdef _MSC_VER
-#pragma optimize("t",off)
-#endif
-
-int
-genborn_allvsall_calc_still_radii_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- gmx_localtop_t * top,
- double * x,
- t_commrec * cr,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int * mask;
- int * pmask0;
- int * pmask1;
- int * emask0;
- int * emask1;
- double ix, iy, iz;
- double jx, jy, jz;
- double dx, dy, dz;
- double rsq, rinv;
- double gpi, rai, vai;
- double prod_ai;
- double irsq, idr4, idr6;
- double raj, rvdw, ratio;
- double vaj, ccf, dccf, theta, cosq;
- double term, prod, icf4, icf6, gpi2, factor, sinq;
- double * gb_radius;
- double * vsolv;
- double * work;
- double tmpsum[2];
- double * x_align;
- double * y_align;
- double * z_align;
- int * jindex;
- double * dadx;
-
- __m128d ix_SSE0, iy_SSE0, iz_SSE0;
- __m128d ix_SSE1, iy_SSE1, iz_SSE1;
- __m128d gpi_SSE0, rai_SSE0, prod_ai_SSE0;
- __m128d gpi_SSE1, rai_SSE1, prod_ai_SSE1;
- __m128d imask_SSE0, jmask_SSE0;
- __m128d imask_SSE1, jmask_SSE1;
- __m128d jx_SSE, jy_SSE, jz_SSE;
- __m128d dx_SSE0, dy_SSE0, dz_SSE0;
- __m128d dx_SSE1, dy_SSE1, dz_SSE1;
- __m128d rsq_SSE0, rinv_SSE0, irsq_SSE0, idr4_SSE0, idr6_SSE0;
- __m128d rsq_SSE1, rinv_SSE1, irsq_SSE1, idr4_SSE1, idr6_SSE1;
- __m128d raj_SSE, vaj_SSE, prod_SSE;
- __m128d rvdw_SSE0, ratio_SSE0;
- __m128d rvdw_SSE1, ratio_SSE1;
- __m128d theta_SSE0, sinq_SSE0, cosq_SSE0, term_SSE0;
- __m128d theta_SSE1, sinq_SSE1, cosq_SSE1, term_SSE1;
- __m128d ccf_SSE0, dccf_SSE0;
- __m128d ccf_SSE1, dccf_SSE1;
- __m128d icf4_SSE0, icf6_SSE0;
- __m128d icf4_SSE1, icf6_SSE1;
- __m128d half_SSE, one_SSE, two_SSE, four_SSE;
- __m128d still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
-
- n = 0;
-
- aadata = *((gmx_allvsallgb2_data_t **)paadata);
-
-
- if (aadata == NULL)
- {
- genborn_allvsall_setup(&aadata, top, born, mdatoms, 0.0,
- egbSTILL, FALSE, FALSE, TRUE);
- *((gmx_allvsallgb2_data_t **)paadata) = aadata;
- }
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
-
- gb_radius = aadata->gb_radius;
- vsolv = aadata->workparam;
- work = aadata->work;
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
-
- still_p4_SSE = _mm_set1_pd(STILL_P4);
- still_p5inv_SSE = _mm_set1_pd(STILL_P5INV);
- still_pip5_SSE = _mm_set1_pd(STILL_PIP5);
- half_SSE = _mm_set1_pd(0.5);
- one_SSE = _mm_set1_pd(1.0);
- two_SSE = _mm_set1_pd(2.0);
- four_SSE = _mm_set1_pd(4.0);
-
- /* This will be summed, so it has to extend to natoms + buffer */
- for (i = 0; i < natoms+1+natoms/2; i++)
- {
- work[i] = 0;
- }
-
- for (i = ni0; i < ni1+1+natoms/2; i++)
- {
- k = i%natoms;
- x_align[i] = x[3*k];
- y_align[i] = x[3*k+1];
- z_align[i] = x[3*k+2];
- work[i] = 0;
- }
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
- /* Load i atom data */
- ix_SSE0 = _mm_load1_pd(x_align+i);
- iy_SSE0 = _mm_load1_pd(y_align+i);
- iz_SSE0 = _mm_load1_pd(z_align+i);
- ix_SSE1 = _mm_load1_pd(x_align+i+1);
- iy_SSE1 = _mm_load1_pd(y_align+i+1);
- iz_SSE1 = _mm_load1_pd(z_align+i+1);
-
- gpi_SSE0 = _mm_setzero_pd();
- gpi_SSE1 = _mm_setzero_pd();
-
- rai_SSE0 = _mm_load1_pd(gb_radius+i);
- rai_SSE1 = _mm_load1_pd(gb_radius+i+1);
-
- prod_ai_SSE0 = _mm_set1_pd(STILL_P4*vsolv[i]);
- prod_ai_SSE1 = _mm_set1_pd(STILL_P4*vsolv[i+1]);
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj1 = jindex[4*i+1];
- nj2 = jindex[4*i+2];
- nj3 = jindex[4*i+3];
-
- pmask0 = aadata->prologue_mask_gb[i];
- pmask1 = aadata->prologue_mask_gb[i+1];
- emask0 = aadata->epilogue_mask[i];
- emask1 = aadata->epilogue_mask[i+1];
-
- imask_SSE0 = _mm_load1_pd((double *)(aadata->imask+2*i));
- imask_SSE1 = _mm_load1_pd((double *)(aadata->imask+2*i+2));
-
- /* Prologue part, including exclusion mask */
- for (j = nj0; j < nj1; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_pd((double *)pmask0);
- jmask_SSE1 = _mm_load_pd((double *)pmask1);
- pmask0 += 2*UNROLLJ;
- pmask1 += 2*UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_pd(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_pd(jmask_SSE1, imask_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, jmask_SSE1);
-
- irsq_SSE0 = _mm_mul_pd(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_pd(rinv_SSE1, rinv_SSE1);
- idr4_SSE0 = _mm_mul_pd(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_pd(irsq_SSE1, irsq_SSE1);
- idr6_SSE0 = _mm_mul_pd(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_pd(idr4_SSE1, irsq_SSE1);
-
- raj_SSE = _mm_load_pd(gb_radius+j);
- vaj_SSE = _mm_load_pd(vsolv+j);
-
- rvdw_SSE0 = _mm_add_pd(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_pd(rai_SSE1, raj_SSE);
-
- ratio_SSE0 = _mm_mul_pd(rsq_SSE0, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_pd(rsq_SSE1, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE1, rvdw_SSE1)));
-
- ratio_SSE0 = _mm_min_pd(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_pd(ratio_SSE1, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_pd(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_pd(ratio_SSE1, still_pip5_SSE);
- gmx_mm_sincos_pd(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_pd(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- term_SSE0 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE1));
- ccf_SSE0 = _mm_mul_pd(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_pd(term_SSE1, term_SSE1);
- dccf_SSE0 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE0),
- _mm_mul_pd(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE1),
- _mm_mul_pd(sinq_SSE1, theta_SSE1));
-
- prod_SSE = _mm_mul_pd(still_p4_SSE, vaj_SSE);
- icf4_SSE0 = _mm_mul_pd(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_pd(ccf_SSE1, idr4_SSE1);
- icf6_SSE0 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_mul_pd(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_pd(prod_ai_SSE1, icf4_SSE1))));
-
-
- gpi_SSE0 = _mm_add_pd(gpi_SSE0, _mm_mul_pd(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_pd(gpi_SSE1, _mm_mul_pd(prod_SSE, icf4_SSE1));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE1));
- dadx += 2;
-
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE0, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE1, icf6_SSE1));
- dadx += 2;
- }
-
- /* Main part, no exclusions */
- for (j = nj1; j < nj2; j += UNROLLJ)
- {
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, imask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, imask_SSE1);
-
- irsq_SSE0 = _mm_mul_pd(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_pd(rinv_SSE1, rinv_SSE1);
- idr4_SSE0 = _mm_mul_pd(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_pd(irsq_SSE1, irsq_SSE1);
- idr6_SSE0 = _mm_mul_pd(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_pd(idr4_SSE1, irsq_SSE1);
-
- raj_SSE = _mm_load_pd(gb_radius+j);
-
- rvdw_SSE0 = _mm_add_pd(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_pd(rai_SSE1, raj_SSE);
- vaj_SSE = _mm_load_pd(vsolv+j);
-
- ratio_SSE0 = _mm_mul_pd(rsq_SSE0, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_pd(rsq_SSE1, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE1, rvdw_SSE1)));
-
- ratio_SSE0 = _mm_min_pd(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_pd(ratio_SSE1, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_pd(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_pd(ratio_SSE1, still_pip5_SSE);
- gmx_mm_sincos_pd(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_pd(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- term_SSE0 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE1));
- ccf_SSE0 = _mm_mul_pd(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_pd(term_SSE1, term_SSE1);
- dccf_SSE0 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE0),
- _mm_mul_pd(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE1),
- _mm_mul_pd(sinq_SSE1, theta_SSE1));
-
- prod_SSE = _mm_mul_pd(still_p4_SSE, vaj_SSE );
- icf4_SSE0 = _mm_mul_pd(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_pd(ccf_SSE1, idr4_SSE1);
- icf6_SSE0 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_mul_pd(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_pd(prod_ai_SSE1, icf4_SSE1))));
-
- gpi_SSE0 = _mm_add_pd(gpi_SSE0, _mm_mul_pd(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_pd(gpi_SSE1, _mm_mul_pd(prod_SSE, icf4_SSE1));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE1));
- dadx += 2;
-
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE0, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE1, icf6_SSE1));
- dadx += 2;
- }
- /* Epilogue part, including exclusion mask */
- for (j = nj2; j < nj3; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_pd((double *)emask0);
- jmask_SSE1 = _mm_load_pd((double *)emask1);
- emask0 += 2*UNROLLJ;
- emask1 += 2*UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_pd(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_pd(jmask_SSE1, imask_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, jmask_SSE1);
-
- irsq_SSE0 = _mm_mul_pd(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_pd(rinv_SSE1, rinv_SSE1);
- idr4_SSE0 = _mm_mul_pd(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_pd(irsq_SSE1, irsq_SSE1);
- idr6_SSE0 = _mm_mul_pd(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_pd(idr4_SSE1, irsq_SSE1);
-
- raj_SSE = _mm_load_pd(gb_radius+j);
- vaj_SSE = _mm_load_pd(vsolv+j);
-
- rvdw_SSE0 = _mm_add_pd(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_pd(rai_SSE1, raj_SSE);
-
- ratio_SSE0 = _mm_mul_pd(rsq_SSE0, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_pd(rsq_SSE1, gmx_mm_inv_pd( _mm_mul_pd(rvdw_SSE1, rvdw_SSE1)));
-
- ratio_SSE0 = _mm_min_pd(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_pd(ratio_SSE1, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_pd(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_pd(ratio_SSE1, still_pip5_SSE);
- gmx_mm_sincos_pd(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_pd(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- term_SSE0 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_pd(half_SSE, _mm_sub_pd(one_SSE, cosq_SSE1));
- ccf_SSE0 = _mm_mul_pd(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_pd(term_SSE1, term_SSE1);
- dccf_SSE0 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE0),
- _mm_mul_pd(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_pd(_mm_mul_pd(two_SSE, term_SSE1),
- _mm_mul_pd(sinq_SSE1, theta_SSE1));
-
- prod_SSE = _mm_mul_pd(still_p4_SSE, vaj_SSE);
- icf4_SSE0 = _mm_mul_pd(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_pd(ccf_SSE1, idr4_SSE1);
- icf6_SSE0 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_mul_pd(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_pd(prod_ai_SSE1, icf4_SSE1))));
-
- gpi_SSE0 = _mm_add_pd(gpi_SSE0, _mm_mul_pd(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_pd(gpi_SSE1, _mm_mul_pd(prod_SSE, icf4_SSE1));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_SSE, icf6_SSE1));
- dadx += 2;
-
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE0, icf6_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai_SSE1, icf6_SSE1));
- dadx += 2;
- }
- GMX_MM_TRANSPOSE2_PD(gpi_SSE0, gpi_SSE1);
- gpi_SSE0 = _mm_add_pd(gpi_SSE0, gpi_SSE1);
- _mm_store_pd(work+i, _mm_add_pd(gpi_SSE0, _mm_load_pd(work+i)));
- }
-
- /* In case we have written anything beyond natoms, move it back.
- * Never mind that we leave stuff above natoms; that will not
- * be accessed later in the routine.
- * In principle this should be a move rather than sum, but this
- * way we dont have to worry about even/odd offsets...
- */
- for (i = natoms; i < ni1+1+natoms/2; i++)
- {
- work[i-natoms] += work[i];
- }
-
- /* Parallel summations would go here if ever implemented with DD */
-
- factor = 0.5 * ONE_4PI_EPS0;
- /* Calculate the radii - should we do all atoms, or just our local ones? */
- for (i = 0; i < natoms; i++)
- {
- if (born->use[i] != 0)
- {
- gpi = born->gpol[i]+work[i];
- gpi2 = gpi * gpi;
- born->bRad[i] = factor*gmx_invsqrt(gpi2);
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- return 0;
-}
-/* Reinstate MSVC optimization */
-#ifdef _MSC_VER
-#pragma optimize("",on)
-#endif
-
-
-int
-genborn_allvsall_calc_hct_obc_radii_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- int gb_algorithm,
- gmx_localtop_t * top,
- double * x,
- t_commrec * cr,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int * mask;
- int * pmask0;
- int * pmask1;
- int * emask0;
- int * emask1;
- double * gb_radius;
- double * vsolv;
- double * work;
- double tmpsum[2];
- double * x_align;
- double * y_align;
- double * z_align;
- int * jindex;
- double * dadx;
- double * obc_param;
- double rad, min_rad;
- double rai, rai_inv, rai_inv2, sum_ai, sum_ai2, sum_ai3, tsum, tchain;
-
- __m128d ix_SSE0, iy_SSE0, iz_SSE0;
- __m128d ix_SSE1, iy_SSE1, iz_SSE1;
- __m128d gpi_SSE0, rai_SSE0, prod_ai_SSE0;
- __m128d gpi_SSE1, rai_SSE1, prod_ai_SSE1;
- __m128d imask_SSE0, jmask_SSE0;
- __m128d imask_SSE1, jmask_SSE1;
- __m128d jx_SSE, jy_SSE, jz_SSE;
- __m128d dx_SSE0, dy_SSE0, dz_SSE0;
- __m128d dx_SSE1, dy_SSE1, dz_SSE1;
- __m128d rsq_SSE0, rinv_SSE0, irsq_SSE0, idr4_SSE0, idr6_SSE0;
- __m128d rsq_SSE1, rinv_SSE1, irsq_SSE1, idr4_SSE1, idr6_SSE1;
- __m128d raj_SSE, raj_inv_SSE, sk_aj_SSE, sk2_aj_SSE;
- __m128d ccf_SSE0, dccf_SSE0, prod_SSE0;
- __m128d ccf_SSE1, dccf_SSE1, prod_SSE1;
- __m128d icf4_SSE0, icf6_SSE0;
- __m128d icf4_SSE1, icf6_SSE1;
- __m128d oneeighth_SSE, onefourth_SSE, half_SSE, one_SSE, two_SSE, four_SSE;
- __m128d still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
- __m128d rai_inv_SSE0;
- __m128d rai_inv_SSE1;
- __m128d sk_ai_SSE0, sk2_ai_SSE0, sum_ai_SSE0;
- __m128d sk_ai_SSE1, sk2_ai_SSE1, sum_ai_SSE1;
- __m128d lij_inv_SSE0, sk2_rinv_SSE0;
- __m128d lij_inv_SSE1, sk2_rinv_SSE1;
- __m128d dr_SSE0;
- __m128d dr_SSE1;
- __m128d t1_SSE0, t2_SSE0, t3_SSE0, t4_SSE0;
- __m128d t1_SSE1, t2_SSE1, t3_SSE1, t4_SSE1;
- __m128d obc_mask1_SSE0, obc_mask2_SSE0, obc_mask3_SSE0;
- __m128d obc_mask1_SSE1, obc_mask2_SSE1, obc_mask3_SSE1;
- __m128d uij_SSE0, uij2_SSE0, uij3_SSE0;
- __m128d uij_SSE1, uij2_SSE1, uij3_SSE1;
- __m128d lij_SSE0, lij2_SSE0, lij3_SSE0;
- __m128d lij_SSE1, lij2_SSE1, lij3_SSE1;
- __m128d dlij_SSE0, diff2_SSE0, logterm_SSE0;
- __m128d dlij_SSE1, diff2_SSE1, logterm_SSE1;
- __m128d doffset_SSE, tmpSSE;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
-
- n = 0;
-
- aadata = *((gmx_allvsallgb2_data_t **)paadata);
-
-
- if (aadata == NULL)
- {
- genborn_allvsall_setup(&aadata, top, born, mdatoms, born->gb_doffset,
- egbOBC, TRUE, TRUE, TRUE);
- *((gmx_allvsallgb2_data_t **)paadata) = aadata;
- }
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
-
- gb_radius = aadata->gb_radius;
- work = aadata->work;
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
- obc_param = aadata->workparam;
-
- oneeighth_SSE = _mm_set1_pd(0.125);
- onefourth_SSE = _mm_set1_pd(0.25);
- half_SSE = _mm_set1_pd(0.5);
- one_SSE = _mm_set1_pd(1.0);
- two_SSE = _mm_set1_pd(2.0);
- four_SSE = _mm_set1_pd(4.0);
- doffset_SSE = _mm_set1_pd(born->gb_doffset);
-
- for (i = 0; i < natoms; i++)
- {
- x_align[i] = x[3*i];
- y_align[i] = x[3*i+1];
- z_align[i] = x[3*i+2];
- }
-
- /* Copy again */
- for (i = 0; i < natoms/2+1; i++)
- {
- x_align[natoms+i] = x_align[i];
- y_align[natoms+i] = y_align[i];
- z_align[natoms+i] = z_align[i];
- }
-
- for (i = 0; i < natoms+natoms/2+1; i++)
- {
- work[i] = 0;
- }
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
-
- /* Load i atom data */
- ix_SSE0 = _mm_load1_pd(x_align+i);
- iy_SSE0 = _mm_load1_pd(y_align+i);
- iz_SSE0 = _mm_load1_pd(z_align+i);
- ix_SSE1 = _mm_load1_pd(x_align+i+1);
- iy_SSE1 = _mm_load1_pd(y_align+i+1);
- iz_SSE1 = _mm_load1_pd(z_align+i+1);
-
- rai_SSE0 = _mm_load1_pd(gb_radius+i);
- rai_SSE1 = _mm_load1_pd(gb_radius+i+1);
- rai_inv_SSE0 = gmx_mm_inv_pd(rai_SSE0);
- rai_inv_SSE1 = gmx_mm_inv_pd(rai_SSE1);
-
- sk_ai_SSE0 = _mm_load1_pd(obc_param+i);
- sk_ai_SSE1 = _mm_load1_pd(obc_param+i+1);
- sk2_ai_SSE0 = _mm_mul_pd(sk_ai_SSE0, sk_ai_SSE0);
- sk2_ai_SSE1 = _mm_mul_pd(sk_ai_SSE1, sk_ai_SSE1);
-
- sum_ai_SSE0 = _mm_setzero_pd();
- sum_ai_SSE1 = _mm_setzero_pd();
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj1 = jindex[4*i+1];
- nj2 = jindex[4*i+2];
- nj3 = jindex[4*i+3];
-
- pmask0 = aadata->prologue_mask_gb[i];
- pmask1 = aadata->prologue_mask_gb[i+1];
- emask0 = aadata->epilogue_mask[i];
- emask1 = aadata->epilogue_mask[i+1];
-
- imask_SSE0 = _mm_load1_pd((double *)(aadata->imask+2*i));
- imask_SSE1 = _mm_load1_pd((double *)(aadata->imask+2*i+2));
-
- /* Prologue part, including exclusion mask */
- for (j = nj0; j < nj1; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_pd((double *)pmask0);
- jmask_SSE1 = _mm_load_pd((double *)pmask1);
- pmask0 += 2*UNROLLJ;
- pmask1 += 2*UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_pd(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_pd(jmask_SSE1, imask_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, jmask_SSE1);
-
- dr_SSE0 = _mm_mul_pd(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_pd(rsq_SSE1, rinv_SSE1);
-
- sk_aj_SSE = _mm_load_pd(obc_param+j);
- raj_SSE = _mm_load_pd(gb_radius+j);
- raj_inv_SSE = gmx_mm_inv_pd(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_aj_SSE);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_aj_SSE);
- t3_SSE0 = _mm_sub_pd(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_aj_SSE, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(rai_SSE1, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(rai_SSE1, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(rai_SSE1, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, jmask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, rai_inv_SSE1));
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_aj_SSE = _mm_mul_pd(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
-
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
-
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE1, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- sum_ai_SSE0 = _mm_add_pd(sum_ai_SSE0, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_pd(sum_ai_SSE1, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
-
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_ai_SSE1);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_ai_SSE1);
- t3_SSE0 = _mm_sub_pd(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_ai_SSE1, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(raj_SSE, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(raj_SSE, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(raj_SSE, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, jmask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, raj_inv_SSE));
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_ai_SSE1, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_and_pd(t1_SSE0, obc_mask1_SSE0),
- _mm_and_pd(t1_SSE1, obc_mask1_SSE1))));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
-
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
-
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
- }
-
- /* Main part, no exclusions */
- for (j = nj1; j < nj2; j += UNROLLJ)
- {
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, imask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, imask_SSE1);
-
- dr_SSE0 = _mm_mul_pd(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_pd(rsq_SSE1, rinv_SSE1);
-
- sk_aj_SSE = _mm_load_pd(obc_param+j);
- raj_SSE = _mm_load_pd(gb_radius+j);
-
- raj_inv_SSE = gmx_mm_inv_pd(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_aj_SSE);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_aj_SSE);
- t3_SSE0 = _mm_sub_pd(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_aj_SSE, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(rai_SSE1, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(rai_SSE1, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(rai_SSE1, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, imask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, imask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, rai_inv_SSE1));
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_aj_SSE = _mm_mul_pd(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
-
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
-
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE1, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- sum_ai_SSE0 = _mm_add_pd(sum_ai_SSE0, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_pd(sum_ai_SSE1, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
-
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
-
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_ai_SSE1);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_ai_SSE1);
- t3_SSE0 = _mm_sub_pd(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_ai_SSE1, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(raj_SSE, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(raj_SSE, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(raj_SSE, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, imask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, imask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, raj_inv_SSE));
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_ai_SSE1, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_and_pd(t1_SSE0, obc_mask1_SSE0),
- _mm_and_pd(t1_SSE1, obc_mask1_SSE1))));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
-
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
-
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
- }
-
- /* Epilogue part, including exclusion mask */
- for (j = nj2; j < nj3; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_pd((double *)emask0);
- jmask_SSE1 = _mm_load_pd((double *)emask1);
- emask0 += 2*UNROLLJ;
- emask1 += 2*UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_pd(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_pd(dx_SSE1, dy_SSE1, dz_SSE1);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_pd(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_pd(jmask_SSE1, imask_SSE1);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_pd(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_pd(rsq_SSE1);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_pd(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_pd(rinv_SSE1, jmask_SSE1);
-
- dr_SSE0 = _mm_mul_pd(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_pd(rsq_SSE1, rinv_SSE1);
-
- sk_aj_SSE = _mm_load_pd(obc_param+j);
- raj_SSE = _mm_load_pd(gb_radius+j);
-
- raj_inv_SSE = gmx_mm_inv_pd(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_aj_SSE);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_aj_SSE);
- t3_SSE0 = _mm_sub_pd(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_aj_SSE, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(rai_SSE1, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(rai_SSE1, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(rai_SSE1, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, jmask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, rai_inv_SSE1));
-
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_aj_SSE = _mm_mul_pd(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_aj_SSE, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
-
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
-
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(rai_inv_SSE1, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- sum_ai_SSE0 = _mm_add_pd(sum_ai_SSE0, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_pd(sum_ai_SSE1, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
-
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_pd(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_pd(dr_SSE1, sk_ai_SSE1);
- t2_SSE0 = _mm_sub_pd(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_pd(dr_SSE1, sk_ai_SSE1);
- t3_SSE0 = _mm_sub_pd(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_pd(sk_ai_SSE1, dr_SSE1);
-
- obc_mask1_SSE0 = _mm_cmplt_pd(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_pd(raj_SSE, t1_SSE1);
- obc_mask2_SSE0 = _mm_cmplt_pd(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_pd(raj_SSE, t2_SSE1);
- obc_mask3_SSE0 = _mm_cmplt_pd(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_pd(raj_SSE, t3_SSE1);
- obc_mask1_SSE0 = _mm_and_pd(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_pd(obc_mask1_SSE1, jmask_SSE1);
-
- uij_SSE0 = gmx_mm_inv_pd(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_pd(t1_SSE1);
- lij_SSE0 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE0, gmx_mm_inv_pd(t2_SSE0)),
- _mm_andnot_pd(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_pd( _mm_and_pd(obc_mask2_SSE1, gmx_mm_inv_pd(t2_SSE1)),
- _mm_andnot_pd(obc_mask2_SSE1, raj_inv_SSE));
-
- dlij_SSE0 = _mm_and_pd(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_pd(one_SSE, obc_mask2_SSE1);
-
- uij2_SSE0 = _mm_mul_pd(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_pd(uij_SSE1, uij_SSE1);
- uij3_SSE0 = _mm_mul_pd(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_pd(uij2_SSE1, uij_SSE1);
- lij2_SSE0 = _mm_mul_pd(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_pd(lij_SSE1, lij_SSE1);
- lij3_SSE0 = _mm_mul_pd(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_pd(lij2_SSE1, lij_SSE1);
-
- diff2_SSE0 = _mm_sub_pd(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_pd(uij2_SSE1, lij2_SSE1);
- lij_inv_SSE0 = gmx_mm_invsqrt_pd(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_pd(lij2_SSE1);
- sk2_rinv_SSE0 = _mm_mul_pd(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_pd(sk2_ai_SSE1, rinv_SSE1);
- prod_SSE0 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_pd(onefourth_SSE, sk2_rinv_SSE1);
-
- logterm_SSE0 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_pd(_mm_mul_pd(uij_SSE1, lij_inv_SSE1));
- t1_SSE0 = _mm_sub_pd(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_pd(lij_SSE1, uij_SSE1);
- t2_SSE0 = _mm_mul_pd(diff2_SSE0,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_pd(diff2_SSE1,
- _mm_sub_pd(_mm_mul_pd(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t3_SSE0 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_pd(half_SSE, _mm_mul_pd(rinv_SSE1, logterm_SSE1));
- t1_SSE0 = _mm_add_pd(t1_SSE0, _mm_add_pd(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_pd(t1_SSE1, _mm_add_pd(t2_SSE1, t3_SSE1));
- t4_SSE0 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_pd(two_SSE, _mm_sub_pd(raj_inv_SSE, lij_SSE1));
- t4_SSE0 = _mm_and_pd(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_pd(t4_SSE1, obc_mask3_SSE1);
- t1_SSE0 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_pd(half_SSE, _mm_add_pd(t1_SSE1, t4_SSE1));
-
- _mm_store_pd(work+j, _mm_add_pd(_mm_load_pd(work+j),
- _mm_add_pd(_mm_and_pd(t1_SSE0, obc_mask1_SSE0),
- _mm_and_pd(t1_SSE1, obc_mask1_SSE1))));
-
- t1_SSE0 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE0),
- _mm_mul_pd(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_pd(_mm_mul_pd(half_SSE, lij2_SSE1),
- _mm_mul_pd(prod_SSE1, lij3_SSE1));
-
- t1_SSE0 = _mm_sub_pd(t1_SSE0,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE0, rinv_SSE0),
- _mm_mul_pd(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_pd(t1_SSE1,
- _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(lij_SSE1, rinv_SSE1),
- _mm_mul_pd(lij3_SSE1, dr_SSE1))));
- t2_SSE0 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE0, rinv_SSE0),
- _mm_mul_pd(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_pd(onefourth_SSE,
- _mm_add_pd(_mm_mul_pd(uij_SSE1, rinv_SSE1),
- _mm_mul_pd(uij3_SSE1, dr_SSE1)));
- t2_SSE0 = _mm_sub_pd(t2_SSE0,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE0),
- _mm_mul_pd(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_pd(t2_SSE1,
- _mm_add_pd(_mm_mul_pd(half_SSE, uij2_SSE1),
- _mm_mul_pd(prod_SSE1, uij3_SSE1)));
-
- t3_SSE0 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE0),
- _mm_mul_pd(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_pd(_mm_mul_pd(onefourth_SSE, logterm_SSE1),
- _mm_mul_pd(rinv_SSE1, rinv_SSE1));
-
- t3_SSE0 = _mm_sub_pd(t3_SSE0,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE0, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_pd(t3_SSE1,
- _mm_mul_pd(_mm_mul_pd(diff2_SSE1, oneeighth_SSE),
- _mm_add_pd(one_SSE,
- _mm_mul_pd(sk2_rinv_SSE1, rinv_SSE1))));
-
- t1_SSE0 = _mm_mul_pd(rinv_SSE0,
- _mm_add_pd(_mm_mul_pd(dlij_SSE0, t1_SSE0),
- _mm_add_pd(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_pd(rinv_SSE1,
- _mm_add_pd(_mm_mul_pd(dlij_SSE1, t1_SSE1),
- _mm_add_pd(t2_SSE1, t3_SSE1)));
-
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE0, obc_mask1_SSE0));
- dadx += 2;
- _mm_store_pd(dadx, _mm_and_pd(t1_SSE1, obc_mask1_SSE1));
- dadx += 2;
- }
- GMX_MM_TRANSPOSE2_PD(sum_ai_SSE0, sum_ai_SSE1);
- sum_ai_SSE0 = _mm_add_pd(sum_ai_SSE0, sum_ai_SSE1);
- _mm_store_pd(work+i, _mm_add_pd(sum_ai_SSE0, _mm_load_pd(work+i)));
- }
-
-
- for (i = 0; i < natoms/2+1; i++)
- {
- work[i] += work[natoms+i];
- }
-
- /* Parallel summations would go here if ever implemented in DD */
-
- if (gb_algorithm == egbHCT)
- {
- /* HCT */
- for (i = 0; i < natoms; i++)
- {
- if (born->use[i] != 0)
- {
- rai = top->atomtypes.gb_radius[mdatoms->typeA[i]]-born->gb_doffset;
- sum_ai = 1.0/rai - work[i];
- min_rad = rai + born->gb_doffset;
- rad = 1.0/sum_ai;
-
- born->bRad[i] = rad > min_rad ? rad : min_rad;
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- }
- else
- {
- /* OBC */
-
- /* Calculate the radii */
- for (i = 0; i < natoms; i++)
- {
-
- if (born->use[i] != 0)
- {
- rai = top->atomtypes.gb_radius[mdatoms->typeA[i]];
- rai_inv2 = 1.0/rai;
- rai = rai-born->gb_doffset;
- rai_inv = 1.0/rai;
- sum_ai = rai * work[i];
- sum_ai2 = sum_ai * sum_ai;
- sum_ai3 = sum_ai2 * sum_ai;
-
- tsum = tanh(born->obc_alpha*sum_ai-born->obc_beta*sum_ai2+born->obc_gamma*sum_ai3);
- born->bRad[i] = rai_inv - tsum*rai_inv2;
- born->bRad[i] = 1.0 / born->bRad[i];
-
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
-
- tchain = rai * (born->obc_alpha-2*born->obc_beta*sum_ai+3*born->obc_gamma*sum_ai2);
- born->drobc[i] = (1.0-tsum*tsum)*tchain*rai_inv2;
- }
- }
- }
-
- return 0;
-}
-
-
-
-
-
-
-
-
-int
-genborn_allvsall_calc_chainrule_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- double * x,
- double * f,
- int gb_algorithm,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int idx;
- int * mask;
- int * pmask0;
- int * emask0;
- int * jindex;
-
- double ix, iy, iz;
- double fix, fiy, fiz;
- double jx, jy, jz;
- double dx, dy, dz;
- double tx, ty, tz;
- double rbai, rbaj, fgb, fgb_ai, rbi;
- double * rb;
- double * dadx;
- double * x_align;
- double * y_align;
- double * z_align;
- double * fx_align;
- double * fy_align;
- double * fz_align;
- double tmpsum[2];
-
- __m128d jmask_SSE0, jmask_SSE1;
- __m128d ix_SSE0, iy_SSE0, iz_SSE0;
- __m128d ix_SSE1, iy_SSE1, iz_SSE1;
- __m128d fix_SSE0, fiy_SSE0, fiz_SSE0;
- __m128d fix_SSE1, fiy_SSE1, fiz_SSE1;
- __m128d rbai_SSE0, rbai_SSE1;
- __m128d imask_SSE0, imask_SSE1;
- __m128d jx_SSE, jy_SSE, jz_SSE, rbaj_SSE;
- __m128d dx_SSE0, dy_SSE0, dz_SSE0;
- __m128d dx_SSE1, dy_SSE1, dz_SSE1;
- __m128d fgb_SSE0, fgb_ai_SSE0;
- __m128d fgb_SSE1, fgb_ai_SSE1;
- __m128d tx_SSE0, ty_SSE0, tz_SSE0;
- __m128d tx_SSE1, ty_SSE1, tz_SSE1;
- __m128d t1, t2, tmpSSE;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
-
- aadata = (gmx_allvsallgb2_data_t *)paadata;
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
- fx_align = aadata->fx_align;
- fy_align = aadata->fy_align;
- fz_align = aadata->fz_align;
-
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
-
- n = 0;
- rb = aadata->work;
-
- /* Loop to get the proper form for the Born radius term */
- if (gb_algorithm == egbSTILL)
- {
- for (i = 0; i < natoms; i++)
- {
- rbi = born->bRad[i];
- rb[i] = (2 * rbi * rbi * fr->dvda[i])/ONE_4PI_EPS0;
- }
- }
- else if (gb_algorithm == egbHCT)
- {
- for (i = 0; i < natoms; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * fr->dvda[i];
- }
- }
- else if (gb_algorithm == egbOBC)
- {
- for (idx = 0; idx < natoms; idx++)
- {
- rbi = born->bRad[idx];
- rb[idx] = rbi * rbi * born->drobc[idx] * fr->dvda[idx];
- }
- }
-
- for (i = 0; i < 2*natoms; i++)
- {
- fx_align[i] = 0;
- fy_align[i] = 0;
- fz_align[i] = 0;
- }
-
-
- for (i = 0; i < natoms; i++)
- {
- rb[i+natoms] = rb[i];
- }
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
-
- /* Load i atom data */
- ix_SSE0 = _mm_load1_pd(x_align+i);
- iy_SSE0 = _mm_load1_pd(y_align+i);
- iz_SSE0 = _mm_load1_pd(z_align+i);
- ix_SSE1 = _mm_load1_pd(x_align+i+1);
- iy_SSE1 = _mm_load1_pd(y_align+i+1);
- iz_SSE1 = _mm_load1_pd(z_align+i+1);
-
- fix_SSE0 = _mm_setzero_pd();
- fiy_SSE0 = _mm_setzero_pd();
- fiz_SSE0 = _mm_setzero_pd();
- fix_SSE1 = _mm_setzero_pd();
- fiy_SSE1 = _mm_setzero_pd();
- fiz_SSE1 = _mm_setzero_pd();
-
- rbai_SSE0 = _mm_load1_pd(rb+i);
- rbai_SSE1 = _mm_load1_pd(rb+i+1);
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj3 = jindex[4*i+3];
-
- /* No masks necessary, since the stored chain rule derivatives will be zero in those cases! */
- for (j = nj0; j < nj3; j += UNROLLJ)
- {
- /* load j atom coordinates */
- jx_SSE = _mm_load_pd(x_align+j);
- jy_SSE = _mm_load_pd(y_align+j);
- jz_SSE = _mm_load_pd(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_pd(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_pd(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_pd(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_pd(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_pd(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_pd(iz_SSE1, jz_SSE);
-
- rbaj_SSE = _mm_load_pd(rb+j);
-
- fgb_SSE0 = _mm_mul_pd(rbai_SSE0, _mm_load_pd(dadx));
- dadx += 2;
- fgb_SSE1 = _mm_mul_pd(rbai_SSE1, _mm_load_pd(dadx));
- dadx += 2;
-
- fgb_ai_SSE0 = _mm_mul_pd(rbaj_SSE, _mm_load_pd(dadx));
- dadx += 2;
- fgb_ai_SSE1 = _mm_mul_pd(rbaj_SSE, _mm_load_pd(dadx));
- dadx += 2;
-
- /* Total force between ai and aj is the sum of ai->aj and aj->ai */
- fgb_SSE0 = _mm_add_pd(fgb_SSE0, fgb_ai_SSE0);
- fgb_SSE1 = _mm_add_pd(fgb_SSE1, fgb_ai_SSE1);
-
- /* Calculate temporary vectorial force */
- tx_SSE0 = _mm_mul_pd(fgb_SSE0, dx_SSE0);
- ty_SSE0 = _mm_mul_pd(fgb_SSE0, dy_SSE0);
- tz_SSE0 = _mm_mul_pd(fgb_SSE0, dz_SSE0);
- tx_SSE1 = _mm_mul_pd(fgb_SSE1, dx_SSE1);
- ty_SSE1 = _mm_mul_pd(fgb_SSE1, dy_SSE1);
- tz_SSE1 = _mm_mul_pd(fgb_SSE1, dz_SSE1);
-
- /* Increment i atom force */
- fix_SSE0 = _mm_add_pd(fix_SSE0, tx_SSE0);
- fiy_SSE0 = _mm_add_pd(fiy_SSE0, ty_SSE0);
- fiz_SSE0 = _mm_add_pd(fiz_SSE0, tz_SSE0);
- fix_SSE1 = _mm_add_pd(fix_SSE1, tx_SSE1);
- fiy_SSE1 = _mm_add_pd(fiy_SSE1, ty_SSE1);
- fiz_SSE1 = _mm_add_pd(fiz_SSE1, tz_SSE1);
-
- /* Decrement j atom force */
- _mm_store_pd(fx_align+j,
- _mm_sub_pd( _mm_load_pd(fx_align+j), _mm_add_pd(tx_SSE0, tx_SSE1) ));
- _mm_store_pd(fy_align+j,
- _mm_sub_pd( _mm_load_pd(fy_align+j), _mm_add_pd(ty_SSE0, ty_SSE1) ));
- _mm_store_pd(fz_align+j,
- _mm_sub_pd( _mm_load_pd(fz_align+j), _mm_add_pd(tz_SSE0, tz_SSE1) ));
- }
-
- /* Add i forces to mem */
- GMX_MM_TRANSPOSE2_PD(fix_SSE0, fix_SSE1);
- fix_SSE0 = _mm_add_pd(fix_SSE0, fix_SSE1);
- _mm_store_pd(fx_align+i, _mm_add_pd(fix_SSE0, _mm_load_pd(fx_align+i)));
-
- GMX_MM_TRANSPOSE2_PD(fiy_SSE0, fiy_SSE1);
- fiy_SSE0 = _mm_add_pd(fiy_SSE0, fiy_SSE1);
- _mm_store_pd(fy_align+i, _mm_add_pd(fiy_SSE0, _mm_load_pd(fy_align+i)));
-
- GMX_MM_TRANSPOSE2_PD(fiz_SSE0, fiz_SSE1);
- fiz_SSE0 = _mm_add_pd(fiz_SSE0, fiz_SSE1);
- _mm_store_pd(fz_align+i, _mm_add_pd(fiz_SSE0, _mm_load_pd(fz_align+i)));
- }
-
- for (i = 0; i < natoms; i++)
- {
- f[3*i] += fx_align[i] + fx_align[natoms+i];
- f[3*i+1] += fy_align[i] + fy_align[natoms+i];
- f[3*i+2] += fz_align[i] + fz_align[natoms+i];
- }
-
- return 0;
-}
-
-#else
-/* dummy variable when not using SSE */
-int genborn_allvsall_sse2_double_dummy;
-
-
-#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef _GENBORN_ALLVSALL_SSE2_DOUBLE_H
-#define _GENBORN_ALLVSALL_SSE2_DOUBLE_H
-
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/legacyheaders/types/simple.h"
-
-int
-genborn_allvsall_calc_still_radii_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- gmx_localtop_t * top,
- double * x,
- t_commrec * cr,
- void * work);
-
-int
-genborn_allvsall_calc_hct_obc_radii_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- int gb_algorithm,
- gmx_localtop_t * top,
- double * x,
- t_commrec * cr,
- void * work);
-
-int
-genborn_allvsall_calc_chainrule_sse2_double(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- double * x,
- double * f,
- int gb_algorithm,
- void * work);
-
-#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include <math.h>
-
-#include "gromacs/legacyheaders/genborn.h"
-#include "gromacs/legacyheaders/network.h"
-#include "gromacs/legacyheaders/types/simple.h"
-#include "gromacs/math/units.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/genborn_allvsall.h"
-#include "gromacs/utility/smalloc.h"
-
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
-
-#include <gmx_sse2_single.h>
-
-
-#define SIMD_WIDTH 4
-#define UNROLLI 4
-#define UNROLLJ 4
-
-
-
-
-
-
-
-
-
-typedef struct
-{
- int * jindex_gb;
- int ** prologue_mask_gb;
- int ** epilogue_mask;
- int * imask;
- real * gb_radius;
- real * workparam;
- real * work;
- real * x_align;
- real * y_align;
- real * z_align;
- real * fx_align;
- real * fy_align;
- real * fz_align;
-}
-gmx_allvsallgb2_data_t;
-
-
-static int
-calc_maxoffset(int i, int natoms)
-{
- int maxoffset;
-
- if ((natoms % 2) == 1)
- {
- /* Odd number of atoms, easy */
- maxoffset = natoms/2;
- }
- else if ((natoms % 4) == 0)
- {
- /* Multiple of four is hard */
- if (i < natoms/2)
- {
- if ((i % 2) == 0)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
- else
- {
- if ((i % 2) == 1)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
- }
- else
- {
- /* natoms/2 = odd */
- if ((i % 2) == 0)
- {
- maxoffset = natoms/2;
- }
- else
- {
- maxoffset = natoms/2-1;
- }
- }
-
- return maxoffset;
-}
-
-static void
-setup_gb_exclusions_and_indices(gmx_allvsallgb2_data_t * aadata,
- t_ilist * ilist,
- int start,
- int end,
- int natoms,
- gmx_bool bInclude12,
- gmx_bool bInclude13,
- gmx_bool bInclude14)
-{
- int i, j, k, tp;
- int a1, a2;
- int ni0, ni1, nj0, nj1, nj;
- int imin, imax, iexcl;
- int max_offset;
- int max_excl_offset;
- int firstinteraction;
- int ibase;
- int *pi;
-
- /* This routine can appear to be a bit complex, but it is mostly book-keeping.
- * To enable the fast all-vs-all kernel we need to be able to stream through all coordinates
- * whether they should interact or not.
- *
- * To avoid looping over the exclusions, we create a simple mask that is 1 if the interaction
- * should be present, otherwise 0. Since exclusions typically only occur when i & j are close,
- * we create a jindex array with three elements per i atom: the starting point, the point to
- * which we need to check exclusions, and the end point.
- * This way we only have to allocate a short exclusion mask per i atom.
- */
-
- ni0 = (start/UNROLLI)*UNROLLI;
- ni1 = ((end+UNROLLI-1)/UNROLLI)*UNROLLI;
-
- /* Set the interaction mask to only enable the i atoms we want to include */
- snew(pi, natoms+UNROLLI+2*SIMD_WIDTH);
- aadata->imask = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->imask[i] = (i >= start && i < end) ? 0xFFFFFFFF : 0;
- }
-
- /* Allocate memory for our modified jindex array */
- snew(aadata->jindex_gb, 4*(natoms+UNROLLI));
- for (i = 0; i < 4*(natoms+UNROLLI); i++)
- {
- aadata->jindex_gb[i] = 0;
- }
-
- /* Create the exclusion masks for the prologue part */
- snew(aadata->prologue_mask_gb, natoms+UNROLLI); /* list of pointers */
-
- /* First zero everything to avoid uninitialized data */
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->prologue_mask_gb[i] = NULL;
- }
-
- /* Calculate the largest exclusion range we need for each UNROLLI-tuplet of i atoms. */
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- max_excl_offset = -1;
-
- /* First find maxoffset for the next 4 atoms (or fewer if we are close to end) */
- imax = ((ibase+UNROLLI) < end) ? (ibase+UNROLLI) : end;
-
- /* Which atom is the first we (might) interact with? */
- imin = natoms; /* Guaranteed to be overwritten by one of 'firstinteraction' */
- for (i = ibase; i < imax; i++)
- {
- /* Before exclusions, which atom is the first we (might) interact with? */
- firstinteraction = i+1;
- max_offset = calc_maxoffset(i, natoms);
-
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k == firstinteraction)
- {
- firstinteraction++;
- }
- }
- }
- imin = (firstinteraction < imin) ? firstinteraction : imin;
- }
- /* round down to j unrolling factor */
- imin = (imin/UNROLLJ)*UNROLLJ;
-
- for (i = ibase; i < imax; i++)
- {
- max_offset = calc_maxoffset(i, natoms);
-
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k < imin)
- {
- k += natoms;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
-
- k = k - imin;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
- max_excl_offset = (k > max_excl_offset) ? k : max_excl_offset;
- }
- }
- }
-
- /* The offset specifies the last atom to be excluded, so add one unit to get an upper loop limit */
- max_excl_offset++;
- /* round up to j unrolling factor */
- max_excl_offset = (max_excl_offset/UNROLLJ+1)*UNROLLJ;
-
- /* Set all the prologue masks length to this value (even for i>end) */
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- aadata->jindex_gb[4*i] = imin;
- aadata->jindex_gb[4*i+1] = imin+max_excl_offset;
- }
- }
-
- /* Now the hard part, loop over it all again to calculate the actual contents of the prologue masks */
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- nj = aadata->jindex_gb[4*i+1] - aadata->jindex_gb[4*i];
- imin = aadata->jindex_gb[4*i];
-
- /* Allocate aligned memory */
- snew(pi, nj+2*SIMD_WIDTH);
- aadata->prologue_mask_gb[i] = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
-
- max_offset = calc_maxoffset(i, natoms);
-
- /* Include interactions i+1 <= j < i+maxoffset */
- for (k = 0; k < nj; k++)
- {
- j = imin + k;
-
- if ( (j > i) && (j <= i+max_offset) )
- {
- aadata->prologue_mask_gb[i][k] = 0xFFFFFFFF;
- }
- else
- {
- aadata->prologue_mask_gb[i][k] = 0;
- }
- }
-
- /* Clear out the explicit exclusions */
- if (i < end)
- {
- if (!bInclude12)
- {
- for (j = 0; j < ilist[F_GB12].nr; j += 3)
- {
- a1 = ilist[F_GB12].iatoms[j+1];
- a2 = ilist[F_GB12].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][k] = 0;
- }
- }
- }
- if (!bInclude13)
- {
- for (j = 0; j < ilist[F_GB13].nr; j += 3)
- {
- a1 = ilist[F_GB13].iatoms[j+1];
- a2 = ilist[F_GB13].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][k] = 0;
- }
- }
- }
- if (!bInclude14)
- {
- for (j = 0; j < ilist[F_GB14].nr; j += 3)
- {
- a1 = ilist[F_GB14].iatoms[j+1];
- a2 = ilist[F_GB14].iatoms[j+2];
-
- if (a1 == i)
- {
- k = a2;
- }
- else if (a2 == i)
- {
- k = a1;
- }
- else
- {
- continue;
- }
-
- if (k > i+max_offset)
- {
- continue;
- }
- k = k-i;
-
- if (k+natoms <= max_offset)
- {
- k += natoms;
- }
-
- k = k+i-imin;
- if (k >= 0)
- {
- aadata->prologue_mask_gb[i][k] = 0;
- }
- }
- }
- }
- }
- }
-
- /* Construct the epilogue mask - this just contains the check for maxoffset */
- snew(aadata->epilogue_mask, natoms+UNROLLI);
-
- /* First zero everything to avoid uninitialized data */
- for (i = 0; i < natoms+UNROLLI; i++)
- {
- aadata->jindex_gb[4*i+2] = aadata->jindex_gb[4*i+1];
- aadata->jindex_gb[4*i+3] = aadata->jindex_gb[4*i+1];
- aadata->epilogue_mask[i] = NULL;
- }
-
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- /* Find the lowest index for which we need to use the epilogue */
- imin = ibase;
- max_offset = calc_maxoffset(imin, natoms);
-
- imin = imin + 1 + max_offset;
-
- /* Find largest index for which we need to use the epilogue */
- imax = ibase + UNROLLI-1;
- imax = (imax < end) ? imax : end;
-
- max_offset = calc_maxoffset(imax, natoms);
- imax = imax + 1 + max_offset + UNROLLJ - 1;
-
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
- /* Start of epilogue - round down to j tile limit */
- aadata->jindex_gb[4*i+2] = (imin/UNROLLJ)*UNROLLJ;
- /* Make sure we dont overlap - for small systems everything is done in the prologue */
- aadata->jindex_gb[4*i+2] = (aadata->jindex_gb[4*i+1] > aadata->jindex_gb[4*i+2]) ? aadata->jindex_gb[4*i+1] : aadata->jindex_gb[4*i+2];
- /* Round upwards to j tile limit */
- aadata->jindex_gb[4*i+3] = (imax/UNROLLJ)*UNROLLJ;
- /* Make sure we dont have a negative range for the epilogue */
- aadata->jindex_gb[4*i+3] = (aadata->jindex_gb[4*i+2] > aadata->jindex_gb[4*i+3]) ? aadata->jindex_gb[4*i+2] : aadata->jindex_gb[4*i+3];
- }
- }
-
- /* And fill it with data... */
-
- for (ibase = ni0; ibase < ni1; ibase += UNROLLI)
- {
- for (i = ibase; i < ibase+UNROLLI; i++)
- {
-
- nj = aadata->jindex_gb[4*i+3] - aadata->jindex_gb[4*i+2];
-
- /* Allocate aligned memory */
- snew(pi, nj+2*SIMD_WIDTH);
- aadata->epilogue_mask[i] = (int *) (((size_t) pi + 16) & (~((size_t) 15)));
-
- max_offset = calc_maxoffset(i, natoms);
-
- for (k = 0; k < nj; k++)
- {
- j = aadata->jindex_gb[4*i+2] + k;
- aadata->epilogue_mask[i][k] = (j <= i+max_offset) ? 0xFFFFFFFF : 0;
- }
- }
- }
-}
-
-
-static void
-genborn_allvsall_setup(gmx_allvsallgb2_data_t ** p_aadata,
- gmx_localtop_t * top,
- gmx_genborn_t * born,
- t_mdatoms * mdatoms,
- real radius_offset,
- int gb_algorithm,
- gmx_bool bInclude12,
- gmx_bool bInclude13,
- gmx_bool bInclude14)
-{
- int i, j, idx;
- int natoms;
- gmx_allvsallgb2_data_t *aadata;
- real *p;
-
- natoms = mdatoms->nr;
-
- snew(aadata, 1);
- *p_aadata = aadata;
-
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->x_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->y_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->z_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fx_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fy_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
- snew(p, 2*natoms+2*SIMD_WIDTH);
- aadata->fz_align = (real *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->gb_radius = (real *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->workparam = (real *) (((size_t) p + 16) & (~((size_t) 15)));
-
- snew(p, 2*natoms+UNROLLJ+SIMD_WIDTH);
- aadata->work = (real *) (((size_t) p + 16) & (~((size_t) 15)));
-
- for (i = 0; i < mdatoms->nr; i++)
- {
- aadata->gb_radius[i] = top->atomtypes.gb_radius[mdatoms->typeA[i]] - radius_offset;
- if (gb_algorithm == egbSTILL)
- {
- aadata->workparam[i] = born->vsolv[i];
- }
- else if (gb_algorithm == egbOBC)
- {
- aadata->workparam[i] = born->param[i];
- }
- aadata->work[i] = 0.0;
- }
- for (i = 0; i < mdatoms->nr; i++)
- {
- aadata->gb_radius[natoms+i] = aadata->gb_radius[i];
- aadata->workparam[natoms+i] = aadata->workparam[i];
- aadata->work[natoms+i] = aadata->work[i];
- }
-
- for (i = 0; i < 2*natoms+SIMD_WIDTH; i++)
- {
- aadata->x_align[i] = 0.0;
- aadata->y_align[i] = 0.0;
- aadata->z_align[i] = 0.0;
- aadata->fx_align[i] = 0.0;
- aadata->fy_align[i] = 0.0;
- aadata->fz_align[i] = 0.0;
- }
-
- setup_gb_exclusions_and_indices(aadata, top->idef.il, 0, mdatoms->homenr, mdatoms->nr,
- bInclude12, bInclude13, bInclude14);
-}
-
-
-int
-genborn_allvsall_calc_still_radii_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- gmx_localtop_t * top,
- real * x,
- t_commrec * cr,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int * mask;
- int * pmask0;
- int * pmask1;
- int * pmask2;
- int * pmask3;
- int * emask0;
- int * emask1;
- int * emask2;
- int * emask3;
- real ix, iy, iz;
- real jx, jy, jz;
- real dx, dy, dz;
- real rsq, rinv;
- real gpi, rai, vai;
- real prod_ai;
- real irsq, idr4, idr6;
- real raj, rvdw, ratio;
- real vaj, ccf, dccf, theta, cosq;
- real term, prod, icf4, icf6, gpi2, factor, sinq;
- real * gb_radius;
- real * vsolv;
- real * work;
- real tmpsum[4];
- real * x_align;
- real * y_align;
- real * z_align;
- int * jindex;
- real * dadx;
-
- __m128 ix_SSE0, iy_SSE0, iz_SSE0;
- __m128 ix_SSE1, iy_SSE1, iz_SSE1;
- __m128 ix_SSE2, iy_SSE2, iz_SSE2;
- __m128 ix_SSE3, iy_SSE3, iz_SSE3;
- __m128 gpi_SSE0, rai_SSE0, prod_ai_SSE0;
- __m128 gpi_SSE1, rai_SSE1, prod_ai_SSE1;
- __m128 gpi_SSE2, rai_SSE2, prod_ai_SSE2;
- __m128 gpi_SSE3, rai_SSE3, prod_ai_SSE3;
- __m128 imask_SSE0, jmask_SSE0;
- __m128 imask_SSE1, jmask_SSE1;
- __m128 imask_SSE2, jmask_SSE2;
- __m128 imask_SSE3, jmask_SSE3;
- __m128 jx_SSE, jy_SSE, jz_SSE;
- __m128 dx_SSE0, dy_SSE0, dz_SSE0;
- __m128 dx_SSE1, dy_SSE1, dz_SSE1;
- __m128 dx_SSE2, dy_SSE2, dz_SSE2;
- __m128 dx_SSE3, dy_SSE3, dz_SSE3;
- __m128 rsq_SSE0, rinv_SSE0, irsq_SSE0, idr4_SSE0, idr6_SSE0;
- __m128 rsq_SSE1, rinv_SSE1, irsq_SSE1, idr4_SSE1, idr6_SSE1;
- __m128 rsq_SSE2, rinv_SSE2, irsq_SSE2, idr4_SSE2, idr6_SSE2;
- __m128 rsq_SSE3, rinv_SSE3, irsq_SSE3, idr4_SSE3, idr6_SSE3;
- __m128 raj_SSE, vaj_SSE, prod_SSE;
- __m128 rvdw_SSE0, ratio_SSE0;
- __m128 rvdw_SSE1, ratio_SSE1;
- __m128 rvdw_SSE2, ratio_SSE2;
- __m128 rvdw_SSE3, ratio_SSE3;
- __m128 theta_SSE0, sinq_SSE0, cosq_SSE0, term_SSE0;
- __m128 theta_SSE1, sinq_SSE1, cosq_SSE1, term_SSE1;
- __m128 theta_SSE2, sinq_SSE2, cosq_SSE2, term_SSE2;
- __m128 theta_SSE3, sinq_SSE3, cosq_SSE3, term_SSE3;
- __m128 ccf_SSE0, dccf_SSE0;
- __m128 ccf_SSE1, dccf_SSE1;
- __m128 ccf_SSE2, dccf_SSE2;
- __m128 ccf_SSE3, dccf_SSE3;
- __m128 icf4_SSE0, icf6_SSE0;
- __m128 icf4_SSE1, icf6_SSE1;
- __m128 icf4_SSE2, icf6_SSE2;
- __m128 icf4_SSE3, icf6_SSE3;
- __m128 half_SSE, one_SSE, two_SSE, four_SSE;
- __m128 still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
-
- n = 0;
-
- aadata = *((gmx_allvsallgb2_data_t **)paadata);
-
-
- if (aadata == NULL)
- {
- genborn_allvsall_setup(&aadata, top, born, mdatoms, 0.0,
- egbSTILL, FALSE, FALSE, TRUE);
- *((gmx_allvsallgb2_data_t **)paadata) = aadata;
- }
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
-
- gb_radius = aadata->gb_radius;
- vsolv = aadata->workparam;
- work = aadata->work;
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
-
- still_p4_SSE = _mm_set1_ps(STILL_P4);
- still_p5inv_SSE = _mm_set1_ps(STILL_P5INV);
- still_pip5_SSE = _mm_set1_ps(STILL_PIP5);
- half_SSE = _mm_set1_ps(0.5);
- one_SSE = _mm_set1_ps(1.0);
- two_SSE = _mm_set1_ps(2.0);
- four_SSE = _mm_set1_ps(4.0);
-
- /* This will be summed, so it has to extend to natoms + buffer */
- for (i = 0; i < natoms+1+natoms/2; i++)
- {
- work[i] = 0;
- }
-
- for (i = ni0; i < ni1+1+natoms/2; i++)
- {
- k = i%natoms;
- x_align[i] = x[3*k];
- y_align[i] = x[3*k+1];
- z_align[i] = x[3*k+2];
- work[i] = 0;
- }
-
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
-
- /* Load i atom data */
- ix_SSE0 = _mm_load1_ps(x_align+i);
- iy_SSE0 = _mm_load1_ps(y_align+i);
- iz_SSE0 = _mm_load1_ps(z_align+i);
- ix_SSE1 = _mm_load1_ps(x_align+i+1);
- iy_SSE1 = _mm_load1_ps(y_align+i+1);
- iz_SSE1 = _mm_load1_ps(z_align+i+1);
- ix_SSE2 = _mm_load1_ps(x_align+i+2);
- iy_SSE2 = _mm_load1_ps(y_align+i+2);
- iz_SSE2 = _mm_load1_ps(z_align+i+2);
- ix_SSE3 = _mm_load1_ps(x_align+i+3);
- iy_SSE3 = _mm_load1_ps(y_align+i+3);
- iz_SSE3 = _mm_load1_ps(z_align+i+3);
-
- gpi_SSE0 = _mm_setzero_ps();
- gpi_SSE1 = _mm_setzero_ps();
- gpi_SSE2 = _mm_setzero_ps();
- gpi_SSE3 = _mm_setzero_ps();
-
- rai_SSE0 = _mm_load1_ps(gb_radius+i);
- rai_SSE1 = _mm_load1_ps(gb_radius+i+1);
- rai_SSE2 = _mm_load1_ps(gb_radius+i+2);
- rai_SSE3 = _mm_load1_ps(gb_radius+i+3);
-
- prod_ai_SSE0 = _mm_set1_ps(STILL_P4*vsolv[i]);
- prod_ai_SSE1 = _mm_set1_ps(STILL_P4*vsolv[i+1]);
- prod_ai_SSE2 = _mm_set1_ps(STILL_P4*vsolv[i+2]);
- prod_ai_SSE3 = _mm_set1_ps(STILL_P4*vsolv[i+3]);
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj1 = jindex[4*i+1];
- nj2 = jindex[4*i+2];
- nj3 = jindex[4*i+3];
-
- pmask0 = aadata->prologue_mask_gb[i];
- pmask1 = aadata->prologue_mask_gb[i+1];
- pmask2 = aadata->prologue_mask_gb[i+2];
- pmask3 = aadata->prologue_mask_gb[i+3];
- emask0 = aadata->epilogue_mask[i];
- emask1 = aadata->epilogue_mask[i+1];
- emask2 = aadata->epilogue_mask[i+2];
- emask3 = aadata->epilogue_mask[i+3];
-
- imask_SSE0 = _mm_load1_ps((real *)(aadata->imask+i));
- imask_SSE1 = _mm_load1_ps((real *)(aadata->imask+i+1));
- imask_SSE2 = _mm_load1_ps((real *)(aadata->imask+i+2));
- imask_SSE3 = _mm_load1_ps((real *)(aadata->imask+i+3));
-
- /* Prologue part, including exclusion mask */
- for (j = nj0; j < nj1; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_ps((real *)pmask0);
- jmask_SSE1 = _mm_load_ps((real *)pmask1);
- jmask_SSE2 = _mm_load_ps((real *)pmask2);
- jmask_SSE3 = _mm_load_ps((real *)pmask3);
- pmask0 += UNROLLJ;
- pmask1 += UNROLLJ;
- pmask2 += UNROLLJ;
- pmask3 += UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_ps(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_ps(jmask_SSE1, imask_SSE1);
- jmask_SSE2 = _mm_and_ps(jmask_SSE2, imask_SSE2);
- jmask_SSE3 = _mm_and_ps(jmask_SSE3, imask_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, jmask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, jmask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, jmask_SSE3);
-
- irsq_SSE0 = _mm_mul_ps(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_ps(rinv_SSE1, rinv_SSE1);
- irsq_SSE2 = _mm_mul_ps(rinv_SSE2, rinv_SSE2);
- irsq_SSE3 = _mm_mul_ps(rinv_SSE3, rinv_SSE3);
- idr4_SSE0 = _mm_mul_ps(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_ps(irsq_SSE1, irsq_SSE1);
- idr4_SSE2 = _mm_mul_ps(irsq_SSE2, irsq_SSE2);
- idr4_SSE3 = _mm_mul_ps(irsq_SSE3, irsq_SSE3);
- idr6_SSE0 = _mm_mul_ps(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_ps(idr4_SSE1, irsq_SSE1);
- idr6_SSE2 = _mm_mul_ps(idr4_SSE2, irsq_SSE2);
- idr6_SSE3 = _mm_mul_ps(idr4_SSE3, irsq_SSE3);
-
- raj_SSE = _mm_load_ps(gb_radius+j);
- vaj_SSE = _mm_load_ps(vsolv+j);
-
- rvdw_SSE0 = _mm_add_ps(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_ps(rai_SSE1, raj_SSE);
- rvdw_SSE2 = _mm_add_ps(rai_SSE2, raj_SSE);
- rvdw_SSE3 = _mm_add_ps(rai_SSE3, raj_SSE);
-
- ratio_SSE0 = _mm_mul_ps(rsq_SSE0, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_ps(rsq_SSE1, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE1, rvdw_SSE1)));
- ratio_SSE2 = _mm_mul_ps(rsq_SSE2, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE2, rvdw_SSE2)));
- ratio_SSE3 = _mm_mul_ps(rsq_SSE3, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE3, rvdw_SSE3)));
-
- ratio_SSE0 = _mm_min_ps(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_ps(ratio_SSE1, still_p5inv_SSE);
- ratio_SSE2 = _mm_min_ps(ratio_SSE2, still_p5inv_SSE);
- ratio_SSE3 = _mm_min_ps(ratio_SSE3, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_ps(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_ps(ratio_SSE1, still_pip5_SSE);
- theta_SSE2 = _mm_mul_ps(ratio_SSE2, still_pip5_SSE);
- theta_SSE3 = _mm_mul_ps(ratio_SSE3, still_pip5_SSE);
- gmx_mm_sincos_ps(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_ps(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- gmx_mm_sincos_ps(theta_SSE2, &sinq_SSE2, &cosq_SSE2);
- gmx_mm_sincos_ps(theta_SSE3, &sinq_SSE3, &cosq_SSE3);
- term_SSE0 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE1));
- term_SSE2 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE2));
- term_SSE3 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE3));
- ccf_SSE0 = _mm_mul_ps(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_ps(term_SSE1, term_SSE1);
- ccf_SSE2 = _mm_mul_ps(term_SSE2, term_SSE2);
- ccf_SSE3 = _mm_mul_ps(term_SSE3, term_SSE3);
- dccf_SSE0 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE0),
- _mm_mul_ps(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE1),
- _mm_mul_ps(sinq_SSE1, theta_SSE1));
- dccf_SSE2 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE2),
- _mm_mul_ps(sinq_SSE2, theta_SSE2));
- dccf_SSE3 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE3),
- _mm_mul_ps(sinq_SSE3, theta_SSE3));
-
- prod_SSE = _mm_mul_ps(still_p4_SSE, vaj_SSE);
- icf4_SSE0 = _mm_mul_ps(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_ps(ccf_SSE1, idr4_SSE1);
- icf4_SSE2 = _mm_mul_ps(ccf_SSE2, idr4_SSE2);
- icf4_SSE3 = _mm_mul_ps(ccf_SSE3, idr4_SSE3);
- icf6_SSE0 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
- icf6_SSE2 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE2), dccf_SSE2), idr6_SSE2);
- icf6_SSE3 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE3), dccf_SSE3), idr6_SSE3);
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_mul_ps(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_ps(prod_ai_SSE1, icf4_SSE1),
- _mm_mul_ps(prod_ai_SSE2, icf4_SSE2),
- _mm_mul_ps(prod_ai_SSE3, icf4_SSE3))));
-
- gpi_SSE0 = _mm_add_ps(gpi_SSE0, _mm_mul_ps(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_ps(gpi_SSE1, _mm_mul_ps(prod_SSE, icf4_SSE1));
- gpi_SSE2 = _mm_add_ps(gpi_SSE2, _mm_mul_ps(prod_SSE, icf4_SSE2));
- gpi_SSE3 = _mm_add_ps(gpi_SSE3, _mm_mul_ps(prod_SSE, icf4_SSE3));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE3));
- dadx += 4;
-
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE0, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE1, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE2, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE3, icf6_SSE3));
- dadx += 4;
- }
-
- /* Main part, no exclusions */
- for (j = nj1; j < nj2; j += UNROLLJ)
- {
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, imask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, imask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, imask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, imask_SSE3);
-
- irsq_SSE0 = _mm_mul_ps(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_ps(rinv_SSE1, rinv_SSE1);
- irsq_SSE2 = _mm_mul_ps(rinv_SSE2, rinv_SSE2);
- irsq_SSE3 = _mm_mul_ps(rinv_SSE3, rinv_SSE3);
- idr4_SSE0 = _mm_mul_ps(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_ps(irsq_SSE1, irsq_SSE1);
- idr4_SSE2 = _mm_mul_ps(irsq_SSE2, irsq_SSE2);
- idr4_SSE3 = _mm_mul_ps(irsq_SSE3, irsq_SSE3);
- idr6_SSE0 = _mm_mul_ps(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_ps(idr4_SSE1, irsq_SSE1);
- idr6_SSE2 = _mm_mul_ps(idr4_SSE2, irsq_SSE2);
- idr6_SSE3 = _mm_mul_ps(idr4_SSE3, irsq_SSE3);
-
- raj_SSE = _mm_load_ps(gb_radius+j);
-
- rvdw_SSE0 = _mm_add_ps(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_ps(rai_SSE1, raj_SSE);
- rvdw_SSE2 = _mm_add_ps(rai_SSE2, raj_SSE);
- rvdw_SSE3 = _mm_add_ps(rai_SSE3, raj_SSE);
- vaj_SSE = _mm_load_ps(vsolv+j);
-
- ratio_SSE0 = _mm_mul_ps(rsq_SSE0, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_ps(rsq_SSE1, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE1, rvdw_SSE1)));
- ratio_SSE2 = _mm_mul_ps(rsq_SSE2, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE2, rvdw_SSE2)));
- ratio_SSE3 = _mm_mul_ps(rsq_SSE3, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE3, rvdw_SSE3)));
-
- ratio_SSE0 = _mm_min_ps(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_ps(ratio_SSE1, still_p5inv_SSE);
- ratio_SSE2 = _mm_min_ps(ratio_SSE2, still_p5inv_SSE);
- ratio_SSE3 = _mm_min_ps(ratio_SSE3, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_ps(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_ps(ratio_SSE1, still_pip5_SSE);
- theta_SSE2 = _mm_mul_ps(ratio_SSE2, still_pip5_SSE);
- theta_SSE3 = _mm_mul_ps(ratio_SSE3, still_pip5_SSE);
- gmx_mm_sincos_ps(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_ps(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- gmx_mm_sincos_ps(theta_SSE2, &sinq_SSE2, &cosq_SSE2);
- gmx_mm_sincos_ps(theta_SSE3, &sinq_SSE3, &cosq_SSE3);
- term_SSE0 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE1));
- term_SSE2 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE2));
- term_SSE3 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE3));
- ccf_SSE0 = _mm_mul_ps(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_ps(term_SSE1, term_SSE1);
- ccf_SSE2 = _mm_mul_ps(term_SSE2, term_SSE2);
- ccf_SSE3 = _mm_mul_ps(term_SSE3, term_SSE3);
- dccf_SSE0 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE0),
- _mm_mul_ps(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE1),
- _mm_mul_ps(sinq_SSE1, theta_SSE1));
- dccf_SSE2 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE2),
- _mm_mul_ps(sinq_SSE2, theta_SSE2));
- dccf_SSE3 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE3),
- _mm_mul_ps(sinq_SSE3, theta_SSE3));
-
- prod_SSE = _mm_mul_ps(still_p4_SSE, vaj_SSE );
- icf4_SSE0 = _mm_mul_ps(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_ps(ccf_SSE1, idr4_SSE1);
- icf4_SSE2 = _mm_mul_ps(ccf_SSE2, idr4_SSE2);
- icf4_SSE3 = _mm_mul_ps(ccf_SSE3, idr4_SSE3);
- icf6_SSE0 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
- icf6_SSE2 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE2), dccf_SSE2), idr6_SSE2);
- icf6_SSE3 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE3), dccf_SSE3), idr6_SSE3);
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_mul_ps(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_ps(prod_ai_SSE1, icf4_SSE1),
- _mm_mul_ps(prod_ai_SSE2, icf4_SSE2),
- _mm_mul_ps(prod_ai_SSE3, icf4_SSE3))));
-
- gpi_SSE0 = _mm_add_ps(gpi_SSE0, _mm_mul_ps(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_ps(gpi_SSE1, _mm_mul_ps(prod_SSE, icf4_SSE1));
- gpi_SSE2 = _mm_add_ps(gpi_SSE2, _mm_mul_ps(prod_SSE, icf4_SSE2));
- gpi_SSE3 = _mm_add_ps(gpi_SSE3, _mm_mul_ps(prod_SSE, icf4_SSE3));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE3));
- dadx += 4;
-
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE0, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE1, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE2, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE3, icf6_SSE3));
- dadx += 4;
- }
- /* Epilogue part, including exclusion mask */
- for (j = nj2; j < nj3; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_ps((real *)emask0);
- jmask_SSE1 = _mm_load_ps((real *)emask1);
- jmask_SSE2 = _mm_load_ps((real *)emask2);
- jmask_SSE3 = _mm_load_ps((real *)emask3);
- emask0 += UNROLLJ;
- emask1 += UNROLLJ;
- emask2 += UNROLLJ;
- emask3 += UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_ps(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_ps(jmask_SSE1, imask_SSE1);
- jmask_SSE2 = _mm_and_ps(jmask_SSE2, imask_SSE2);
- jmask_SSE3 = _mm_and_ps(jmask_SSE3, imask_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, jmask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, jmask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, jmask_SSE3);
-
- irsq_SSE0 = _mm_mul_ps(rinv_SSE0, rinv_SSE0);
- irsq_SSE1 = _mm_mul_ps(rinv_SSE1, rinv_SSE1);
- irsq_SSE2 = _mm_mul_ps(rinv_SSE2, rinv_SSE2);
- irsq_SSE3 = _mm_mul_ps(rinv_SSE3, rinv_SSE3);
- idr4_SSE0 = _mm_mul_ps(irsq_SSE0, irsq_SSE0);
- idr4_SSE1 = _mm_mul_ps(irsq_SSE1, irsq_SSE1);
- idr4_SSE2 = _mm_mul_ps(irsq_SSE2, irsq_SSE2);
- idr4_SSE3 = _mm_mul_ps(irsq_SSE3, irsq_SSE3);
- idr6_SSE0 = _mm_mul_ps(idr4_SSE0, irsq_SSE0);
- idr6_SSE1 = _mm_mul_ps(idr4_SSE1, irsq_SSE1);
- idr6_SSE2 = _mm_mul_ps(idr4_SSE2, irsq_SSE2);
- idr6_SSE3 = _mm_mul_ps(idr4_SSE3, irsq_SSE3);
-
- raj_SSE = _mm_load_ps(gb_radius+j);
- vaj_SSE = _mm_load_ps(vsolv+j);
-
- rvdw_SSE0 = _mm_add_ps(rai_SSE0, raj_SSE);
- rvdw_SSE1 = _mm_add_ps(rai_SSE1, raj_SSE);
- rvdw_SSE2 = _mm_add_ps(rai_SSE2, raj_SSE);
- rvdw_SSE3 = _mm_add_ps(rai_SSE3, raj_SSE);
-
- ratio_SSE0 = _mm_mul_ps(rsq_SSE0, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE0, rvdw_SSE0)));
- ratio_SSE1 = _mm_mul_ps(rsq_SSE1, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE1, rvdw_SSE1)));
- ratio_SSE2 = _mm_mul_ps(rsq_SSE2, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE2, rvdw_SSE2)));
- ratio_SSE3 = _mm_mul_ps(rsq_SSE3, gmx_mm_inv_ps( _mm_mul_ps(rvdw_SSE3, rvdw_SSE3)));
-
- ratio_SSE0 = _mm_min_ps(ratio_SSE0, still_p5inv_SSE);
- ratio_SSE1 = _mm_min_ps(ratio_SSE1, still_p5inv_SSE);
- ratio_SSE2 = _mm_min_ps(ratio_SSE2, still_p5inv_SSE);
- ratio_SSE3 = _mm_min_ps(ratio_SSE3, still_p5inv_SSE);
- theta_SSE0 = _mm_mul_ps(ratio_SSE0, still_pip5_SSE);
- theta_SSE1 = _mm_mul_ps(ratio_SSE1, still_pip5_SSE);
- theta_SSE2 = _mm_mul_ps(ratio_SSE2, still_pip5_SSE);
- theta_SSE3 = _mm_mul_ps(ratio_SSE3, still_pip5_SSE);
- gmx_mm_sincos_ps(theta_SSE0, &sinq_SSE0, &cosq_SSE0);
- gmx_mm_sincos_ps(theta_SSE1, &sinq_SSE1, &cosq_SSE1);
- gmx_mm_sincos_ps(theta_SSE2, &sinq_SSE2, &cosq_SSE2);
- gmx_mm_sincos_ps(theta_SSE3, &sinq_SSE3, &cosq_SSE3);
- term_SSE0 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE0));
- term_SSE1 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE1));
- term_SSE2 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE2));
- term_SSE3 = _mm_mul_ps(half_SSE, _mm_sub_ps(one_SSE, cosq_SSE3));
- ccf_SSE0 = _mm_mul_ps(term_SSE0, term_SSE0);
- ccf_SSE1 = _mm_mul_ps(term_SSE1, term_SSE1);
- ccf_SSE2 = _mm_mul_ps(term_SSE2, term_SSE2);
- ccf_SSE3 = _mm_mul_ps(term_SSE3, term_SSE3);
- dccf_SSE0 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE0),
- _mm_mul_ps(sinq_SSE0, theta_SSE0));
- dccf_SSE1 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE1),
- _mm_mul_ps(sinq_SSE1, theta_SSE1));
- dccf_SSE2 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE2),
- _mm_mul_ps(sinq_SSE2, theta_SSE2));
- dccf_SSE3 = _mm_mul_ps(_mm_mul_ps(two_SSE, term_SSE3),
- _mm_mul_ps(sinq_SSE3, theta_SSE3));
-
- prod_SSE = _mm_mul_ps(still_p4_SSE, vaj_SSE);
- icf4_SSE0 = _mm_mul_ps(ccf_SSE0, idr4_SSE0);
- icf4_SSE1 = _mm_mul_ps(ccf_SSE1, idr4_SSE1);
- icf4_SSE2 = _mm_mul_ps(ccf_SSE2, idr4_SSE2);
- icf4_SSE3 = _mm_mul_ps(ccf_SSE3, idr4_SSE3);
- icf6_SSE0 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE0), dccf_SSE0), idr6_SSE0);
- icf6_SSE1 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE1), dccf_SSE1), idr6_SSE1);
- icf6_SSE2 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE2), dccf_SSE2), idr6_SSE2);
- icf6_SSE3 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four_SSE, ccf_SSE3), dccf_SSE3), idr6_SSE3);
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_mul_ps(prod_ai_SSE0, icf4_SSE0),
- _mm_mul_ps(prod_ai_SSE1, icf4_SSE1),
- _mm_mul_ps(prod_ai_SSE2, icf4_SSE2),
- _mm_mul_ps(prod_ai_SSE3, icf4_SSE3))));
-
- gpi_SSE0 = _mm_add_ps(gpi_SSE0, _mm_mul_ps(prod_SSE, icf4_SSE0));
- gpi_SSE1 = _mm_add_ps(gpi_SSE1, _mm_mul_ps(prod_SSE, icf4_SSE1));
- gpi_SSE2 = _mm_add_ps(gpi_SSE2, _mm_mul_ps(prod_SSE, icf4_SSE2));
- gpi_SSE3 = _mm_add_ps(gpi_SSE3, _mm_mul_ps(prod_SSE, icf4_SSE3));
-
- /* Save ai->aj and aj->ai chain rule terms */
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_SSE, icf6_SSE3));
- dadx += 4;
-
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE0, icf6_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE1, icf6_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE2, icf6_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai_SSE3, icf6_SSE3));
- dadx += 4;
- }
- _MM_TRANSPOSE4_PS(gpi_SSE0, gpi_SSE1, gpi_SSE2, gpi_SSE3);
- gpi_SSE0 = _mm_add_ps(gpi_SSE0, gpi_SSE1);
- gpi_SSE2 = _mm_add_ps(gpi_SSE2, gpi_SSE3);
- gpi_SSE0 = _mm_add_ps(gpi_SSE0, gpi_SSE2);
- _mm_store_ps(work+i, _mm_add_ps(gpi_SSE0, _mm_load_ps(work+i)));
- }
-
- /* In case we have written anything beyond natoms, move it back.
- * Never mind that we leave stuff above natoms; that will not
- * be accessed later in the routine.
- * In principle this should be a move rather than sum, but this
- * way we dont have to worry about even/odd offsets...
- */
- for (i = natoms; i < ni1+1+natoms/2; i++)
- {
- work[i-natoms] += work[i];
- }
-
- /* Parallel summations would go here if ever implemented with DD */
-
- factor = 0.5 * ONE_4PI_EPS0;
- /* Calculate the radii - should we do all atoms, or just our local ones? */
- for (i = 0; i < natoms; i++)
- {
- if (born->use[i] != 0)
- {
- gpi = born->gpol[i]+work[i];
- gpi2 = gpi * gpi;
- born->bRad[i] = factor*gmx_invsqrt(gpi2);
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- return 0;
-}
-
-
-
-int
-genborn_allvsall_calc_hct_obc_radii_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- int gb_algorithm,
- gmx_localtop_t * top,
- real * x,
- t_commrec * cr,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int * mask;
- int * pmask0;
- int * pmask1;
- int * pmask2;
- int * pmask3;
- int * emask0;
- int * emask1;
- int * emask2;
- int * emask3;
- real * gb_radius;
- real * vsolv;
- real * work;
- real tmpsum[4];
- real * x_align;
- real * y_align;
- real * z_align;
- int * jindex;
- real * dadx;
- real * obc_param;
- real rad, min_rad;
- real rai, rai_inv, rai_inv2, sum_ai, sum_ai2, sum_ai3, tsum, tchain;
-
- __m128 ix_SSE0, iy_SSE0, iz_SSE0;
- __m128 ix_SSE1, iy_SSE1, iz_SSE1;
- __m128 ix_SSE2, iy_SSE2, iz_SSE2;
- __m128 ix_SSE3, iy_SSE3, iz_SSE3;
- __m128 gpi_SSE0, rai_SSE0, prod_ai_SSE0;
- __m128 gpi_SSE1, rai_SSE1, prod_ai_SSE1;
- __m128 gpi_SSE2, rai_SSE2, prod_ai_SSE2;
- __m128 gpi_SSE3, rai_SSE3, prod_ai_SSE3;
- __m128 imask_SSE0, jmask_SSE0;
- __m128 imask_SSE1, jmask_SSE1;
- __m128 imask_SSE2, jmask_SSE2;
- __m128 imask_SSE3, jmask_SSE3;
- __m128 jx_SSE, jy_SSE, jz_SSE;
- __m128 dx_SSE0, dy_SSE0, dz_SSE0;
- __m128 dx_SSE1, dy_SSE1, dz_SSE1;
- __m128 dx_SSE2, dy_SSE2, dz_SSE2;
- __m128 dx_SSE3, dy_SSE3, dz_SSE3;
- __m128 rsq_SSE0, rinv_SSE0, irsq_SSE0, idr4_SSE0, idr6_SSE0;
- __m128 rsq_SSE1, rinv_SSE1, irsq_SSE1, idr4_SSE1, idr6_SSE1;
- __m128 rsq_SSE2, rinv_SSE2, irsq_SSE2, idr4_SSE2, idr6_SSE2;
- __m128 rsq_SSE3, rinv_SSE3, irsq_SSE3, idr4_SSE3, idr6_SSE3;
- __m128 raj_SSE, raj_inv_SSE, sk_aj_SSE, sk2_aj_SSE;
- __m128 ccf_SSE0, dccf_SSE0, prod_SSE0;
- __m128 ccf_SSE1, dccf_SSE1, prod_SSE1;
- __m128 ccf_SSE2, dccf_SSE2, prod_SSE2;
- __m128 ccf_SSE3, dccf_SSE3, prod_SSE3;
- __m128 icf4_SSE0, icf6_SSE0;
- __m128 icf4_SSE1, icf6_SSE1;
- __m128 icf4_SSE2, icf6_SSE2;
- __m128 icf4_SSE3, icf6_SSE3;
- __m128 oneeighth_SSE, onefourth_SSE, half_SSE, one_SSE, two_SSE, four_SSE;
- __m128 still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
- __m128 rai_inv_SSE0;
- __m128 rai_inv_SSE1;
- __m128 rai_inv_SSE2;
- __m128 rai_inv_SSE3;
- __m128 sk_ai_SSE0, sk2_ai_SSE0, sum_ai_SSE0;
- __m128 sk_ai_SSE1, sk2_ai_SSE1, sum_ai_SSE1;
- __m128 sk_ai_SSE2, sk2_ai_SSE2, sum_ai_SSE2;
- __m128 sk_ai_SSE3, sk2_ai_SSE3, sum_ai_SSE3;
- __m128 lij_inv_SSE0, sk2_rinv_SSE0;
- __m128 lij_inv_SSE1, sk2_rinv_SSE1;
- __m128 lij_inv_SSE2, sk2_rinv_SSE2;
- __m128 lij_inv_SSE3, sk2_rinv_SSE3;
- __m128 dr_SSE0;
- __m128 dr_SSE1;
- __m128 dr_SSE2;
- __m128 dr_SSE3;
- __m128 t1_SSE0, t2_SSE0, t3_SSE0, t4_SSE0;
- __m128 t1_SSE1, t2_SSE1, t3_SSE1, t4_SSE1;
- __m128 t1_SSE2, t2_SSE2, t3_SSE2, t4_SSE2;
- __m128 t1_SSE3, t2_SSE3, t3_SSE3, t4_SSE3;
- __m128 obc_mask1_SSE0, obc_mask2_SSE0, obc_mask3_SSE0;
- __m128 obc_mask1_SSE1, obc_mask2_SSE1, obc_mask3_SSE1;
- __m128 obc_mask1_SSE2, obc_mask2_SSE2, obc_mask3_SSE2;
- __m128 obc_mask1_SSE3, obc_mask2_SSE3, obc_mask3_SSE3;
- __m128 uij_SSE0, uij2_SSE0, uij3_SSE0;
- __m128 uij_SSE1, uij2_SSE1, uij3_SSE1;
- __m128 uij_SSE2, uij2_SSE2, uij3_SSE2;
- __m128 uij_SSE3, uij2_SSE3, uij3_SSE3;
- __m128 lij_SSE0, lij2_SSE0, lij3_SSE0;
- __m128 lij_SSE1, lij2_SSE1, lij3_SSE1;
- __m128 lij_SSE2, lij2_SSE2, lij3_SSE2;
- __m128 lij_SSE3, lij2_SSE3, lij3_SSE3;
- __m128 dlij_SSE0, diff2_SSE0, logterm_SSE0;
- __m128 dlij_SSE1, diff2_SSE1, logterm_SSE1;
- __m128 dlij_SSE2, diff2_SSE2, logterm_SSE2;
- __m128 dlij_SSE3, diff2_SSE3, logterm_SSE3;
- __m128 doffset_SSE;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
-
- n = 0;
-
- aadata = *((gmx_allvsallgb2_data_t **)paadata);
-
-
- if (aadata == NULL)
- {
- genborn_allvsall_setup(&aadata, top, born, mdatoms, born->gb_doffset,
- egbOBC, TRUE, TRUE, TRUE);
- *((gmx_allvsallgb2_data_t **)paadata) = aadata;
- }
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
-
- gb_radius = aadata->gb_radius;
- work = aadata->work;
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
- obc_param = aadata->workparam;
-
- oneeighth_SSE = _mm_set1_ps(0.125);
- onefourth_SSE = _mm_set1_ps(0.25);
- half_SSE = _mm_set1_ps(0.5);
- one_SSE = _mm_set1_ps(1.0);
- two_SSE = _mm_set1_ps(2.0);
- four_SSE = _mm_set1_ps(4.0);
- doffset_SSE = _mm_set1_ps(born->gb_doffset);
-
- for (i = 0; i < natoms; i++)
- {
- x_align[i] = x[3*i];
- y_align[i] = x[3*i+1];
- z_align[i] = x[3*i+2];
- }
-
- /* Copy again */
- for (i = 0; i < natoms/2+1; i++)
- {
- x_align[natoms+i] = x_align[i];
- y_align[natoms+i] = y_align[i];
- z_align[natoms+i] = z_align[i];
- }
-
- for (i = 0; i < natoms+natoms/2+1; i++)
- {
- work[i] = 0;
- }
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
-
- /* Load i atom data */
- ix_SSE0 = _mm_load1_ps(x_align+i);
- iy_SSE0 = _mm_load1_ps(y_align+i);
- iz_SSE0 = _mm_load1_ps(z_align+i);
- ix_SSE1 = _mm_load1_ps(x_align+i+1);
- iy_SSE1 = _mm_load1_ps(y_align+i+1);
- iz_SSE1 = _mm_load1_ps(z_align+i+1);
- ix_SSE2 = _mm_load1_ps(x_align+i+2);
- iy_SSE2 = _mm_load1_ps(y_align+i+2);
- iz_SSE2 = _mm_load1_ps(z_align+i+2);
- ix_SSE3 = _mm_load1_ps(x_align+i+3);
- iy_SSE3 = _mm_load1_ps(y_align+i+3);
- iz_SSE3 = _mm_load1_ps(z_align+i+3);
-
- rai_SSE0 = _mm_load1_ps(gb_radius+i);
- rai_SSE1 = _mm_load1_ps(gb_radius+i+1);
- rai_SSE2 = _mm_load1_ps(gb_radius+i+2);
- rai_SSE3 = _mm_load1_ps(gb_radius+i+3);
- rai_inv_SSE0 = gmx_mm_inv_ps(rai_SSE0);
- rai_inv_SSE1 = gmx_mm_inv_ps(rai_SSE1);
- rai_inv_SSE2 = gmx_mm_inv_ps(rai_SSE2);
- rai_inv_SSE3 = gmx_mm_inv_ps(rai_SSE3);
-
- sk_ai_SSE0 = _mm_load1_ps(obc_param+i);
- sk_ai_SSE1 = _mm_load1_ps(obc_param+i+1);
- sk_ai_SSE2 = _mm_load1_ps(obc_param+i+2);
- sk_ai_SSE3 = _mm_load1_ps(obc_param+i+3);
- sk2_ai_SSE0 = _mm_mul_ps(sk_ai_SSE0, sk_ai_SSE0);
- sk2_ai_SSE1 = _mm_mul_ps(sk_ai_SSE1, sk_ai_SSE1);
- sk2_ai_SSE2 = _mm_mul_ps(sk_ai_SSE2, sk_ai_SSE2);
- sk2_ai_SSE3 = _mm_mul_ps(sk_ai_SSE3, sk_ai_SSE3);
-
- sum_ai_SSE0 = _mm_setzero_ps();
- sum_ai_SSE1 = _mm_setzero_ps();
- sum_ai_SSE2 = _mm_setzero_ps();
- sum_ai_SSE3 = _mm_setzero_ps();
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj1 = jindex[4*i+1];
- nj2 = jindex[4*i+2];
- nj3 = jindex[4*i+3];
-
- pmask0 = aadata->prologue_mask_gb[i];
- pmask1 = aadata->prologue_mask_gb[i+1];
- pmask2 = aadata->prologue_mask_gb[i+2];
- pmask3 = aadata->prologue_mask_gb[i+3];
- emask0 = aadata->epilogue_mask[i];
- emask1 = aadata->epilogue_mask[i+1];
- emask2 = aadata->epilogue_mask[i+2];
- emask3 = aadata->epilogue_mask[i+3];
-
- imask_SSE0 = _mm_load1_ps((real *)(aadata->imask+i));
- imask_SSE1 = _mm_load1_ps((real *)(aadata->imask+i+1));
- imask_SSE2 = _mm_load1_ps((real *)(aadata->imask+i+2));
- imask_SSE3 = _mm_load1_ps((real *)(aadata->imask+i+3));
-
- /* Prologue part, including exclusion mask */
- for (j = nj0; j < nj1; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_ps((real *)pmask0);
- jmask_SSE1 = _mm_load_ps((real *)pmask1);
- jmask_SSE2 = _mm_load_ps((real *)pmask2);
- jmask_SSE3 = _mm_load_ps((real *)pmask3);
- pmask0 += UNROLLJ;
- pmask1 += UNROLLJ;
- pmask2 += UNROLLJ;
- pmask3 += UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_ps(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_ps(jmask_SSE1, imask_SSE1);
- jmask_SSE2 = _mm_and_ps(jmask_SSE2, imask_SSE2);
- jmask_SSE3 = _mm_and_ps(jmask_SSE3, imask_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, jmask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, jmask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, jmask_SSE3);
-
- dr_SSE0 = _mm_mul_ps(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_ps(rsq_SSE1, rinv_SSE1);
- dr_SSE2 = _mm_mul_ps(rsq_SSE2, rinv_SSE2);
- dr_SSE3 = _mm_mul_ps(rsq_SSE3, rinv_SSE3);
-
- sk_aj_SSE = _mm_load_ps(obc_param+j);
- raj_SSE = _mm_load_ps(gb_radius+j);
- raj_inv_SSE = gmx_mm_inv_ps(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_aj_SSE);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_aj_SSE);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_aj_SSE);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_aj_SSE);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_aj_SSE);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_aj_SSE);
- t3_SSE0 = _mm_sub_ps(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_aj_SSE, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_aj_SSE, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_aj_SSE, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(rai_SSE1, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(rai_SSE2, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(rai_SSE3, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(rai_SSE1, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(rai_SSE2, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(rai_SSE3, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(rai_SSE1, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(rai_SSE2, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(rai_SSE3, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, jmask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, jmask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, jmask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, rai_inv_SSE1));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, rai_inv_SSE2));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, rai_inv_SSE3));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_aj_SSE = _mm_mul_ps(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
-
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
-
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE1, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE2, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE3, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- sum_ai_SSE0 = _mm_add_ps(sum_ai_SSE0, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_ps(sum_ai_SSE1, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- sum_ai_SSE2 = _mm_add_ps(sum_ai_SSE2, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- sum_ai_SSE3 = _mm_add_ps(sum_ai_SSE3, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
-
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_ai_SSE1);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_ai_SSE2);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_ai_SSE3);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_ai_SSE1);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_ai_SSE2);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_ai_SSE3);
- t3_SSE0 = _mm_sub_ps(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_ai_SSE1, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_ai_SSE2, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_ai_SSE3, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(raj_SSE, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(raj_SSE, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(raj_SSE, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(raj_SSE, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(raj_SSE, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(raj_SSE, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(raj_SSE, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(raj_SSE, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(raj_SSE, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, jmask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, jmask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, jmask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, raj_inv_SSE));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, raj_inv_SSE));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, raj_inv_SSE));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_ai_SSE1, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_ai_SSE2, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_ai_SSE3, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_and_ps(t1_SSE0, obc_mask1_SSE0),
- _mm_and_ps(t1_SSE1, obc_mask1_SSE1),
- _mm_and_ps(t1_SSE2, obc_mask1_SSE2),
- _mm_and_ps(t1_SSE3, obc_mask1_SSE3))));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
-
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
-
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
-
- }
-
- /* Main part, no exclusions */
- for (j = nj1; j < nj2; j += UNROLLJ)
- {
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, imask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, imask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, imask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, imask_SSE3);
-
- dr_SSE0 = _mm_mul_ps(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_ps(rsq_SSE1, rinv_SSE1);
- dr_SSE2 = _mm_mul_ps(rsq_SSE2, rinv_SSE2);
- dr_SSE3 = _mm_mul_ps(rsq_SSE3, rinv_SSE3);
-
- sk_aj_SSE = _mm_load_ps(obc_param+j);
- raj_SSE = _mm_load_ps(gb_radius+j);
-
- raj_inv_SSE = gmx_mm_inv_ps(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_aj_SSE);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_aj_SSE);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_aj_SSE);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_aj_SSE);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_aj_SSE);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_aj_SSE);
- t3_SSE0 = _mm_sub_ps(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_aj_SSE, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_aj_SSE, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_aj_SSE, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(rai_SSE1, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(rai_SSE2, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(rai_SSE3, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(rai_SSE1, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(rai_SSE2, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(rai_SSE3, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(rai_SSE1, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(rai_SSE2, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(rai_SSE3, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, imask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, imask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, imask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, imask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, rai_inv_SSE1));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, rai_inv_SSE2));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, rai_inv_SSE3));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_aj_SSE = _mm_mul_ps(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
-
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
-
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE1, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE2, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE3, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- sum_ai_SSE0 = _mm_add_ps(sum_ai_SSE0, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_ps(sum_ai_SSE1, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- sum_ai_SSE2 = _mm_add_ps(sum_ai_SSE2, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- sum_ai_SSE3 = _mm_add_ps(sum_ai_SSE3, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
-
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_ai_SSE1);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_ai_SSE2);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_ai_SSE3);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_ai_SSE1);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_ai_SSE2);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_ai_SSE3);
- t3_SSE0 = _mm_sub_ps(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_ai_SSE1, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_ai_SSE2, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_ai_SSE3, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(raj_SSE, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(raj_SSE, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(raj_SSE, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(raj_SSE, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(raj_SSE, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(raj_SSE, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(raj_SSE, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(raj_SSE, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(raj_SSE, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, imask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, imask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, imask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, imask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, raj_inv_SSE));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, raj_inv_SSE));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, raj_inv_SSE));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_ai_SSE1, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_ai_SSE2, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_ai_SSE3, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_and_ps(t1_SSE0, obc_mask1_SSE0),
- _mm_and_ps(t1_SSE1, obc_mask1_SSE1),
- _mm_and_ps(t1_SSE2, obc_mask1_SSE2),
- _mm_and_ps(t1_SSE3, obc_mask1_SSE3))));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
-
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
-
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
- }
-
- /* Epilogue part, including exclusion mask */
- for (j = nj2; j < nj3; j += UNROLLJ)
- {
- jmask_SSE0 = _mm_load_ps((real *)emask0);
- jmask_SSE1 = _mm_load_ps((real *)emask1);
- jmask_SSE2 = _mm_load_ps((real *)emask2);
- jmask_SSE3 = _mm_load_ps((real *)emask3);
- emask0 += UNROLLJ;
- emask1 += UNROLLJ;
- emask2 += UNROLLJ;
- emask3 += UNROLLJ;
-
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- /* rsq = dx*dx+dy*dy+dz*dz */
- rsq_SSE0 = gmx_mm_calc_rsq_ps(dx_SSE0, dy_SSE0, dz_SSE0);
- rsq_SSE1 = gmx_mm_calc_rsq_ps(dx_SSE1, dy_SSE1, dz_SSE1);
- rsq_SSE2 = gmx_mm_calc_rsq_ps(dx_SSE2, dy_SSE2, dz_SSE2);
- rsq_SSE3 = gmx_mm_calc_rsq_ps(dx_SSE3, dy_SSE3, dz_SSE3);
-
- /* Combine masks */
- jmask_SSE0 = _mm_and_ps(jmask_SSE0, imask_SSE0);
- jmask_SSE1 = _mm_and_ps(jmask_SSE1, imask_SSE1);
- jmask_SSE2 = _mm_and_ps(jmask_SSE2, imask_SSE2);
- jmask_SSE3 = _mm_and_ps(jmask_SSE3, imask_SSE3);
-
- /* Calculate 1/r and 1/r2 */
- rinv_SSE0 = gmx_mm_invsqrt_ps(rsq_SSE0);
- rinv_SSE1 = gmx_mm_invsqrt_ps(rsq_SSE1);
- rinv_SSE2 = gmx_mm_invsqrt_ps(rsq_SSE2);
- rinv_SSE3 = gmx_mm_invsqrt_ps(rsq_SSE3);
-
- /* Apply mask */
- rinv_SSE0 = _mm_and_ps(rinv_SSE0, jmask_SSE0);
- rinv_SSE1 = _mm_and_ps(rinv_SSE1, jmask_SSE1);
- rinv_SSE2 = _mm_and_ps(rinv_SSE2, jmask_SSE2);
- rinv_SSE3 = _mm_and_ps(rinv_SSE3, jmask_SSE3);
-
- dr_SSE0 = _mm_mul_ps(rsq_SSE0, rinv_SSE0);
- dr_SSE1 = _mm_mul_ps(rsq_SSE1, rinv_SSE1);
- dr_SSE2 = _mm_mul_ps(rsq_SSE2, rinv_SSE2);
- dr_SSE3 = _mm_mul_ps(rsq_SSE3, rinv_SSE3);
-
- sk_aj_SSE = _mm_load_ps(obc_param+j);
- raj_SSE = _mm_load_ps(gb_radius+j);
-
- raj_inv_SSE = gmx_mm_inv_ps(raj_SSE);
-
- /* Evaluate influence of atom aj -> ai */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_aj_SSE);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_aj_SSE);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_aj_SSE);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_aj_SSE);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_aj_SSE);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_aj_SSE);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_aj_SSE);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_aj_SSE);
- t3_SSE0 = _mm_sub_ps(sk_aj_SSE, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_aj_SSE, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_aj_SSE, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_aj_SSE, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(rai_SSE0, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(rai_SSE1, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(rai_SSE2, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(rai_SSE3, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(rai_SSE0, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(rai_SSE1, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(rai_SSE2, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(rai_SSE3, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(rai_SSE0, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(rai_SSE1, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(rai_SSE2, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(rai_SSE3, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, jmask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, jmask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, jmask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, rai_inv_SSE0));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, rai_inv_SSE1));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, rai_inv_SSE2));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, rai_inv_SSE3));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_aj_SSE = _mm_mul_ps(sk_aj_SSE, sk_aj_SSE);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_aj_SSE, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
-
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
-
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE0, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE1, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE2, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(rai_inv_SSE3, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- sum_ai_SSE0 = _mm_add_ps(sum_ai_SSE0, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- sum_ai_SSE1 = _mm_add_ps(sum_ai_SSE1, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- sum_ai_SSE2 = _mm_add_ps(sum_ai_SSE2, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- sum_ai_SSE3 = _mm_add_ps(sum_ai_SSE3, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
-
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
-
- /* Evaluate influence of atom ai -> aj */
- t1_SSE0 = _mm_add_ps(dr_SSE0, sk_ai_SSE0);
- t1_SSE1 = _mm_add_ps(dr_SSE1, sk_ai_SSE1);
- t1_SSE2 = _mm_add_ps(dr_SSE2, sk_ai_SSE2);
- t1_SSE3 = _mm_add_ps(dr_SSE3, sk_ai_SSE3);
- t2_SSE0 = _mm_sub_ps(dr_SSE0, sk_ai_SSE0);
- t2_SSE1 = _mm_sub_ps(dr_SSE1, sk_ai_SSE1);
- t2_SSE2 = _mm_sub_ps(dr_SSE2, sk_ai_SSE2);
- t2_SSE3 = _mm_sub_ps(dr_SSE3, sk_ai_SSE3);
- t3_SSE0 = _mm_sub_ps(sk_ai_SSE0, dr_SSE0);
- t3_SSE1 = _mm_sub_ps(sk_ai_SSE1, dr_SSE1);
- t3_SSE2 = _mm_sub_ps(sk_ai_SSE2, dr_SSE2);
- t3_SSE3 = _mm_sub_ps(sk_ai_SSE3, dr_SSE3);
-
- obc_mask1_SSE0 = _mm_cmplt_ps(raj_SSE, t1_SSE0);
- obc_mask1_SSE1 = _mm_cmplt_ps(raj_SSE, t1_SSE1);
- obc_mask1_SSE2 = _mm_cmplt_ps(raj_SSE, t1_SSE2);
- obc_mask1_SSE3 = _mm_cmplt_ps(raj_SSE, t1_SSE3);
- obc_mask2_SSE0 = _mm_cmplt_ps(raj_SSE, t2_SSE0);
- obc_mask2_SSE1 = _mm_cmplt_ps(raj_SSE, t2_SSE1);
- obc_mask2_SSE2 = _mm_cmplt_ps(raj_SSE, t2_SSE2);
- obc_mask2_SSE3 = _mm_cmplt_ps(raj_SSE, t2_SSE3);
- obc_mask3_SSE0 = _mm_cmplt_ps(raj_SSE, t3_SSE0);
- obc_mask3_SSE1 = _mm_cmplt_ps(raj_SSE, t3_SSE1);
- obc_mask3_SSE2 = _mm_cmplt_ps(raj_SSE, t3_SSE2);
- obc_mask3_SSE3 = _mm_cmplt_ps(raj_SSE, t3_SSE3);
- obc_mask1_SSE0 = _mm_and_ps(obc_mask1_SSE0, jmask_SSE0);
- obc_mask1_SSE1 = _mm_and_ps(obc_mask1_SSE1, jmask_SSE1);
- obc_mask1_SSE2 = _mm_and_ps(obc_mask1_SSE2, jmask_SSE2);
- obc_mask1_SSE3 = _mm_and_ps(obc_mask1_SSE3, jmask_SSE3);
-
- uij_SSE0 = gmx_mm_inv_ps(t1_SSE0);
- uij_SSE1 = gmx_mm_inv_ps(t1_SSE1);
- uij_SSE2 = gmx_mm_inv_ps(t1_SSE2);
- uij_SSE3 = gmx_mm_inv_ps(t1_SSE3);
- lij_SSE0 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE0, gmx_mm_inv_ps(t2_SSE0)),
- _mm_andnot_ps(obc_mask2_SSE0, raj_inv_SSE));
- lij_SSE1 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE1, gmx_mm_inv_ps(t2_SSE1)),
- _mm_andnot_ps(obc_mask2_SSE1, raj_inv_SSE));
- lij_SSE2 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE2, gmx_mm_inv_ps(t2_SSE2)),
- _mm_andnot_ps(obc_mask2_SSE2, raj_inv_SSE));
- lij_SSE3 = _mm_or_ps( _mm_and_ps(obc_mask2_SSE3, gmx_mm_inv_ps(t2_SSE3)),
- _mm_andnot_ps(obc_mask2_SSE3, raj_inv_SSE));
- dlij_SSE0 = _mm_and_ps(one_SSE, obc_mask2_SSE0);
- dlij_SSE1 = _mm_and_ps(one_SSE, obc_mask2_SSE1);
- dlij_SSE2 = _mm_and_ps(one_SSE, obc_mask2_SSE2);
- dlij_SSE3 = _mm_and_ps(one_SSE, obc_mask2_SSE3);
-
- uij2_SSE0 = _mm_mul_ps(uij_SSE0, uij_SSE0);
- uij2_SSE1 = _mm_mul_ps(uij_SSE1, uij_SSE1);
- uij2_SSE2 = _mm_mul_ps(uij_SSE2, uij_SSE2);
- uij2_SSE3 = _mm_mul_ps(uij_SSE3, uij_SSE3);
- uij3_SSE0 = _mm_mul_ps(uij2_SSE0, uij_SSE0);
- uij3_SSE1 = _mm_mul_ps(uij2_SSE1, uij_SSE1);
- uij3_SSE2 = _mm_mul_ps(uij2_SSE2, uij_SSE2);
- uij3_SSE3 = _mm_mul_ps(uij2_SSE3, uij_SSE3);
- lij2_SSE0 = _mm_mul_ps(lij_SSE0, lij_SSE0);
- lij2_SSE1 = _mm_mul_ps(lij_SSE1, lij_SSE1);
- lij2_SSE2 = _mm_mul_ps(lij_SSE2, lij_SSE2);
- lij2_SSE3 = _mm_mul_ps(lij_SSE3, lij_SSE3);
- lij3_SSE0 = _mm_mul_ps(lij2_SSE0, lij_SSE0);
- lij3_SSE1 = _mm_mul_ps(lij2_SSE1, lij_SSE1);
- lij3_SSE2 = _mm_mul_ps(lij2_SSE2, lij_SSE2);
- lij3_SSE3 = _mm_mul_ps(lij2_SSE3, lij_SSE3);
-
- diff2_SSE0 = _mm_sub_ps(uij2_SSE0, lij2_SSE0);
- diff2_SSE1 = _mm_sub_ps(uij2_SSE1, lij2_SSE1);
- diff2_SSE2 = _mm_sub_ps(uij2_SSE2, lij2_SSE2);
- diff2_SSE3 = _mm_sub_ps(uij2_SSE3, lij2_SSE3);
- lij_inv_SSE0 = gmx_mm_invsqrt_ps(lij2_SSE0);
- lij_inv_SSE1 = gmx_mm_invsqrt_ps(lij2_SSE1);
- lij_inv_SSE2 = gmx_mm_invsqrt_ps(lij2_SSE2);
- lij_inv_SSE3 = gmx_mm_invsqrt_ps(lij2_SSE3);
- sk2_rinv_SSE0 = _mm_mul_ps(sk2_ai_SSE0, rinv_SSE0);
- sk2_rinv_SSE1 = _mm_mul_ps(sk2_ai_SSE1, rinv_SSE1);
- sk2_rinv_SSE2 = _mm_mul_ps(sk2_ai_SSE2, rinv_SSE2);
- sk2_rinv_SSE3 = _mm_mul_ps(sk2_ai_SSE3, rinv_SSE3);
- prod_SSE0 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE0);
- prod_SSE1 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE1);
- prod_SSE2 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE2);
- prod_SSE3 = _mm_mul_ps(onefourth_SSE, sk2_rinv_SSE3);
-
- logterm_SSE0 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE0, lij_inv_SSE0));
- logterm_SSE1 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE1, lij_inv_SSE1));
- logterm_SSE2 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE2, lij_inv_SSE2));
- logterm_SSE3 = gmx_mm_log_ps(_mm_mul_ps(uij_SSE3, lij_inv_SSE3));
- t1_SSE0 = _mm_sub_ps(lij_SSE0, uij_SSE0);
- t1_SSE1 = _mm_sub_ps(lij_SSE1, uij_SSE1);
- t1_SSE2 = _mm_sub_ps(lij_SSE2, uij_SSE2);
- t1_SSE3 = _mm_sub_ps(lij_SSE3, uij_SSE3);
- t2_SSE0 = _mm_mul_ps(diff2_SSE0,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE0),
- prod_SSE0));
- t2_SSE1 = _mm_mul_ps(diff2_SSE1,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE1),
- prod_SSE1));
- t2_SSE2 = _mm_mul_ps(diff2_SSE2,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE2),
- prod_SSE2));
- t2_SSE3 = _mm_mul_ps(diff2_SSE3,
- _mm_sub_ps(_mm_mul_ps(onefourth_SSE, dr_SSE3),
- prod_SSE3));
- t3_SSE0 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE0, logterm_SSE0));
- t3_SSE1 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE1, logterm_SSE1));
- t3_SSE2 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE2, logterm_SSE2));
- t3_SSE3 = _mm_mul_ps(half_SSE, _mm_mul_ps(rinv_SSE3, logterm_SSE3));
- t1_SSE0 = _mm_add_ps(t1_SSE0, _mm_add_ps(t2_SSE0, t3_SSE0));
- t1_SSE1 = _mm_add_ps(t1_SSE1, _mm_add_ps(t2_SSE1, t3_SSE1));
- t1_SSE2 = _mm_add_ps(t1_SSE2, _mm_add_ps(t2_SSE2, t3_SSE2));
- t1_SSE3 = _mm_add_ps(t1_SSE3, _mm_add_ps(t2_SSE3, t3_SSE3));
- t4_SSE0 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE0));
- t4_SSE1 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE1));
- t4_SSE2 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE2));
- t4_SSE3 = _mm_mul_ps(two_SSE, _mm_sub_ps(raj_inv_SSE, lij_SSE3));
- t4_SSE0 = _mm_and_ps(t4_SSE0, obc_mask3_SSE0);
- t4_SSE1 = _mm_and_ps(t4_SSE1, obc_mask3_SSE1);
- t4_SSE2 = _mm_and_ps(t4_SSE2, obc_mask3_SSE2);
- t4_SSE3 = _mm_and_ps(t4_SSE3, obc_mask3_SSE3);
- t1_SSE0 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE0, t4_SSE0));
- t1_SSE1 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE1, t4_SSE1));
- t1_SSE2 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE2, t4_SSE2));
- t1_SSE3 = _mm_mul_ps(half_SSE, _mm_add_ps(t1_SSE3, t4_SSE3));
-
- _mm_store_ps(work+j, _mm_add_ps(_mm_load_ps(work+j),
- gmx_mm_sum4_ps(_mm_and_ps(t1_SSE0, obc_mask1_SSE0),
- _mm_and_ps(t1_SSE1, obc_mask1_SSE1),
- _mm_and_ps(t1_SSE2, obc_mask1_SSE2),
- _mm_and_ps(t1_SSE3, obc_mask1_SSE3))));
-
- t1_SSE0 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE0),
- _mm_mul_ps(prod_SSE0, lij3_SSE0));
- t1_SSE1 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE1),
- _mm_mul_ps(prod_SSE1, lij3_SSE1));
- t1_SSE2 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE2),
- _mm_mul_ps(prod_SSE2, lij3_SSE2));
- t1_SSE3 = _mm_add_ps(_mm_mul_ps(half_SSE, lij2_SSE3),
- _mm_mul_ps(prod_SSE3, lij3_SSE3));
- t1_SSE0 = _mm_sub_ps(t1_SSE0,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE0, rinv_SSE0),
- _mm_mul_ps(lij3_SSE0, dr_SSE0))));
- t1_SSE1 = _mm_sub_ps(t1_SSE1,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE1, rinv_SSE1),
- _mm_mul_ps(lij3_SSE1, dr_SSE1))));
- t1_SSE2 = _mm_sub_ps(t1_SSE2,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE2, rinv_SSE2),
- _mm_mul_ps(lij3_SSE2, dr_SSE2))));
- t1_SSE3 = _mm_sub_ps(t1_SSE3,
- _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(lij_SSE3, rinv_SSE3),
- _mm_mul_ps(lij3_SSE3, dr_SSE3))));
- t2_SSE0 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE0, rinv_SSE0),
- _mm_mul_ps(uij3_SSE0, dr_SSE0)));
- t2_SSE1 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE1, rinv_SSE1),
- _mm_mul_ps(uij3_SSE1, dr_SSE1)));
- t2_SSE2 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE2, rinv_SSE2),
- _mm_mul_ps(uij3_SSE2, dr_SSE2)));
- t2_SSE3 = _mm_mul_ps(onefourth_SSE,
- _mm_add_ps(_mm_mul_ps(uij_SSE3, rinv_SSE3),
- _mm_mul_ps(uij3_SSE3, dr_SSE3)));
- t2_SSE0 = _mm_sub_ps(t2_SSE0,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE0),
- _mm_mul_ps(prod_SSE0, uij3_SSE0)));
- t2_SSE1 = _mm_sub_ps(t2_SSE1,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE1),
- _mm_mul_ps(prod_SSE1, uij3_SSE1)));
- t2_SSE2 = _mm_sub_ps(t2_SSE2,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE2),
- _mm_mul_ps(prod_SSE2, uij3_SSE2)));
- t2_SSE3 = _mm_sub_ps(t2_SSE3,
- _mm_add_ps(_mm_mul_ps(half_SSE, uij2_SSE3),
- _mm_mul_ps(prod_SSE3, uij3_SSE3)));
-
- t3_SSE0 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE0),
- _mm_mul_ps(rinv_SSE0, rinv_SSE0));
- t3_SSE1 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE1),
- _mm_mul_ps(rinv_SSE1, rinv_SSE1));
- t3_SSE2 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE2),
- _mm_mul_ps(rinv_SSE2, rinv_SSE2));
- t3_SSE3 = _mm_mul_ps(_mm_mul_ps(onefourth_SSE, logterm_SSE3),
- _mm_mul_ps(rinv_SSE3, rinv_SSE3));
-
- t3_SSE0 = _mm_sub_ps(t3_SSE0,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE0, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE0, rinv_SSE0))));
- t3_SSE1 = _mm_sub_ps(t3_SSE1,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE1, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE1, rinv_SSE1))));
- t3_SSE2 = _mm_sub_ps(t3_SSE2,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE2, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE2, rinv_SSE2))));
- t3_SSE3 = _mm_sub_ps(t3_SSE3,
- _mm_mul_ps(_mm_mul_ps(diff2_SSE3, oneeighth_SSE),
- _mm_add_ps(one_SSE,
- _mm_mul_ps(sk2_rinv_SSE3, rinv_SSE3))));
-
-
- t1_SSE0 = _mm_mul_ps(rinv_SSE0,
- _mm_add_ps(_mm_mul_ps(dlij_SSE0, t1_SSE0),
- _mm_add_ps(t2_SSE0, t3_SSE0)));
- t1_SSE1 = _mm_mul_ps(rinv_SSE1,
- _mm_add_ps(_mm_mul_ps(dlij_SSE1, t1_SSE1),
- _mm_add_ps(t2_SSE1, t3_SSE1)));
- t1_SSE2 = _mm_mul_ps(rinv_SSE2,
- _mm_add_ps(_mm_mul_ps(dlij_SSE2, t1_SSE2),
- _mm_add_ps(t2_SSE2, t3_SSE2)));
- t1_SSE3 = _mm_mul_ps(rinv_SSE3,
- _mm_add_ps(_mm_mul_ps(dlij_SSE3, t1_SSE3),
- _mm_add_ps(t2_SSE3, t3_SSE3)));
-
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE0, obc_mask1_SSE0));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE1, obc_mask1_SSE1));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE2, obc_mask1_SSE2));
- dadx += 4;
- _mm_store_ps(dadx, _mm_and_ps(t1_SSE3, obc_mask1_SSE3));
- dadx += 4;
- }
- _MM_TRANSPOSE4_PS(sum_ai_SSE0, sum_ai_SSE1, sum_ai_SSE2, sum_ai_SSE3);
- sum_ai_SSE0 = _mm_add_ps(sum_ai_SSE0, sum_ai_SSE1);
- sum_ai_SSE2 = _mm_add_ps(sum_ai_SSE2, sum_ai_SSE3);
- sum_ai_SSE0 = _mm_add_ps(sum_ai_SSE0, sum_ai_SSE2);
- _mm_store_ps(work+i, _mm_add_ps(sum_ai_SSE0, _mm_load_ps(work+i)));
- }
-
-
- for (i = 0; i < natoms/2+1; i++)
- {
- work[i] += work[natoms+i];
- }
-
- /* Parallel summations would go here if ever implemented with DD */
-
- if (gb_algorithm == egbHCT)
- {
- /* HCT */
- for (i = 0; i < natoms; i++)
- {
- if (born->use[i] != 0)
- {
- rai = top->atomtypes.gb_radius[mdatoms->typeA[i]]-born->gb_doffset;
- sum_ai = 1.0/rai - work[i];
- min_rad = rai + born->gb_doffset;
- rad = 1.0/sum_ai;
-
- born->bRad[i] = rad > min_rad ? rad : min_rad;
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- }
- else
- {
- /* OBC */
-
- /* Calculate the radii */
- for (i = 0; i < natoms; i++)
- {
-
- if (born->use[i] != 0)
- {
- rai = top->atomtypes.gb_radius[mdatoms->typeA[i]];
- rai_inv2 = 1.0/rai;
- rai = rai-born->gb_doffset;
- rai_inv = 1.0/rai;
- sum_ai = rai * work[i];
- sum_ai2 = sum_ai * sum_ai;
- sum_ai3 = sum_ai2 * sum_ai;
-
- tsum = tanh(born->obc_alpha*sum_ai-born->obc_beta*sum_ai2+born->obc_gamma*sum_ai3);
- born->bRad[i] = rai_inv - tsum*rai_inv2;
- born->bRad[i] = 1.0 / born->bRad[i];
-
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
-
- tchain = rai * (born->obc_alpha-2*born->obc_beta*sum_ai+3*born->obc_gamma*sum_ai2);
- born->drobc[i] = (1.0-tsum*tsum)*tchain*rai_inv2;
- }
- }
- }
-
- return 0;
-}
-
-
-
-
-
-
-
-
-int
-genborn_allvsall_calc_chainrule_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- real * x,
- real * f,
- int gb_algorithm,
- void * paadata)
-{
- gmx_allvsallgb2_data_t *aadata;
- int natoms;
- int ni0, ni1;
- int nj0, nj1, nj2, nj3;
- int i, j, k, n;
- int idx;
- int * mask;
- int * pmask0;
- int * emask0;
- int * jindex;
-
- real ix, iy, iz;
- real fix, fiy, fiz;
- real jx, jy, jz;
- real dx, dy, dz;
- real tx, ty, tz;
- real rbai, rbaj, fgb, fgb_ai, rbi;
- real * rb;
- real * dadx;
- real * x_align;
- real * y_align;
- real * z_align;
- real * fx_align;
- real * fy_align;
- real * fz_align;
- real tmpsum[4];
-
- __m128 jmask_SSE0, jmask_SSE1, jmask_SSE2, jmask_SSE3;
- __m128 ix_SSE0, iy_SSE0, iz_SSE0;
- __m128 ix_SSE1, iy_SSE1, iz_SSE1;
- __m128 ix_SSE2, iy_SSE2, iz_SSE2;
- __m128 ix_SSE3, iy_SSE3, iz_SSE3;
- __m128 fix_SSE0, fiy_SSE0, fiz_SSE0;
- __m128 fix_SSE1, fiy_SSE1, fiz_SSE1;
- __m128 fix_SSE2, fiy_SSE2, fiz_SSE2;
- __m128 fix_SSE3, fiy_SSE3, fiz_SSE3;
- __m128 rbai_SSE0, rbai_SSE1, rbai_SSE2, rbai_SSE3;
- __m128 imask_SSE0, imask_SSE1, imask_SSE2, imask_SSE3;
- __m128 jx_SSE, jy_SSE, jz_SSE, rbaj_SSE;
- __m128 dx_SSE0, dy_SSE0, dz_SSE0;
- __m128 dx_SSE1, dy_SSE1, dz_SSE1;
- __m128 dx_SSE2, dy_SSE2, dz_SSE2;
- __m128 dx_SSE3, dy_SSE3, dz_SSE3;
- __m128 fgb_SSE0, fgb_ai_SSE0;
- __m128 fgb_SSE1, fgb_ai_SSE1;
- __m128 fgb_SSE2, fgb_ai_SSE2;
- __m128 fgb_SSE3, fgb_ai_SSE3;
- __m128 tx_SSE0, ty_SSE0, tz_SSE0;
- __m128 tx_SSE1, ty_SSE1, tz_SSE1;
- __m128 tx_SSE2, ty_SSE2, tz_SSE2;
- __m128 tx_SSE3, ty_SSE3, tz_SSE3;
- __m128 t1, t2;
-
- natoms = mdatoms->nr;
- ni0 = 0;
- ni1 = mdatoms->homenr;
- dadx = fr->dadx;
-
- aadata = (gmx_allvsallgb2_data_t *)paadata;
-
- x_align = aadata->x_align;
- y_align = aadata->y_align;
- z_align = aadata->z_align;
- fx_align = aadata->fx_align;
- fy_align = aadata->fy_align;
- fz_align = aadata->fz_align;
-
- jindex = aadata->jindex_gb;
- dadx = fr->dadx;
-
- n = 0;
- rb = aadata->work;
-
- /* Loop to get the proper form for the Born radius term */
- if (gb_algorithm == egbSTILL)
- {
- for (i = 0; i < natoms; i++)
- {
- rbi = born->bRad[i];
- rb[i] = (2 * rbi * rbi * fr->dvda[i])/ONE_4PI_EPS0;
- }
- }
- else if (gb_algorithm == egbHCT)
- {
- for (i = 0; i < natoms; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * fr->dvda[i];
- }
- }
- else if (gb_algorithm == egbOBC)
- {
- for (idx = 0; idx < natoms; idx++)
- {
- rbi = born->bRad[idx];
- rb[idx] = rbi * rbi * born->drobc[idx] * fr->dvda[idx];
- }
- }
-
- for (i = 0; i < 2*natoms; i++)
- {
- fx_align[i] = 0;
- fy_align[i] = 0;
- fz_align[i] = 0;
- }
-
-
- for (i = 0; i < natoms; i++)
- {
- rb[i+natoms] = rb[i];
- }
-
- for (i = ni0; i < ni1; i += UNROLLI)
- {
- /* We assume shifts are NOT used for all-vs-all interactions */
-
- /* Load i atom data */
- ix_SSE0 = _mm_load1_ps(x_align+i);
- iy_SSE0 = _mm_load1_ps(y_align+i);
- iz_SSE0 = _mm_load1_ps(z_align+i);
- ix_SSE1 = _mm_load1_ps(x_align+i+1);
- iy_SSE1 = _mm_load1_ps(y_align+i+1);
- iz_SSE1 = _mm_load1_ps(z_align+i+1);
- ix_SSE2 = _mm_load1_ps(x_align+i+2);
- iy_SSE2 = _mm_load1_ps(y_align+i+2);
- iz_SSE2 = _mm_load1_ps(z_align+i+2);
- ix_SSE3 = _mm_load1_ps(x_align+i+3);
- iy_SSE3 = _mm_load1_ps(y_align+i+3);
- iz_SSE3 = _mm_load1_ps(z_align+i+3);
-
- fix_SSE0 = _mm_setzero_ps();
- fiy_SSE0 = _mm_setzero_ps();
- fiz_SSE0 = _mm_setzero_ps();
- fix_SSE1 = _mm_setzero_ps();
- fiy_SSE1 = _mm_setzero_ps();
- fiz_SSE1 = _mm_setzero_ps();
- fix_SSE2 = _mm_setzero_ps();
- fiy_SSE2 = _mm_setzero_ps();
- fiz_SSE2 = _mm_setzero_ps();
- fix_SSE3 = _mm_setzero_ps();
- fiy_SSE3 = _mm_setzero_ps();
- fiz_SSE3 = _mm_setzero_ps();
-
- rbai_SSE0 = _mm_load1_ps(rb+i);
- rbai_SSE1 = _mm_load1_ps(rb+i+1);
- rbai_SSE2 = _mm_load1_ps(rb+i+2);
- rbai_SSE3 = _mm_load1_ps(rb+i+3);
-
- /* Load limits for loop over neighbors */
- nj0 = jindex[4*i];
- nj3 = jindex[4*i+3];
-
- /* No masks necessary, since the stored chain rule derivatives will be zero in those cases! */
- for (j = nj0; j < nj3; j += UNROLLJ)
- {
- /* load j atom coordinates */
- jx_SSE = _mm_load_ps(x_align+j);
- jy_SSE = _mm_load_ps(y_align+j);
- jz_SSE = _mm_load_ps(z_align+j);
-
- /* Calculate distance */
- dx_SSE0 = _mm_sub_ps(ix_SSE0, jx_SSE);
- dy_SSE0 = _mm_sub_ps(iy_SSE0, jy_SSE);
- dz_SSE0 = _mm_sub_ps(iz_SSE0, jz_SSE);
- dx_SSE1 = _mm_sub_ps(ix_SSE1, jx_SSE);
- dy_SSE1 = _mm_sub_ps(iy_SSE1, jy_SSE);
- dz_SSE1 = _mm_sub_ps(iz_SSE1, jz_SSE);
- dx_SSE2 = _mm_sub_ps(ix_SSE2, jx_SSE);
- dy_SSE2 = _mm_sub_ps(iy_SSE2, jy_SSE);
- dz_SSE2 = _mm_sub_ps(iz_SSE2, jz_SSE);
- dx_SSE3 = _mm_sub_ps(ix_SSE3, jx_SSE);
- dy_SSE3 = _mm_sub_ps(iy_SSE3, jy_SSE);
- dz_SSE3 = _mm_sub_ps(iz_SSE3, jz_SSE);
-
- rbaj_SSE = _mm_load_ps(rb+j);
-
- fgb_SSE0 = _mm_mul_ps(rbai_SSE0, _mm_load_ps(dadx));
- dadx += 4;
- fgb_SSE1 = _mm_mul_ps(rbai_SSE1, _mm_load_ps(dadx));
- dadx += 4;
- fgb_SSE2 = _mm_mul_ps(rbai_SSE2, _mm_load_ps(dadx));
- dadx += 4;
- fgb_SSE3 = _mm_mul_ps(rbai_SSE3, _mm_load_ps(dadx));
- dadx += 4;
-
- fgb_ai_SSE0 = _mm_mul_ps(rbaj_SSE, _mm_load_ps(dadx));
- dadx += 4;
- fgb_ai_SSE1 = _mm_mul_ps(rbaj_SSE, _mm_load_ps(dadx));
- dadx += 4;
- fgb_ai_SSE2 = _mm_mul_ps(rbaj_SSE, _mm_load_ps(dadx));
- dadx += 4;
- fgb_ai_SSE3 = _mm_mul_ps(rbaj_SSE, _mm_load_ps(dadx));
- dadx += 4;
-
- /* Total force between ai and aj is the sum of ai->aj and aj->ai */
- fgb_SSE0 = _mm_add_ps(fgb_SSE0, fgb_ai_SSE0);
- fgb_SSE1 = _mm_add_ps(fgb_SSE1, fgb_ai_SSE1);
- fgb_SSE2 = _mm_add_ps(fgb_SSE2, fgb_ai_SSE2);
- fgb_SSE3 = _mm_add_ps(fgb_SSE3, fgb_ai_SSE3);
-
- /* Calculate temporary vectorial force */
- tx_SSE0 = _mm_mul_ps(fgb_SSE0, dx_SSE0);
- ty_SSE0 = _mm_mul_ps(fgb_SSE0, dy_SSE0);
- tz_SSE0 = _mm_mul_ps(fgb_SSE0, dz_SSE0);
- tx_SSE1 = _mm_mul_ps(fgb_SSE1, dx_SSE1);
- ty_SSE1 = _mm_mul_ps(fgb_SSE1, dy_SSE1);
- tz_SSE1 = _mm_mul_ps(fgb_SSE1, dz_SSE1);
- tx_SSE2 = _mm_mul_ps(fgb_SSE2, dx_SSE2);
- ty_SSE2 = _mm_mul_ps(fgb_SSE2, dy_SSE2);
- tz_SSE2 = _mm_mul_ps(fgb_SSE2, dz_SSE2);
- tx_SSE3 = _mm_mul_ps(fgb_SSE3, dx_SSE3);
- ty_SSE3 = _mm_mul_ps(fgb_SSE3, dy_SSE3);
- tz_SSE3 = _mm_mul_ps(fgb_SSE3, dz_SSE3);
-
- /* Increment i atom force */
- fix_SSE0 = _mm_add_ps(fix_SSE0, tx_SSE0);
- fiy_SSE0 = _mm_add_ps(fiy_SSE0, ty_SSE0);
- fiz_SSE0 = _mm_add_ps(fiz_SSE0, tz_SSE0);
- fix_SSE1 = _mm_add_ps(fix_SSE1, tx_SSE1);
- fiy_SSE1 = _mm_add_ps(fiy_SSE1, ty_SSE1);
- fiz_SSE1 = _mm_add_ps(fiz_SSE1, tz_SSE1);
- fix_SSE2 = _mm_add_ps(fix_SSE2, tx_SSE2);
- fiy_SSE2 = _mm_add_ps(fiy_SSE2, ty_SSE2);
- fiz_SSE2 = _mm_add_ps(fiz_SSE2, tz_SSE2);
- fix_SSE3 = _mm_add_ps(fix_SSE3, tx_SSE3);
- fiy_SSE3 = _mm_add_ps(fiy_SSE3, ty_SSE3);
- fiz_SSE3 = _mm_add_ps(fiz_SSE3, tz_SSE3);
-
- /* Decrement j atom force */
- _mm_store_ps(fx_align+j,
- _mm_sub_ps( _mm_load_ps(fx_align+j), gmx_mm_sum4_ps(tx_SSE0, tx_SSE1, tx_SSE2, tx_SSE3) ));
- _mm_store_ps(fy_align+j,
- _mm_sub_ps( _mm_load_ps(fy_align+j), gmx_mm_sum4_ps(ty_SSE0, ty_SSE1, ty_SSE2, ty_SSE3) ));
- _mm_store_ps(fz_align+j,
- _mm_sub_ps( _mm_load_ps(fz_align+j), gmx_mm_sum4_ps(tz_SSE0, tz_SSE1, tz_SSE2, tz_SSE3) ));
- }
- /* Add i forces to mem and shifted force list */
- _MM_TRANSPOSE4_PS(fix_SSE0, fix_SSE1, fix_SSE2, fix_SSE3);
- fix_SSE0 = _mm_add_ps(fix_SSE0, fix_SSE1);
- fix_SSE2 = _mm_add_ps(fix_SSE2, fix_SSE3);
- fix_SSE0 = _mm_add_ps(fix_SSE0, fix_SSE2);
- _mm_store_ps(fx_align+i, _mm_add_ps(fix_SSE0, _mm_load_ps(fx_align+i)));
-
- _MM_TRANSPOSE4_PS(fiy_SSE0, fiy_SSE1, fiy_SSE2, fiy_SSE3);
- fiy_SSE0 = _mm_add_ps(fiy_SSE0, fiy_SSE1);
- fiy_SSE2 = _mm_add_ps(fiy_SSE2, fiy_SSE3);
- fiy_SSE0 = _mm_add_ps(fiy_SSE0, fiy_SSE2);
- _mm_store_ps(fy_align+i, _mm_add_ps(fiy_SSE0, _mm_load_ps(fy_align+i)));
-
- _MM_TRANSPOSE4_PS(fiz_SSE0, fiz_SSE1, fiz_SSE2, fiz_SSE3);
- fiz_SSE0 = _mm_add_ps(fiz_SSE0, fiz_SSE1);
- fiz_SSE2 = _mm_add_ps(fiz_SSE2, fiz_SSE3);
- fiz_SSE0 = _mm_add_ps(fiz_SSE0, fiz_SSE2);
- _mm_store_ps(fz_align+i, _mm_add_ps(fiz_SSE0, _mm_load_ps(fz_align+i)));
- }
-
- for (i = 0; i < natoms; i++)
- {
- f[3*i] += fx_align[i] + fx_align[natoms+i];
- f[3*i+1] += fy_align[i] + fy_align[natoms+i];
- f[3*i+2] += fz_align[i] + fz_align[natoms+i];
- }
-
- return 0;
-}
-
-#else
-/* dummy variable when not using SSE */
-int genborn_allvsall_sse2_single_dummy;
-
-
-#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2010,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef _GENBORN_ALLVSALL_SSE2_SINGLE_H
-#define _GENBORN_ALLVSALL_SSE2_SINGLE_H
-
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/legacyheaders/types/simple.h"
-
-int
-genborn_allvsall_calc_still_radii_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- gmx_localtop_t * top,
- real * x,
- t_commrec * cr,
- void * work);
-
-int
-genborn_allvsall_calc_hct_obc_radii_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- int gb_algorithm,
- gmx_localtop_t * top,
- real * x,
- t_commrec * cr,
- void * work);
-
-int
-genborn_allvsall_calc_chainrule_sse2_single(t_forcerec * fr,
- t_mdatoms * mdatoms,
- gmx_genborn_t * born,
- real * x,
- real * f,
- int gb_algorithm,
- void * work);
-
-#endif
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "gromacs/domdec/domdec.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/legacyheaders/genborn.h"
-#include "gromacs/legacyheaders/names.h"
-#include "gromacs/legacyheaders/network.h"
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/math/units.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/gmxmpi.h"
-#include "gromacs/utility/smalloc.h"
-
-/* Only compile this file if SSE2 intrinsics are available */
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
-#include "genborn_sse2_double.h"
-
-#include <emmintrin.h>
-#include <gmx_sse2_double.h>
-
-int
-calc_gb_rad_still_sse2_double(t_commrec *cr, t_forcerec *fr,
- int natoms, gmx_localtop_t *top,
- double *x, t_nblist *nl,
- gmx_genborn_t *born)
-{
- int i, k, n, ii, is3, ii3, nj0, nj1, offset;
- int jnrA, jnrB, j3A, j3B;
- int *mdtype;
- double shX, shY, shZ;
- int *jjnr;
- double *shiftvec;
-
- double gpi_ai, gpi2;
- double factor;
- double *gb_radius;
- double *vsolv;
- double *work;
- double *dadx;
-
- __m128d ix, iy, iz;
- __m128d jx, jy, jz;
- __m128d dx, dy, dz;
- __m128d tx, ty, tz;
- __m128d rsq, rinv, rinv2, rinv4, rinv6;
- __m128d ratio, gpi, rai, raj, vai, vaj, rvdw;
- __m128d ccf, dccf, theta, cosq, term, sinq, res, prod, prod_ai, tmp;
- __m128d mask, icf4, icf6, mask_cmp;
-
- const __m128d half = _mm_set1_pd(0.5);
- const __m128d three = _mm_set1_pd(3.0);
- const __m128d one = _mm_set1_pd(1.0);
- const __m128d two = _mm_set1_pd(2.0);
- const __m128d zero = _mm_set1_pd(0.0);
- const __m128d four = _mm_set1_pd(4.0);
-
- const __m128d still_p5inv = _mm_set1_pd(STILL_P5INV);
- const __m128d still_pip5 = _mm_set1_pd(STILL_PIP5);
- const __m128d still_p4 = _mm_set1_pd(STILL_P4);
-
- factor = 0.5 * ONE_4PI_EPS0;
-
- gb_radius = born->gb_radius;
- vsolv = born->vsolv;
- work = born->gpol_still_work;
- jjnr = nl->jjnr;
- shiftvec = fr->shift_vec[0];
- dadx = fr->dadx;
-
- jnrA = jnrB = 0;
- jx = _mm_setzero_pd();
- jy = _mm_setzero_pd();
- jz = _mm_setzero_pd();
-
- n = 0;
-
- for (i = 0; i < natoms; i++)
- {
- work[i] = 0;
- }
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_pd(shX+x[ii3+0]);
- iy = _mm_set1_pd(shY+x[ii3+1]);
- iz = _mm_set1_pd(shZ+x[ii3+2]);
-
-
- /* Polarization energy for atom ai */
- gpi = _mm_setzero_pd();
-
- rai = _mm_load1_pd(gb_radius+ii);
- prod_ai = _mm_set1_pd(STILL_P4*vsolv[ii]);
-
- for (k = nj0; k < nj1-1; k += 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(x+j3A, x+j3B, jx, jy, jz);
-
- GMX_MM_LOAD_2VALUES_PD(gb_radius+jnrA, gb_radius+jnrB, raj);
- GMX_MM_LOAD_2VALUES_PD(vsolv+jnrA, vsolv+jnrB, vaj);
-
- dx = _mm_sub_pd(ix, jx);
- dy = _mm_sub_pd(iy, jy);
- dz = _mm_sub_pd(iz, jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx, dy, dz);
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinv2 = _mm_mul_pd(rinv, rinv);
- rinv4 = _mm_mul_pd(rinv2, rinv2);
- rinv6 = _mm_mul_pd(rinv4, rinv2);
-
- rvdw = _mm_add_pd(rai, raj);
- ratio = _mm_mul_pd(rsq, gmx_mm_inv_pd( _mm_mul_pd(rvdw, rvdw)));
-
- mask_cmp = _mm_cmple_pd(ratio, still_p5inv);
-
- /* gmx_mm_sincos_pd() is quite expensive, so avoid calculating it if we can! */
- if (0 == _mm_movemask_pd(mask_cmp) )
- {
- /* if ratio>still_p5inv for ALL elements */
- ccf = one;
- dccf = _mm_setzero_pd();
- }
- else
- {
- ratio = _mm_min_pd(ratio, still_p5inv);
- theta = _mm_mul_pd(ratio, still_pip5);
- gmx_mm_sincos_pd(theta, &sinq, &cosq);
- term = _mm_mul_pd(half, _mm_sub_pd(one, cosq));
- ccf = _mm_mul_pd(term, term);
- dccf = _mm_mul_pd(_mm_mul_pd(two, term),
- _mm_mul_pd(sinq, theta));
- }
-
- prod = _mm_mul_pd(still_p4, vaj);
- icf4 = _mm_mul_pd(ccf, rinv4);
- icf6 = _mm_mul_pd( _mm_sub_pd( _mm_mul_pd(four, ccf), dccf), rinv6);
-
- GMX_MM_INCREMENT_2VALUES_PD(work+jnrA, work+jnrB, _mm_mul_pd(prod_ai, icf4));
-
- gpi = _mm_add_pd(gpi, _mm_mul_pd(prod, icf4) );
-
- _mm_store_pd(dadx, _mm_mul_pd(prod, icf6));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai, icf6));
- dadx += 2;
- }
-
- if (k < nj1)
- {
- jnrA = jjnr[k];
-
- j3A = 3*jnrA;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(x+j3A, jx, jy, jz);
-
- GMX_MM_LOAD_1VALUE_PD(gb_radius+jnrA, raj);
- GMX_MM_LOAD_1VALUE_PD(vsolv+jnrA, vaj);
-
- dx = _mm_sub_sd(ix, jx);
- dy = _mm_sub_sd(iy, jy);
- dz = _mm_sub_sd(iz, jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx, dy, dz);
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinv2 = _mm_mul_sd(rinv, rinv);
- rinv4 = _mm_mul_sd(rinv2, rinv2);
- rinv6 = _mm_mul_sd(rinv4, rinv2);
-
- rvdw = _mm_add_sd(rai, raj);
- ratio = _mm_mul_sd(rsq, gmx_mm_inv_pd( _mm_mul_pd(rvdw, rvdw)));
-
- mask_cmp = _mm_cmple_sd(ratio, still_p5inv);
-
- /* gmx_mm_sincos_pd() is quite expensive, so avoid calculating it if we can! */
- if (0 == _mm_movemask_pd(mask_cmp) )
- {
- /* if ratio>still_p5inv for ALL elements */
- ccf = one;
- dccf = _mm_setzero_pd();
- }
- else
- {
- ratio = _mm_min_sd(ratio, still_p5inv);
- theta = _mm_mul_sd(ratio, still_pip5);
- gmx_mm_sincos_pd(theta, &sinq, &cosq);
- term = _mm_mul_sd(half, _mm_sub_sd(one, cosq));
- ccf = _mm_mul_sd(term, term);
- dccf = _mm_mul_sd(_mm_mul_sd(two, term),
- _mm_mul_sd(sinq, theta));
- }
-
- prod = _mm_mul_sd(still_p4, vaj);
- icf4 = _mm_mul_sd(ccf, rinv4);
- icf6 = _mm_mul_sd( _mm_sub_sd( _mm_mul_sd(four, ccf), dccf), rinv6);
-
- GMX_MM_INCREMENT_1VALUE_PD(work+jnrA, _mm_mul_sd(prod_ai, icf4));
-
- gpi = _mm_add_sd(gpi, _mm_mul_sd(prod, icf4) );
-
- _mm_store_pd(dadx, _mm_mul_pd(prod, icf6));
- dadx += 2;
- _mm_store_pd(dadx, _mm_mul_pd(prod_ai, icf6));
- dadx += 2;
- }
- gmx_mm_update_1pot_pd(gpi, work+ii);
- }
-
- /* Sum up the polarization energy from other nodes */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_sum_real(cr->dd, work);
- }
-
- /* Compute the radii */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- gpi_ai = born->gpol[i] + work[i]; /* add gpi to the initial pol energy gpi_ai*/
- gpi2 = gpi_ai * gpi_ai;
- born->bRad[i] = factor*gmx_invsqrt(gpi2);
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- /* Extra (local) communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- }
-
- return 0;
-}
-
-
-int
-calc_gb_rad_hct_obc_sse2_double(t_commrec *cr, t_forcerec * fr, int natoms, gmx_localtop_t *top,
- double *x, t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, int gb_algorithm)
-{
- int i, ai, k, n, ii, ii3, is3, nj0, nj1, at0, at1, offset;
- int jnrA, jnrB;
- int j3A, j3B;
- double shX, shY, shZ;
- double rr, rr_inv, rr_inv2, sum_tmp, sum, sum2, sum3, gbr;
- double sum_ai2, sum_ai3, tsum, tchain, doffset;
- double *obc_param;
- double *gb_radius;
- double *work;
- int * jjnr;
- double *dadx;
- double *shiftvec;
- double min_rad, rad;
-
- __m128d ix, iy, iz, jx, jy, jz;
- __m128d dx, dy, dz, t1, t2, t3, t4;
- __m128d rsq, rinv, r;
- __m128d rai, rai_inv, raj, raj_inv, rai_inv2, sk, sk2, lij, dlij, duij;
- __m128d uij, lij2, uij2, lij3, uij3, diff2;
- __m128d lij_inv, sk2_inv, prod, log_term, tmp, tmp_sum;
- __m128d sum_ai, tmp_ai, sk_ai, sk_aj, sk2_ai, sk2_aj, sk2_rinv;
- __m128d dadx1, dadx2;
- __m128d logterm;
- __m128d mask;
- __m128d obc_mask1, obc_mask2, obc_mask3;
-
- __m128d oneeighth = _mm_set1_pd(0.125);
- __m128d onefourth = _mm_set1_pd(0.25);
-
- const __m128d half = _mm_set1_pd(0.5);
- const __m128d three = _mm_set1_pd(3.0);
- const __m128d one = _mm_set1_pd(1.0);
- const __m128d two = _mm_set1_pd(2.0);
- const __m128d zero = _mm_set1_pd(0.0);
- const __m128d neg = _mm_set1_pd(-1.0);
-
- /* Set the dielectric offset */
- doffset = born->gb_doffset;
- gb_radius = born->gb_radius;
- obc_param = born->param;
- work = born->gpol_hct_work;
- jjnr = nl->jjnr;
- dadx = fr->dadx;
- shiftvec = fr->shift_vec[0];
-
- jx = _mm_setzero_pd();
- jy = _mm_setzero_pd();
- jz = _mm_setzero_pd();
-
- jnrA = jnrB = 0;
-
- for (i = 0; i < born->nr; i++)
- {
- work[i] = 0;
- }
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_pd(shX+x[ii3+0]);
- iy = _mm_set1_pd(shY+x[ii3+1]);
- iz = _mm_set1_pd(shZ+x[ii3+2]);
-
- rai = _mm_load1_pd(gb_radius+ii);
- rai_inv = gmx_mm_inv_pd(rai);
-
- sum_ai = _mm_setzero_pd();
-
- sk_ai = _mm_load1_pd(born->param+ii);
- sk2_ai = _mm_mul_pd(sk_ai, sk_ai);
-
- for (k = nj0; k < nj1-1; k += 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(x+j3A, x+j3B, jx, jy, jz);
- GMX_MM_LOAD_2VALUES_PD(gb_radius+jnrA, gb_radius+jnrB, raj);
- GMX_MM_LOAD_2VALUES_PD(obc_param+jnrA, obc_param+jnrB, sk_aj);
-
- dx = _mm_sub_pd(ix, jx);
- dy = _mm_sub_pd(iy, jy);
- dz = _mm_sub_pd(iz, jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx, dy, dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- r = _mm_mul_pd(rsq, rinv);
-
- /* Compute raj_inv aj1-4 */
- raj_inv = gmx_mm_inv_pd(raj);
-
- /* Evaluate influence of atom aj -> ai */
- t1 = _mm_add_pd(r, sk_aj);
- t2 = _mm_sub_pd(r, sk_aj);
- t3 = _mm_sub_pd(sk_aj, r);
- obc_mask1 = _mm_cmplt_pd(rai, t1);
- obc_mask2 = _mm_cmplt_pd(rai, t2);
- obc_mask3 = _mm_cmplt_pd(rai, t3);
-
- uij = gmx_mm_inv_pd(t1);
- lij = _mm_or_pd( _mm_and_pd(obc_mask2, gmx_mm_inv_pd(t2)),
- _mm_andnot_pd(obc_mask2, rai_inv));
- dlij = _mm_and_pd(one, obc_mask2);
- uij2 = _mm_mul_pd(uij, uij);
- uij3 = _mm_mul_pd(uij2, uij);
- lij2 = _mm_mul_pd(lij, lij);
- lij3 = _mm_mul_pd(lij2, lij);
-
- diff2 = _mm_sub_pd(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_pd(lij2);
- sk2_aj = _mm_mul_pd(sk_aj, sk_aj);
- sk2_rinv = _mm_mul_pd(sk2_aj, rinv);
- prod = _mm_mul_pd(onefourth, sk2_rinv);
-
- logterm = gmx_mm_log_pd(_mm_mul_pd(uij, lij_inv));
-
- t1 = _mm_sub_pd(lij, uij);
- t2 = _mm_mul_pd(diff2,
- _mm_sub_pd(_mm_mul_pd(onefourth, r),
- prod));
- t3 = _mm_mul_pd(half, _mm_mul_pd(rinv, logterm));
- t1 = _mm_add_pd(t1, _mm_add_pd(t2, t3));
- t4 = _mm_mul_pd(two, _mm_sub_pd(rai_inv, lij));
- t4 = _mm_and_pd(t4, obc_mask3);
- t1 = _mm_mul_pd(half, _mm_add_pd(t1, t4));
-
- sum_ai = _mm_add_pd(sum_ai, _mm_and_pd(t1, obc_mask1) );
-
- t1 = _mm_add_pd(_mm_mul_pd(half, lij2),
- _mm_mul_pd(prod, lij3));
- t1 = _mm_sub_pd(t1,
- _mm_mul_pd(onefourth,
- _mm_add_pd(_mm_mul_pd(lij, rinv),
- _mm_mul_pd(lij3, r))));
- t2 = _mm_mul_pd(onefourth,
- _mm_add_pd(_mm_mul_pd(uij, rinv),
- _mm_mul_pd(uij3, r)));
- t2 = _mm_sub_pd(t2,
- _mm_add_pd(_mm_mul_pd(half, uij2),
- _mm_mul_pd(prod, uij3)));
- t3 = _mm_mul_pd(_mm_mul_pd(onefourth, logterm),
- _mm_mul_pd(rinv, rinv));
- t3 = _mm_sub_pd(t3,
- _mm_mul_pd(_mm_mul_pd(diff2, oneeighth),
- _mm_add_pd(one,
- _mm_mul_pd(sk2_rinv, rinv))));
- t1 = _mm_mul_pd(rinv,
- _mm_add_pd(_mm_mul_pd(dlij, t1),
- _mm_add_pd(t2, t3)));
-
- dadx1 = _mm_and_pd(t1, obc_mask1);
-
- /* Evaluate influence of atom ai -> aj */
- t1 = _mm_add_pd(r, sk_ai);
- t2 = _mm_sub_pd(r, sk_ai);
- t3 = _mm_sub_pd(sk_ai, r);
- obc_mask1 = _mm_cmplt_pd(raj, t1);
- obc_mask2 = _mm_cmplt_pd(raj, t2);
- obc_mask3 = _mm_cmplt_pd(raj, t3);
-
- uij = gmx_mm_inv_pd(t1);
- lij = _mm_or_pd( _mm_and_pd(obc_mask2, gmx_mm_inv_pd(t2)),
- _mm_andnot_pd(obc_mask2, raj_inv));
- dlij = _mm_and_pd(one, obc_mask2);
- uij2 = _mm_mul_pd(uij, uij);
- uij3 = _mm_mul_pd(uij2, uij);
- lij2 = _mm_mul_pd(lij, lij);
- lij3 = _mm_mul_pd(lij2, lij);
-
- diff2 = _mm_sub_pd(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_pd(lij2);
- sk2_rinv = _mm_mul_pd(sk2_ai, rinv);
- prod = _mm_mul_pd(onefourth, sk2_rinv);
-
- logterm = gmx_mm_log_pd(_mm_mul_pd(uij, lij_inv));
-
- t1 = _mm_sub_pd(lij, uij);
- t2 = _mm_mul_pd(diff2,
- _mm_sub_pd(_mm_mul_pd(onefourth, r),
- prod));
- t3 = _mm_mul_pd(half, _mm_mul_pd(rinv, logterm));
- t1 = _mm_add_pd(t1, _mm_add_pd(t2, t3));
- t4 = _mm_mul_pd(two, _mm_sub_pd(raj_inv, lij));
- t4 = _mm_and_pd(t4, obc_mask3);
- t1 = _mm_mul_pd(half, _mm_add_pd(t1, t4));
-
- GMX_MM_INCREMENT_2VALUES_PD(work+jnrA, work+jnrB, _mm_and_pd(t1, obc_mask1));
-
- t1 = _mm_add_pd(_mm_mul_pd(half, lij2),
- _mm_mul_pd(prod, lij3));
- t1 = _mm_sub_pd(t1,
- _mm_mul_pd(onefourth,
- _mm_add_pd(_mm_mul_pd(lij, rinv),
- _mm_mul_pd(lij3, r))));
- t2 = _mm_mul_pd(onefourth,
- _mm_add_pd(_mm_mul_pd(uij, rinv),
- _mm_mul_pd(uij3, r)));
- t2 = _mm_sub_pd(t2,
- _mm_add_pd(_mm_mul_pd(half, uij2),
- _mm_mul_pd(prod, uij3)));
- t3 = _mm_mul_pd(_mm_mul_pd(onefourth, logterm),
- _mm_mul_pd(rinv, rinv));
- t3 = _mm_sub_pd(t3,
- _mm_mul_pd(_mm_mul_pd(diff2, oneeighth),
- _mm_add_pd(one,
- _mm_mul_pd(sk2_rinv, rinv))));
- t1 = _mm_mul_pd(rinv,
- _mm_add_pd(_mm_mul_pd(dlij, t1),
- _mm_add_pd(t2, t3)));
-
- dadx2 = _mm_and_pd(t1, obc_mask1);
-
- _mm_store_pd(dadx, dadx1);
- dadx += 2;
- _mm_store_pd(dadx, dadx2);
- dadx += 2;
- } /* end normal inner loop */
-
- if (k < nj1)
- {
- jnrA = jjnr[k];
-
- j3A = 3*jnrA;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(x+j3A, jx, jy, jz);
- GMX_MM_LOAD_1VALUE_PD(gb_radius+jnrA, raj);
- GMX_MM_LOAD_1VALUE_PD(obc_param+jnrA, sk_aj);
-
- dx = _mm_sub_sd(ix, jx);
- dy = _mm_sub_sd(iy, jy);
- dz = _mm_sub_sd(iz, jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx, dy, dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- r = _mm_mul_sd(rsq, rinv);
-
- /* Compute raj_inv aj1-4 */
- raj_inv = gmx_mm_inv_pd(raj);
-
- /* Evaluate influence of atom aj -> ai */
- t1 = _mm_add_sd(r, sk_aj);
- t2 = _mm_sub_sd(r, sk_aj);
- t3 = _mm_sub_sd(sk_aj, r);
- obc_mask1 = _mm_cmplt_sd(rai, t1);
- obc_mask2 = _mm_cmplt_sd(rai, t2);
- obc_mask3 = _mm_cmplt_sd(rai, t3);
-
- uij = gmx_mm_inv_pd(t1);
- lij = _mm_or_pd(_mm_and_pd(obc_mask2, gmx_mm_inv_pd(t2)),
- _mm_andnot_pd(obc_mask2, rai_inv));
- dlij = _mm_and_pd(one, obc_mask2);
- uij2 = _mm_mul_sd(uij, uij);
- uij3 = _mm_mul_sd(uij2, uij);
- lij2 = _mm_mul_sd(lij, lij);
- lij3 = _mm_mul_sd(lij2, lij);
-
- diff2 = _mm_sub_sd(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_pd(lij2);
- sk2_aj = _mm_mul_sd(sk_aj, sk_aj);
- sk2_rinv = _mm_mul_sd(sk2_aj, rinv);
- prod = _mm_mul_sd(onefourth, sk2_rinv);
-
- logterm = gmx_mm_log_pd(_mm_mul_sd(uij, lij_inv));
-
- t1 = _mm_sub_sd(lij, uij);
- t2 = _mm_mul_sd(diff2,
- _mm_sub_sd(_mm_mul_pd(onefourth, r),
- prod));
- t3 = _mm_mul_sd(half, _mm_mul_sd(rinv, logterm));
- t1 = _mm_add_sd(t1, _mm_add_sd(t2, t3));
- t4 = _mm_mul_sd(two, _mm_sub_sd(rai_inv, lij));
- t4 = _mm_and_pd(t4, obc_mask3);
- t1 = _mm_mul_sd(half, _mm_add_sd(t1, t4));
-
- sum_ai = _mm_add_sd(sum_ai, _mm_and_pd(t1, obc_mask1) );
-
- t1 = _mm_add_sd(_mm_mul_sd(half, lij2),
- _mm_mul_sd(prod, lij3));
- t1 = _mm_sub_sd(t1,
- _mm_mul_sd(onefourth,
- _mm_add_sd(_mm_mul_sd(lij, rinv),
- _mm_mul_sd(lij3, r))));
- t2 = _mm_mul_sd(onefourth,
- _mm_add_sd(_mm_mul_sd(uij, rinv),
- _mm_mul_sd(uij3, r)));
- t2 = _mm_sub_sd(t2,
- _mm_add_sd(_mm_mul_sd(half, uij2),
- _mm_mul_sd(prod, uij3)));
- t3 = _mm_mul_sd(_mm_mul_sd(onefourth, logterm),
- _mm_mul_sd(rinv, rinv));
- t3 = _mm_sub_sd(t3,
- _mm_mul_sd(_mm_mul_sd(diff2, oneeighth),
- _mm_add_sd(one,
- _mm_mul_sd(sk2_rinv, rinv))));
- t1 = _mm_mul_sd(rinv,
- _mm_add_sd(_mm_mul_sd(dlij, t1),
- _mm_add_pd(t2, t3)));
-
- dadx1 = _mm_and_pd(t1, obc_mask1);
-
- /* Evaluate influence of atom ai -> aj */
- t1 = _mm_add_sd(r, sk_ai);
- t2 = _mm_sub_sd(r, sk_ai);
- t3 = _mm_sub_sd(sk_ai, r);
- obc_mask1 = _mm_cmplt_sd(raj, t1);
- obc_mask2 = _mm_cmplt_sd(raj, t2);
- obc_mask3 = _mm_cmplt_sd(raj, t3);
-
- uij = gmx_mm_inv_pd(t1);
- lij = _mm_or_pd( _mm_and_pd(obc_mask2, gmx_mm_inv_pd(t2)),
- _mm_andnot_pd(obc_mask2, raj_inv));
- dlij = _mm_and_pd(one, obc_mask2);
- uij2 = _mm_mul_sd(uij, uij);
- uij3 = _mm_mul_sd(uij2, uij);
- lij2 = _mm_mul_sd(lij, lij);
- lij3 = _mm_mul_sd(lij2, lij);
-
- diff2 = _mm_sub_sd(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_pd(lij2);
- sk2_rinv = _mm_mul_sd(sk2_ai, rinv);
- prod = _mm_mul_sd(onefourth, sk2_rinv);
-
- logterm = gmx_mm_log_pd(_mm_mul_sd(uij, lij_inv));
-
- t1 = _mm_sub_sd(lij, uij);
- t2 = _mm_mul_sd(diff2,
- _mm_sub_sd(_mm_mul_sd(onefourth, r),
- prod));
- t3 = _mm_mul_sd(half, _mm_mul_sd(rinv, logterm));
- t1 = _mm_add_sd(t1, _mm_add_sd(t2, t3));
- t4 = _mm_mul_sd(two, _mm_sub_sd(raj_inv, lij));
- t4 = _mm_and_pd(t4, obc_mask3);
- t1 = _mm_mul_sd(half, _mm_add_sd(t1, t4));
-
- GMX_MM_INCREMENT_1VALUE_PD(work+jnrA, _mm_and_pd(t1, obc_mask1));
-
- t1 = _mm_add_sd(_mm_mul_sd(half, lij2),
- _mm_mul_sd(prod, lij3));
- t1 = _mm_sub_sd(t1,
- _mm_mul_sd(onefourth,
- _mm_add_sd(_mm_mul_sd(lij, rinv),
- _mm_mul_sd(lij3, r))));
- t2 = _mm_mul_sd(onefourth,
- _mm_add_sd(_mm_mul_sd(uij, rinv),
- _mm_mul_sd(uij3, r)));
- t2 = _mm_sub_sd(t2,
- _mm_add_sd(_mm_mul_sd(half, uij2),
- _mm_mul_sd(prod, uij3)));
- t3 = _mm_mul_sd(_mm_mul_sd(onefourth, logterm),
- _mm_mul_sd(rinv, rinv));
- t3 = _mm_sub_sd(t3,
- _mm_mul_sd(_mm_mul_sd(diff2, oneeighth),
- _mm_add_sd(one,
- _mm_mul_sd(sk2_rinv, rinv))));
- t1 = _mm_mul_sd(rinv,
- _mm_add_sd(_mm_mul_sd(dlij, t1),
- _mm_add_sd(t2, t3)));
-
- dadx2 = _mm_and_pd(t1, obc_mask1);
-
- _mm_store_pd(dadx, dadx1);
- dadx += 2;
- _mm_store_pd(dadx, dadx2);
- dadx += 2;
- }
- gmx_mm_update_1pot_pd(sum_ai, work+ii);
-
- }
-
- /* Parallel summations */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_sum_real(cr->dd, work);
- }
-
- if (gb_algorithm == egbHCT)
- {
- /* HCT */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- rr = top->atomtypes.gb_radius[md->typeA[i]]-doffset;
- sum = 1.0/rr - work[i];
- min_rad = rr + doffset;
- rad = 1.0/sum;
-
- born->bRad[i] = rad > min_rad ? rad : min_rad;
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- /* Extra communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- }
- }
- else
- {
- /* OBC */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- rr = top->atomtypes.gb_radius[md->typeA[i]];
- rr_inv2 = 1.0/rr;
- rr = rr-doffset;
- rr_inv = 1.0/rr;
- sum = rr * work[i];
- sum2 = sum * sum;
- sum3 = sum2 * sum;
-
- tsum = tanh(born->obc_alpha*sum-born->obc_beta*sum2+born->obc_gamma*sum3);
- born->bRad[i] = rr_inv - tsum*rr_inv2;
- born->bRad[i] = 1.0 / born->bRad[i];
-
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
-
- tchain = rr * (born->obc_alpha-2*born->obc_beta*sum+3*born->obc_gamma*sum2);
- born->drobc[i] = (1.0-tsum*tsum)*tchain*rr_inv2;
- }
- }
- /* Extra (local) communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- dd_atom_spread_real(cr->dd, born->drobc);
- }
- }
-
-
-
- return 0;
-}
-
-
-int
-calc_gb_chainrule_sse2_double(int natoms, t_nblist *nl, double *dadx, double *dvda,
- double *x, double *f, double *fshift, double *shiftvec,
- int gb_algorithm, gmx_genborn_t *born, t_mdatoms *md)
-{
- int i, k, n, ii, jnr, ii3, is3, nj0, nj1, n0, n1;
- int jnrA, jnrB;
- int j3A, j3B;
- int * jjnr;
-
- double rbi, shX, shY, shZ;
- double *rb;
-
- __m128d ix, iy, iz;
- __m128d jx, jy, jz;
- __m128d fix, fiy, fiz;
- __m128d dx, dy, dz;
- __m128d tx, ty, tz;
-
- __m128d rbai, rbaj, f_gb, f_gb_ai;
- __m128d xmm1, xmm2, xmm3;
-
- const __m128d two = _mm_set1_pd(2.0);
-
- rb = born->work;
-
- jjnr = nl->jjnr;
-
- /* Loop to get the proper form for the Born radius term, sse style */
- n0 = 0;
- n1 = natoms;
-
- if (gb_algorithm == egbSTILL)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = (2 * rbi * rbi * dvda[i])/ONE_4PI_EPS0;
- }
- }
- else if (gb_algorithm == egbHCT)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * dvda[i];
- }
- }
- else if (gb_algorithm == egbOBC)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * born->drobc[i] * dvda[i];
- }
- }
-
- jz = _mm_setzero_pd();
-
- n = j3A = j3B = 0;
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_pd(shX+x[ii3+0]);
- iy = _mm_set1_pd(shY+x[ii3+1]);
- iz = _mm_set1_pd(shZ+x[ii3+2]);
-
- rbai = _mm_load1_pd(rb+ii);
- fix = _mm_setzero_pd();
- fiy = _mm_setzero_pd();
- fiz = _mm_setzero_pd();
-
-
- for (k = nj0; k < nj1-1; k += 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(x+j3A, x+j3B, jx, jy, jz);
-
- dx = _mm_sub_pd(ix, jx);
- dy = _mm_sub_pd(iy, jy);
- dz = _mm_sub_pd(iz, jz);
-
- GMX_MM_LOAD_2VALUES_PD(rb+jnrA, rb+jnrB, rbaj);
-
- /* load chain rule terms for j1-4 */
- f_gb = _mm_load_pd(dadx);
- dadx += 2;
- f_gb_ai = _mm_load_pd(dadx);
- dadx += 2;
-
- /* calculate scalar force */
- f_gb = _mm_mul_pd(f_gb, rbai);
- f_gb_ai = _mm_mul_pd(f_gb_ai, rbaj);
- f_gb = _mm_add_pd(f_gb, f_gb_ai);
-
- tx = _mm_mul_pd(f_gb, dx);
- ty = _mm_mul_pd(f_gb, dy);
- tz = _mm_mul_pd(f_gb, dz);
-
- fix = _mm_add_pd(fix, tx);
- fiy = _mm_add_pd(fiy, ty);
- fiz = _mm_add_pd(fiz, tz);
-
- GMX_MM_DECREMENT_1RVEC_2POINTERS_PD(f+j3A, f+j3B, tx, ty, tz);
- }
-
- /*deal with odd elements */
- if (k < nj1)
- {
- jnrA = jjnr[k];
- j3A = 3*jnrA;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(x+j3A, jx, jy, jz);
-
- dx = _mm_sub_sd(ix, jx);
- dy = _mm_sub_sd(iy, jy);
- dz = _mm_sub_sd(iz, jz);
-
- GMX_MM_LOAD_1VALUE_PD(rb+jnrA, rbaj);
-
- /* load chain rule terms */
- f_gb = _mm_load_pd(dadx);
- dadx += 2;
- f_gb_ai = _mm_load_pd(dadx);
- dadx += 2;
-
- /* calculate scalar force */
- f_gb = _mm_mul_sd(f_gb, rbai);
- f_gb_ai = _mm_mul_sd(f_gb_ai, rbaj);
- f_gb = _mm_add_sd(f_gb, f_gb_ai);
-
- tx = _mm_mul_sd(f_gb, dx);
- ty = _mm_mul_sd(f_gb, dy);
- tz = _mm_mul_sd(f_gb, dz);
-
- fix = _mm_add_sd(fix, tx);
- fiy = _mm_add_sd(fiy, ty);
- fiz = _mm_add_sd(fiz, tz);
-
- GMX_MM_DECREMENT_1RVEC_1POINTER_PD(f+j3A, tx, ty, tz);
- }
-
- /* fix/fiy/fiz now contain four partial force terms, that all should be
- * added to the i particle forces and shift forces.
- */
- gmx_mm_update_iforce_1atom_pd(&fix, &fiy, &fiz, f+ii3, fshift+is3);
- }
-
- return 0;
-}
-
-#else
-/* keep compiler happy */
-int genborn_sse2_dummy;
-
-#endif /* SSE2 intrinsics available */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "gromacs/domdec/domdec.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/legacyheaders/genborn.h"
-#include "gromacs/legacyheaders/names.h"
-#include "gromacs/legacyheaders/network.h"
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/math/units.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/gmxmpi.h"
-#include "gromacs/utility/smalloc.h"
-
-
-/* Only compile this file if SSE intrinsics are available */
-#if 0 && defined (GMX_SIMD_X86_SSE2_OR_HIGHER)
-
-#include "genborn_sse2_single.h"
-
-#include <emmintrin.h>
-#include <gmx_sse2_single.h>
-
-
-int
-calc_gb_rad_still_sse2_single(t_commrec *cr, t_forcerec *fr,
- int natoms, gmx_localtop_t *top,
- float *x, t_nblist *nl,
- gmx_genborn_t *born)
-{
- int i, k, n, ii, is3, ii3, nj0, nj1, offset;
- int jnrA, jnrB, jnrC, jnrD, j3A, j3B, j3C, j3D;
- int jnrE, jnrF, jnrG, jnrH, j3E, j3F, j3G, j3H;
- int shift;
- int *mdtype;
- real shX, shY, shZ;
- int *jjnr;
- real *shiftvec;
-
- float gpi_ai, gpi2;
- float factor;
- float *gb_radius;
- float *vsolv;
- float *work;
- float *dadx;
-
- __m128 ix, iy, iz;
- __m128 jx, jy, jz;
- __m128 dx, dy, dz;
- __m128 tx, ty, tz;
- __m128 jxB, jyB, jzB;
- __m128 dxB, dyB, dzB;
- __m128 txB, tyB, tzB;
- __m128 rsq, rinv, rinv2, rinv4, rinv6;
- __m128 rsqB, rinvB, rinv2B, rinv4B, rinv6B;
- __m128 ratio, gpi, rai, raj, vai, vaj, rvdw;
- __m128 ratioB, rajB, vajB, rvdwB;
- __m128 ccf, dccf, theta, cosq, term, sinq, res, prod, prod_ai, tmp;
- __m128 ccfB, dccfB, thetaB, cosqB, termB, sinqB, resB, prodB;
- __m128 mask, icf4, icf6, mask_cmp;
- __m128 icf4B, icf6B, mask_cmpB;
-
- __m128 mask1 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0, 0, 0xffffffff) );
- __m128 mask2 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0, 0xffffffff, 0xffffffff) );
- __m128 mask3 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0xffffffff, 0xffffffff, 0xffffffff) );
-
- const __m128 half = _mm_set1_ps(0.5f);
- const __m128 three = _mm_set1_ps(3.0f);
- const __m128 one = _mm_set1_ps(1.0f);
- const __m128 two = _mm_set1_ps(2.0f);
- const __m128 zero = _mm_set1_ps(0.0f);
- const __m128 four = _mm_set1_ps(4.0f);
-
- const __m128 still_p5inv = _mm_set1_ps(STILL_P5INV);
- const __m128 still_pip5 = _mm_set1_ps(STILL_PIP5);
- const __m128 still_p4 = _mm_set1_ps(STILL_P4);
-
- factor = 0.5 * ONE_4PI_EPS0;
-
- gb_radius = born->gb_radius;
- vsolv = born->vsolv;
- work = born->gpol_still_work;
- jjnr = nl->jjnr;
- shiftvec = fr->shift_vec[0];
- dadx = fr->dadx;
-
- jnrA = jnrB = jnrC = jnrD = 0;
- jx = _mm_setzero_ps();
- jy = _mm_setzero_ps();
- jz = _mm_setzero_ps();
-
- n = 0;
-
- for (i = 0; i < natoms; i++)
- {
- work[i] = 0;
- }
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_ps(shX+x[ii3+0]);
- iy = _mm_set1_ps(shY+x[ii3+1]);
- iz = _mm_set1_ps(shZ+x[ii3+2]);
-
- offset = (nj1-nj0)%4;
-
- /* Polarization energy for atom ai */
- gpi = _mm_setzero_ps();
-
- rai = _mm_load1_ps(gb_radius+ii);
- prod_ai = _mm_set1_ps(STILL_P4*vsolv[ii]);
-
- for (k = nj0; k < nj1-4-offset; k += 8)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- jnrD = jjnr[k+3];
- jnrE = jjnr[k+4];
- jnrF = jjnr[k+5];
- jnrG = jjnr[k+6];
- jnrH = jjnr[k+7];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- j3D = 3*jnrD;
- j3E = 3*jnrE;
- j3F = 3*jnrF;
- j3G = 3*jnrG;
- j3H = 3*jnrH;
-
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3A, x+j3B, x+j3C, x+j3D, jx, jy, jz);
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3E, x+j3F, x+j3G, x+j3H, jxB, jyB, jzB);
-
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, gb_radius+jnrD, raj);
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrE, gb_radius+jnrF, gb_radius+jnrG, gb_radius+jnrH, rajB);
- GMX_MM_LOAD_4VALUES_PS(vsolv+jnrA, vsolv+jnrB, vsolv+jnrC, vsolv+jnrD, vaj);
- GMX_MM_LOAD_4VALUES_PS(vsolv+jnrE, vsolv+jnrF, vsolv+jnrG, vsolv+jnrH, vajB);
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
- dxB = _mm_sub_ps(ix, jxB);
- dyB = _mm_sub_ps(iy, jyB);
- dzB = _mm_sub_ps(iz, jzB);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
- rsqB = gmx_mm_calc_rsq_ps(dxB, dyB, dzB);
- rinv = gmx_mm_invsqrt_ps(rsq);
- rinvB = gmx_mm_invsqrt_ps(rsqB);
- rinv2 = _mm_mul_ps(rinv, rinv);
- rinv2B = _mm_mul_ps(rinvB, rinvB);
- rinv4 = _mm_mul_ps(rinv2, rinv2);
- rinv4B = _mm_mul_ps(rinv2B, rinv2B);
- rinv6 = _mm_mul_ps(rinv4, rinv2);
- rinv6B = _mm_mul_ps(rinv4B, rinv2B);
-
- rvdw = _mm_add_ps(rai, raj);
- rvdwB = _mm_add_ps(rai, rajB);
- ratio = _mm_mul_ps(rsq, gmx_mm_inv_ps( _mm_mul_ps(rvdw, rvdw)));
- ratioB = _mm_mul_ps(rsqB, gmx_mm_inv_ps( _mm_mul_ps(rvdwB, rvdwB)));
-
- mask_cmp = _mm_cmple_ps(ratio, still_p5inv);
- mask_cmpB = _mm_cmple_ps(ratioB, still_p5inv);
-
- /* gmx_mm_sincos_ps() is quite expensive, so avoid calculating it if we can! */
- if (0 == _mm_movemask_ps(mask_cmp) )
- {
- /* if ratio>still_p5inv for ALL elements */
- ccf = one;
- dccf = _mm_setzero_ps();
- }
- else
- {
- ratio = _mm_min_ps(ratio, still_p5inv);
- theta = _mm_mul_ps(ratio, still_pip5);
- gmx_mm_sincos_ps(theta, &sinq, &cosq);
- term = _mm_mul_ps(half, _mm_sub_ps(one, cosq));
- ccf = _mm_mul_ps(term, term);
- dccf = _mm_mul_ps(_mm_mul_ps(two, term),
- _mm_mul_ps(sinq, theta));
- }
- if (0 == _mm_movemask_ps(mask_cmpB) )
- {
- /* if ratio>still_p5inv for ALL elements */
- ccfB = one;
- dccfB = _mm_setzero_ps();
- }
- else
- {
- ratioB = _mm_min_ps(ratioB, still_p5inv);
- thetaB = _mm_mul_ps(ratioB, still_pip5);
- gmx_mm_sincos_ps(thetaB, &sinqB, &cosqB);
- termB = _mm_mul_ps(half, _mm_sub_ps(one, cosqB));
- ccfB = _mm_mul_ps(termB, termB);
- dccfB = _mm_mul_ps(_mm_mul_ps(two, termB),
- _mm_mul_ps(sinqB, thetaB));
- }
-
- prod = _mm_mul_ps(still_p4, vaj);
- prodB = _mm_mul_ps(still_p4, vajB);
- icf4 = _mm_mul_ps(ccf, rinv4);
- icf4B = _mm_mul_ps(ccfB, rinv4B);
- icf6 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four, ccf), dccf), rinv6);
- icf6B = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four, ccfB), dccfB), rinv6B);
-
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrA, work+jnrB, work+jnrC, work+jnrD, _mm_mul_ps(prod_ai, icf4));
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrE, work+jnrF, work+jnrG, work+jnrH, _mm_mul_ps(prod_ai, icf4B));
-
- gpi = _mm_add_ps(gpi, _mm_add_ps( _mm_mul_ps(prod, icf4), _mm_mul_ps(prodB, icf4B) ) );
-
- _mm_store_ps(dadx, _mm_mul_ps(prod, icf6));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai, icf6));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prodB, icf6B));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai, icf6B));
- dadx += 4;
- }
-
- for (; k < nj1-offset; k += 4)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- jnrD = jjnr[k+3];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- j3D = 3*jnrD;
-
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3A, x+j3B, x+j3C, x+j3D, jx, jy, jz);
-
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, gb_radius+jnrD, raj);
- GMX_MM_LOAD_4VALUES_PS(vsolv+jnrA, vsolv+jnrB, vsolv+jnrC, vsolv+jnrD, vaj);
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
- rinv = gmx_mm_invsqrt_ps(rsq);
- rinv2 = _mm_mul_ps(rinv, rinv);
- rinv4 = _mm_mul_ps(rinv2, rinv2);
- rinv6 = _mm_mul_ps(rinv4, rinv2);
-
- rvdw = _mm_add_ps(rai, raj);
- ratio = _mm_mul_ps(rsq, gmx_mm_inv_ps( _mm_mul_ps(rvdw, rvdw)));
-
- mask_cmp = _mm_cmple_ps(ratio, still_p5inv);
-
- /* gmx_mm_sincos_ps() is quite expensive, so avoid calculating it if we can! */
- if (0 == _mm_movemask_ps(mask_cmp))
- {
- /* if ratio>still_p5inv for ALL elements */
- ccf = one;
- dccf = _mm_setzero_ps();
- }
- else
- {
- ratio = _mm_min_ps(ratio, still_p5inv);
- theta = _mm_mul_ps(ratio, still_pip5);
- gmx_mm_sincos_ps(theta, &sinq, &cosq);
- term = _mm_mul_ps(half, _mm_sub_ps(one, cosq));
- ccf = _mm_mul_ps(term, term);
- dccf = _mm_mul_ps(_mm_mul_ps(two, term),
- _mm_mul_ps(sinq, theta));
- }
-
- prod = _mm_mul_ps(still_p4, vaj);
- icf4 = _mm_mul_ps(ccf, rinv4);
- icf6 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four, ccf), dccf), rinv6);
-
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrA, work+jnrB, work+jnrC, work+jnrD, _mm_mul_ps(prod_ai, icf4));
-
- gpi = _mm_add_ps(gpi, _mm_mul_ps(prod, icf4));
-
- _mm_store_ps(dadx, _mm_mul_ps(prod, icf6));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai, icf6));
- dadx += 4;
- }
-
- if (offset != 0)
- {
- if (offset == 1)
- {
- jnrA = jjnr[k];
- j3A = 3*jnrA;
- GMX_MM_LOAD_1RVEC_1POINTER_PS(x+j3A, jx, jy, jz);
- GMX_MM_LOAD_1VALUE_PS(gb_radius+jnrA, raj);
- GMX_MM_LOAD_1VALUE_PS(vsolv+jnrA, vaj);
- mask = mask1;
- }
- else if (offset == 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- GMX_MM_LOAD_1RVEC_2POINTERS_PS(x+j3A, x+j3B, jx, jy, jz);
- GMX_MM_LOAD_2VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, raj);
- GMX_MM_LOAD_2VALUES_PS(vsolv+jnrA, vsolv+jnrB, vaj);
- mask = mask2;
- }
- else
- {
- /* offset must be 3 */
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- GMX_MM_LOAD_1RVEC_3POINTERS_PS(x+j3A, x+j3B, x+j3C, jx, jy, jz);
- GMX_MM_LOAD_3VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, raj);
- GMX_MM_LOAD_3VALUES_PS(vsolv+jnrA, vsolv+jnrB, vsolv+jnrC, vaj);
- mask = mask3;
- }
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
- rinv = gmx_mm_invsqrt_ps(rsq);
- rinv2 = _mm_mul_ps(rinv, rinv);
- rinv4 = _mm_mul_ps(rinv2, rinv2);
- rinv6 = _mm_mul_ps(rinv4, rinv2);
-
- rvdw = _mm_add_ps(rai, raj);
- ratio = _mm_mul_ps(rsq, gmx_mm_inv_ps( _mm_mul_ps(rvdw, rvdw)));
-
- mask_cmp = _mm_cmple_ps(ratio, still_p5inv);
-
- if (0 == _mm_movemask_ps(mask_cmp))
- {
- /* if ratio>still_p5inv for ALL elements */
- ccf = one;
- dccf = _mm_setzero_ps();
- }
- else
- {
- ratio = _mm_min_ps(ratio, still_p5inv);
- theta = _mm_mul_ps(ratio, still_pip5);
- gmx_mm_sincos_ps(theta, &sinq, &cosq);
- term = _mm_mul_ps(half, _mm_sub_ps(one, cosq));
- ccf = _mm_mul_ps(term, term);
- dccf = _mm_mul_ps(_mm_mul_ps(two, term),
- _mm_mul_ps(sinq, theta));
- }
-
- prod = _mm_mul_ps(still_p4, vaj);
- icf4 = _mm_mul_ps(ccf, rinv4);
- icf6 = _mm_mul_ps( _mm_sub_ps( _mm_mul_ps(four, ccf), dccf), rinv6);
-
- gpi = _mm_add_ps(gpi, _mm_mul_ps(prod, icf4));
-
- _mm_store_ps(dadx, _mm_mul_ps(prod, icf6));
- dadx += 4;
- _mm_store_ps(dadx, _mm_mul_ps(prod_ai, icf6));
- dadx += 4;
-
- tmp = _mm_mul_ps(prod_ai, icf4);
-
- if (offset == 1)
- {
- GMX_MM_INCREMENT_1VALUE_PS(work+jnrA, tmp);
- }
- else if (offset == 2)
- {
- GMX_MM_INCREMENT_2VALUES_PS(work+jnrA, work+jnrB, tmp);
- }
- else
- {
- /* offset must be 3 */
- GMX_MM_INCREMENT_3VALUES_PS(work+jnrA, work+jnrB, work+jnrC, tmp);
- }
- }
- GMX_MM_UPDATE_1POT_PS(gpi, work+ii);
- }
-
- /* Sum up the polarization energy from other nodes */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_sum_real(cr->dd, work);
- }
-
- /* Compute the radii */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- gpi_ai = born->gpol[i] + work[i]; /* add gpi to the initial pol energy gpi_ai*/
- gpi2 = gpi_ai * gpi_ai;
- born->bRad[i] = factor*gmx_invsqrt(gpi2);
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- /* Extra (local) communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- }
-
- return 0;
-}
-
-
-int
-calc_gb_rad_hct_obc_sse2_single(t_commrec *cr, t_forcerec * fr, int natoms, gmx_localtop_t *top,
- float *x, t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, int gb_algorithm)
-{
- int i, ai, k, n, ii, ii3, is3, nj0, nj1, at0, at1, offset;
- int jnrA, jnrB, jnrC, jnrD;
- int j3A, j3B, j3C, j3D;
- int jnrE, jnrF, jnrG, jnrH;
- int j3E, j3F, j3G, j3H;
- float shX, shY, shZ;
- float rr, rr_inv, rr_inv2, sum_tmp, sum, sum2, sum3, gbr;
- float sum_ai2, sum_ai3, tsum, tchain, doffset;
- float *obc_param;
- float *gb_radius;
- float *work;
- int * jjnr;
- float *dadx;
- float *shiftvec;
- float min_rad, rad;
-
- __m128 ix, iy, iz, jx, jy, jz;
- __m128 dx, dy, dz, t1, t2, t3, t4;
- __m128 rsq, rinv, r;
- __m128 rai, rai_inv, raj, raj_inv, rai_inv2, sk, sk2, lij, dlij, duij;
- __m128 uij, lij2, uij2, lij3, uij3, diff2;
- __m128 lij_inv, sk2_inv, prod, log_term, tmp, tmp_sum;
- __m128 sum_ai, tmp_ai, sk_ai, sk_aj, sk2_ai, sk2_aj, sk2_rinv;
- __m128 dadx1, dadx2;
- __m128 logterm;
- __m128 mask;
- __m128 obc_mask1, obc_mask2, obc_mask3;
- __m128 jxB, jyB, jzB, t1B, t2B, t3B, t4B;
- __m128 dxB, dyB, dzB, rsqB, rinvB, rB;
- __m128 rajB, raj_invB, rai_inv2B, sk2B, lijB, dlijB, duijB;
- __m128 uijB, lij2B, uij2B, lij3B, uij3B, diff2B;
- __m128 lij_invB, sk2_invB, prodB;
- __m128 sk_ajB, sk2_ajB, sk2_rinvB;
- __m128 dadx1B, dadx2B;
- __m128 logtermB;
- __m128 obc_mask1B, obc_mask2B, obc_mask3B;
-
- __m128 mask1 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0, 0, 0xffffffff) );
- __m128 mask2 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0, 0xffffffff, 0xffffffff) );
- __m128 mask3 = gmx_mm_castsi128_ps( _mm_set_epi32(0, 0xffffffff, 0xffffffff, 0xffffffff) );
-
- __m128 oneeighth = _mm_set1_ps(0.125);
- __m128 onefourth = _mm_set1_ps(0.25);
-
- const __m128 half = _mm_set1_ps(0.5f);
- const __m128 three = _mm_set1_ps(3.0f);
- const __m128 one = _mm_set1_ps(1.0f);
- const __m128 two = _mm_set1_ps(2.0f);
- const __m128 zero = _mm_set1_ps(0.0f);
- const __m128 neg = _mm_set1_ps(-1.0f);
-
- /* Set the dielectric offset */
- doffset = born->gb_doffset;
- gb_radius = born->gb_radius;
- obc_param = born->param;
- work = born->gpol_hct_work;
- jjnr = nl->jjnr;
- dadx = fr->dadx;
- shiftvec = fr->shift_vec[0];
-
- jx = _mm_setzero_ps();
- jy = _mm_setzero_ps();
- jz = _mm_setzero_ps();
-
- jnrA = jnrB = jnrC = jnrD = 0;
-
- for (i = 0; i < born->nr; i++)
- {
- work[i] = 0;
- }
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_ps(shX+x[ii3+0]);
- iy = _mm_set1_ps(shY+x[ii3+1]);
- iz = _mm_set1_ps(shZ+x[ii3+2]);
-
- offset = (nj1-nj0)%4;
-
- rai = _mm_load1_ps(gb_radius+ii);
- rai_inv = gmx_mm_inv_ps(rai);
-
- sum_ai = _mm_setzero_ps();
-
- sk_ai = _mm_load1_ps(born->param+ii);
- sk2_ai = _mm_mul_ps(sk_ai, sk_ai);
-
- for (k = nj0; k < nj1-4-offset; k += 8)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- jnrD = jjnr[k+3];
- jnrE = jjnr[k+4];
- jnrF = jjnr[k+5];
- jnrG = jjnr[k+6];
- jnrH = jjnr[k+7];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- j3D = 3*jnrD;
- j3E = 3*jnrE;
- j3F = 3*jnrF;
- j3G = 3*jnrG;
- j3H = 3*jnrH;
-
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3A, x+j3B, x+j3C, x+j3D, jx, jy, jz);
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3E, x+j3F, x+j3G, x+j3H, jxB, jyB, jzB);
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, gb_radius+jnrD, raj);
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrE, gb_radius+jnrF, gb_radius+jnrG, gb_radius+jnrH, rajB);
- GMX_MM_LOAD_4VALUES_PS(obc_param+jnrA, obc_param+jnrB, obc_param+jnrC, obc_param+jnrD, sk_aj);
- GMX_MM_LOAD_4VALUES_PS(obc_param+jnrE, obc_param+jnrF, obc_param+jnrG, obc_param+jnrH, sk_ajB);
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
- dxB = _mm_sub_ps(ix, jxB);
- dyB = _mm_sub_ps(iy, jyB);
- dzB = _mm_sub_ps(iz, jzB);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
- rsqB = gmx_mm_calc_rsq_ps(dxB, dyB, dzB);
-
- rinv = gmx_mm_invsqrt_ps(rsq);
- r = _mm_mul_ps(rsq, rinv);
- rinvB = gmx_mm_invsqrt_ps(rsqB);
- rB = _mm_mul_ps(rsqB, rinvB);
-
- /* Compute raj_inv aj1-4 */
- raj_inv = gmx_mm_inv_ps(raj);
- raj_invB = gmx_mm_inv_ps(rajB);
-
- /* Evaluate influence of atom aj -> ai */
- t1 = _mm_add_ps(r, sk_aj);
- t2 = _mm_sub_ps(r, sk_aj);
- t3 = _mm_sub_ps(sk_aj, r);
- t1B = _mm_add_ps(rB, sk_ajB);
- t2B = _mm_sub_ps(rB, sk_ajB);
- t3B = _mm_sub_ps(sk_ajB, rB);
- obc_mask1 = _mm_cmplt_ps(rai, t1);
- obc_mask2 = _mm_cmplt_ps(rai, t2);
- obc_mask3 = _mm_cmplt_ps(rai, t3);
- obc_mask1B = _mm_cmplt_ps(rai, t1B);
- obc_mask2B = _mm_cmplt_ps(rai, t2B);
- obc_mask3B = _mm_cmplt_ps(rai, t3B);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps( _mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, rai_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
-
- uijB = gmx_mm_inv_ps(t1B);
- lijB = _mm_or_ps( _mm_and_ps(obc_mask2B, gmx_mm_inv_ps(t2B)),
- _mm_andnot_ps(obc_mask2B, rai_inv));
- dlijB = _mm_and_ps(one, obc_mask2B);
- uij2B = _mm_mul_ps(uijB, uijB);
- uij3B = _mm_mul_ps(uij2B, uijB);
- lij2B = _mm_mul_ps(lijB, lijB);
- lij3B = _mm_mul_ps(lij2B, lijB);
-
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_aj = _mm_mul_ps(sk_aj, sk_aj);
- sk2_rinv = _mm_mul_ps(sk2_aj, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
-
- diff2B = _mm_sub_ps(uij2B, lij2B);
- lij_invB = gmx_mm_invsqrt_ps(lij2B);
- sk2_ajB = _mm_mul_ps(sk_ajB, sk_ajB);
- sk2_rinvB = _mm_mul_ps(sk2_ajB, rinvB);
- prodB = _mm_mul_ps(onefourth, sk2_rinvB);
-
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- logtermB = gmx_mm_log_ps(_mm_mul_ps(uijB, lij_invB));
-
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(rai_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
-
- t1B = _mm_sub_ps(lijB, uijB);
- t2B = _mm_mul_ps(diff2B,
- _mm_sub_ps(_mm_mul_ps(onefourth, rB),
- prodB));
- t3B = _mm_mul_ps(half, _mm_mul_ps(rinvB, logtermB));
- t1B = _mm_add_ps(t1B, _mm_add_ps(t2B, t3B));
- t4B = _mm_mul_ps(two, _mm_sub_ps(rai_inv, lijB));
- t4B = _mm_and_ps(t4B, obc_mask3B);
- t1B = _mm_mul_ps(half, _mm_add_ps(t1B, t4B));
-
- sum_ai = _mm_add_ps(sum_ai, _mm_add_ps( _mm_and_ps(t1, obc_mask1), _mm_and_ps(t1B, obc_mask1B) ));
-
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
-
-
-
- t1B = _mm_add_ps(_mm_mul_ps(half, lij2B),
- _mm_mul_ps(prodB, lij3B));
- t1B = _mm_sub_ps(t1B,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lijB, rinvB),
- _mm_mul_ps(lij3B, rB))));
- t2B = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uijB, rinvB),
- _mm_mul_ps(uij3B, rB)));
- t2B = _mm_sub_ps(t2B,
- _mm_add_ps(_mm_mul_ps(half, uij2B),
- _mm_mul_ps(prodB, uij3B)));
- t3B = _mm_mul_ps(_mm_mul_ps(onefourth, logtermB),
- _mm_mul_ps(rinvB, rinvB));
- t3B = _mm_sub_ps(t3B,
- _mm_mul_ps(_mm_mul_ps(diff2B, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinvB, rinvB))));
- t1B = _mm_mul_ps(rinvB,
- _mm_add_ps(_mm_mul_ps(dlijB, t1B),
- _mm_add_ps(t2B, t3B)));
-
- dadx1 = _mm_and_ps(t1, obc_mask1);
- dadx1B = _mm_and_ps(t1B, obc_mask1B);
-
-
- /* Evaluate influence of atom ai -> aj */
- t1 = _mm_add_ps(r, sk_ai);
- t2 = _mm_sub_ps(r, sk_ai);
- t3 = _mm_sub_ps(sk_ai, r);
- t1B = _mm_add_ps(rB, sk_ai);
- t2B = _mm_sub_ps(rB, sk_ai);
- t3B = _mm_sub_ps(sk_ai, rB);
- obc_mask1 = _mm_cmplt_ps(raj, t1);
- obc_mask2 = _mm_cmplt_ps(raj, t2);
- obc_mask3 = _mm_cmplt_ps(raj, t3);
- obc_mask1B = _mm_cmplt_ps(rajB, t1B);
- obc_mask2B = _mm_cmplt_ps(rajB, t2B);
- obc_mask3B = _mm_cmplt_ps(rajB, t3B);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps( _mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, raj_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
-
- uijB = gmx_mm_inv_ps(t1B);
- lijB = _mm_or_ps( _mm_and_ps(obc_mask2B, gmx_mm_inv_ps(t2B)),
- _mm_andnot_ps(obc_mask2B, raj_invB));
- dlijB = _mm_and_ps(one, obc_mask2B);
- uij2B = _mm_mul_ps(uijB, uijB);
- uij3B = _mm_mul_ps(uij2B, uijB);
- lij2B = _mm_mul_ps(lijB, lijB);
- lij3B = _mm_mul_ps(lij2B, lijB);
-
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_rinv = _mm_mul_ps(sk2_ai, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
-
- diff2B = _mm_sub_ps(uij2B, lij2B);
- lij_invB = gmx_mm_invsqrt_ps(lij2B);
- sk2_rinvB = _mm_mul_ps(sk2_ai, rinvB);
- prodB = _mm_mul_ps(onefourth, sk2_rinvB);
-
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- logtermB = gmx_mm_log_ps(_mm_mul_ps(uijB, lij_invB));
-
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(raj_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
-
- t1B = _mm_sub_ps(lijB, uijB);
- t2B = _mm_mul_ps(diff2B,
- _mm_sub_ps(_mm_mul_ps(onefourth, rB),
- prodB));
- t3B = _mm_mul_ps(half, _mm_mul_ps(rinvB, logtermB));
- t1B = _mm_add_ps(t1B, _mm_add_ps(t2B, t3B));
- t4B = _mm_mul_ps(two, _mm_sub_ps(raj_invB, lijB));
- t4B = _mm_and_ps(t4B, obc_mask3B);
- t1B = _mm_mul_ps(half, _mm_add_ps(t1B, t4B));
-
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrA, work+jnrB, work+jnrC, work+jnrD, _mm_and_ps(t1, obc_mask1));
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrE, work+jnrF, work+jnrG, work+jnrH, _mm_and_ps(t1B, obc_mask1B));
-
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
-
-
- t1B = _mm_add_ps(_mm_mul_ps(half, lij2B),
- _mm_mul_ps(prodB, lij3B));
- t1B = _mm_sub_ps(t1B,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lijB, rinvB),
- _mm_mul_ps(lij3B, rB))));
- t2B = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uijB, rinvB),
- _mm_mul_ps(uij3B, rB)));
- t2B = _mm_sub_ps(t2B,
- _mm_add_ps(_mm_mul_ps(half, uij2B),
- _mm_mul_ps(prodB, uij3B)));
- t3B = _mm_mul_ps(_mm_mul_ps(onefourth, logtermB),
- _mm_mul_ps(rinvB, rinvB));
- t3B = _mm_sub_ps(t3B,
- _mm_mul_ps(_mm_mul_ps(diff2B, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinvB, rinvB))));
- t1B = _mm_mul_ps(rinvB,
- _mm_add_ps(_mm_mul_ps(dlijB, t1B),
- _mm_add_ps(t2B, t3B)));
-
-
- dadx2 = _mm_and_ps(t1, obc_mask1);
- dadx2B = _mm_and_ps(t1B, obc_mask1B);
-
- _mm_store_ps(dadx, dadx1);
- dadx += 4;
- _mm_store_ps(dadx, dadx2);
- dadx += 4;
- _mm_store_ps(dadx, dadx1B);
- dadx += 4;
- _mm_store_ps(dadx, dadx2B);
- dadx += 4;
-
- } /* end normal inner loop */
-
- for (; k < nj1-offset; k += 4)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- jnrD = jjnr[k+3];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- j3D = 3*jnrD;
-
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3A, x+j3B, x+j3C, x+j3D, jx, jy, jz);
- GMX_MM_LOAD_4VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, gb_radius+jnrD, raj);
- GMX_MM_LOAD_4VALUES_PS(obc_param+jnrA, obc_param+jnrB, obc_param+jnrC, obc_param+jnrD, sk_aj);
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
-
- rinv = gmx_mm_invsqrt_ps(rsq);
- r = _mm_mul_ps(rsq, rinv);
-
- /* Compute raj_inv aj1-4 */
- raj_inv = gmx_mm_inv_ps(raj);
-
- /* Evaluate influence of atom aj -> ai */
- t1 = _mm_add_ps(r, sk_aj);
- obc_mask1 = _mm_cmplt_ps(rai, t1);
-
- if (_mm_movemask_ps(obc_mask1))
- {
- /* If any of the elements has rai<dr+sk, this is executed */
- t2 = _mm_sub_ps(r, sk_aj);
- t3 = _mm_sub_ps(sk_aj, r);
-
- obc_mask2 = _mm_cmplt_ps(rai, t2);
- obc_mask3 = _mm_cmplt_ps(rai, t3);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps( _mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, rai_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_aj = _mm_mul_ps(sk_aj, sk_aj);
- sk2_rinv = _mm_mul_ps(sk2_aj, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(rai_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
- sum_ai = _mm_add_ps(sum_ai, _mm_and_ps(t1, obc_mask1));
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
-
- dadx1 = _mm_and_ps(t1, obc_mask1);
- }
- else
- {
- dadx1 = _mm_setzero_ps();
- }
-
- /* Evaluate influence of atom ai -> aj */
- t1 = _mm_add_ps(r, sk_ai);
- obc_mask1 = _mm_cmplt_ps(raj, t1);
-
- if (_mm_movemask_ps(obc_mask1))
- {
- t2 = _mm_sub_ps(r, sk_ai);
- t3 = _mm_sub_ps(sk_ai, r);
- obc_mask2 = _mm_cmplt_ps(raj, t2);
- obc_mask3 = _mm_cmplt_ps(raj, t3);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps( _mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, raj_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_rinv = _mm_mul_ps(sk2_ai, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(raj_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
-
- GMX_MM_INCREMENT_4VALUES_PS(work+jnrA, work+jnrB, work+jnrC, work+jnrD, _mm_and_ps(t1, obc_mask1));
-
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
- dadx2 = _mm_and_ps(t1, obc_mask1);
- }
- else
- {
- dadx2 = _mm_setzero_ps();
- }
-
- _mm_store_ps(dadx, dadx1);
- dadx += 4;
- _mm_store_ps(dadx, dadx2);
- dadx += 4;
- } /* end normal inner loop */
-
- if (offset != 0)
- {
- if (offset == 1)
- {
- jnrA = jjnr[k];
- j3A = 3*jnrA;
- GMX_MM_LOAD_1RVEC_1POINTER_PS(x+j3A, jx, jy, jz);
- GMX_MM_LOAD_1VALUE_PS(gb_radius+jnrA, raj);
- GMX_MM_LOAD_1VALUE_PS(obc_param+jnrA, sk_aj);
- mask = mask1;
- }
- else if (offset == 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- GMX_MM_LOAD_1RVEC_2POINTERS_PS(x+j3A, x+j3B, jx, jy, jz);
- GMX_MM_LOAD_2VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, raj);
- GMX_MM_LOAD_2VALUES_PS(obc_param+jnrA, obc_param+jnrB, sk_aj);
- mask = mask2;
- }
- else
- {
- /* offset must be 3 */
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- GMX_MM_LOAD_1RVEC_3POINTERS_PS(x+j3A, x+j3B, x+j3C, jx, jy, jz);
- GMX_MM_LOAD_3VALUES_PS(gb_radius+jnrA, gb_radius+jnrB, gb_radius+jnrC, raj);
- GMX_MM_LOAD_3VALUES_PS(obc_param+jnrA, obc_param+jnrB, obc_param+jnrC, sk_aj);
- mask = mask3;
- }
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- rsq = gmx_mm_calc_rsq_ps(dx, dy, dz);
-
- rinv = gmx_mm_invsqrt_ps(rsq);
- r = _mm_mul_ps(rsq, rinv);
-
- /* Compute raj_inv aj1-4 */
- raj_inv = gmx_mm_inv_ps(raj);
-
- /* Evaluate influence of atom aj -> ai */
- t1 = _mm_add_ps(r, sk_aj);
- obc_mask1 = _mm_cmplt_ps(rai, t1);
- obc_mask1 = _mm_and_ps(obc_mask1, mask);
-
- if (_mm_movemask_ps(obc_mask1))
- {
- t2 = _mm_sub_ps(r, sk_aj);
- t3 = _mm_sub_ps(sk_aj, r);
- obc_mask2 = _mm_cmplt_ps(rai, t2);
- obc_mask3 = _mm_cmplt_ps(rai, t3);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps( _mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, rai_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_aj = _mm_mul_ps(sk_aj, sk_aj);
- sk2_rinv = _mm_mul_ps(sk2_aj, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(rai_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
- sum_ai = _mm_add_ps(sum_ai, _mm_and_ps(t1, obc_mask1));
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
- dadx1 = _mm_and_ps(t1, obc_mask1);
- }
- else
- {
- dadx1 = _mm_setzero_ps();
- }
-
- /* Evaluate influence of atom ai -> aj */
- t1 = _mm_add_ps(r, sk_ai);
- obc_mask1 = _mm_cmplt_ps(raj, t1);
- obc_mask1 = _mm_and_ps(obc_mask1, mask);
-
- if (_mm_movemask_ps(obc_mask1))
- {
- t2 = _mm_sub_ps(r, sk_ai);
- t3 = _mm_sub_ps(sk_ai, r);
- obc_mask2 = _mm_cmplt_ps(raj, t2);
- obc_mask3 = _mm_cmplt_ps(raj, t3);
-
- uij = gmx_mm_inv_ps(t1);
- lij = _mm_or_ps(_mm_and_ps(obc_mask2, gmx_mm_inv_ps(t2)),
- _mm_andnot_ps(obc_mask2, raj_inv));
- dlij = _mm_and_ps(one, obc_mask2);
- uij2 = _mm_mul_ps(uij, uij);
- uij3 = _mm_mul_ps(uij2, uij);
- lij2 = _mm_mul_ps(lij, lij);
- lij3 = _mm_mul_ps(lij2, lij);
- diff2 = _mm_sub_ps(uij2, lij2);
- lij_inv = gmx_mm_invsqrt_ps(lij2);
- sk2_rinv = _mm_mul_ps(sk2_ai, rinv);
- prod = _mm_mul_ps(onefourth, sk2_rinv);
- logterm = gmx_mm_log_ps(_mm_mul_ps(uij, lij_inv));
- t1 = _mm_sub_ps(lij, uij);
- t2 = _mm_mul_ps(diff2,
- _mm_sub_ps(_mm_mul_ps(onefourth, r),
- prod));
- t3 = _mm_mul_ps(half, _mm_mul_ps(rinv, logterm));
- t1 = _mm_add_ps(t1, _mm_add_ps(t2, t3));
- t4 = _mm_mul_ps(two, _mm_sub_ps(raj_inv, lij));
- t4 = _mm_and_ps(t4, obc_mask3);
- t1 = _mm_mul_ps(half, _mm_add_ps(t1, t4));
-
- tmp = _mm_and_ps(t1, obc_mask1);
-
- t1 = _mm_add_ps(_mm_mul_ps(half, lij2),
- _mm_mul_ps(prod, lij3));
- t1 = _mm_sub_ps(t1,
- _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(lij, rinv),
- _mm_mul_ps(lij3, r))));
- t2 = _mm_mul_ps(onefourth,
- _mm_add_ps(_mm_mul_ps(uij, rinv),
- _mm_mul_ps(uij3, r)));
- t2 = _mm_sub_ps(t2,
- _mm_add_ps(_mm_mul_ps(half, uij2),
- _mm_mul_ps(prod, uij3)));
- t3 = _mm_mul_ps(_mm_mul_ps(onefourth, logterm),
- _mm_mul_ps(rinv, rinv));
- t3 = _mm_sub_ps(t3,
- _mm_mul_ps(_mm_mul_ps(diff2, oneeighth),
- _mm_add_ps(one,
- _mm_mul_ps(sk2_rinv, rinv))));
- t1 = _mm_mul_ps(rinv,
- _mm_add_ps(_mm_mul_ps(dlij, t1),
- _mm_add_ps(t2, t3)));
- dadx2 = _mm_and_ps(t1, obc_mask1);
- }
- else
- {
- dadx2 = _mm_setzero_ps();
- tmp = _mm_setzero_ps();
- }
-
- _mm_store_ps(dadx, dadx1);
- dadx += 4;
- _mm_store_ps(dadx, dadx2);
- dadx += 4;
-
- if (offset == 1)
- {
- GMX_MM_INCREMENT_1VALUE_PS(work+jnrA, tmp);
- }
- else if (offset == 2)
- {
- GMX_MM_INCREMENT_2VALUES_PS(work+jnrA, work+jnrB, tmp);
- }
- else
- {
- /* offset must be 3 */
- GMX_MM_INCREMENT_3VALUES_PS(work+jnrA, work+jnrB, work+jnrC, tmp);
- }
-
- }
- GMX_MM_UPDATE_1POT_PS(sum_ai, work+ii);
-
- }
-
- /* Parallel summations */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_sum_real(cr->dd, work);
- }
-
- if (gb_algorithm == egbHCT)
- {
- /* HCT */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- rr = top->atomtypes.gb_radius[md->typeA[i]]-doffset;
- sum = 1.0/rr - work[i];
- min_rad = rr + doffset;
- rad = 1.0/sum;
-
- born->bRad[i] = rad > min_rad ? rad : min_rad;
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
- }
- }
-
- /* Extra communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- }
- }
- else
- {
- /* OBC */
- for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
- {
- if (born->use[i] != 0)
- {
- rr = top->atomtypes.gb_radius[md->typeA[i]];
- rr_inv2 = 1.0/rr;
- rr = rr-doffset;
- rr_inv = 1.0/rr;
- sum = rr * work[i];
- sum2 = sum * sum;
- sum3 = sum2 * sum;
-
- tsum = tanh(born->obc_alpha*sum-born->obc_beta*sum2+born->obc_gamma*sum3);
- born->bRad[i] = rr_inv - tsum*rr_inv2;
- born->bRad[i] = 1.0 / born->bRad[i];
-
- fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
-
- tchain = rr * (born->obc_alpha-2*born->obc_beta*sum+3*born->obc_gamma*sum2);
- born->drobc[i] = (1.0-tsum*tsum)*tchain*rr_inv2;
- }
- }
- /* Extra (local) communication required for DD */
- if (DOMAINDECOMP(cr))
- {
- dd_atom_spread_real(cr->dd, born->bRad);
- dd_atom_spread_real(cr->dd, fr->invsqrta);
- dd_atom_spread_real(cr->dd, born->drobc);
- }
- }
-
-
-
- return 0;
-}
-
-
-
-float calc_gb_chainrule_sse2_single(int natoms, t_nblist *nl, float *dadx, float *dvda,
- float *x, float *f, float *fshift, float *shiftvec,
- int gb_algorithm, gmx_genborn_t *born, t_mdatoms *md)
-{
- int i, k, n, ii, jnr, ii3, is3, nj0, nj1, offset, n0, n1;
- int jnrA, jnrB, jnrC, jnrD;
- int j3A, j3B, j3C, j3D;
- int jnrE, jnrF, jnrG, jnrH;
- int j3E, j3F, j3G, j3H;
- int * jjnr;
-
- float rbi, shX, shY, shZ;
- float *rb;
-
- __m128 ix, iy, iz;
- __m128 jx, jy, jz;
- __m128 jxB, jyB, jzB;
- __m128 fix, fiy, fiz;
- __m128 dx, dy, dz;
- __m128 tx, ty, tz;
- __m128 dxB, dyB, dzB;
- __m128 txB, tyB, tzB;
-
- __m128 rbai, rbaj, rbajB, f_gb, f_gb_ai, f_gbB, f_gb_aiB;
- __m128 xmm1, xmm2, xmm3;
-
- const __m128 two = _mm_set1_ps(2.0f);
-
- rb = born->work;
-
- jjnr = nl->jjnr;
-
- /* Loop to get the proper form for the Born radius term, sse style */
- offset = natoms%4;
-
- n0 = 0;
- n1 = natoms;
-
- if (gb_algorithm == egbSTILL)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = (2 * rbi * rbi * dvda[i])/ONE_4PI_EPS0;
- }
- }
- else if (gb_algorithm == egbHCT)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * dvda[i];
- }
- }
- else if (gb_algorithm == egbOBC)
- {
- for (i = n0; i < n1; i++)
- {
- rbi = born->bRad[i];
- rb[i] = rbi * rbi * born->drobc[i] * dvda[i];
- }
- }
-
- jz = _mm_setzero_ps();
-
- n = j3A = j3B = j3C = j3D = 0;
-
- for (i = 0; i < nl->nri; i++)
- {
- ii = nl->iinr[i];
- ii3 = ii*3;
- is3 = 3*nl->shift[i];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = nl->jindex[i];
- nj1 = nl->jindex[i+1];
-
- ix = _mm_set1_ps(shX+x[ii3+0]);
- iy = _mm_set1_ps(shY+x[ii3+1]);
- iz = _mm_set1_ps(shZ+x[ii3+2]);
-
- offset = (nj1-nj0)%4;
-
- rbai = _mm_load1_ps(rb+ii);
- fix = _mm_setzero_ps();
- fiy = _mm_setzero_ps();
- fiz = _mm_setzero_ps();
-
-
- for (k = nj0; k < nj1-offset; k += 4)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- jnrD = jjnr[k+3];
-
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- j3D = 3*jnrD;
-
- GMX_MM_LOAD_1RVEC_4POINTERS_PS(x+j3A, x+j3B, x+j3C, x+j3D, jx, jy, jz);
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- GMX_MM_LOAD_4VALUES_PS(rb+jnrA, rb+jnrB, rb+jnrC, rb+jnrD, rbaj);
-
- /* load chain rule terms for j1-4 */
- f_gb = _mm_load_ps(dadx);
- dadx += 4;
- f_gb_ai = _mm_load_ps(dadx);
- dadx += 4;
-
- /* calculate scalar force */
- f_gb = _mm_mul_ps(f_gb, rbai);
- f_gb_ai = _mm_mul_ps(f_gb_ai, rbaj);
- f_gb = _mm_add_ps(f_gb, f_gb_ai);
-
- tx = _mm_mul_ps(f_gb, dx);
- ty = _mm_mul_ps(f_gb, dy);
- tz = _mm_mul_ps(f_gb, dz);
-
- fix = _mm_add_ps(fix, tx);
- fiy = _mm_add_ps(fiy, ty);
- fiz = _mm_add_ps(fiz, tz);
-
- GMX_MM_DECREMENT_1RVEC_4POINTERS_PS(f+j3A, f+j3B, f+j3C, f+j3D, tx, ty, tz);
- }
-
- /*deal with odd elements */
- if (offset != 0)
- {
- if (offset == 1)
- {
- jnrA = jjnr[k];
- j3A = 3*jnrA;
- GMX_MM_LOAD_1RVEC_1POINTER_PS(x+j3A, jx, jy, jz);
- GMX_MM_LOAD_1VALUE_PS(rb+jnrA, rbaj);
- }
- else if (offset == 2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- GMX_MM_LOAD_1RVEC_2POINTERS_PS(x+j3A, x+j3B, jx, jy, jz);
- GMX_MM_LOAD_2VALUES_PS(rb+jnrA, rb+jnrB, rbaj);
- }
- else
- {
- /* offset must be 3 */
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
- jnrC = jjnr[k+2];
- j3A = 3*jnrA;
- j3B = 3*jnrB;
- j3C = 3*jnrC;
- GMX_MM_LOAD_1RVEC_3POINTERS_PS(x+j3A, x+j3B, x+j3C, jx, jy, jz);
- GMX_MM_LOAD_3VALUES_PS(rb+jnrA, rb+jnrB, rb+jnrC, rbaj);
- }
-
- dx = _mm_sub_ps(ix, jx);
- dy = _mm_sub_ps(iy, jy);
- dz = _mm_sub_ps(iz, jz);
-
- /* load chain rule terms for j1-4 */
- f_gb = _mm_load_ps(dadx);
- dadx += 4;
- f_gb_ai = _mm_load_ps(dadx);
- dadx += 4;
-
- /* calculate scalar force */
- f_gb = _mm_mul_ps(f_gb, rbai);
- f_gb_ai = _mm_mul_ps(f_gb_ai, rbaj);
- f_gb = _mm_add_ps(f_gb, f_gb_ai);
-
- tx = _mm_mul_ps(f_gb, dx);
- ty = _mm_mul_ps(f_gb, dy);
- tz = _mm_mul_ps(f_gb, dz);
-
- fix = _mm_add_ps(fix, tx);
- fiy = _mm_add_ps(fiy, ty);
- fiz = _mm_add_ps(fiz, tz);
-
- if (offset == 1)
- {
- GMX_MM_DECREMENT_1RVEC_1POINTER_PS(f+j3A, tx, ty, tz);
- }
- else if (offset == 2)
- {
- GMX_MM_DECREMENT_1RVEC_2POINTERS_PS(f+j3A, f+j3B, tx, ty, tz);
- }
- else
- {
- /* offset must be 3 */
- GMX_MM_DECREMENT_1RVEC_3POINTERS_PS(f+j3A, f+j3B, f+j3C, tx, ty, tz);
- }
- }
-
- /* fix/fiy/fiz now contain four partial force terms, that all should be
- * added to the i particle forces and shift forces.
- */
- gmx_mm_update_iforce_1atom_ps(&fix, &fiy, &fiz, f+ii3, fshift+is3);
- }
-
- return 0;
-}
-
-
-#else
-/* keep compiler happy */
-int genborn_sse_dummy;
-
-#endif /* SSE intrinsics available */
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
#include "gromacs/fileio/enxio.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/legacyheaders/mdebin.h"
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/utility/fatalerror.h"
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
sys.path.append('../../../../../admin')
from copyright import create_copyright_header
-FileHeader = create_copyright_header('2012,2013,2014')
+FileHeader = create_copyright_header('2012,2013,2014,2015')
FileHeader += """/*
* Note: this file was generated by the Verlet kernel generator for
* kernel type {0}.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
+#include "gromacs/mdlib/nbnxn_simd.h"
+
#define GMX_SIMD_J_UNROLL_SIZE {7}
#include "{4}"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gmxpre.h"
+#include "gromacs/mdlib/nbnxn_simd.h"
+
#define GMX_SIMD_J_UNROLL_SIZE {7}
#include "{4}"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/gmx_omp_nthreads.h"
#include "gromacs/legacyheaders/types/force_flags.h"
#include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_common.h"
+#include "gromacs/simd/simd.h"
#include "gromacs/utility/fatalerror.h"
/*! \brief Kinds of electrostatic treatments in SIMD Verlet kernels
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/mdlib/nbnxn_pairlist.h"
-#include "gromacs/mdlib/nbnxn_simd.h"
#ifdef __cplusplus
extern "C" {{
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/domdec/domdec.h"
#include "gromacs/legacyheaders/force.h"
#include "gromacs/legacyheaders/macros.h"
static int
round_up_to_simd_width(int length, int simd_width)
{
- int offset, newlength;
+ int offset;
offset = (simd_width > 0) ? length % simd_width : 0;
{
t_nblist *nl;
int homenr;
- int i, nn;
+ int i;
for (i = 0; (i < 2); i++)
{
*/
int maxsr, maxsr_wat, maxlr, maxlr_wat;
int ielec, ivdw, ielecmod, ivdwmod, type;
- int solvent;
int igeometry_def, igeometry_w, igeometry_ww;
int i;
gmx_bool bElecAndVdwSwitchDiffers;
* all the nlist arrays many times in a row.
* The numbers seem very accurate, but they are uncritical.
*/
- maxsr_wat = min(fr->nWatMol, (homenr+2)/3);
+ maxsr_wat = std::min(fr->nWatMol, (homenr+2)/3);
if (fr->bTwinRange)
{
maxlr = 50;
- maxlr_wat = min(maxsr_wat, maxlr);
+ maxlr_wat = std::min(maxsr_wat, maxlr);
}
else
{
static gmx_inline void new_i_nblist(t_nblist *nlist, atom_id i_atom, int shift, int gid)
{
- int i, k, nri, nshift;
-
- nri = nlist->nri;
+ int nri = nlist->nri;
/* Check whether we have to increase the i counter */
if ((nri == -1) ||
t_nblist * vdwc_ww = NULL;
t_nblist * coul_ww = NULL;
- int i, j, jcg, igid, gid, nbl_ind, ind_ij;
+ int i, j, jcg, igid, gid, nbl_ind;
atom_id jj, jj0, jj1, i_atom;
- int i0, nicg, len;
+ int i0, nicg;
int *cginfo;
int *type, *typeB;
real *charge, *chargeB;
- real qi, qiB, qq, rlj;
+ real qi, qiB;
gmx_bool bFreeEnergy, bFree, bFreeJ, bNotEx, *bPert;
gmx_bool bDoVdW_i, bDoCoul_i, bDoCoul_i_sol;
int iwater, jwater;
gmx_bool bLR,
gmx_bool bDoVdW,
gmx_bool bDoCoul,
- int solvent_opt)
+ int gmx_unused solvent_opt)
{
/* The a[] index has been removed,
* to put it back in i_atom should be a[i0] and jj should be a[jj].
t_nblist * vdwc_adress = NULL;
t_nblist * vdw_adress = NULL;
t_nblist * coul_adress = NULL;
- t_nblist * vdwc_ww = NULL;
- t_nblist * coul_ww = NULL;
int i, j, jcg, igid, gid, nbl_ind, nbl_ind_adress;
atom_id jj, jj0, jj1, i_atom;
- int i0, nicg, len;
+ int i0, nicg;
int *cginfo;
- int *type, *typeB;
- real *charge, *chargeB;
+ int *type;
+ real *charge;
real *wf;
- real qi, qiB, qq, rlj;
- gmx_bool bFreeEnergy, bFree, bFreeJ, bNotEx, *bPert;
- gmx_bool bDoVdW_i, bDoCoul_i, bDoCoul_i_sol;
+ real qi;
+ gmx_bool bNotEx;
+ gmx_bool bDoVdW_i, bDoCoul_i;
gmx_bool b_hybrid;
- gmx_bool j_all_atom;
- int iwater, jwater;
t_nblist *nlist, *nlist_adress;
gmx_bool bEnergyGroupCG;
/* Copy some pointers */
cginfo = fr->cginfo;
charge = md->chargeA;
- chargeB = md->chargeB;
type = md->typeA;
- typeB = md->typeB;
- bPert = md->bPerturbed;
wf = md->wf;
/* Get atom range */
/* Get the i charge group info */
igid = GET_CGINFO_GID(cginfo[icg]);
- iwater = (solvent_opt != esolNO) ? GET_CGINFO_SOLOPT(cginfo[icg]) : esolNO;
-
if (md->nPerturbed)
{
gmx_fatal(FARGS, "AdResS does not support free energy pertubation\n");
/* Perform NINT operation, using trunc operation, therefore
* we first add 2.5 then subtract 2 again
*/
- tz = dz*b_inv[ZZ] + h25;
+ tz = static_cast<int>(dz*b_inv[ZZ] + h25);
tz -= 2;
dz -= tz*box[ZZ][ZZ];
dy -= tz*box[ZZ][YY];
dx -= tz*box[ZZ][XX];
- ty = dy*b_inv[YY] + h25;
+ ty = static_cast<int>(dy*b_inv[YY] + h25);
ty -= 2;
dy -= ty*box[YY][YY];
dx -= ty*box[YY][XX];
- tx = dx*b_inv[XX]+h25;
+ tx = static_cast<int>(dx*b_inv[XX]+h25);
tx -= 2;
dx -= tx*box[XX][XX];
/* Perform NINT operation, using trunc operation, therefore
* we first add 1.5 then subtract 1 again
*/
- tx = dx*b_inv[XX] + h15;
- ty = dy*b_inv[YY] + h15;
- tz = dz*b_inv[ZZ] + h15;
+ tx = static_cast<int>(dx*b_inv[XX] + h15);
+ ty = static_cast<int>(dy*b_inv[YY] + h15);
+ tz = static_cast<int>(dz*b_inv[ZZ] + h15);
tx--;
ty--;
tz--;
return r2;
}
-static void add_simple(t_ns_buf *nsbuf, int nrj, atom_id cg_j,
+static void add_simple(t_ns_buf * nsbuf, int nrj, atom_id cg_j,
gmx_bool bHaveVdW[], int ngid, t_mdatoms *md,
int icg, int jgid, t_block *cgs, t_excl bexcl[],
int shift, t_forcerec *fr, put_in_list_t *put_in_list)
int j, nrj, jgid;
int *cginfo = fr->cginfo;
atom_id cg_j, *cgindex;
- t_ns_buf *nsbuf;
cgindex = cgs->index;
shift = CENTRAL;
int j, nrj, jgid;
int *cginfo = fr->cginfo;
atom_id cg_j, *cgindex;
- t_ns_buf *nsbuf;
cgindex = cgs->index;
if (bBox)
{
int naaj, k;
real rlist2;
- int nsearch, icg, jcg, igid, i0, nri, nn;
+ int nsearch, icg, igid, nn;
int *cginfo;
t_ns_buf *nsbuf;
/* atom_id *i_atoms; */
*rvdw2 = *rs2;
*rcoul2 = *rs2;
}
- *rm2 = min(*rvdw2, *rcoul2);
- *rl2 = max(*rvdw2, *rcoul2);
+ *rm2 = std::min(*rvdw2, *rcoul2);
+ *rl2 = std::max(*rvdw2, *rcoul2);
}
static void init_nsgrid_lists(t_forcerec *fr, int ngid, gmx_ns_t *ns)
#endif
int dx0, dx1, dy0, dy1, dz0, dz1;
int Nx, Ny, Nz, shift = -1, j, nrj, nns, nn = -1;
- real gridx, gridy, gridz, grid_x, grid_y, grid_z;
+ real gridx, gridy, gridz, grid_x, grid_y;
real *dcx2, *dcy2, *dcz2;
int zgi, ygi, xgi;
- int cg0, cg1, icg = -1, cgsnr, i0, igid, nri, naaj, max_jcg;
+ int cg0, cg1, icg = -1, cgsnr, i0, igid, naaj, max_jcg;
int jcg0, jcg1, jjcg, cgj0, jgid;
int *grida, *gridnra, *gridind;
gmx_bool rvdw_lt_rcoul, rcoul_lt_rvdw;
- rvec xi, *cgcm, grid_offset;
- real r2, rs2, rvdw2, rcoul2, rm2, rl2, XI, YI, ZI, dcx, dcy, dcz, tmp1, tmp2;
+ rvec *cgcm, grid_offset;
+ real r2, rs2, rvdw2, rcoul2, rm2, rl2, XI, YI, ZI, tmp1, tmp2;
int *i_egp_flags;
gmx_bool bDomDec, bTriclinicX, bTriclinicY;
ivec ncpddc;
gridz = grid->cell_size[ZZ];
grid_x = 1/gridx;
grid_y = 1/gridy;
- grid_z = 1/gridz;
copy_rvec(grid->cell_offset, grid_offset);
copy_ivec(grid->ncpddc, ncpddc);
dcx2 = grid->dcx2;
else
{
if (d == XX &&
- box[XX][XX] - fabs(box[YY][XX]) - fabs(box[ZZ][XX]) < sqrt(rl2))
+ box[XX][XX] - fabs(box[YY][XX]) - fabs(box[ZZ][XX]) < std::sqrt(rl2))
{
shp[d] = 2;
}
}
}
}
- /* setexcl(nri,i_atoms,&top->atoms.excl,FALSE,bexcl); */
setexcl(cgs->index[icg], cgs->index[icg+1], &top->excls, FALSE, bexcl);
}
/* No need to perform any left-over force calculations anymore (as we used to do here)
{
int mt, icg, nr_in_cg, maxcg, i, j, jcg, ngid, ncg;
t_block *cgs;
- char *ptr;
/* Compute largest charge groups size (# atoms) */
nr_in_cg = 1;
cgs = &mtop->moltype[mt].cgs;
for (icg = 0; (icg < cgs->nr); icg++)
{
- nr_in_cg = max(nr_in_cg, (int)(cgs->index[icg+1]-cgs->index[icg]));
+ nr_in_cg = std::max(nr_in_cg, (int)(cgs->index[icg+1]-cgs->index[icg]));
}
}
{
t_block *cgs = &(top->cgs);
rvec box_size, grid_x0, grid_x1;
- int i, j, m, ngid;
+ int m, ngid;
real min_size, grid_dens;
int nsearch;
gmx_bool bGrid;
- char *ptr;
- gmx_bool *i_egp_flags;
- int cg_start, cg_end, start, end;
+ int start, end;
gmx_ns_t *ns;
t_grid *grid;
gmx_domdec_zones_t *dd_zones;
}
if (!bGrid)
{
- min_size = min(box_size[XX], min(box_size[YY], box_size[ZZ]));
+ min_size = std::min(box_size[XX], std::min(box_size[YY], box_size[ZZ]));
if (2*fr->rlistlong >= min_size)
{
gmx_fatal(FARGS, "One of the box diagonal elements has become smaller than twice the cut-off length.");
#include <stdio.h>
#include <stdlib.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/domdec/domdec.h"
#include "gromacs/fileio/pdbio.h"
#include "gromacs/legacyheaders/macros.h"
for (d = 0; d < DIM; d++)
{
av[d] = s1[d];
- stddev[d] = sqrt(s2[d] - s1[d]*s1[d]);
+ stddev[d] = std::sqrt(s2[d] - s1[d]*s1[d]);
}
}
{
int i, j;
gmx_bool bDD, bDDRect;
- rvec av, stddev;
rvec izones_size;
real inv_r_ideal, size, add_tric, radd;
}
/* Use the ideal number of cg's per cell to set the ideal cell size */
- inv_r_ideal = pow(grid_density/grid->ncg_ideal, 1.0/3.0);
+ inv_r_ideal = std::pow((real)(grid_density/grid->ncg_ideal), (real)(1.0/3.0));
if (rlist > 0 && inv_r_ideal*rlist < 1)
{
inv_r_ideal = 1/rlist;
/* Check if the cell boundary in this direction is
* perpendicular to the Cartesian axis.
+ * Since grid->npbcdim isan integer that in principle can take
+ * any value, we help the compiler avoid warnings and potentially
+ * optimize by ensuring that j < DIM here.
*/
- for (j = i+1; j < grid->npbcdim; j++)
+ for (j = i+1; j < grid->npbcdim && j < DIM; j++)
{
if (box[j][i] != 0)
{
t_grid *init_grid(FILE *fplog, t_forcerec *fr)
{
- int d, m;
char *ptr;
t_grid *grid;
real rlistlong, real grid_density)
{
int i, m;
- ivec cx;
set_grid_sizes(box, izones_x0, izones_x1, rlistlong, dd, ddbox, grid, grid_density);
}
}
- m = max(grid->n[XX], max(grid->n[YY], grid->n[ZZ]));
+ m = std::max(grid->n[XX], std::max(grid->n[YY], grid->n[ZZ]));
if (m > grid->dc_nalloc)
{
/* Allocate with double the initial size for box scaling */
int cg0, int cg1, rvec cg_cm[])
{
int *cell_index;
- int nrx, nry, nrz;
+ int nry, nrz;
rvec n_box, offset;
int zone, ccg0, ccg1, cg, d, not_used;
ivec shift0, useall, b0, b1, ind;
cell_index = grid->cell_index;
/* Initiate cell borders */
- nrx = grid->n[XX];
nry = grid->n[YY];
nrz = grid->n[ZZ];
for (d = 0; d < DIM; d++)
{
for (d = 0; d < DIM; d++)
{
- ind[d] = (cg_cm[cg][d] - offset[d])*n_box[d];
+ ind[d] = static_cast<int>((cg_cm[cg][d] - offset[d])*n_box[d]);
/* With pbc we should be done here.
* Without pbc cg's outside the grid
* should be assigned to the closest grid cell.
bUse = TRUE;
for (d = 0; d < DIM; d++)
{
- ind[d] = (cg_cm[cg][d] - offset[d])*n_box[d];
+ ind[d] = static_cast<int>((cg_cm[cg][d] - offset[d])*n_box[d]);
/* Here we have to correct for rounding problems,
* as this cg_cm to cell index operation is not necessarily
* binary identical to the operation for the DD zone assignment
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_QMMM_GAMESS
+#if GMX_QMMM_GAMESS
#include <math.h>
#include <stdio.h>
#include "gromacs/legacyheaders/qmmm.h"
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/types/commrec.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
#include "gromacs/utility/fatalerror.h"
void
-F77_FUNC(inigms, IMIGMS) (void);
+ F77_FUNC(inigms, IMIGMS) (void);
void
-F77_FUNC(endgms, ENDGMS) (void);
+ F77_FUNC(endgms, ENDGMS) (void);
void
-F77_FUNC(grads, GRADS) (int *nrqmat, real *qmcrd, int *nrmmat, real *mmchrg,
- real *mmcrd, real *qmgrad, real *mmgrad, real *energy);
+ F77_FUNC(grads, GRADS) (int *nrqmat, real *qmcrd, int *nrmmat, real *mmchrg,
+ real *mmcrd, real *qmgrad, real *mmgrad, real *energy);
* dynamics simulations. 7-6-2002 (London)
*/
int
- i, j, rank;
+ i, j;
FILE
*out;
char
}
}
-real call_gamess(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm,
+real call_gamess(t_forcerec *fr, t_QMrec *qm, t_MMrec *mm,
rvec f[], rvec fshift[])
{
/* do the actual QMMM calculation using GAMESS-UK. In this
* gradient routines linked directly
*/
int
- i, j, rank;
+ i, j;
real
QMener = 0.0, *qmgrad, *mmgrad, *mmcrd, *qmcrd, energy;
t_QMMMrec
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_QMMM_GAUSSIAN
+#if GMX_QMMM_GAUSSIAN
#include <math.h>
#include <stdio.h>
#include "gromacs/legacyheaders/typedefs.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
-
/* TODO: this should be made thread-safe */
/* Gaussian interface routines */
-void init_gaussian(t_commrec *cr, t_QMrec *qm, t_MMrec *mm)
+void init_gaussian(t_QMrec *qm)
{
- FILE
- *rffile = NULL, *out = NULL;
+ FILE *out = NULL;
ivec
- basissets[eQMbasisNR] = {{0, 3, 0},
+ basissets[eQMbasisNR] = {{0, 3, 0},
{0, 3, 0}, /*added for double sto-3g entry in names.c*/
{5, 0, 0},
{5, 0, 1},
{1, 6, 11},
{4, 6, 0}};
char
- *buf = NULL;
+ *buf = NULL;
int
- i;
+ i;
/* using the ivec above to convert the basis read form the mdp file
* in a human readable format into some numbers for the gaussian
} /* write_gaussian_input */
-real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], int step,
- t_QMrec *qm, t_MMrec *mm)
+real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], t_QMrec *qm, t_MMrec *mm)
{
int
i, j, atnum;
return(QMener);
}
-real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step,
- gmx_bool swapped, t_QMrec *qm, t_MMrec *mm)
+real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QMrec *qm, t_MMrec *mm)
{
int
i;
}
}
-real call_gaussian(t_commrec *cr, t_forcerec *fr,
- t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
+real call_gaussian(t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
{
/* normal gaussian jobs */
static int
write_gaussian_input(step, fr, qm, mm);
do_gaussian(step, exe);
- QMener = read_gaussian_output(QMgrad, MMgrad, step, qm, mm);
+ QMener = read_gaussian_output(QMgrad, MMgrad, qm, mm);
/* put the QMMM forces in the force array and to the fshift
*/
for (i = 0; i < qm->nrQMatoms; i++)
} /* call_gaussian */
-real call_gaussian_SH(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm,
- rvec f[], rvec fshift[])
+real call_gaussian_SH(t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
{
/* a gaussian call routine intended for doing diabatic surface
* "sliding". See the manual for the theoretical background of this
write_gaussian_SH_input(step, swapped, fr, qm, mm);
do_gaussian(step, exe);
- QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, swapped, qm, mm);
+ QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, qm, mm);
/* check for a surface hop. Only possible if we were already state
* averaging.
{
write_gaussian_SH_input(step, swapped, fr, qm, mm);
do_gaussian(step, exe);
- QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, swapped, qm, mm);
+ QMener = read_gaussian_SH_output(QMgrad, MMgrad, step, qm, mm);
}
}
/* add the QMMM forces to the gmx force array and fshift
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_QMMM_MOPAC
+#if GMX_QMMM_MOPAC
#include <math.h>
#include <stdio.h>
/* mopac interface routines */
void
-F77_FUNC(domldt, DOMLDT) (int *nrqmat, int labels[], char keywords[]);
+ F77_FUNC(domldt, DOMLDT) (int *nrqmat, int labels[], char keywords[]);
void
-F77_FUNC(domop, DOMOP) (int *nrqmat, double qmcrd[], int *nrmmat,
- double mmchrg[], double mmcrd[], double qmgrad[],
- double mmgrad[], double *energy, double qmcharges[]);
+ F77_FUNC(domop, DOMOP) (int *nrqmat, double qmcrd[], int *nrmmat,
+ double mmchrg[], double mmcrd[], double qmgrad[],
+ double mmgrad[], double *energy, double qmcharges[]);
-void init_mopac(t_commrec *cr, t_QMrec *qm, t_MMrec *mm)
+void init_mopac(t_QMrec *qm)
{
/* initializes the mopac routines ans sets up the semiempirical
* computation by calling moldat(). The inline mopac routines can
} /* init_mopac */
-real call_mopac(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm,
- rvec f[], rvec fshift[])
+real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
{
/* do the actual QMMM calculation using directly linked mopac subroutines
*/
return (QMener);
}
-real call_mopac_SH(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm,
- rvec f[], rvec fshift[])
+real call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
{
/* do the actual SH QMMM calculation using directly linked mopac
subroutines */
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
int
i, j, atnum;
char
- buf[300], tmp[300], orca_xyzFilename[300], orca_pcgradFilename[300], orca_engradFilename[300];
+ buf[300], orca_xyzFilename[300], orca_pcgradFilename[300], orca_engradFilename[300];
real
QMener;
FILE
gmx_fatal(FARGS, "Unexpected end of ORCA output");
}
#ifdef GMX_DOUBLE
- sscanf(buf, "%s%lf%lf%lf\n",
- tmp,
+ sscanf(buf, "%d%lf%lf%lf\n",
+ &atnum,
&qm->xQM[i][XX],
&qm->xQM[i][YY],
&qm->xQM[i][ZZ]);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <stdlib.h>
#include <string.h>
+#include <cmath>
+
+#include <algorithm>
+
#include "gromacs/fileio/confio.h"
#include "gromacs/legacyheaders/force.h"
#include "gromacs/legacyheaders/macros.h"
/* declarations of the interfaces to the QM packages. The _SH indicate
* the QM interfaces can be used for Surface Hopping simulations
*/
-#ifdef GMX_QMMM_GAMESS
+#if GMX_QMMM_GAMESS
/* GAMESS interface */
void
init_gamess(t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
real
-call_gamess(t_commrec *cr, t_forcerec *fr,
+call_gamess(t_forcerec *fr,
t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
-#elif defined GMX_QMMM_MOPAC
+#elif GMX_QMMM_MOPAC
/* MOPAC interface */
void
-init_mopac(t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
+init_mopac(t_QMrec *qm);
real
-call_mopac(t_commrec *cr, t_forcerec *fr, t_QMrec *qm,
- t_MMrec *mm, rvec f[], rvec fshift[]);
+call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
real
-call_mopac_SH(t_commrec *cr, t_forcerec *fr, t_QMrec *qm,
- t_MMrec *mm, rvec f[], rvec fshift[]);
+call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
-#elif defined GMX_QMMM_GAUSSIAN
+#elif GMX_QMMM_GAUSSIAN
/* GAUSSIAN interface */
void
-init_gaussian(t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
+init_gaussian(t_QMrec *qm);
real
-call_gaussian_SH(t_commrec *cr, t_forcerec *fr, t_QMrec *qm,
- t_MMrec *mm, rvec f[], rvec fshift[]);
+call_gaussian_SH(t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
real
-call_gaussian(t_commrec *cr, t_forcerec *fr, t_QMrec *qm,
- t_MMrec *mm, rvec f[], rvec fshift[]);
+call_gaussian(t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
-#elif defined GMX_QMMM_ORCA
+#elif GMX_QMMM_ORCA
/* ORCA interface */
void
if (qm->QMmethod < eQMmethodRHF && !(mm->nrMMatoms))
{
-#ifdef GMX_QMMM_MOPAC
+#if GMX_QMMM_MOPAC
if (qm->bSH)
{
- QMener = call_mopac_SH(cr, fr, qm, mm, f, fshift);
+ QMener = call_mopac_SH(qm, mm, f, fshift);
}
else
{
- QMener = call_mopac(cr, fr, qm, mm, f, fshift);
+ QMener = call_mopac(qm, mm, f, fshift);
}
#else
gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
/* do an ab-initio calculation */
if (qm->bSH && qm->QMmethod == eQMmethodCASSCF)
{
-#ifdef GMX_QMMM_GAUSSIAN
- QMener = call_gaussian_SH(cr, fr, qm, mm, f, fshift);
+#if GMX_QMMM_GAUSSIAN
+ QMener = call_gaussian_SH(fr, qm, mm, f, fshift);
#else
gmx_fatal(FARGS, "Ab-initio Surface-hopping only supported with Gaussian.");
#endif
}
else
{
-#ifdef GMX_QMMM_GAMESS
- QMener = call_gamess(cr, fr, qm, mm, f, fshift);
-#elif defined GMX_QMMM_GAUSSIAN
- QMener = call_gaussian(cr, fr, qm, mm, f, fshift);
-#elif defined GMX_QMMM_ORCA
+#if GMX_QMMM_GAMESS
+ QMener = call_gamess(fr, qm, mm, f, fshift);
+#elif GMX_QMMM_GAUSSIAN
+ QMener = call_gaussian(fr, qm, mm, f, fshift);
+#elif GMX_QMMM_ORCA
QMener = call_orca(fr, qm, mm, f, fshift);
#else
gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
*/
if (qm->QMmethod < eQMmethodRHF)
{
-#ifdef GMX_QMMM_MOPAC
+#if GMX_QMMM_MOPAC
/* do a semi-empiprical calculation */
- init_mopac(cr, qm, mm);
+ init_mopac(qm);
#else
gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
#endif
else
{
/* do an ab-initio calculation */
-#ifdef GMX_QMMM_GAMESS
+#if GMX_QMMM_GAMESS
init_gamess(cr, qm, mm);
-#elif defined GMX_QMMM_GAUSSIAN
- init_gaussian(cr, qm, mm);
-#elif defined GMX_QMMM_ORCA
+#elif GMX_QMMM_GAUSSIAN
+ init_gaussian(qm);
+#elif GMX_QMMM_ORCA
init_orca(qm);
#else
gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
FILE
*out = NULL;
int
- i, j, k, nrexcl = 0, *excluded = NULL, max = 0;
+ i, j, k, nrexcl = 0, *excluded = NULL, max_excl = 0;
out = fopen("QMMMexcl.dat", "w");
{
if (mm->indexMM[k] == excls->a[j]) /* the excluded MM atom */
{
- if (nrexcl >= max)
+ if (nrexcl >= max_excl)
{
- max += 1000;
- srenew(excluded, max);
+ max_excl += 1000;
+ srenew(excluded, max_excl);
}
excluded[nrexcl++] = k;
continue;
t_ilist *ilist_mol;
gmx_mtop_atomlookup_t alook;
- c6au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM, 6));
- c12au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM, 12));
+ c6au = (HARTREE2KJ*AVOGADRO*std::pow(BOHR2NM, 6));
+ c12au = (HARTREE2KJ*AVOGADRO*std::pow(BOHR2NM, 12));
/* issue a fatal if the user wants to run with more than one node */
if (PAR(cr))
{
*/
if (qr->qm[0]->QMmethod < eQMmethodRHF)
{
-#ifdef GMX_QMMM_MOPAC
+#if GMX_QMMM_MOPAC
/* semi-empiprical 1-layer ONIOM calculation requested (mopac93) */
- init_mopac(cr, qr->qm[0], qr->mm);
+ init_mopac(qr->qm[0]);
#else
gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
#endif
else
{
/* ab initio calculation requested (gamess/gaussian/ORCA) */
-#ifdef GMX_QMMM_GAMESS
+#if GMX_QMMM_GAMESS
init_gamess(cr, qr->qm[0], qr->mm);
-#elif defined GMX_QMMM_GAUSSIAN
- init_gaussian(cr, qr->qm[0], qr->mm);
-#elif defined GMX_QMMM_ORCA
+#elif GMX_QMMM_GAUSSIAN
+ init_gaussian(qr->qm[0]);
+#elif GMX_QMMM_ORCA
init_orca(qr->qm[0]);
#else
gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
QMMMlist;
rvec
dx, crd;
- int
- *MMatoms;
t_QMrec
*qm;
t_MMrec
real
c12au, c6au;
- c6au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM, 6));
- c12au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM, 12));
+ c6au = (HARTREE2KJ*AVOGADRO*std::pow(BOHR2NM, 6));
+ c12au = (HARTREE2KJ*AVOGADRO*std::pow(BOHR2NM, 12));
/* every cpu has this array. On every processor we fill this array
* with 1's and 0's. 1's indicate the atoms is a QM atom on the
crd[0] = IS2X(QMMMlist.shift[i]) + IS2X(qm_i_particles[i].shift);
crd[1] = IS2Y(QMMMlist.shift[i]) + IS2Y(qm_i_particles[i].shift);
crd[2] = IS2Z(QMMMlist.shift[i]) + IS2Z(qm_i_particles[i].shift);
- is = XYZ2IS(crd[0], crd[1], crd[2]);
+ is = static_cast<int>(XYZ2IS(crd[0], crd[1], crd[2]));
for (j = QMMMlist.jindex[i];
j < QMMMlist.jindex[i+1];
j++)
qsort(qm_i_particles, QMMMlist.nri,
(size_t)sizeof(qm_i_particles[0]),
struct_comp);
- qsort(mm_j_particles, mm_nr,
- (size_t)sizeof(mm_j_particles[0]),
- struct_comp);
+ /* The mm_j_particles argument to qsort is not allowed to be NULL */
+ if (mm_nr > 0)
+ {
+ qsort(mm_j_particles, mm_nr,
+ (size_t)sizeof(mm_j_particles[0]),
+ struct_comp);
+ }
/* remove multiples in the QM shift array, since in init_QMMM() we
* went through the atom numbers from 0 to md.nr, the order sorted
* here matches the one of QMindex already.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/pbcutil/mshift.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
#include "gromacs/domdec/domdec.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/legacyheaders/checkpoint.h"
#include "gromacs/legacyheaders/constr.h"
#include <math.h>
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/force.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/math/units.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/domdec/domdec.h"
#include "gromacs/ewald/pme.h"
#include "gromacs/fileio/confio.h"
-#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxlib/conformation-utilities.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/timing/walltime_accounting.h"
#include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
* it can be rewrapped for console output.
* - helpformat.h provides some general text-processing classes, currently
* focused on producing aligned tables for console output.
- * - helptopicinterface.h, helptopic.h, and helpmanager.h provide classes for
+ * - ihelptopic.h, helptopic.h, and helpmanager.h provide classes for
* managing a hierarchy of help topics and printing out help from this
* hierarchy.
*
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class File;
class HelpWriterContext;
/*! \libinternal \brief
#include <string>
#include <vector>
-#include "gromacs/onlinehelp/helptopicinterface.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/stringutil.h"
{
public:
//! Container type for keeping the stack of active topics.
- typedef std::vector<const HelpTopicInterface *> TopicStack;
+ typedef std::vector<const IHelpTopic *> TopicStack;
//! Initializes a new manager with the given context.
explicit Impl(const HelpWriterContext &context)
//! Whether the active topic is the root topic.
bool isAtRootTopic() const { return topicStack_.size() == 1; }
//! Returns the active topic.
- const HelpTopicInterface ¤tTopic() const
+ const IHelpTopic ¤tTopic() const
{
return *topicStack_.back();
}
* HelpManager
*/
-HelpManager::HelpManager(const HelpTopicInterface &rootTopic,
+HelpManager::HelpManager(const IHelpTopic &rootTopic,
const HelpWriterContext &context)
: impl_(new Impl(context))
{
void HelpManager::enterTopic(const char *name)
{
- const HelpTopicInterface &topic = impl_->currentTopic();
+ const IHelpTopic &topic = impl_->currentTopic();
if (!topic.hasSubTopics())
{
GMX_THROW(InvalidInputError(
formatString("Help topic '%s' has no subtopics",
impl_->currentTopicAsString().c_str())));
}
- const HelpTopicInterface *newTopic = topic.findSubTopic(name);
+ const IHelpTopic *newTopic = topic.findSubTopic(name);
if (newTopic == NULL)
{
if (impl_->isAtRootTopic())
void HelpManager::writeCurrentTopic() const
{
- const HelpTopicInterface &topic = impl_->currentTopic();
+ const IHelpTopic &topic = impl_->currentTopic();
const char *title = topic.title();
HelpWriterContext context(impl_->rootContext_);
context.enterSubSection(title != NULL ? title : "");
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class HelpTopicInterface;
class HelpWriterContext;
+class IHelpTopic;
/*! \libinternal \brief
* Helper for providing interactive online help.
* The provided topic and context objects must remain valid for the
* lifetime of this manager object.
*/
- HelpManager(const HelpTopicInterface &rootTopic,
+ HelpManager(const IHelpTopic &rootTopic,
const HelpWriterContext &context);
~HelpManager();
#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
namespace gmx
{
return false;
}
-const HelpTopicInterface *
+const IHelpTopic *
AbstractSimpleHelpTopic::findSubTopic(const char * /* name */) const
{
return NULL;
//! Container for subtopics.
typedef std::vector<HelpTopicPointer> SubTopicList;
//! Container for mapping subtopic names to help topic objects.
- typedef std::map<std::string, const HelpTopicInterface *> SubTopicMap;
+ typedef std::map<std::string, const IHelpTopic *> SubTopicMap;
/*! \brief
* Subtopics in the order they were added.
return !impl_->subTopics_.empty();
}
-const HelpTopicInterface *
+const IHelpTopic *
AbstractCompositeHelpTopic::findSubTopic(const char *name) const
{
Impl::SubTopicMap::const_iterator topic = impl_->subTopicMap_.find(name);
{
return false;
}
- File &file = context.outputFile();
+ TextWriter &file = context.outputFile();
TextTableFormatter formatter;
formatter.addColumn(NULL, maxNameLength + 1, false);
formatter.addColumn(NULL, 72 - maxNameLength, true);
{
GMX_ASSERT(impl_->subTopicMap_.find(topic->name()) == impl_->subTopicMap_.end(),
"Attempted to register a duplicate help topic name");
- const HelpTopicInterface *topicPtr = topic.get();
+ const IHelpTopic *topicPtr = topic.get();
impl_->subTopics_.reserve(impl_->subTopics_.size() + 1);
impl_->subTopicMap_.insert(std::make_pair(std::string(topicPtr->name()), topicPtr));
impl_->subTopics_.push_back(move(topic));
*/
/*! \libinternal \file
* \brief
- * Declares helper classes for implementing gmx::HelpTopicInterface.
+ * Declares helper classes for implementing gmx::IHelpTopic.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
#ifndef GMX_ONLINEHELP_HELPTOPIC_H
#define GMX_ONLINEHELP_HELPTOPIC_H
-#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
#include "gromacs/utility/classhelpers.h"
#include "gromacs/utility/stringutil.h"
#include "gromacs/utility/uniqueptr.h"
/*! \libinternal \brief
* Abstract base class for help topics that have simple text and no subtopics.
*
- * This class implements subtopic-related methods from HelpTopicInterface such
+ * This class implements subtopic-related methods from IHelpTopic such
* that there are no subtopics. writeHelp() is also implemented such that it
* uses HelpTopicContext::writeTextBlock() to write out the text returned by a
* new virtual method helpText().
* \inlibraryapi
* \ingroup module_onlinehelp
*/
-class AbstractSimpleHelpTopic : public HelpTopicInterface
+class AbstractSimpleHelpTopic : public IHelpTopic
{
public:
virtual const char *name() const = 0;
virtual const char *title() const = 0;
virtual bool hasSubTopics() const;
- virtual const HelpTopicInterface *findSubTopic(const char *name) const;
+ virtual const IHelpTopic *findSubTopic(const char *name) const;
virtual void writeHelp(const HelpWriterContext &context) const;
* Abstract base class for help topics that have simple text and subtopics.
*
* This class implements an internal container for subtopics and provides
- * public methods for adding subtopics (as HelpTopicInterface objects).
- * Subtopic-related methods from HelpTopicInterface are implemented to access
+ * public methods for adding subtopics (as IHelpTopic objects).
+ * Subtopic-related methods from IHelpTopic are implemented to access
* the internal container. writeHelp() is also implemented such that it
* uses HelpTopicContext::writeTextBlock() to write out the text returned by a
* new virtual method helpText(), and a list of subtopics is written after the
* \inlibraryapi
* \ingroup module_onlinehelp
*/
-class AbstractCompositeHelpTopic : public HelpTopicInterface
+class AbstractCompositeHelpTopic : public IHelpTopic
{
public:
AbstractCompositeHelpTopic();
virtual const char *title() const = 0;
virtual bool hasSubTopics() const;
- virtual const HelpTopicInterface *findSubTopic(const char *name) const;
+ virtual const IHelpTopic *findSubTopic(const char *name) const;
virtual void writeHelp(const HelpWriterContext &context) const;
* \throws std::bad_alloc if out of memory.
*
* \p Topic must be default-constructible and implement
- * HelpTopicInterface.
+ * IHelpTopic.
*
* This method is provided as a convenient alternative to addSubTopic()
* for cases where each topic is implemented by a different type
#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "rstparser.h"
* Provides an interface that is used to implement different types of output
* from HelpWriterContext::Impl::processMarkup().
*/
-class WrapperInterface
+class IWrapper
{
public:
- virtual ~WrapperInterface() {}
+ virtual ~IWrapper() {}
/*! \brief
* Provides the wrapping settings.
/*! \brief
* Wraps markup output into a single string.
*/
-class WrapperToString : public WrapperInterface
+class WrapperToString : public IWrapper
{
public:
//! Creates a wrapper with the given settings.
/*! \brief
* Wraps markup output into a vector of string (one line per element).
*/
-class WrapperToVector : public WrapperInterface
+class WrapperToVector : public IWrapper
{
public:
//! Creates a wrapper with the given settings.
{
public:
//! Initializes the state with the given parameters.
- SharedState(File *file, HelpOutputFormat format,
+ SharedState(TextOutputStream *stream, HelpOutputFormat format,
const HelpLinks *links)
- : file_(*file), format_(format), links_(links)
+ : file_(stream), format_(format), links_(links)
{
}
return *consoleOptionsFormatter_;
}
- //! Output file to which the help is written.
- File &file_;
+ //! Writer for writing the help.
+ TextWriter file_;
//! Output format for the help output.
HelpOutputFormat format_;
//! Links to use.
* or providing an interface for the caller to retrieve the output.
*/
void processMarkup(const std::string &text,
- WrapperInterface *wrapper) const;
+ IWrapper *wrapper) const;
//! Constant state shared by all child context objects.
StatePointer state_;
}
void HelpWriterContext::Impl::processMarkup(const std::string &text,
- WrapperInterface *wrapper) const
+ IWrapper *wrapper) const
{
std::string result(text);
for (ReplaceList::const_iterator i = replacements_.begin();
* HelpWriterContext
*/
-HelpWriterContext::HelpWriterContext(File *file, HelpOutputFormat format)
- : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(file, format, NULL)), 0))
+HelpWriterContext::HelpWriterContext(TextOutputStream *stream, HelpOutputFormat format)
+ : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(stream, format, NULL)), 0))
{
}
-HelpWriterContext::HelpWriterContext(File *file, HelpOutputFormat format,
+HelpWriterContext::HelpWriterContext(TextOutputStream *stream, HelpOutputFormat format,
const HelpLinks *links)
- : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(file, format, links)), 0))
+ : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(stream, format, links)), 0))
{
if (links != NULL)
{
return impl_->state_->format_;
}
-File &HelpWriterContext::outputFile() const
+TextWriter &HelpWriterContext::outputFile() const
{
- return impl_->state_->file_;
+ // TODO: Consider how to deal with the const/non-const difference better.
+ return const_cast<TextWriter &>(impl_->state_->file_);
}
void HelpWriterContext::enterSubSection(const std::string &title)
{
return;
}
- File &file = outputFile();
+ TextWriter &file = outputFile();
switch (outputFormat())
{
case eHelpOutputFormat_Console:
const std::string &info,
const std::string &description) const
{
- File &file = outputFile();
+ TextWriter &file = outputFile();
switch (outputFormat())
{
case eHelpOutputFormat_Console:
namespace gmx
{
-class File;
class TextLineWrapperSettings;
+class TextOutputStream;
+class TextWriter;
/*! \cond libapi */
//! \libinternal Output format for help writing.
{
public:
/*! \brief
- * Initializes a context with the given output file and format.
+ * Initializes a context with the given output stream and format.
*
* \throws std::bad_alloc if out of memory.
*/
- HelpWriterContext(File *file, HelpOutputFormat format);
+ HelpWriterContext(TextOutputStream *stream, HelpOutputFormat format);
/*! \brief
- * Initializes a context with the given output file, format and links.
+ * Initializes a context with the given output stream, format and links.
*
* \throws std::bad_alloc if out of memory.
*
* is destructed. The caller is responsible for ensuring that the
* links object remains valid long enough.
*/
- HelpWriterContext(File *file, HelpOutputFormat format,
+ HelpWriterContext(TextOutputStream *stream, HelpOutputFormat format,
const HelpLinks *links);
//! Creates a copy of the context.
HelpWriterContext(const HelpWriterContext &other);
*/
HelpOutputFormat outputFormat() const;
/*! \brief
- * Returns the raw output file for writing the help.
+ * Returns the raw writer for writing the help.
*
- * Using this file directly should be avoided, as it requires one to
+ * Using this writer directly should be avoided, as it requires one to
* have different code for each output format.
* Using other methods in this class should be preferred.
*
* Does not throw.
*/
- File &outputFile() const;
+ TextWriter &outputFile() const;
/*! \brief
* Creates a subsection in the output help.
*/
/*! \libinternal \file
* \brief
- * Declares gmx::HelpTopicInterface.
+ * Declares gmx::IHelpTopic.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
* \ingroup module_onlinehelp
*/
-#ifndef GMX_ONLINEHELP_HELPTOPICINTERFACE_H
-#define GMX_ONLINEHELP_HELPTOPICINTERFACE_H
+#ifndef GMX_ONLINEHELP_IHELPTOPIC_H
+#define GMX_ONLINEHELP_IHELPTOPIC_H
#include "gromacs/utility/uniqueptr.h"
* \inlibraryapi
* \ingroup module_onlinehelp
*/
-class HelpTopicInterface
+class IHelpTopic
{
public:
- virtual ~HelpTopicInterface() {}
+ virtual ~IHelpTopic() {}
/*! \brief
* Returns the name of the topic.
* \returns Pointer to the found subtopic, or NULL if matching topic
* is not found.
*/
- virtual const HelpTopicInterface *findSubTopic(const char *name) const = 0;
+ virtual const IHelpTopic *findSubTopic(const char *name) const = 0;
/*! \brief
* Prints the help text for this topic.
virtual void writeHelp(const HelpWriterContext &context) const = 0;
};
-//! Smart pointer type to manage a HelpTopicInterface object.
-typedef gmx_unique_ptr<HelpTopicInterface>::type HelpTopicPointer;
+//! Smart pointer type to manage a IHelpTopic object.
+typedef gmx_unique_ptr<IHelpTopic>::type HelpTopicPointer;
} // namespace gmx
#include "gromacs/onlinehelp/helptopic.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/stringstream.h"
#include "gromacs/onlinehelp/tests/mock_helptopic.h"
#include "testutils/stringtest.h"
#include "testutils/testasserts.h"
-#include "testutils/testfilemanager.h"
namespace
{
public:
HelpTestBase();
- gmx::test::TestFileManager tempFiles_;
MockHelpTopic rootTopic_;
- std::string filename_;
- gmx::File helpFile_;
+ gmx::StringOutputStream helpFile_;
gmx::HelpWriterContext context_;
gmx::HelpManager manager_;
};
HelpTestBase::HelpTestBase()
: rootTopic_("", NULL, "Root topic text"),
- filename_(tempFiles_.getTemporaryFilePath("helptext.txt")),
- helpFile_(filename_, "w"),
context_(&helpFile_, gmx::eHelpOutputFormat_Console),
manager_(rootTopic_, context_)
{
ASSERT_NO_THROW_GMX(manager_.writeCurrentTopic());
helpFile_.close();
- checkFileContents(filename_, "HelpText");
+ checkText(helpFile_.toString(), "HelpText");
}
TEST_F(HelpTopicFormattingTest, FormatsSimpleTopic)
*/
/*! \libinternal \file
* \brief
- * Declares mock implementation of gmx::HelpTopicInterface.
+ * Declares mock implementation of gmx::IHelpTopic.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*
* <H3>Basic Use</H3>
*
- * Basic interface for providing options is implemented by the Options class
- * and classes defined in basicoptions.h for specifying individual options.
- * Only these are needed if a class wants to provide a set of standard options.
- * When creating an Options object and adding options, it is possible to add
- * descriptions for individual options as well as for the whole set of options.
- * These can then be used to write out help text.
+ * Code that provides options does so using methods in gmx::IOptionsContainer
+ * and classes defined in basicoptions.h.
+ * Only these are needed if a class wants to provide a set of standard options
+ * (other modules can provide additional option types, such as
+ * gmx::SelectionOption).
+ * For each option, the caller provides an output variable that will receive
+ * the final value of the option once user input has been parsed.
+ * When adding options, it is possible to also provide descriptions for the
+ * options for use in generated help text.
+ *
+ * Generic code that handles the user input does so by creating a gmx::Options
+ * instance and passing it (as gmx::IOptionsContainer) to the classes that add
+ * the actual options. It can then use a parser to set values to the options.
+ * Final values for the options can be inspected in the code that added the
+ * individual options, from the provided output variables.
*
* The sequence charts below provides an overview of how the options work from
* usage perspective. They include two fictional modules, A and B, that provide
* typical initialization sequence, where the main routine creates an options
* object, and calls an initOptions() method in each module that can provide
* options (the modules may also request their submodules to add their own
- * options). Each module uses gmx::Options::addOption() to add the options
- * they require, and specify output variables into which the options values are
- * stored.
+ * options). Each module uses gmx::IOptionsContainer::addOption() to add the
+ * options they require, and specify output variables into which the options
+ * values are stored.
* \msc
* main,
* options [ label="Options", URL="\ref gmx::Options" ],
* main box B [ label="main owns all objects" ];
* main => options [ label="create", URL="\ref gmx::Options::Options()" ];
* main => A [ label="initOptions()" ];
- * A => options [ label="addOption()", URL="\ref gmx::Options::addOption()" ];
+ * A => options [ label="addOption()", URL="\ref gmx::IOptionsContainer::addOption()" ];
* ...;
* main << A;
* main => B [ label="initOptions()" ];
- * B => options [ label="addOption()", URL="\ref gmx::Options::addOption()" ];
+ * B => options [ label="addOption()", URL="\ref gmx::IOptionsContainer::addOption()" ];
* ...;
* main << B;
* \endmsc
* the input into option-value pairs (one option may have multiple values), and
* passes these into the gmx::Options object, which is responsible for
* converting them into the appropriate types and storing the values into the
- * variables provided in the calls to gmx::Options::addOption().
+ * variables provided in the calls to gmx::IOptionsContainer::addOption().
* \msc
* main,
* parser [ label="parser" ],
* To implement new option types, it is necessary to subclass the templates
* OptionTemplate and OptionStorageTemplate with the type of the values that
* the option should provide as the template argument. After this is done, it
- * is possible to add options of this new type using Options::addOption().
+ * is possible to add options of this new type using IOptionsContainer::addOption().
*
* To implement new parsers, one can use OptionsAssigner, which provides an
* interface to set values in an Options object.
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2010,2012,2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2010,2012,2013,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
basicoptions.h
filenameoption.h
filenameoptionmanager.h
+ ioptionscontainer.h
optionfiletype.h
optionflags.h
options.h
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings,
OptionFlags staticFlags)
: flags_(settings.flags_ | staticFlags),
+ storeIsSet_(settings.storeIsSet_),
minValueCount_(settings.minValueCount_),
maxValueCount_(settings.maxValueCount_),
bInSet_(false), bSetValuesHadErrors_(false)
{
descr_ = settings.descr_;
}
+ if (storeIsSet_ != NULL)
+ {
+ *storeIsSet_ = false;
+ }
setFlag(efOption_ClearOnNextSet);
}
}
}
+void AbstractOptionStorage::markAsSet()
+{
+ setFlag(efOption_Set);
+ if (storeIsSet_ != NULL)
+ {
+ *storeIsSet_ = true;
+ }
+}
+
void AbstractOptionStorage::finishSet()
{
GMX_RELEASE_ASSERT(bInSet_, "startSet() not called");
// We mark the option as set even when there are errors to avoid additional
// errors from required options not set.
// TODO: There could be a separate flag for this purpose.
- setFlag(efOption_Set);
+ markAsSet();
if (!bSetValuesHadErrors_)
{
// TODO: Correct handling of the efOption_ClearOnNextSet requires
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
class AbstractOptionStorage;
template <typename T> class OptionStorageTemplate;
class OptionManagerContainer;
-class Options;
+
+namespace internal
+{
+class OptionsImpl;
+}
/*! \brief
* Abstract base class for specifying option properties.
//! Initializes the name and default values for an option.
explicit AbstractOption(const char *name)
: minValueCount_(1), maxValueCount_(1),
- name_(name), descr_(NULL)
+ name_(name), descr_(NULL), storeIsSet_(NULL)
{ }
/*! \brief
//! Sets the description for the option.
void setDescription(const char *descr) { descr_ = descr; }
+ //! Sets the storage location for whether the option is set.
+ void setStoreIsSet(bool *store) { storeIsSet_ = store; }
//! Sets a flag for the option.
void setFlag(OptionFlag flag) { flags_.set(flag); }
//! Clears a flag for the option.
//! Pointer to description of the option.
const char *descr_;
OptionFlags flags_;
+ bool *storeIsSet_;
/*! \brief
* Needed to initialize an AbstractOptionStorage object from this class
* without otherwise unnecessary accessors.
*/
friend class AbstractOptionStorage;
- /*! \brief
- * Needed to be able to call createStorage().
- */
- friend class Options;
+ //! Needed to be able to call createStorage().
+ friend class internal::OptionsImpl;
};
/*! \brief
*/
MyClass &storeVector(std::vector<T> *store)
{ storeVector_ = store; return me(); }
+ /*! \brief
+ * Stores whether the option was explicitly set.
+ *
+ * \param[in] store Variable to store the flag in.
+ *
+ * The value is set to `false` on creation of the option, and to `true`
+ * as soon as a value is assigned to the option. A default value does
+ * not set the flag to `true`, but assignment that uses
+ * defaultValueIfSet() does.
+ *
+ * The pointer provided should remain valid as long as the associated
+ * Options object exists.
+ */
+ MyClass &storeIsSet(bool *store)
+ { setStoreIsSet(store); return me(); }
protected:
/*! \cond libapi */
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
OptionFlags staticFlags);
//! Marks the option as set.
- void markAsSet() { flags_.set(efOption_Set); }
+ void markAsSet();
//! Returns true if the given flag is set.
bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
//! Sets the given flag.
std::string descr_;
//! Flags for the option.
OptionFlags flags_;
+ bool *storeIsSet_;
//! Minimum number of values required (in one set).
int minValueCount_;
//! Maximum allowed number of values (in one set), or -1 if no limit.
#include "gromacs/fileio/filenm.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fileredirector.h"
*/
std::string findExistingExtension(const std::string &prefix,
const FileNameOptionInfo &option,
- const FileInputRedirectorInterface *redirector)
+ const IFileInputRedirector *redirector)
{
ConstArrayRef<int> types = option.fileTypes();
ConstArrayRef<int>::const_iterator i;
}
//! Redirector for file existence checks.
- const FileInputRedirectorInterface *redirector_;
+ const IFileInputRedirector *redirector_;
//! Global default file name, if set.
std::string defaultFileName_;
//! Whether input option processing has been disabled.
}
void FileNameOptionManager::setInputRedirector(
- const FileInputRedirectorInterface *redirector)
+ const IFileInputRedirector *redirector)
{
impl_->redirector_ = redirector;
}
}
void FileNameOptionManager::addDefaultFileNameOption(
- Options *options, const char *name)
+ IOptionsContainer *options, const char *name)
{
options->addOption(
StringOption(name).store(&impl_->defaultFileName_)
namespace gmx
{
-class FileInputRedirectorInterface;
class FileNameOptionInfo;
-class Options;
+class IFileInputRedirector;
+class IOptionsContainer;
/*! \brief
* Handles interaction of file name options with global options.
* \inpublicapi
* \ingroup module_selection
*/
-class FileNameOptionManager : public OptionManagerInterface
+class FileNameOptionManager : public IOptionManager
{
public:
FileNameOptionManager();
* For tests, there should only be need to call this a single time,
* right after creating the manager.
*/
- void setInputRedirector(const FileInputRedirectorInterface *redirector);
+ void setInputRedirector(const IFileInputRedirector *redirector);
/*! \brief
* Disables special input file option handling.
* instead from an option-specific default
* (FileNameOption::defaultBaseName()).
*/
- void addDefaultFileNameOption(Options *options, const char *name);
+ void addDefaultFileNameOption(IOptionsContainer *options, const char *name);
/*! \brief
* Completes file name option values.
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief
+ * Declares gmx::IOptionsContainer.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inpublicapi
+ * \ingroup module_options
+ */
+#ifndef GMX_OPTIONS_IOPTIONSCONTAINER_H
+#define GMX_OPTIONS_IOPTIONSCONTAINER_H
+
+#include "gromacs/options/abstractoption.h"
+#include "gromacs/utility/gmxassert.h"
+
+namespace gmx
+{
+
+/*! \brief
+ * Interface for adding input options.
+ *
+ * This interface provides methods to add new options.
+ * Standard usage is for code to receive this interface and populate it with
+ * supported options:
+ * \code
+ // <as class attributes>
+ std::string arg1;
+ int arg2;
+
+ void MyClass::initOptions(gmx::IOptionsContainer *options)
+ {
+ options->addOption(gmx::StringOption("arg1").store(&arg1));
+ options->addOption(gmx::IntegerOption("arg2").store(&arg2));
+ }
+ \endcode
+ * The caller can collect options from multiple sources into a single container
+ * (a gmx::Options), and use a parser implementation such as CommandLineParser
+ * to provide values for the options.
+ *
+ * Header basicoptions.h provides declarations of several standard
+ * option types for use with addOption(). Documentation of those classes
+ * also give more examples of how to define options.
+ *
+ * \inpublicapi
+ * \ingroup module_options
+ */
+class IOptionsContainer
+{
+ public:
+ /*! \brief
+ * Adds a recognized option.
+ *
+ * \param[in] settings Option description.
+ * \returns OptionInfo object for the created option (never NULL).
+ * \throws APIError if invalid option settings are provided.
+ *
+ * This method provides the internal implementation, but in most cases
+ * the templated method is called from user code.
+ * See the templated method for more details.
+ */
+ virtual OptionInfo *addOption(const AbstractOption &settings) = 0;
+ /*! \brief
+ * Adds a recognized option.
+ *
+ * \tparam OptionType Type of the options description object.
+ * \param[in] settings Option description.
+ * \returns OptionInfo object for the created option (never NULL).
+ * \throws APIError if invalid option settings are provided.
+ *
+ * The return value is a pointer for more convenient use in callers:
+ * often callers need to declare the variable that will hold the return
+ * value in wider scope than would be achieved by declaring it at the
+ * site where addOption() is called.
+ * The returned pointer must not be freed.
+ *
+ * See \link Options class documentation \endlink for example usage.
+ *
+ * \libinternal
+ * \p OptionType::InfoType must specify a type that derives from
+ * OptionInfo and matches the type that is returned by
+ * AbstractOptionStorage::optionInfo() for the storage object that
+ * corresponds to \p OptionType.
+ */
+ template <class OptionType>
+ typename OptionType::InfoType *addOption(const OptionType &settings)
+ {
+ OptionInfo *info
+ = addOption(static_cast<const AbstractOption &>(settings));
+ GMX_ASSERT(info->isType<typename OptionType::InfoType>(),
+ "Mismatching option info type declaration and implementation");
+ return info->toType<typename OptionType::InfoType>();
+ }
+
+ protected:
+ // Disallow deletion through the interface.
+ // (no need for the virtual, but some compilers warn otherwise)
+ virtual ~IOptionsContainer();
+
+};
+
+} // namespace
+
+#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class OptionManagerInterface;
+class IOptionManager;
/*! \libinternal
* \brief
bool empty() const { return list_.empty(); }
//! Adds a manager to the container.
- void add(OptionManagerInterface *manager)
+ void add(IOptionManager *manager)
{
list_.push_back(manager);
}
* Retrieves a manager of a certain type.
*
* \tparam ManagerType Type of manager to retrieve
- * (should derive from OptionManagerInterface).
+ * (should derive from IOptionManager).
* \returns The manager, or `NULL` if there is none.
*
* This method is used in AbstractOption::createStorage() to retrieve
private:
//! Shorthand for the internal container type.
- typedef std::vector<OptionManagerInterface *> ListType;
+ typedef std::vector<IOptionManager *> ListType;
ListType list_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_OPTIONS_OPTIONS_IMPL_H
#define GMX_OPTIONS_OPTIONS_IMPL_H
+#include <list>
+#include <map>
#include <string>
#include <vector>
class AbstractOptionStorage;
+namespace internal
+{
+
/*! \internal
* \brief
* Private implementation class for Options.
*
* \ingroup module_options
*/
-class Options::Impl
+class OptionsImpl
{
public:
+ /*! \internal \brief
+ * Describes a group of options (see Options::addGroup()).
+ *
+ * \ingroup module_options
+ */
+ class Group : public IOptionsContainer
+ {
+ public:
+ //! Convenience typedef for list of options.
+ typedef std::vector<AbstractOptionStorage *> OptionList;
+ //! Convenience typedef for list of subgroups.
+ typedef std::list<Group> SubgroupList;
+
+ //! Creates a group within the given Options.
+ explicit Group(OptionsImpl *parent) : parent_(parent) {}
+
+ //! Adds an option subgroup.
+ IOptionsContainer &addGroup();
+ // From IOptionsContainer
+ virtual OptionInfo *addOption(const AbstractOption &settings);
+
+ //! Containing options object.
+ OptionsImpl *parent_;
+ /*! \brief
+ * List of options, in insertion order.
+ *
+ * Pointers in this container point to the objects managed by
+ * Impl::optionsMap_.
+ */
+ OptionList options_;
+ //! List of groups, in insertion order.
+ SubgroupList subgroups_;
+ };
+
//! Smart pointer for managing an AbstractOptionStorage object.
typedef gmx_unique_ptr<AbstractOptionStorage>::type
AbstractOptionStoragePointer;
//! Convenience type for list of sections.
typedef std::vector<Options *> SubSectionList;
- //! Convenience type for list of options.
- typedef std::vector<AbstractOptionStoragePointer> OptionList;
+ //! Convenience typedef for a map that contains all the options.
+ typedef std::map<std::string, AbstractOptionStoragePointer> OptionMap;
//! Sets the name and title.
- Impl(const char *name, const char *title);
- ~Impl();
+ OptionsImpl(const char *name, const char *title);
/*! \brief
* Finds a subsection by name.
//! Name for the Options object.
std::string name_;
- //! Description title for the Options object.
- std::string title_;
- //! Full description for the Options object.
- std::string description_;
/*! \brief
* Option managers set for this collection.
*
* This is non-empty only for the top-level Options object.
*/
OptionManagerContainer managers_;
+ /*! \brief
+ * Group that contains all options (and subgroups).
+ *
+ * This is used to store the insertion order of options.
+ */
+ Group rootGroup_;
+ //! Map from option names to options; owns the option storage objects.
+ OptionMap optionMap_;
/*! \brief
* List of subsections, in insertion order.
*
* management is performed elsewhere.
*/
SubSectionList subSections_;
- /*! \brief
- * List of options, in insertion order.
- *
- * All objects in this container are owned by this object, and are
- * freed in the destructor.
- */
- OptionList options_;
//! Options object that contains this object as a subsection, or NULL.
Options *parent_;
};
+} // namespace internal
+
} // namespace gmx
#endif
#include "options.h"
+#include <utility>
+
#include "gromacs/options/abstractoption.h"
#include "gromacs/options/abstractoptionstorage.h"
#include "gromacs/utility/arrayref.h"
{
/********************************************************************
- * OptionManagerInterface
+ * IOptionManager
*/
-OptionManagerInterface::~OptionManagerInterface()
+IOptionManager::~IOptionManager()
{
}
/********************************************************************
- * Options::Impl
+ * IOptionsContainer
*/
-Options::Impl::Impl(const char *name, const char *title)
- : name_(name != NULL ? name : ""), title_(title != NULL ? title : ""),
- parent_(NULL)
+IOptionsContainer::~IOptionsContainer()
{
}
-Options::Impl::~Impl()
+/********************************************************************
+ * OptionsImpl
+ */
+
+namespace internal
+{
+
+OptionsImpl::OptionsImpl(const char *name, const char * /*title*/)
+ : name_(name != NULL ? name : ""), rootGroup_(this),
+ parent_(NULL)
{
}
-Options *Options::Impl::findSubSection(const char *name) const
+Options *OptionsImpl::findSubSection(const char *name) const
{
SubSectionList::const_iterator i;
for (i = subSections_.begin(); i != subSections_.end(); ++i)
return NULL;
}
-AbstractOptionStorage *Options::Impl::findOption(const char *name) const
+AbstractOptionStorage *OptionsImpl::findOption(const char *name) const
{
- OptionList::const_iterator i;
- for (i = options_.begin(); i != options_.end(); ++i)
+ OptionMap::const_iterator i = optionMap_.find(name);
+ if (i == optionMap_.end())
{
- if ((*i)->name() == name)
- {
- return i->get();
- }
+ return NULL;
}
- return NULL;
+ return i->second.get();
}
-void Options::Impl::startSource()
+void OptionsImpl::startSource()
{
- OptionList::const_iterator i;
- for (i = options_.begin(); i != options_.end(); ++i)
+ OptionMap::const_iterator i;
+ for (i = optionMap_.begin(); i != optionMap_.end(); ++i)
{
- AbstractOptionStorage &option = **i;
+ AbstractOptionStorage &option = *i->second;
option.startSource();
}
SubSectionList::const_iterator j;
}
/********************************************************************
- * Options
+ * OptionsImpl::Group
*/
-Options::Options(const char *name, const char *title)
- : impl_(new Impl(name, title))
+IOptionsContainer &OptionsImpl::Group::addGroup()
{
+ subgroups_.push_back(Group(parent_));
+ return subgroups_.back();
}
-Options::~Options()
+OptionInfo *OptionsImpl::Group::addOption(const AbstractOption &settings)
{
+ OptionsImpl *root = parent_;
+ while (root->parent_ != NULL)
+ {
+ root = root->parent_->impl_.get();
+ }
+ AbstractOptionStoragePointer option(settings.createStorage(root->managers_));
+ options_.reserve(options_.size() + 1);
+ std::pair<OptionMap::iterator, bool> insertionResult =
+ parent_->optionMap_.insert(std::make_pair(option->name(),
+ move(option)));
+ if (!insertionResult.second)
+ {
+ GMX_THROW(APIError("Duplicate option: " + option->name()));
+ }
+ AbstractOptionStorage &insertedOption = *insertionResult.first->second;
+ options_.push_back(&insertedOption);
+ return &insertedOption.optionInfo();
}
-const std::string &Options::name() const
-{
- return impl_->name_;
-}
+} // namespace internal
-const std::string &Options::title() const
-{
- return impl_->title_;
-}
+using internal::OptionsImpl;
+
+/********************************************************************
+ * Options
+ */
-const std::string &Options::description() const
+Options::Options(const char *name, const char *title)
+ : impl_(new OptionsImpl(name, title))
{
- return impl_->description_;
}
-void Options::setDescription(const std::string &desc)
+Options::~Options()
{
- impl_->description_ = desc;
}
-void Options::setDescription(const ConstArrayRef<const char *> &descArray)
+const std::string &Options::name() const
{
- impl_->description_ = joinStrings(descArray, "\n");
+ return impl_->name_;
}
-void Options::addManager(OptionManagerInterface *manager)
+
+void Options::addManager(IOptionManager *manager)
{
GMX_RELEASE_ASSERT(impl_->parent_ == NULL,
"Can only add a manager in a top-level Options object");
// This ensures that all options see the same set of managers.
- GMX_RELEASE_ASSERT(impl_->options_.empty(),
+ GMX_RELEASE_ASSERT(impl_->optionMap_.empty(),
"Can only add a manager before options");
// This check could be relaxed if we instead checked that the subsections
// do not have options.
{
// This is required, because managers are used from the root Options
// object, so they are only seen after the subsection has been added.
- GMX_RELEASE_ASSERT(section->impl_->options_.empty(),
+ GMX_RELEASE_ASSERT(section->impl_->optionMap_.empty(),
"Can only add a subsection before it has any options");
GMX_RELEASE_ASSERT(section->impl_->managers_.empty(),
"Can only have managers in a top-level Options object");
section->impl_->parent_ = this;
}
-OptionInfo *Options::addOption(const AbstractOption &settings)
+IOptionsContainer &Options::addGroup()
{
- Options::Impl *root = impl_.get();
- while (root->parent_ != NULL)
- {
- root = root->parent_->impl_.get();
- }
- Impl::AbstractOptionStoragePointer option(settings.createStorage(root->managers_));
- if (impl_->findOption(option->name().c_str()) != NULL)
- {
- GMX_THROW(APIError("Duplicate option: " + option->name()));
- }
- impl_->options_.push_back(move(option));
- return &impl_->options_.back()->optionInfo();
+ return impl_->rootGroup_.addGroup();
}
-bool Options::isSet(const char *name) const
+OptionInfo *Options::addOption(const AbstractOption &settings)
{
- AbstractOptionStorage *option = impl_->findOption(name);
- return (option != NULL ? option->isSet() : false);
+ return impl_->rootGroup_.addOption(settings);
}
void Options::finish()
{
// TODO: Consider how to customize these error messages based on context.
- ExceptionInitializer errors("Invalid input values");
- Impl::OptionList::const_iterator i;
- for (i = impl_->options_.begin(); i != impl_->options_.end(); ++i)
+ ExceptionInitializer errors("Invalid input values");
+ OptionsImpl::OptionMap::const_iterator i;
+ for (i = impl_->optionMap_.begin(); i != impl_->optionMap_.end(); ++i)
{
- AbstractOptionStorage &option = **i;
+ AbstractOptionStorage &option = *i->second;
try
{
option.finish();
errors.addCurrentExceptionAsNested();
}
}
- Impl::SubSectionList::const_iterator j;
+ OptionsImpl::SubSectionList::const_iterator j;
for (j = impl_->subSections_.begin(); j != impl_->subSections_.end(); ++j)
{
Options §ion = **j;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string>
-#include "gromacs/options/abstractoption.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/classhelpers.h"
-#include "gromacs/utility/gmxassert.h"
namespace gmx
{
-template <typename T> class ConstArrayRef;
-
class AbstractOption;
class OptionsAssigner;
class OptionsIterator;
+namespace internal
+{
+class OptionsImpl;
+}
+
/*! \brief
* Base class for option managers.
*
* \inlibraryapi
* \ingroup module_options
*/
-class OptionManagerInterface
+class IOptionManager
{
protected:
- virtual ~OptionManagerInterface();
+ virtual ~IOptionManager();
};
/*! \brief
* Collection of options.
*
- * This class provides a standard interface for implementing input options.
- * Standard usage is to write a method that creates an Options that is owned by
- * the object, populates it with supported options, and then returns it:
- * \code
- // <as class attributes>
- using gmx::Options;
- Options options("common", "Common Options");
- std::string arg1;
- int arg2;
-
- // <populating>
- using gmx::StringOption;
- using gmx::IntegerOption;
- options.addOption(StringOption("arg1").store(&arg1));
- options.addOption(IntegerOption("arg2").store(&arg2));
- return &options;
- \endcode
- * The caller of that method can then use a parser implementation such as
- * CommandLineParser to provide values for the options.
+ * See \ref module_options for an overview of how the options work.
+ * The IOptionsContainer interface documents how to add options.
*
- * Header basicoptions.h provides declarations of several standard
- * option types for use with addOption(). Documentation of those classes
- * also give more examples of how to define options.
- *
- * In order to keep the public interface of this class simple and to reduce
- * build dependencies on objects that simply provide options, functionality
+ * In order to keep the public interface of this class simple, functionality
* to assign values to options is provided by a separate OptionsAssigner class.
* Similarly, functionality for looping over all options (e.g., for writing out
* help) is provided by OptionsIterator.
* \inpublicapi
* \ingroup module_options
*/
-class Options
+class Options : public IOptionsContainer
{
public:
/*! \brief
//! Returns the short name of the option collection.
const std::string &name() const;
- //! Returns the title of the option collection.
- const std::string &title() const;
- //! Returns the full description of the option collection.
- const std::string &description() const;
-
- /*! \brief
- * Sets the full description of the option collection.
- *
- * \param[in] desc String to set as the description.
- *
- * This overload is mainly useful if the description is very short.
- * Currently this is mostly the case in unit testing.
- */
- void setDescription(const std::string &desc);
- /*! \brief
- * Sets the full description of the option collection from string array.
- *
- * \param[in] descArray String array to set as the description.
- *
- * All strings in `descArray` are concatenated to form the description.
- * Spaces are inserted between strings if they are missing.
- *
- * Example usage:
- * \code
- const char *const desc[] = {
- "This is the description",
- "for the options"
- };
-
- gmx::Options options(NULL, NULL);
- options.setDescription(desc);
- \endcode
- *
- * To use this overload, you must also include
- * `gromacs/utility/arrayref.h`.
- */
- void setDescription(const ConstArrayRef<const char *> &descArray);
/*! \brief
* Adds an option manager.
*
* This method cannot be called after adding options or subsections.
*/
- void addManager(OptionManagerInterface *manager);
+ void addManager(IOptionManager *manager);
/*! \brief
* Adds an option collection as a subsection of this collection.
* If an attempt is made, the function asserts.
*/
void addSubSection(Options *section);
+
/*! \brief
- * Adds a recognized option to the collection.
- *
- * \param[in] settings Option description.
- * \returns OptionInfo object for the created option (never NULL).
- * \throws APIError if invalid option settings are provided.
- *
- * This method provides the internal implementation, but in most cases
- * the templated method is called from user code.
- * See the templated method for more details.
- */
- OptionInfo *addOption(const AbstractOption &settings);
- /*! \brief
- * Adds a recognized option to the collection.
- *
- * \tparam OptionType Type of the options description object.
- * \param[in] settings Option description.
- * \returns OptionInfo object for the created option (never NULL).
- * \throws APIError if invalid option settings are provided.
+ * Creates a subgroup of options within the current options.
*
- * The return value is a pointer for more convenient use in callers:
- * often callers need to declare the variable that will hold the return
- * value in wider scope than would be achieved by declaring it at the
- * site where addOption() is called.
- * The returned pointer must not be freed.
+ * To add options to the group, use the returned interface.
*
- * See \link Options class documentation \endlink for example usage.
- *
- * \libinternal
- * \p OptionType::InfoType must specify a type that derives from
- * OptionInfo and matches the type that is returned by
- * AbstractOptionStorage::optionInfo() for the storage object that
- * corresponds to \p OptionType.
+ * Currently, this is only used to influence the order of options:
+ * all options in a group appear before options in a group added after
+ * it, no matter in which order the options are added to the groups.
+ * In the future, the groups could also be used to influence the help
+ * output.
*/
- template <class OptionType>
- typename OptionType::InfoType *addOption(const OptionType &settings)
- {
- OptionInfo *info
- = addOption(static_cast<const AbstractOption &>(settings));
- GMX_ASSERT(info->isType<typename OptionType::InfoType>(),
- "Mismatching option info type declaration and implementation");
- return info->toType<typename OptionType::InfoType>();
- }
+ IOptionsContainer &addGroup();
+
+ // From IOptionsContainer
+ virtual OptionInfo *addOption(const AbstractOption &settings);
+ using IOptionsContainer::addOption;
- //! Returns true if option \p name is set.
- bool isSet(const char *name) const;
/*! \brief
* Notifies the collection that all option values are assigned.
*
void finish();
private:
- class Impl;
-
- PrivateImplPointer<Impl> impl_;
+ PrivateImplPointer<internal::OptionsImpl> impl_;
+ //! Needed for the implementation to access subsections.
+ friend class internal::OptionsImpl;
//! Needed to be able to extend the interface of this object.
friend class OptionsAssigner;
//! Needed to be able to extend the interface of this object.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
Options &options_;
//! Recognize boolean option "name" also as "noname".
bool bAcceptBooleanNoPrefix_;
- //! Look for options in all sections, not just the current one.
- bool bNoStrictSectioning_;
/*! \brief
* List of (sub)sections being assigned to.
*
OptionsAssigner::Impl::Impl(Options *options)
: options_(*options), bAcceptBooleanNoPrefix_(false),
- bNoStrictSectioning_(false), currentOption_(NULL),
- currentValueCount_(0), reverseBoolean_(false)
+ currentOption_(NULL), currentValueCount_(0), reverseBoolean_(false)
{
sectionStack_.push_back(&options_);
}
{
GMX_RELEASE_ASSERT(currentOption_ == NULL,
"Cannot search for another option while processing one");
- AbstractOptionStorage *option = NULL;
- Options *section = NULL;
- Options *root = ¤tSection();
- Options *oldRoot = NULL;
- int upcount = 0;
- std::deque<Options *> searchList;
- searchList.push_back(root);
- while (option == NULL && !searchList.empty())
+ const Options §ion = currentSection();
+ AbstractOptionStorage *option = section.impl_->findOption(name);
+ if (option == NULL && bAcceptBooleanNoPrefix_)
{
- section = searchList.front();
- option = section->impl_->findOption(name);
- if (option == NULL && bAcceptBooleanNoPrefix_)
+ if (name[0] == 'n' && name[1] == 'o')
{
- if (name[0] == 'n' && name[1] == 'o')
+ option = section.impl_->findOption(name + 2);
+ if (option != NULL && option->isBoolean())
{
- option = section->impl_->findOption(name + 2);
- if (option != NULL && option->isBoolean())
- {
- reverseBoolean_ = true;
- }
- else
- {
- option = NULL;
- }
+ reverseBoolean_ = true;
}
- }
- searchList.pop_front();
- if (bNoStrictSectioning_)
- {
- Options::Impl::SubSectionList::const_iterator i;
- for (i = section->impl_->subSections_.begin();
- i != section->impl_->subSections_.end(); ++i)
+ else
{
- if (*i != oldRoot)
- {
- searchList.push_back(*i);
- }
- }
- if (searchList.empty() && root != &options_)
- {
- root = root->impl_->parent_;
- ++upcount;
- searchList.push_back(root);
+ option = NULL;
}
}
}
- if (bNoStrictSectioning_ && option != NULL)
- {
- while (upcount > 0)
- {
- sectionStack_.pop_back();
- --upcount;
- }
- std::vector<Options *> sections;
- while (section != ¤tSection())
- {
- sections.push_back(section);
- section = section->impl_->parent_;
- }
- while (!sections.empty())
- {
- sectionStack_.push_back(sections.back());
- sections.pop_back();
- }
- }
return option;
}
impl_->bAcceptBooleanNoPrefix_ = bEnabled;
}
-void OptionsAssigner::setNoStrictSectioning(bool bEnabled)
-{
- impl_->bNoStrictSectioning_ = bEnabled;
-}
-
void OptionsAssigner::start()
{
impl_->options_.impl_->startSource();
void OptionsAssigner::finish()
{
GMX_RELEASE_ASSERT(impl_->currentOption_ == NULL, "finishOption() not called");
- if (impl_->bNoStrictSectioning_)
- {
- while (impl_->inSubSection())
- {
- finishSubSection();
- }
- }
GMX_RELEASE_ASSERT(!impl_->inSubSection(), "finishSubSection() not called");
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* Does not throw.
*/
void setAcceptBooleanNoPrefix(bool bEnabled);
- /*! \brief
- * Sets the assigner to find options in non-active sections.
- *
- * By default, options are only looked for in the currently active
- * subsection. With this option set, if no matching option is found in
- * the current section, a breadth-first search is performed, first on
- * all subsections of the current section, and then going up one level
- * at a time. The first matching option is used, and the current
- * section is changed to the section that contains the matching option.
- *
- * Can be set or cleared at any time, and will have effect on all
- * subsequent calls of startOption().
- *
- * Does not throw.
- */
- void setNoStrictSectioning(bool bEnabled);
/*! \brief
* Starts assigning values.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
+using internal::OptionsImpl;
+
+namespace
+{
+
+//! Helper function to call visitOptions() and handle correct indirection.
+void visitOption(OptionsVisitor *visitor, OptionInfo &optionInfo)
+{
+ visitor->visitOption(optionInfo);
+}
+//! Helper function to call visitOptions() and handle correct indirection.
+void visitOption(OptionsModifyingVisitor *visitor, OptionInfo &optionInfo)
+{
+ visitor->visitOption(&optionInfo);
+}
+
+//! Helper function to recursively visit all options in a group.
+template <class VisitorType>
+void acceptOptionsGroup(const OptionsImpl::Group &group, VisitorType *visitor)
+{
+ OptionsImpl::Group::OptionList::const_iterator option;
+ for (option = group.options_.begin(); option != group.options_.end(); ++option)
+ {
+ visitOption(visitor, (*option)->optionInfo());
+ }
+ OptionsImpl::Group::SubgroupList::const_iterator subgroup;
+ for (subgroup = group.subgroups_.begin(); subgroup != group.subgroups_.end(); ++subgroup)
+ {
+ acceptOptionsGroup(*subgroup, visitor);
+ }
+}
+
+} // namespace
+
/********************************************************************
* OptionsIterator
*/
void OptionsIterator::acceptSubSections(OptionsVisitor *visitor) const
{
- const Options::Impl::SubSectionList &subSectionList =
+ const OptionsImpl::SubSectionList &subSectionList =
options_.impl_->subSections_;
- Options::Impl::SubSectionList::const_iterator i;
+ OptionsImpl::SubSectionList::const_iterator i;
for (i = subSectionList.begin(); i != subSectionList.end(); ++i)
{
visitor->visitSubSection(*(*i));
void OptionsIterator::acceptOptions(OptionsVisitor *visitor) const
{
- const Options::Impl::OptionList &optionList =
- options_.impl_->options_;
- Options::Impl::OptionList::const_iterator i;
- for (i = optionList.begin(); i != optionList.end(); ++i)
- {
- // This is not strictly const-correct, since optionInfo() is
- // not const (while the input options is), but this makes things much
- // simpler.
- visitor->visitOption((*i)->optionInfo());
- }
+ acceptOptionsGroup(options_.impl_->rootGroup_, visitor);
}
/********************************************************************
void OptionsModifyingIterator::acceptSubSections(OptionsModifyingVisitor *visitor) const
{
- const Options::Impl::SubSectionList &subSectionList =
+ const OptionsImpl::SubSectionList &subSectionList =
options_.impl_->subSections_;
- Options::Impl::SubSectionList::const_iterator i;
+ OptionsImpl::SubSectionList::const_iterator i;
for (i = subSectionList.begin(); i != subSectionList.end(); ++i)
{
visitor->visitSubSection(*i);
void OptionsModifyingIterator::acceptOptions(OptionsModifyingVisitor *visitor) const
{
- const Options::Impl::OptionList &optionList =
- options_.impl_->options_;
- Options::Impl::OptionList::const_iterator i;
- for (i = optionList.begin(); i != optionList.end(); ++i)
- {
- visitor->visitOption(&(*i)->optionInfo());
- }
+ acceptOptionsGroup(options_.impl_->rootGroup_, visitor);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/stringutil.h"
+#include "testutils/testasserts.h"
+
namespace
{
{
gmx::Options options(NULL, NULL);
std::vector<int> values;
+ bool bIsSet;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
- IntegerOption("p").storeVector(&values).multiValue()));
+ IntegerOption("p")
+ .storeVector(&values).storeIsSet(&bIsSet)
+ .multiValue()));
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_TRUE(options.isSet("p"));
+ EXPECT_TRUE(bIsSet);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(1, values[0]);
}
{
gmx::Options options(NULL, NULL);
std::vector<int> values;
+ bool bIsSet;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
- IntegerOption("p").storeVector(&values).allowMultiple()));
-
- gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startOption("p"));
- ASSERT_NO_THROW(assigner.appendValue("1"));
- EXPECT_NO_THROW(assigner.finishOption());
- ASSERT_NO_THROW(assigner.startOption("p"));
- ASSERT_NO_THROW(assigner.appendValue("2"));
- EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
-
- EXPECT_TRUE(options.isSet("p"));
+ IntegerOption("p")
+ .storeVector(&values).storeIsSet(&bIsSet)
+ .allowMultiple()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW_GMX(assigner.start());
+ ASSERT_NO_THROW_GMX(assigner.startOption("p"));
+ ASSERT_NO_THROW_GMX(assigner.appendValue("1"));
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ ASSERT_NO_THROW_GMX(assigner.startOption("p"));
+ ASSERT_NO_THROW_GMX(assigner.appendValue("2"));
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
+
+ EXPECT_TRUE(bIsSet);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(1, values[0]);
EXPECT_EQ(2, values[1]);
EXPECT_EQ(0, value1);
}
-TEST(OptionsAssignerTest, HandlesSubSections)
+TEST(OptionsAssignerTest, HandlesGroups)
{
- gmx::Options options(NULL, NULL);
- gmx::Options sub1("section1", NULL);
- gmx::Options sub2("section2", NULL);
- int value = 3;
- int value1 = 1;
- int value2 = 2;
+ gmx::Options options(NULL, NULL);
+ gmx::IOptionsContainer &group1 = options.addGroup();
+ gmx::IOptionsContainer &group2 = options.addGroup();
+ int value = 3;
+ int value1 = 1;
+ int value2 = 2;
using gmx::IntegerOption;
- ASSERT_NO_THROW(options.addSubSection(&sub1));
- ASSERT_NO_THROW(options.addSubSection(&sub2));
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
- ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
- ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
+ ASSERT_NO_THROW(group1.addOption(IntegerOption("q").store(&value1)));
+ ASSERT_NO_THROW(group2.addOption(IntegerOption("r").store(&value2)));
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startSubSection("section1"));
ASSERT_NO_THROW(assigner.startOption("p"));
EXPECT_NO_THROW(assigner.appendValue("5"));
EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finishSubSection());
- ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.startOption("q"));
EXPECT_NO_THROW(assigner.appendValue("4"));
EXPECT_NO_THROW(assigner.finishOption());
- ASSERT_NO_THROW(assigner.startSubSection("section2"));
- ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.startOption("r"));
EXPECT_NO_THROW(assigner.appendValue("6"));
EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finishSubSection());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(4, value);
- EXPECT_EQ(5, value1);
+ EXPECT_EQ(5, value);
+ EXPECT_EQ(4, value1);
EXPECT_EQ(6, value2);
}
-TEST(OptionsAssignerTest, HandlesNoStrictSubSections)
+TEST(OptionsAssignerTest, HandlesSubSections)
{
gmx::Options options(NULL, NULL);
gmx::Options sub1("section1", NULL);
gmx::Options sub2("section2", NULL);
- int pvalue = 3;
- int pvalue1 = 1;
- int qvalue = 4;
- int pvalue2 = 2;
- int rvalue = 5;
+ int value = 3;
+ int value1 = 1;
+ int value2 = 2;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addSubSection(&sub1));
ASSERT_NO_THROW(options.addSubSection(&sub2));
- ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
- ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
- ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
- ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
- ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
+ ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
+ ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
gmx::OptionsAssigner assigner(&options);
- assigner.setNoStrictSectioning(true);
EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startOption("q"));
- EXPECT_NO_THROW(assigner.appendValue("6"));
- EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startSubSection("section1"));
ASSERT_NO_THROW(assigner.startOption("p"));
- EXPECT_NO_THROW(assigner.appendValue("7"));
- EXPECT_NO_THROW(assigner.finishOption());
- ASSERT_NO_THROW(assigner.startOption("r"));
- EXPECT_NO_THROW(assigner.appendValue("8"));
+ EXPECT_NO_THROW(assigner.appendValue("5"));
EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finishSubSection());
ASSERT_NO_THROW(assigner.startOption("p"));
- EXPECT_NO_THROW(assigner.appendValue("9"));
+ EXPECT_NO_THROW(assigner.appendValue("4"));
EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finishSubSection());
+ ASSERT_NO_THROW(assigner.startSubSection("section2"));
ASSERT_NO_THROW(assigner.startOption("p"));
- EXPECT_NO_THROW(assigner.appendValue("10"));
+ EXPECT_NO_THROW(assigner.appendValue("6"));
EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finishSubSection());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(6, qvalue);
- EXPECT_EQ(7, pvalue1);
- EXPECT_EQ(8, rvalue);
- EXPECT_EQ(9, pvalue2);
- EXPECT_EQ(10, pvalue);
+ EXPECT_EQ(4, value);
+ EXPECT_EQ(5, value1);
+ EXPECT_EQ(6, value2);
}
TEST(OptionsAssignerTest, HandlesMultipleSources)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <algorithm>
#include "gromacs/options/basicoptions.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/utility/arrayref.h"
}
}
-void TimeUnitManager::addTimeUnitOption(Options *options, const char *name)
+void TimeUnitManager::addTimeUnitOption(IOptionsContainer *options, const char *name)
{
options->addOption(StringOption(name).enumValue(g_timeUnits)
.defaultValue(g_timeUnits[timeUnit()])
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
+class IOptionsContainer;
class Options;
/*! \brief
* Adds an enum option to \p options to select the time unit for this
* manager.
*/
- void addTimeUnitOption(Options *options, const char *name);
+ void addTimeUnitOption(IOptionsContainer *options, const char *name);
/*! \brief
* Scales user input values given to time options.
*
#include "gromacs/domdec/domdec.h"
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/copyrite.h"
#include "gromacs/legacyheaders/gmx_ga2la.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
/********************************************************************
* gmx_ana_indexgrps_t functions
}
/*!
- * \param[in] fp Where to print the output.
+ * \param[in] writer Writer to use for output.
* \param[in] g Index groups to print.
* \param[in] maxn Maximum number of indices to print
* (-1 = print all, 0 = print only names).
*/
void
-gmx_ana_indexgrps_print(FILE *fp, gmx_ana_indexgrps_t *g, int maxn)
+gmx_ana_indexgrps_print(gmx::TextWriter *writer, gmx_ana_indexgrps_t *g, int maxn)
{
for (int i = 0; i < g->nr; ++i)
{
- fprintf(fp, " Group %2d \"%s\" ", i, g->names[i].c_str());
- gmx_ana_index_dump(fp, &g->g[i], maxn);
+ writer->writeString(gmx::formatString(" Group %2d \"%s\" ",
+ i, g->names[i].c_str()));
+ gmx_ana_index_dump(writer, &g->g[i], maxn);
}
}
}
/*!
- * \param[in] fp Where to print the output.
+ * \param[in] writer Writer to use for output.
* \param[in] g Index group to print.
* \param[in] maxn Maximum number of indices to print (-1 = print all).
*/
void
-gmx_ana_index_dump(FILE *fp, gmx_ana_index_t *g, int maxn)
+gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn)
{
- int j, n;
-
- fprintf(fp, "(%d atoms)", g->isize);
+ writer->writeString(gmx::formatString("(%d atoms)", g->isize));
if (maxn != 0)
{
- fprintf(fp, ":");
- n = g->isize;
+ writer->writeString(":");
+ int n = g->isize;
if (maxn >= 0 && n > maxn)
{
n = maxn;
}
- for (j = 0; j < n; ++j)
+ for (int j = 0; j < n; ++j)
{
- fprintf(fp, " %d", g->index[j]+1);
+ writer->writeString(gmx::formatString(" %d", g->index[j]+1));
}
if (n < g->isize)
{
- fprintf(fp, " ...");
+ writer->writeString(" ...");
}
}
- fprintf(fp, "\n");
+ writer->writeLine();
}
int
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/types/simple.h"
#include "gromacs/topology/block.h"
+namespace gmx
+{
+class TextWriter;
+}
+
struct t_topology;
/** Stores a set of index groups. */
/** Writes out a list of index groups. */
void
-gmx_ana_indexgrps_print(FILE *fp, gmx_ana_indexgrps_t *g, int maxn);
+gmx_ana_indexgrps_print(gmx::TextWriter *writer, gmx_ana_indexgrps_t *g, int maxn);
/*@}*/
/*! \name Functions for handling gmx_ana_index_t
/** Writes out the contents of a index group. */
void
-gmx_ana_index_dump(FILE *fp, gmx_ana_index_t *g, int maxn);
+gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn);
/*! \brief
* Returns maximum atom index that appears in an index group.
#include <algorithm>
#include <vector>
-#include "thread_mpi/mutex.h"
-
#include "gromacs/legacyheaders/names.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/mutex.h"
#include "gromacs/utility/stringutil.h"
namespace gmx
//! Data structure to hold the grid cell contents.
CellList cells_;
- tMPI::mutex createPairSearchMutex_;
+ Mutex createPairSearchMutex_;
PairSearchList pairSearchList_;
friend class AnalysisNeighborhoodPairSearchImpl;
AnalysisNeighborhoodSearchImpl::PairSearchImplPointer
AnalysisNeighborhoodSearchImpl::getPairSearch()
{
- tMPI::lock_guard<tMPI::mutex> lock(createPairSearchMutex_);
+ lock_guard<Mutex> lock(createPairSearchMutex_);
// TODO: Consider whether this needs to/can be faster, e.g., by keeping a
// separate pool of unused search objects.
PairSearchList::const_iterator i;
SearchImplPointer getSearch();
- tMPI::mutex createSearchMutex_;
+ Mutex createSearchMutex_;
SearchList searchList_;
real cutoff_;
const t_blocka *excls_;
AnalysisNeighborhood::Impl::SearchImplPointer
AnalysisNeighborhood::Impl::getSearch()
{
- tMPI::lock_guard<tMPI::mutex> lock(createSearchMutex_);
+ lock_guard<Mutex> lock(createSearchMutex_);
// TODO: Consider whether this needs to/can be faster, e.g., by keeping a
// separate pool of unused search objects.
SearchList::const_iterator i;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
}
//!\}
-#ifndef GMX_CXX11
+#if !GMX_CXX11
//! No-op to enable use of same get()/set() implementation as with C++11.
static gmx::SelectionParserValue &move(gmx::SelectionParserValue &src)
{
* \param[in] src Semantic value to get the value from.
* \returns Retrieved value.
* \throws unspecified Any exception thrown by the move constructor of
- * ValueType (copy constructor if GMX_CXX11 is not set).
+ * ValueType (copy constructor if GMX_CXX11 is 0).
*
* There should be no statements that may throw exceptions in actions before
* this function has been called for all semantic values that have a C++ object
* \param[in] value Value to put into the semantic value.
* \throws std::bad_alloc if out of memory.
* \throws unspecified Any exception thrown by the move constructor of
- * ValueType (copy constructor if GMX_CXX11 is not set).
+ * ValueType (copy constructor if GMX_CXX11 is 0).
*
* This should be the last statement before ::END_ACTION, except for a
* possible ::CHECK_SEL.
* methods and initializes the children of the method element.
* - selectioncollection.h, selectioncollection.cpp:
* These files define the high-level public interface to the parser
- * through SelectionCollection::parseFromStdin(),
- * SelectionCollection::parseFromFile() and
+ * through SelectionCollection::parseInteractive(),
+ * SelectionCollection::parseFromStdin(),
+ * SelectionCollection::parseFromFile(), and
* SelectionCollection::parseFromString().
*
* The basic control flow in the parser is as follows: when a parser function
#include "gromacs/selection/selection.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "keywords.h"
#include "poscalc.h"
catch (gmx::UserInputError &ex)
{
ex.prependContext(context);
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter
+ = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- gmx::formatExceptionMessageToFile(stderr, ex);
+ gmx::formatExceptionMessageToWriter(statusWriter, ex);
return true;
}
throw;
root->fillNameIfMissing(_gmx_sel_lexer_pselstr(scanner));
/* Print out some information if the parser is interactive */
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- fprintf(stderr, "Selection '%s' parsed\n",
- _gmx_sel_lexer_pselstr(scanner));
+ const std::string message
+ = gmx::formatString("Selection '%s' parsed",
+ _gmx_sel_lexer_pselstr(scanner));
+ statusWriter->writeLine(message);
}
return root;
srenew(sc->varstrs, sc->nvars + 1);
sc->varstrs[sc->nvars] = gmx_strdup(pselstr);
++sc->nvars;
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- fprintf(stderr, "Variable '%s' parsed\n", pselstr);
+ const std::string message
+ = gmx::formatString("Variable '%s' parsed", pselstr);
+ statusWriter->writeLine(message);
}
return root;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
YY_RULE_SETUP
#line 137 "scanner.l"
{
- if (yytext[0] == ';' || state->bInteractive)
+ if (yytext[0] == ';' || state->statusWriter != NULL)
{
rtrim(state->pselstr);
state->bCmdStart = true;
#include "parser.h"
+namespace gmx
+{
+class TextWriter;
+}
+
struct gmx_ana_indexgrps_t;
struct gmx_ana_selcollection_t;
/** Initializes the selection scanner. */
void
_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
- bool bInteractive, int maxnr, bool bGroups,
+ gmx::TextWriter *statusWriter, int maxnr, bool bGroups,
struct gmx_ana_indexgrps_t *grps);
/** Frees memory allocated for the selection scanner. */
void
void
_gmx_sel_lexer_rethrow_exception_if_occurred(yyscan_t scanner);
-/** Returns true if the scanner is interactive. */
-bool
-_gmx_sel_is_lexer_interactive(yyscan_t scanner);
+/** Returns writer for status output (if not NULL, the scanner is interactive). */
+gmx::TextWriter *
+_gmx_sel_lexer_get_status_writer(yyscan_t scanner);
/** Returns the selection collection for the scanner. */
struct gmx_ana_selcollection_t *
_gmx_sel_lexer_selcollection(yyscan_t scanner);
\\\n { _gmx_sel_lexer_add_token(yylloc, " ", 1, state); break; }
";"|\n {
- if (yytext[0] == ';' || state->bInteractive)
+ if (yytext[0] == ';' || state->statusWriter != NULL)
{
rtrim(state->pselstr);
state->bCmdStart = true;
void
_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
- bool bInteractive, int maxnr, bool bGroups,
- struct gmx_ana_indexgrps_t *grps)
+ gmx::TextWriter *statusWriter, int maxnr,
+ bool bGroups, struct gmx_ana_indexgrps_t *grps)
{
int rc = _gmx_sel_yylex_init(scannerp);
if (rc != 0)
state->grps = grps;
state->nexpsel = (maxnr > 0 ? static_cast<int>(sc->sel.size()) + maxnr : -1);
- state->bInteractive = bInteractive;
+ state->statusWriter = statusWriter;
snew(state->pselstr, STRSTORE_ALLOCSTEP);
state->pselstr[0] = 0;
}
}
-bool
-_gmx_sel_is_lexer_interactive(yyscan_t scanner)
+gmx::TextWriter *
+_gmx_sel_lexer_get_status_writer(yyscan_t scanner)
{
gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
- return state->bInteractive;
+ return state->statusWriter;
}
struct gmx_ana_selcollection_t *
namespace gmx
{
class SelectionParserSymbol;
+class TextWriter;
}
/* These need to be defined before including scanner_flex.h, because it
//! Number of selections at which the parser should stop.
int nexpsel;
- //! Whether the parser is interactive.
- bool bInteractive;
+ //! Writer to use for status output (if not NULL, parser is interactive).
+ gmx::TextWriter *statusWriter;
//! Pretty-printed version of the string parsed since last clear.
char *pselstr;
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "selelem.h"
#include "selvalue.h"
fprintf(fp, " Group ");
gmx_ana_index_t g;
gmx_ana_index_set(&g, p.m.mapb.nra, p.m.mapb.a, 0);
- gmx_ana_index_dump(fp, &g, nmaxind);
+ TextWriter writer(fp);
+ gmx_ana_index_dump(&writer, &g, nmaxind);
fprintf(fp, " Block (size=%d):", p.m.mapb.nr);
if (!p.m.mapb.index)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <boost/scoped_ptr.hpp>
-#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
#include "gromacs/selection/indexutil.h"
#include "gromacs/selection/selection.h" // For gmx::SelectionList
#include "gromacs/selection/selectioncollection.h"
#include <string>
#include <vector>
+#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include "gromacs/fileio/trx.h"
#include "gromacs/onlinehelp/helpmanager.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selhelp.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "compiler.h"
#include "mempool.h"
/*! \brief
* Reads a single selection line from stdin.
*
- * \param[in] infile File to read from (typically File::standardInput()).
- * \param[in] bInteractive Whether to print interactive prompts.
+ * \param[in] inputStream Stream to read from (typically the StandardInputStream).
+ * \param[in] statusWriter Stream to print prompts to (if NULL, no output is done).
* \param[out] line The read line in stored here.
* \returns true if something was read, false if at end of input.
*
* Handles line continuation, reading also the continuing line(s) in one call.
*/
-bool promptLine(File *infile, bool bInteractive, std::string *line)
+bool promptLine(TextInputStream *inputStream, TextWriter *statusWriter,
+ std::string *line)
{
- if (bInteractive)
+ if (statusWriter != NULL)
{
- fprintf(stderr, "> ");
+ statusWriter->writeString("> ");
}
- if (!infile->readLineWithTrailingSpace(line))
+ if (!inputStream->readLine(line))
{
return false;
}
while (endsWith(*line, "\\\n"))
{
line->resize(line->length() - 2);
- if (bInteractive)
+ if (statusWriter != NULL)
{
- fprintf(stderr, "... ");
+ statusWriter->writeString("... ");
}
std::string buffer;
// Return value ignored, buffer remains empty and works correctly
// if there is nothing to read.
- infile->readLineWithTrailingSpace(&buffer);
+ inputStream->readLine(&buffer);
line->append(buffer);
}
if (endsWith(*line, "\n"))
{
line->resize(line->length() - 1);
}
- else if (bInteractive)
+ else if (statusWriter != NULL)
{
- fprintf(stderr, "\n");
+ statusWriter->writeLine();
}
return true;
}
bool bInteractive)
{
int status = YYPUSH_MORE;
- int prevToken = 0;
do
{
YYSTYPE value;
YYLTYPE location;
int token = _gmx_sel_yylex(&value, &location, scanner);
- if (bInteractive)
+ if (bInteractive && token == 0)
{
- if (token == 0)
- {
- break;
- }
- // Empty commands cause the interactive parser to print out
- // status information. This avoids producing those unnecessarily,
- // e.g., from "resname RA;;".
- if (prevToken == CMD_SEP && token == CMD_SEP)
- {
- continue;
- }
- prevToken = token;
+ break;
}
status = _gmx_sel_yypush_parse(parserState, token, &value, &location, scanner);
}
/*! \brief
* Print current status in response to empty line in interactive input.
*
+ * \param[in] writer Writer to use for the output.
* \param[in] sc Selection collection data structure.
* \param[in] grps Available index groups.
* \param[in] firstSelection Index of first selection from this interactive
*
* Prints the available index groups and currently provided selections.
*/
-void printCurrentStatus(gmx_ana_selcollection_t *sc, gmx_ana_indexgrps_t *grps,
- size_t firstSelection, int maxCount,
- const std::string &context, bool bFirst)
+void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc,
+ gmx_ana_indexgrps_t *grps, size_t firstSelection,
+ int maxCount, const std::string &context, bool bFirst)
{
if (grps != NULL)
{
- std::fprintf(stderr, "Available static index groups:\n");
- gmx_ana_indexgrps_print(stderr, grps, 0);
+ writer->writeLine("Available static index groups:");
+ gmx_ana_indexgrps_print(writer, grps, 0);
}
- std::fprintf(stderr, "Specify ");
+ writer->writeString("Specify ");
if (maxCount < 0)
{
- std::fprintf(stderr, "any number of selections");
+ writer->writeString("any number of selections");
}
else if (maxCount == 1)
{
- std::fprintf(stderr, "a selection");
+ writer->writeString("a selection");
}
else
{
- std::fprintf(stderr, "%d selections", maxCount);
+ writer->writeString(formatString("%d selections", maxCount));
}
- std::fprintf(stderr, "%s%s:\n",
- context.empty() ? "" : " ", context.c_str());
- std::fprintf(stderr,
- "(one per line, <enter> for status/groups, 'help' for help%s)\n",
- maxCount < 0 ? ", Ctrl-D to end" : "");
+ writer->writeString(formatString("%s%s:\n",
+ context.empty() ? "" : " ", context.c_str()));
+ writer->writeString(formatString(
+ "(one per line, <enter> for status/groups, 'help' for help%s)\n",
+ maxCount < 0 ? ", Ctrl-D to end" : ""));
if (!bFirst && (sc->nvars > 0 || sc->sel.size() > firstSelection))
{
- std::fprintf(stderr, "Currently provided selections:\n");
+ writer->writeLine("Currently provided selections:");
for (int i = 0; i < sc->nvars; ++i)
{
- std::fprintf(stderr, " %s\n", sc->varstrs[i]);
+ writer->writeString(formatString(" %s\n", sc->varstrs[i]));
}
for (size_t i = firstSelection; i < sc->sel.size(); ++i)
{
- std::fprintf(stderr, " %2d. %s\n",
- static_cast<int>(i - firstSelection + 1),
- sc->sel[i]->selectionText());
+ writer->writeString(formatString(
+ " %2d. %s\n",
+ static_cast<int>(i - firstSelection + 1),
+ sc->sel[i]->selectionText()));
}
if (maxCount > 0)
{
const int remaining
= maxCount - static_cast<int>(sc->sel.size() - firstSelection);
- std::fprintf(stderr, "(%d more selection%s required)\n",
- remaining, remaining > 1 ? "s" : "");
+ writer->writeString(formatString(
+ "(%d more selection%s required)\n",
+ remaining, remaining > 1 ? "s" : ""));
}
}
}
/*! \brief
* Prints selection help in interactive selection input.
*
+ * \param[in] writer Writer to use for the output.
* \param[in] sc Selection collection data structure.
* \param[in] line Line of user input requesting help (starting with `help`).
*
* Initializes the selection help if not yet initialized, and finds the help
* topic based on words on the input line.
*/
-void printHelp(gmx_ana_selcollection_t *sc, const std::string &line)
+void printHelp(TextWriter *writer, gmx_ana_selcollection_t *sc,
+ const std::string &line)
{
if (sc->rootHelp.get() == NULL)
{
sc->rootHelp = createSelectionHelpTopic();
}
- HelpWriterContext context(&File::standardError(),
- eHelpOutputFormat_Console);
+ HelpWriterContext context(&writer->stream(), eHelpOutputFormat_Console);
HelpManager manager(*sc->rootHelp, context);
try
{
}
catch (const InvalidInputError &ex)
{
- fprintf(stderr, "%s\n", ex.what());
+ writer->writeLine(ex.what());
return;
}
manager.writeCurrentTopic();
* Helper function that runs the parser once the tokenizer has been
* initialized.
*
- * \param[in,out] scanner Scanner data structure.
- * \param[in] bStdIn Whether to use a line-based reading
+ * \param[in,out] scanner Scanner data structure.
+ * \param[in] inputStream Stream to use for input (currently only with
+ * `bInteractive==true`).
+ * \param[in] bInteractive Whether to use a line-based reading
* algorithm designed for interactive input.
* \param[in] maxnr Maximum number of selections to parse
* (if -1, parse as many as provided by the user).
* \throws std::bad_alloc if out of memory.
* \throws InvalidInputError if there is a parsing error.
*
- * Used internally to implement parseFromStdin(), parseFromFile() and
+ * Used internally to implement parseInteractive(), parseFromFile() and
* parseFromString().
*/
-SelectionList runParser(yyscan_t scanner, bool bStdIn, int maxnr,
- const std::string &context)
+SelectionList runParser(yyscan_t scanner, TextInputStream *inputStream,
+ bool bInteractive, int maxnr, const std::string &context)
{
boost::shared_ptr<void> scannerGuard(scanner, &_gmx_sel_free_lexer);
gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner);
{
boost::shared_ptr<_gmx_sel_yypstate> parserState(
_gmx_sel_yypstate_new(), &_gmx_sel_yypstate_delete);
- if (bStdIn)
+ if (bInteractive)
{
- File &stdinFile(File::standardInput());
- const bool bInteractive = _gmx_sel_is_lexer_interactive(scanner);
- if (bInteractive)
+ TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- printCurrentStatus(sc, grps, oldCount, maxnr, context, true);
+ printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, true);
}
std::string line;
int status;
- while (promptLine(&stdinFile, bInteractive, &line))
+ while (promptLine(inputStream, statusWriter, &line))
{
- if (bInteractive)
+ if (statusWriter != NULL)
{
line = stripString(line);
if (line.empty())
{
- printCurrentStatus(sc, grps, oldCount, maxnr, context, false);
+ printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, false);
continue;
}
if (startsWith(line, "help")
&& (line[4] == 0 || std::isspace(line[4])))
{
- printHelp(sc, line);
+ printHelp(statusWriter, sc, line);
continue;
}
}
void
-SelectionCollection::initOptions(Options *options)
+SelectionCollection::initOptions(IOptionsContainer *options)
{
const char * const debug_levels[]
= { "no", "basic", "compile", "eval", "full" };
return false;
}
-
SelectionList
-SelectionCollection::parseFromStdin(int nr, bool bInteractive,
+SelectionCollection::parseFromStdin(int count, bool bInteractive,
const std::string &context)
+{
+ return parseInteractive(count, &StandardInputStream::instance(),
+ bInteractive ? &TextOutputFile::standardError() : NULL,
+ context);
+}
+
+SelectionList
+SelectionCollection::parseInteractive(int count,
+ TextInputStream *inputStream,
+ TextOutputStream *statusStream,
+ const std::string &context)
{
yyscan_t scanner;
- _gmx_sel_init_lexer(&scanner, &impl_->sc_, bInteractive, nr,
- impl_->bExternalGroupsSet_,
- impl_->grps_);
- return runParser(scanner, true, nr, context);
+ boost::scoped_ptr<TextWriter> statusWriter;
+ if (statusStream != NULL)
+ {
+ statusWriter.reset(new TextWriter(statusStream));
+ statusWriter->wrapperSettings().setLineLength(78);
+ }
+ _gmx_sel_init_lexer(&scanner, &impl_->sc_, statusWriter.get(),
+ count, impl_->bExternalGroupsSet_, impl_->grps_);
+ return runParser(scanner, inputStream, true, count, context);
}
try
{
- yyscan_t scanner;
- File file(filename, "r");
+ yyscan_t scanner;
+ TextInputFile file(filename);
// TODO: Exception-safe way of using the lexer.
- _gmx_sel_init_lexer(&scanner, &impl_->sc_, false, -1,
+ _gmx_sel_init_lexer(&scanner, &impl_->sc_, NULL, -1,
impl_->bExternalGroupsSet_,
impl_->grps_);
_gmx_sel_set_lex_input_file(scanner, file.handle());
- return runParser(scanner, false, -1, std::string());
+ return runParser(scanner, NULL, false, -1, std::string());
}
catch (GromacsException &ex)
{
{
yyscan_t scanner;
- _gmx_sel_init_lexer(&scanner, &impl_->sc_, false, -1,
+ _gmx_sel_init_lexer(&scanner, &impl_->sc_, NULL, -1,
impl_->bExternalGroupsSet_,
impl_->grps_);
_gmx_sel_set_lex_input_str(scanner, str.c_str());
- return runParser(scanner, false, -1, std::string());
+ return runParser(scanner, NULL, false, -1, std::string());
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class Options;
+class IOptionsContainer;
class SelectionCompiler;
class SelectionEvaluator;
+class TextInputStream;
+class TextOutputStream;
/*! \brief
* Collection of selections.
* initialization options.
*
* After setting the default values, one or more selections can be parsed with
- * one or more calls to parseFromStdin(), parseFromFile(), and/or
+ * one or more calls to parseInteractive(), parseFromStdin(), parseFromFile(), and/or
* parseFromString(). After all selections are parsed, the topology must be
* set with setTopology() unless requiresTopology() returns false (the topology
* can also be set earlier).
* position types (see setReferencePosType() and setOutputPosType())
* and debugging flags.
*/
- void initOptions(Options *options);
+ void initOptions(IOptionsContainer *options);
/*! \brief
* Sets the default reference position handling for a selection
*/
SelectionList parseFromStdin(int count, bool bInteractive,
const std::string &context);
+ /*! \brief
+ * Parses selection(s) interactively using provided streams.
+ *
+ * \param[in] count Number of selections to parse
+ * (if -1, parse as many as provided by the user).
+ * \param[in] inputStream Stream to use for input.
+ * \param[in] outputStream Stream to use for output
+ * (if NULL, the parser runs non-interactively and does not
+ * produce any status messages).
+ * \param[in] context Context to print for interactive input.
+ * \returns Vector of parsed selections.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if there is a parsing error
+ * (an interactive parser only throws this if too few selections
+ * are provided and the user forced the end of input).
+ *
+ * Works the same as parseFromStdin(), except that the caller can
+ * provide streams to use instead of `stdin` and `stderr`.
+ *
+ * Mainly usable for unit testing interactive input.
+ */
+ SelectionList parseInteractive(int count,
+ TextInputStream *inputStream,
+ TextOutputStream *outputStream,
+ const std::string &context);
/*! \brief
* Parses selection(s) from a file.
*
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* appropriate. Otherwise, values that are provided before adjustments will
* need to follow the more strict checks. In most cases in trajectory analysis
* (which is the main use case for selection options), the adjustments should
- * be done in TrajectoryAnalysisModule::initOptionsDone() for them to take
+ * be done in TrajectoryAnalysisModule::optionsFinished() for them to take
* place before interactive selection prompts.
*
* An instance of this class for a selection option can be obtained with
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* \inpublicapi
* \ingroup module_selection
*/
-class SelectionOptionManager : public OptionManagerInterface
+class SelectionOptionManager : public IOptionManager
{
public:
/*! \brief
#include "gromacs/onlinehelp/helptopic.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "selmethod.h"
#include "symrec.h"
e_selvalue_t type,
bool bModifiers) const
{
- File &file = context.outputFile();
+ TextWriter &file = context.outputFile();
MethodList::const_iterator iter;
for (iter = methods_.begin(); iter != methods_.end(); ++iter)
{
}
}
- const HelpTopicInterface *subTopic = findSubTopic(iter->first.c_str());
+ const IHelpTopic *subTopic = findSubTopic(iter->first.c_str());
GMX_RELEASE_ASSERT(subTopic != NULL, "Keyword subtopic no longer exists");
HelpWriterContext subContext(context);
subContext.enterSubSection(title);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_SELECTION_SELHELP_H
#define GMX_SELECTION_SELHELP_H
-#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/onlinehelp/ihelptopic.h"
namespace gmx
{
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+foo = resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Variable 'foo = resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+resname RB
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RB' parsed
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+"Name" resname RC
+]]></String>
+ <String Name="Output3"><![CDATA[
+Selection '"Name" resname RC' parsed
+> ]]></String>
+ <String Name="Input4"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RB and \
+]]></String>
+ <String Name="Output1"><![CDATA[
+... ]]></String>
+ <String Name="Input2"><![CDATA[
+resname RC
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RB and resname RC' parsed
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RA;
+]]></String>
+ <String Name="Output1"><![CDATA[
+Selection 'resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+; resname RB;;
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RB' parsed
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+
+]]></String>
+ <String Name="Output3"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+Currently provided selections:
+ 1. resname RA
+ 2. resname RB
+> ]]></String>
+ <String Name="Input4"><![CDATA[
+;
+]]></String>
+ <String Name="Output4"><![CDATA[
+> ]]></String>
+ <String Name="Input5"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+"Sel" resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Selection '"Sel" resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+"Sel2" resname RB
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection '"Sel2" resname RB' parsed
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+
+]]></String>
+ <String Name="Output3"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+Currently provided selections:
+ 1. "Sel" resname RA
+ 2. "Sel2" resname RB
+> ]]></String>
+ <String Name="Input4"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify 2 selections for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RA; resname RB and \
+]]></String>
+ <String Name="Output1"><![CDATA[
+... ]]></String>
+ <String Name="Input2"><![CDATA[
+resname RC
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RA' parsed
+Selection 'resname RB and resname RC' parsed
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RA]]></String>
+ <String Name="Output1"><![CDATA[
+
+Selection 'resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Input1"><![CDATA[
+foo = resname RA
+]]></String>
+ <String Name="Input2"><![CDATA[
+resname RB
+]]></String>
+ <String Name="Input3"><![CDATA[
+"Name" resname RC
+]]></String>
+ <String Name="Input4"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify a selection for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+foo = resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Variable 'foo = resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+resname RA
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RA' parsed
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Input1"><![CDATA[
+foo = resname RA
+]]></String>
+ <String Name="Input2"><![CDATA[
+resname RA
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify a selection for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+foo = resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Variable 'foo = resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+
+]]></String>
+ <String Name="Output2"><![CDATA[
+Specify a selection for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+Currently provided selections:
+ foo = resname RA
+(1 more selection required)
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+resname RB
+]]></String>
+ <String Name="Output3"><![CDATA[
+Selection 'resname RB' parsed
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+
+]]></String>
+ <String Name="Output1"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+Currently provided selections:
+ foo = resname RA
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+bar = resname RC
+]]></String>
+ <String Name="Output2"><![CDATA[
+Variable 'bar = resname RC' parsed
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+resname RA
+]]></String>
+ <String Name="Output3"><![CDATA[
+Selection 'resname RA' parsed
+> ]]></String>
+ <String Name="Input4"><![CDATA[
+
+]]></String>
+ <String Name="Output4"><![CDATA[
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+Currently provided selections:
+ foo = resname RA
+ bar = resname RC
+ 1. resname RA
+> ]]></String>
+ <String Name="Input5"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Available static index groups:
+ Group 0 "GrpA" (5 atoms)
+ Group 1 "GrpB" (5 atoms)
+ Group 2 "GrpUnsorted" (8 atoms)
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Selection 'resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+
+]]></String>
+ <String Name="Output2"><![CDATA[
+Available static index groups:
+ Group 0 "GrpA" (5 atoms)
+ Group 1 "GrpB" (5 atoms)
+ Group 2 "GrpUnsorted" (8 atoms)
+Specify any number of selections for test context:
+(one per line, <enter> for status/groups, 'help' for help, Ctrl-D to end)
+Currently provided selections:
+ 1. resname RA
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify 2 selections for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Selection 'resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+resname RB
+]]></String>
+ <String Name="Output2"><![CDATA[
+Selection 'resname RB' parsed
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <InteractiveSession Name="Interactive">
+ <String Name="Output0"><![CDATA[
+Specify 2 selections for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+> ]]></String>
+ <String Name="Input1"><![CDATA[
+"Sel" resname RA
+]]></String>
+ <String Name="Output1"><![CDATA[
+Selection '"Sel" resname RA' parsed
+> ]]></String>
+ <String Name="Input2"><![CDATA[
+
+]]></String>
+ <String Name="Output2"><![CDATA[
+Specify 2 selections for test context:
+(one per line, <enter> for status/groups, 'help' for help)
+Currently provided selections:
+ 1. "Sel" resname RA
+(1 more selection required)
+> ]]></String>
+ <String Name="Input3"><![CDATA[
+resname RB
+]]></String>
+ <String Name="Output3"><![CDATA[
+Selection 'resname RB' parsed
+]]></String>
+ </InteractiveSession>
+</ReferenceData>
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="InteractiveSession">
+ <pre>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="starts-with(@Name, 'Output')">
+ <xsl:value-of select="substring(.,2)"/>
+ </xsl:when>
+ <xsl:when test="string-length(.)=1">
+ <xsl:text>►</xsl:text>
+ <xsl:text>¶</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(substring(.,2), ' ')">
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="translate(substring(.,2), ' ', '⏎')"/>
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="substring(.,2)"/>
+ <xsl:text>¶</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:text>[EOF]</xsl:text>
+ </pre>
+</xsl:template>
+
</xsl:stylesheet>
<xsl:key name="SelectionName" match="ParsedSelections/ParsedSelection" use="@Name"/>
+<xsl:template match="InteractiveSession">
+ <h2>Interactive Session</h2>
+ <xsl:apply-imports />
+</xsl:template>
+
<xsl:template match="ParsedSelections">
<h2>Parsed Selections</h2>
<table border="1">
#include "gromacs/fileio/trx.h"
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/selection/indexutil.h"
#include "gromacs/selection/selection.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/gmxregex.h"
#include "gromacs/utility/stringutil.h"
+#include "testutils/interactivetest.h"
#include "testutils/refdata.h"
#include "testutils/testasserts.h"
#include "testutils/testfilemanager.h"
}
+/********************************************************************
+ * Test fixture for interactive SelectionCollection tests
+ */
+
+class SelectionCollectionInteractiveTest : public SelectionCollectionTest
+{
+ public:
+ SelectionCollectionInteractiveTest()
+ : helper_(data_.rootChecker())
+ {
+ }
+
+ void runTest(int count, bool bInteractive,
+ const gmx::ConstArrayRef<const char *> &input);
+
+ gmx::test::TestReferenceData data_;
+ gmx::test::InteractiveTestHelper helper_;
+};
+
+void SelectionCollectionInteractiveTest::runTest(
+ int count, bool bInteractive,
+ const gmx::ConstArrayRef<const char *> &inputLines)
+{
+ helper_.setInputLines(inputLines);
+ // TODO: Check something about the returned selections as well.
+ ASSERT_NO_THROW_GMX(sc_.parseInteractive(
+ count, &helper_.inputStream(),
+ bInteractive ? &helper_.outputStream() : NULL,
+ "for test context"));
+ helper_.checkSession();
+}
+
+
/********************************************************************
* Test fixture for selection testing with reference data
*/
// TODO: Tests for more evaluation errors
+/********************************************************************
+ * Tests for interactive selection input
+ */
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesBasicInput)
+{
+ const char *const input[] = {
+ "foo = resname RA",
+ "resname RB",
+ "\"Name\" resname RC"
+ };
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesContinuation)
+{
+ const char *const input[] = {
+ "resname RB and \\",
+ "resname RC"
+ };
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInput)
+{
+ const char *const input[] = {
+ "foo = resname RA",
+ "resname RA"
+ };
+ runTest(1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesTwoSelectionInput)
+{
+ const char *const input[] = {
+ "resname RA",
+ "resname RB"
+ };
+ runTest(2, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesStatusWithGroups)
+{
+ const char *const input[] = {
+ "resname RA",
+ ""
+ };
+ loadIndexGroups("simple.ndx");
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesStatusWithExistingSelections)
+{
+ const char *const input[] = {
+ "",
+ "bar = resname RC",
+ "resname RA",
+ ""
+ };
+ ASSERT_NO_THROW_GMX(sc_.parseFromString("foo = resname RA"));
+ ASSERT_NO_THROW_GMX(sc_.parseFromString("resname RB"));
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInputStatus)
+{
+ const char *const input[] = {
+ "foo = resname RA",
+ "",
+ "resname RB"
+ };
+ runTest(1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesTwoSelectionInputStatus)
+{
+ const char *const input[] = {
+ "\"Sel\" resname RA",
+ "",
+ "resname RB"
+ };
+ runTest(2, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesMultiSelectionInputStatus)
+{
+ const char *const input[] = {
+ "\"Sel\" resname RA",
+ "\"Sel2\" resname RB",
+ ""
+ };
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesNoFinalNewline)
+{
+ // TODO: There is an extra prompt printed after the input is finished; it
+ // would be cleaner not to have it, but it's only a cosmetic issue.
+ const char *const input[] = {
+ "resname RA"
+ };
+ helper_.setLastNewline(false);
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesEmptySelections)
+{
+ const char *const input[] = {
+ "resname RA;",
+ "; resname RB;;",
+ " ",
+ ";"
+ };
+ runTest(-1, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesMultipleSelectionsOnLine)
+{
+ const char *const input[] = {
+ "resname RA; resname RB and \\",
+ "resname RC"
+ };
+ runTest(2, true, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesNoninteractiveInput)
+{
+ const char *const input[] = {
+ "foo = resname RA",
+ "resname RB",
+ "\"Name\" resname RC"
+ };
+ runTest(-1, false, input);
+}
+
+TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInputNoninteractively)
+{
+ const char *const input[] = {
+ "foo = resname RA",
+ "resname RA"
+ };
+ runTest(1, false, input);
+}
+
/********************************************************************
* Tests for selection keywords
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstring>
-#include "gromacs/fileio/tpxio.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/trx.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#include <math.h>
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/basedefinitions.h"
#include "testutils/testoptions.h"
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014, by the GROMACS development team, led by
+# Copyright (c) 2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-file(GLOB STATISTICS_SOURCES statistics.c)
+file(GLOB STATISTICS_SOURCES *.cpp)
set(LIBGROMACS_SOURCES
${LIBGROMACS_SOURCES} ${STATISTICS_SOURCES} PARENT_SCOPE)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "statistics.h"
-#include <math.h>
+#include <cmath>
#include "gromacs/math/vec.h"
#include "gromacs/utility/real.h"
static int gmx_dnint(double x)
{
- return (int) (x+0.5);
+ return static_cast<int>(x+0.5);
}
typedef struct gmx_stats {
int gmx_stats_add_point(gmx_stats_t gstats, double x, double y,
double dx, double dy)
{
- gmx_stats *stats = (gmx_stats *) gstats;
- int i;
+ gmx_stats *stats = gstats;
if (stats->np+1 >= stats->nalloc)
{
srenew(stats->y, stats->nalloc);
srenew(stats->dx, stats->nalloc);
srenew(stats->dy, stats->nalloc);
- for (i = stats->np; (i < stats->nalloc); i++)
+ for (int i = stats->np; (i < stats->nalloc); i++)
{
stats->x[i] = 0;
stats->y[i] = 0;
int gmx_stats_get_point(gmx_stats_t gstats, real *x, real *y,
real *dx, real *dy, real level)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok, outlier;
real rmsd, r;
outlier = 0;
while ((outlier == 0) && (stats->np_c < stats->np))
{
- r = fabs(stats->x[stats->np_c] - stats->y[stats->np_c]);
+ r = std::abs(stats->x[stats->np_c] - stats->y[stats->np_c]);
outlier = (r > rmsd*level);
if (outlier)
{
int gmx_stats_add_points(gmx_stats_t gstats, int n, real *x, real *y,
real *dx, real *dy)
{
- int i, ok;
-
- for (i = 0; (i < n); i++)
+ for (int i = 0; (i < n); i++)
{
+ int ok;
if ((ok = gmx_stats_add_point(gstats, x[i], y[i],
(NULL != dx) ? dx[i] : 0,
(NULL != dy) ? dy[i] : 0)) != estatsOK)
double yy, yx, xx, sx, sy, dy, chi2, chi2aa, d2;
double ssxx, ssyy, ssxy;
double w, wtot, yx_nw, sy_nw, sx_nw, yy_nw, xx_nw, dx2, dy2;
- int i, N;
- N = stats->np;
+ int N = stats->np;
+
if (stats->computed == 0)
{
if (N < 1)
sy = sy_nw = 0;
wtot = 0;
d2 = 0;
- for (i = 0; (i < N); i++)
+ for (int i = 0; (i < N); i++)
{
d2 += dsqr(stats->x[i]-stats->y[i]);
if ((stats->dy[i]) && (weight == elsqWEIGHT_Y))
/* Compute average, sigma and error */
stats->aver = sy_nw/N;
- stats->sigma_aver = sqrt(yy_nw/N - dsqr(sy_nw/N));
- stats->error = stats->sigma_aver/sqrt(N);
+ stats->sigma_aver = std::sqrt(yy_nw/N - dsqr(sy_nw/N));
+ stats->error = stats->sigma_aver/std::sqrt(static_cast<double>(N));
/* Compute RMSD between x and y */
- stats->rmsd = sqrt(d2/N);
+ stats->rmsd = std::sqrt(d2/N);
/* Correlation coefficient for data */
yx_nw /= N;
ssxx = N*(xx_nw - dsqr(sx_nw));
ssyy = N*(yy_nw - dsqr(sy_nw));
ssxy = N*(yx_nw - (sx_nw*sy_nw));
- stats->Rdata = sqrt(dsqr(ssxy)/(ssxx*ssyy));
+ stats->Rdata = std::sqrt(dsqr(ssxy)/(ssxx*ssyy));
/* Compute straight line through datapoints, either with intercept
zero (result in aa) or with intercept variable (results in a
chi2aa which returns the deviation from a line y = ax. */
chi2 = 0;
chi2aa = 0;
- for (i = 0; (i < N); i++)
+ for (int i = 0; (i < N); i++)
{
if (stats->dy[i] > 0)
{
}
if (N > 2)
{
- stats->chi2 = sqrt(chi2/(N-2));
- stats->chi2aa = sqrt(chi2aa/(N-2));
+ stats->chi2 = std::sqrt(chi2/(N-2));
+ stats->chi2aa = std::sqrt(chi2aa/(N-2));
/* Look up equations! */
dx2 = (xx-sx*sx);
dy2 = (yy-sy*sy);
- stats->sigma_a = sqrt(stats->chi2/((N-2)*dx2));
- stats->sigma_b = stats->sigma_a*sqrt(xx);
- stats->Rfit = fabs(ssxy)/sqrt(ssxx*ssyy);
- /*stats->a*sqrt(dx2/dy2);*/
- stats->Rfitaa = stats->aa*sqrt(dx2/dy2);
+ stats->sigma_a = std::sqrt(stats->chi2/((N-2)*dx2));
+ stats->sigma_b = stats->sigma_a*std::sqrt(xx);
+ stats->Rfit = std::abs(ssxy)/std::sqrt(ssxx*ssyy);
+ stats->Rfitaa = stats->aa*std::sqrt(dx2/dy2);
}
else
{
real *a, real *b, real *da, real *db,
real *chi2, real *Rfit)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, weight)) != estatsOK)
int gmx_stats_get_a(gmx_stats_t gstats, int weight, real *a, real *da,
real *chi2, real *Rfit)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, weight)) != estatsOK)
int gmx_stats_get_average(gmx_stats_t gstats, real *aver)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_get_ase(gmx_stats_t gstats, real *aver, real *sigma, real *error)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_get_sigma(gmx_stats_t gstats, real *sigma)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_get_error(gmx_stats_t gstats, real *error)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_get_corr_coeff(gmx_stats_t gstats, real *R)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_get_rmsd(gmx_stats_t gstats, real *rmsd)
{
- gmx_stats *stats = (gmx_stats *) gstats;
+ gmx_stats *stats = gstats;
int ok;
if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK)
int gmx_stats_dump_xy(gmx_stats_t gstats, FILE *fp)
{
- gmx_stats *stats = (gmx_stats *) gstats;
- int i, ok;
+ gmx_stats *stats = gstats;
- for (i = 0; (i < stats->np); i++)
+ for (int i = 0; (i < stats->np); i++)
{
fprintf(fp, "%12g %12g %12g %12g\n", stats->x[i], stats->y[i],
stats->dx[i], stats->dy[i]);
int gmx_stats_remove_outliers(gmx_stats_t gstats, double level)
{
- gmx_stats *stats = (gmx_stats *) gstats;
- int i, iter = 1, done = 0, ok;
+ gmx_stats *stats = gstats;
+ int iter = 1, done = 0, ok;
real rmsd, r;
while ((stats->np >= 10) && !done)
return ok;
}
done = 1;
- for (i = 0; (i < stats->np); )
+ for (int i = 0; (i < stats->np); )
{
- r = fabs(stats->x[i]-stats->y[i]);
+ r = std::abs(stats->x[i]-stats->y[i]);
if (r > level*rmsd)
{
fprintf(stderr, "Removing outlier, iter = %d, rmsd = %g, x = %g, y = %g\n",
int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb,
int ehisto, int normalized, real **x, real **y)
{
- gmx_stats *stats = (gmx_stats *) gstats;
- int i, ok, index = 0, nbins = *nb, *nindex;
+ gmx_stats *stats = gstats;
+ int index = 0, nbins = *nb, *nindex;
double minx, maxx, maxy, miny, delta, dd, minh;
if (((binwidth <= 0) && (nbins <= 0)) ||
}
minx = maxx = stats->x[0];
miny = maxy = stats->y[0];
- for (i = 1; (i < stats->np); i++)
+ for (int i = 1; (i < stats->np); i++)
{
miny = (stats->y[i] < miny) ? stats->y[i] : miny;
maxy = (stats->y[i] > maxy) ? stats->y[i] : maxy;
}
snew(*x, nbins);
snew(nindex, nbins);
- for (i = 0; (i < nbins); i++)
+ for (int i = 0; (i < nbins); i++)
{
(*x)[i] = minh + binwidth*(i+0.5);
}
}
snew(*y, nbins);
- for (i = 0; (i < stats->np); i++)
+ for (int i = 0; (i < stats->np); i++)
{
if (ehisto == ehistoY)
{
- index = (stats->y[i]-miny)/binwidth;
+ index = static_cast<int>((stats->y[i]-miny)/binwidth);
}
else if (ehisto == ehistoX)
{
- index = (stats->x[i]-minx)/binwidth;
+ index = static_cast<int>((stats->x[i]-minx)/binwidth);
}
if (index < 0)
{
{
*nb = nbins;
}
- for (i = 0; (i < nbins); i++)
+ for (int i = 0; (i < nbins); i++)
{
if (nindex[i] > 0)
{
return ok;
}
- /* int i;
- double xx,yx;
-
- yx=xx=0.0;
- for (i=0; i<n; i++) {
- yx+=y[i]*x[i];
- xx+=x[i]*x[i];
- }
- * a=yx/xx;
- */
return estatsOK;
}
static int low_lsq_y_ax_b(int n, real *xr, double *xd, real yr[],
real *a, real *b, real *r, real *chi2)
{
- int i, ok;
- gmx_stats_t lsq;
+ gmx_stats_t lsq = gmx_stats_init();
+ int ok;
- lsq = gmx_stats_init();
- for (i = 0; (i < n); i++)
+ for (int i = 0; (i < n); i++)
{
- if ((ok = gmx_stats_add_point(lsq, (NULL != xd) ? xd[i] : xr[i], yr[i], 0, 0))
- != estatsOK)
+ double pt;
+
+ if (xd != NULL)
+ {
+ pt = xd[i];
+ }
+ else if (xr != NULL)
+ {
+ pt = xr[i];
+ }
+ else
+ {
+ gmx_incons("Either xd or xr has to be non-NULL in low_lsq_y_ax_b()");
+ }
+
+ if ((ok = gmx_stats_add_point(lsq, pt, yr[i], 0, 0)) != estatsOK)
{
return ok;
}
}
return estatsOK;
- /*
- double x,y,yx,xx,yy,sx,sy,chi2;
-
- yx=xx=yy=sx=sy=0.0;
- for (i=0; i<n; i++) {
- if (xd != NULL) {
- x = xd[i];
- } else {
- x = xr[i];
- }
- y = yr[i];
-
- yx += y*x;
- xx += x*x;
- yy += y*y;
- sx += x;
- sy += y;
- }
- * a = (n*yx-sy*sx)/(n*xx-sx*sx);
- * b = (sy-(*a)*sx)/n;
- * r = sqrt((xx-sx*sx)/(yy-sy*sy));
-
- chi2 = 0;
- if (xd != NULL) {
- for(i=0; i<n; i++)
- chi2 += dsqr(yr[i] - ((*a)*xd[i] + (*b)));
- } else {
- for(i=0; i<n; i++)
- chi2 += dsqr(yr[i] - ((*a)*xr[i] + (*b)));
- }
-
- if (n > 2)
- return sqrt(chi2/(n-2));
- else
- return 0;
- */
}
int lsq_y_ax_b(int n, real x[], real y[], real *a, real *b, real *r, real *chi2)
real *a, real *b, real *da, real *db,
real *r, real *chi2)
{
- gmx_stats_t lsq;
- int i, ok;
+ gmx_stats_t lsq = gmx_stats_init();
+ int ok;
- lsq = gmx_stats_init();
- for (i = 0; (i < n); i++)
+ for (int i = 0; (i < n); i++)
{
if ((ok = gmx_stats_add_point(lsq, x[i], y[i], 0, dy[i])) != estatsOK)
{
sfree(lsq);
return estatsOK;
- /*
- double sxy,sxx,syy,sx,sy,w,s_2,dx2,dy2,mins;
-
- sxy=sxx=syy=sx=sy=w=0.0;
- mins = dy[0];
- for(i=1; (i<n); i++)
- mins = min(mins,dy[i]);
- if (mins <= 0)
- gmx_fatal(FARGS,"Zero or negative weigths in linear regression analysis");
-
- for (i=0; i<n; i++) {
- s_2 = dsqr(1.0/dy[i]);
- sxx += s_2*dsqr(x[i]);
- sxy += s_2*y[i]*x[i];
- syy += s_2*dsqr(y[i]);
- sx += s_2*x[i];
- sy += s_2*y[i];
- w += s_2;
- }
- sxx = sxx/w;
- sxy = sxy/w;
- syy = syy/w;
- sx = sx/w;
- sy = sy/w;
- dx2 = (sxx-sx*sx);
- dy2 = (syy-sy*sy);
- * a=(sxy-sy*sx)/dx2;
- * b=(sy-(*a)*sx);
-
- * chi2=0;
- for(i=0; i<n; i++)
- * chi2+=dsqr((y[i]-((*a)*x[i]+(*b)))/dy[i]);
- * chi2 = *chi2/w;
-
- * da = sqrt(*chi2/((n-2)*dx2));
- * db = *da*sqrt(sxx);
- * r = *a*sqrt(dx2/dy2);
-
- if (debug)
- fprintf(debug,"sx = %g, sy = %g, sxy = %g, sxx = %g, w = %g\n"
- "chi2 = %g, dx2 = %g\n",
- sx,sy,sxy,sxx,w,*chi2,dx2);
-
- if (n > 2)
- * chi2 = sqrt(*chi2/(n-2));
- else
- * chi2 = 0;
- */
}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2011,2014, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include <stdio.h>
-
-#include "gromacs/math/vec.h"
-#include "gromacs/random/random.h"
-#include "gromacs/statistics/statistics.h"
-#include "gromacs/utility/real.h"
-#include "gromacs/utility/smalloc.h"
-
-static void horizontal()
-{
- gmx_rng_t rng;
- gmx_stats_t straight;
- int i, ok, n = 1000;
- real y, a, b, da, db, aver, sigma, error, chi2, R, *xh, *yh;
- FILE *fp;
-
- rng = gmx_rng_init(13);
- straight = gmx_stats_init();
- for (i = 0; (i < n); i++)
- {
- y = gmx_rng_uniform_real(rng);
- if ((ok = gmx_stats_add_point(straight, i, y, 0, 0)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- }
- /* Horizontal test */
- if ((ok = gmx_stats_get_ase(straight, &aver, &sigma, &error)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- fp = fopen("straight.xvg", "w");
- if ((ok = gmx_stats_dump_xy(straight, fp)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- fclose(fp);
- printf("Horizontal line: average %g, sigma %g, error %g\n", aver, sigma, error);
- if ((ok = gmx_stats_done(straight)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
-}
-
-static void line()
-{
- gmx_rng_t rng;
- gmx_stats_t line;
- int i, dy, ok, n = 1000;
- real y, a, b, da, db, aver, sigma, error, chi2, R, rfit;
- const real a0 = 0.23, b0 = 2.7;
- FILE *fp;
-
- for (dy = 0; (dy < 2); dy++)
- {
- rng = gmx_rng_init(13);
- line = gmx_stats_init();
- for (i = 0; (i < n); i++)
- {
- y = a0*i+b0+50*(gmx_rng_uniform_real(rng)-0.5);
- if ((ok = gmx_stats_add_point(line, i, y, 0, dy*0.1)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- }
- /* Line with slope test */
- if ((ok = gmx_stats_get_ab(line, elsqWEIGHT_NONE, &a, &b, &da, &db, &chi2, &rfit)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- if ((ok = gmx_stats_get_corr_coeff(line, &R)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- if (dy == 0)
- {
- fp = fopen("line0.xvg", "w");
- }
- else
- {
- fp = fopen("line1.xvg", "w");
- }
- if ((ok = gmx_stats_dump_xy(line, fp)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- fclose(fp);
- printf("Line with eqn. y = %gx + %g with noise%s\n", a0, b0,
- (dy == 0) ? "" : " and uncertainties");
- printf("Found: a = %g +/- %g, b = %g +/- %g\n", a, da, b, db);
- if ((ok = gmx_stats_done(line)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- gmx_rng_destroy(rng);
- }
-}
-
-static void histogram()
-{
- gmx_rng_t rng;
- gmx_stats_t camel;
- int i, ok, n = 1000, norm;
- real y, a, b, da, db, aver, sigma, error, chi2, R, *xh, *yh;
- const real a0 = 0.23, b0 = 2.7;
- FILE *fp;
- char fn[256];
-
- for (norm = 0; (norm < 2); norm++)
- {
- rng = gmx_rng_init(13);
- camel = gmx_stats_init();
- for (i = 0; (i < n); i++)
- {
- y = sqr(gmx_rng_uniform_real(rng));
- if ((ok = gmx_stats_add_point(camel, i, y+1, 0, 0)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- y = sqr(gmx_rng_uniform_real(rng));
- if ((ok = gmx_stats_add_point(camel, i+0.5, y+2, 0, 0)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- }
- /* Histogram test */
- if ((ok = gmx_stats_make_histogram(camel, 0, 101, norm, &xh, &yh)) != estatsOK)
- {
- fprintf(stderr, "%s\n", gmx_stats_message(ok));
- }
- sprintf(fn, "histo%d-data.xvg", norm);
- fp = fopen(fn, "w");
- gmx_stats_dump_xy(camel, fp);
- fclose(fp);
- sprintf(fn, "histo%d.xvg", norm);
- fp = fopen(fn, "w");
- for (i = 0; (i < 101); i++)
- {
- fprintf(fp, "%12g %12g\n", xh[i], yh[i]);
- }
- fclose(fp);
- sfree(xh);
- sfree(yh);
- }
-}
-
-int main(int argc, char *argv[])
-{
- line();
- horizontal();
- histogram();
-
- return 0;
-}
#include <time.h>
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/legacyheaders/copyrite.h"
#include "gromacs/legacyheaders/macros.h"
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2014, by the GROMACS development team, led by
+# Copyright (c) 2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-file(GLOB TOOLS_SOURCES *.cpp *.c)
+file(GLOB TOOLS_SOURCES *.cpp)
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TOOLS_SOURCES} PARENT_SCOPE)
if (BUILD_TESTING)
*/
#include "gmxpre.h"
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/legacyheaders/macros.h"
static void tpx2system(FILE *fp, gmx_mtop_t *mtop)
{
- int i, nmol, nvsite = 0;
+ int nmol, nvsite = 0;
gmx_mtop_atomloop_block_t aloop;
t_atom *atom;
static void tpx2methods(const char *tpx, const char *tex)
{
FILE *fp;
- t_tpxheader sh;
t_inputrec ir;
t_state state;
gmx_mtop_t mtop;
static void chk_bonds(t_idef *idef, int ePBC, rvec *x, matrix box, real tol)
{
- int ftype, i, k, ai, aj, type;
- real b0, blen, deviation, devtot;
+ int ftype, k, ai, aj, type;
+ real b0, blen, deviation;
t_pbc pbc;
rvec dx;
- devtot = 0;
set_pbc(&pbc, ePBC, box);
for (ftype = 0; (ftype < F_NRE); ftype++)
{
b0 = idef->iparams[type].harmonic.rA;
break;
case F_G96BONDS:
- b0 = sqrt(idef->iparams[type].harmonic.rA);
+ b0 = std::sqrt(idef->iparams[type].harmonic.rA);
break;
case F_MORSE:
b0 = idef->iparams[type].morse.b0A;
pbc_dx(&pbc, x[ai], x[aj], dx);
blen = norm(dx);
deviation = sqr(blen-b0);
- if (sqrt(deviation/sqr(b0) > tol))
+ if (std::sqrt(deviation/sqr(b0)) > tol)
{
fprintf(stderr, "Distance between atoms %d and %d is %.3f, should be %.3f\n", ai+1, aj+1, blen, b0);
}
t_count count;
t_fr_time first, last;
int j = -1, new_natoms, natoms;
- real rdum, tt, old_t1, old_t2, prec;
- gmx_bool bShowTimestep = TRUE, bOK, newline = FALSE;
+ real old_t1, old_t2;
+ gmx_bool bShowTimestep = TRUE, newline = FALSE;
t_trxstatus *status;
gmx_mtop_t mtop;
gmx_localtop_t *top = NULL;
*(atoms->resinfo[atoms->atom[j].resind].name),
atoms->resinfo[atoms->atom[j].resind].nr,
atom_vdw[j],
- sqrt(r2) );
+ std::sqrt(r2) );
}
}
}
{
t_blocka *grps;
char **grpname;
- int i, j;
+ int i;
grps = init_index(fn, &grpname);
if (debug)
void chk_enx(const char *fn)
{
- int nre, fnr, ndr;
+ int nre, fnr;
ener_file_t in;
gmx_enxnm_t *enm = NULL;
t_enxframe *fr;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_TOOLS_CHECK_H
#define GMX_TOOLS_CHECK_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
/*! \brief Implements gmx check
*
* \param[in] argc argc value passed to main().
*/
int gmx_check(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
* the research papers on the package. Check out http://www.gromacs.org.
*/
/* This file is completely threadsafe - keep it that way! */
+
#include "gmxpre.h"
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
+
+#include <algorithm>
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/tpxio.h"
if (i1 != i2)
{
fprintf(fp, "%s (", s);
- fprintf(fp, "%"GMX_PRId64, i1);
+ fprintf(fp, "%" GMX_PRId64, i1);
fprintf(fp, " - ");
- fprintf(fp, "%"GMX_PRId64, i2);
+ fprintf(fp, "%" GMX_PRId64, i2);
fprintf(fp, ")\n");
}
}
static void cmp_str(FILE *fp, const char *s, int index,
const char *s1, const char *s2)
{
- if (strcmp(s1, s2) != 0)
+ if (std::strcmp(s1, s2) != 0)
{
if (index != -1)
{
{
cmp_int(fp, "idef->ntypes", -1, id1->ntypes, id2->ntypes);
cmp_int(fp, "idef->atnr", -1, id1->atnr, id2->atnr);
- for (i = 0; (i < min(id1->ntypes, id2->ntypes)); i++)
+ for (i = 0; (i < std::min(id1->ntypes, id2->ntypes)); i++)
{
sprintf(buf1, "idef->functype[%d]", i);
sprintf(buf2, "idef->iparam[%d]", i);
static void cmp_block(FILE *fp, t_block *b1, t_block *b2, const char *s)
{
- int i, j, k;
char buf[32];
fprintf(fp, "comparing block %s\n", s);
static void cmp_blocka(FILE *fp, t_blocka *b1, t_blocka *b2, const char *s)
{
- int i, j, k;
char buf[32];
fprintf(fp, "comparing blocka %s\n", s);
static void cmp_atom(FILE *fp, int index, t_atom *a1, t_atom *a2, real ftol, real abstol)
{
- int i;
- char buf[256];
-
if (a2)
{
cmp_us(fp, "atom.type", index, a1->type, a2->type);
static void cmp_top(FILE *fp, t_topology *t1, t_topology *t2, real ftol, real abstol)
{
- int i;
-
fprintf(fp, "comparing top\n");
if (t2)
{
static void cmp_groups(FILE *fp, gmx_groups_t *g0, gmx_groups_t *g1,
int natoms0, int natoms1)
{
- int i, j, ndiff;
+ int i, j;
char buf[32];
fprintf(fp, "comparing groups\n");
ssd += d*d;
}
}
- fprintf(fp, "%s RMSD %g\n", title, sqrt(ssd/n));
+ fprintf(fp, "%s RMSD %g\n", title, std::sqrt(ssd/n));
}
else
{
rms_x1 += d*d;
}
}
- rms_x1 = sqrt(rms_x1/(DIM*n));
+ rms_x1 = std::sqrt(rms_x1/(DIM*n));
/* And now do the actual comparision with a hopefully realistic abstol. */
for (i = 0; (i < n); i++)
{
cmp_int(fp, "inputrec->grpopts.ngacc", -1, opt1->ngacc, opt2->ngacc);
cmp_int(fp, "inputrec->grpopts.ngfrz", -1, opt1->ngfrz, opt2->ngfrz);
cmp_int(fp, "inputrec->grpopts.ngener", -1, opt1->ngener, opt2->ngener);
- for (i = 0; (i < min(opt1->ngtc, opt2->ngtc)); i++)
+ for (i = 0; (i < std::min(opt1->ngtc, opt2->ngtc)); i++)
{
cmp_real(fp, "inputrec->grpopts.nrdf", i, opt1->nrdf[i], opt2->nrdf[i], ftol, abstol);
cmp_real(fp, "inputrec->grpopts.ref_t", i, opt1->ref_t[i], opt2->ref_t[i], ftol, abstol);
}
}
}
- for (i = 0; (i < min(opt1->ngacc, opt2->ngacc)); i++)
+ for (i = 0; (i < std::min(opt1->ngacc, opt2->ngacc)); i++)
{
cmp_rvec(fp, "inputrec->grpopts.acc", i, opt1->acc[i], opt2->acc[i], ftol, abstol);
}
- for (i = 0; (i < min(opt1->ngfrz, opt2->ngfrz)); i++)
+ for (i = 0; (i < std::min(opt1->ngfrz, opt2->ngfrz)); i++)
{
cmp_ivec(fp, "inputrec->grpopts.nFreeze", i, opt1->nFreeze[i], opt2->nFreeze[i]);
}
{
sprintf(buf, "inputrec->%s[%d]", s, m);
cmp_int(fp, buf, 0, c1->n, c2->n);
- for (i = 0; (i < min(c1->n, c2->n)); i++)
+ for (i = 0; (i < std::min(c1->n, c2->n)); i++)
{
cmp_real(fp, buf, i, c1->a[i], c2->a[i], ftol, abstol);
cmp_real(fp, buf, i, c1->phi[i], c2->phi[i], ftol, abstol);
cmp_int(fp, "inputrec->fepvals->n_lambda", -1, fep1->n_lambda, fep2->n_lambda);
for (i = 0; i < efptNR; i++)
{
- for (j = 0; j < min(fep1->n_lambda, fep2->n_lambda); j++)
+ for (j = 0; j < std::min(fep1->n_lambda, fep2->n_lambda); j++)
{
cmp_double(fp, "inputrec->fepvals->all_lambda", -1, fep1->all_lambda[i][j], fep2->all_lambda[i][j], ftol, abstol);
}
cmp_int(fp, "inputrec->bSimTemp", -1, ir1->bSimTemp, ir2->bSimTemp);
if ((ir1->bSimTemp == ir2->bSimTemp) && (ir1->bSimTemp))
{
- cmp_simtempvals(fp, ir1->simtempvals, ir2->simtempvals, min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
+ cmp_simtempvals(fp, ir1->simtempvals, ir2->simtempvals, std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
}
cmp_int(fp, "inputrec->bExpanded", -1, ir1->bExpanded, ir2->bExpanded);
if ((ir1->bExpanded == ir2->bExpanded) && (ir1->bExpanded))
{
- cmp_expandedvals(fp, ir1->expandedvals, ir2->expandedvals, min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
+ cmp_expandedvals(fp, ir1->expandedvals, ir2->expandedvals, std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol);
}
cmp_int(fp, "inputrec->nwall", -1, ir1->nwall, ir2->nwall);
cmp_int(fp, "inputrec->wall_type", -1, ir1->wall_type, ir2->wall_type);
gmx_bool bRMSD, real ftol, real abstol)
{
const char *ff[2];
- t_tpxheader sh[2];
t_inputrec ir[2];
t_state state[2];
gmx_mtop_t mtop[2];
}
if (cmp_bool(fp, "bX", -1, fr1->bX, fr2->bX))
{
- cmp_rvecs(fp, "x", min(fr1->natoms, fr2->natoms), fr1->x, fr2->x, bRMSD, ftol, abstol);
+ cmp_rvecs(fp, "x", std::min(fr1->natoms, fr2->natoms), fr1->x, fr2->x, bRMSD, ftol, abstol);
}
if (cmp_bool(fp, "bV", -1, fr1->bV, fr2->bV))
{
- cmp_rvecs(fp, "v", min(fr1->natoms, fr2->natoms), fr1->v, fr2->v, bRMSD, ftol, abstol);
+ cmp_rvecs(fp, "v", std::min(fr1->natoms, fr2->natoms), fr1->v, fr2->v, bRMSD, ftol, abstol);
}
if (cmp_bool(fp, "bF", -1, fr1->bF, fr2->bF))
{
if (bRMSD)
{
- cmp_rvecs(fp, "f", min(fr1->natoms, fr2->natoms), fr1->f, fr2->f, bRMSD, ftol, abstol);
+ cmp_rvecs(fp, "f", std::min(fr1->natoms, fr2->natoms), fr1->f, fr2->f, bRMSD, ftol, abstol);
}
else
{
- cmp_rvecs_rmstol(fp, "f", min(fr1->natoms, fr2->natoms), fr1->f, fr2->f, ftol, abstol);
+ cmp_rvecs_rmstol(fp, "f", std::min(fr1->natoms, fr2->natoms), fr1->f, fr2->f, ftol, abstol);
}
}
if (cmp_bool(fp, "bBox", -1, fr1->bBox, fr2->bBox))
int *tensi, int i,
t_energy e1[], t_energy e2[])
{
- int d1, d2;
- int len;
- int j;
- real prod1, prod2;
- int nfound;
+ int d1, d2;
+ int j;
+ real prod1, prod2;
+ int nfound;
+ size_t len;
d1 = tensi[i]/DIM;
d2 = tensi[i] - d1*DIM;
/* Find the diagonal elements d1 and d2 */
- len = strlen(enm1[ind1[i]].name);
+ len = std::strlen(enm1[ind1[i]].name);
prod1 = 1;
prod2 = 1;
nfound = 0;
for (j = 0; j < n; j++)
{
if (tensi[j] >= 0 &&
- strlen(enm1[ind1[j]].name) == len &&
- strncmp(enm1[ind1[i]].name, enm1[ind1[j]].name, len-2) == 0 &&
+ std::strlen(enm1[ind1[j]].name) == len &&
+ std::strncmp(enm1[ind1[i]].name, enm1[ind1[j]].name, len-2) == 0 &&
(tensi[j] == d1*DIM+d1 || tensi[j] == d2*DIM+d2))
{
prod1 *= fabs(e1[ind1[j]].e);
if (nfound == 2)
{
- return 0.5*(sqrt(prod1) + sqrt(prod2));
+ return 0.5*(std::sqrt(prod1) + std::sqrt(prod2));
}
else
{
{
int len1, len2;
- len1 = strlen(nm1);
- len2 = strlen(nm2);
+ len1 = std::strlen(nm1);
+ len2 = std::strlen(nm2);
/* Remove " (bar)" at the end of a name */
- if (len1 > 6 && strcmp(nm1+len1-6, " (bar)") == 0)
+ if (len1 > 6 && std::strcmp(nm1+len1-6, " (bar)") == 0)
{
len1 -= 6;
}
- if (len2 > 6 && strcmp(nm2+len2-6, " (bar)") == 0)
+ if (len2 > 6 && std::strcmp(nm2+len2-6, " (bar)") == 0)
{
len2 -= 6;
}
{
ii = ind1[i];
tensi[i] = -1;
- len = strlen(enm1[ii].name);
+ len = std::strlen(enm1[ii].name);
if (len > 3 && enm1[ii].name[len-3] == '-')
{
d1 = enm1[ii].name[len-2] - 'X';
if (abstol_i > 0)
{
/* We found a diagonal, we need to check with the minimum tolerance */
- abstol_i = min(abstol_i, abstol);
+ abstol_i = std::min(abstol_i, abstol);
}
else
{
void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const char *lastener)
{
- int nre, nre1, nre2, block;
+ int nre, nre1, nre2;
ener_file_t in1, in2;
int i, j, maxener, *ind1, *ind2, *have;
- char buf[256];
gmx_enxnm_t *enm1 = NULL, *enm2 = NULL;
t_enxframe *fr1, *fr2;
gmx_bool b1, b2;
maxener = nre;
for (i = 0; i < nre; i++)
{
- if ((lastener != NULL) && (strstr(enm1[i].name, lastener) != NULL))
+ if ((lastener != NULL) && (std::strstr(enm1[i].name, lastener) != NULL))
{
maxener = i+1;
break;
*/
#include "gmxpre.h"
-#include <math.h>
+#include <cmath>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/gmxpreprocess/readir.h"
#include "gromacs/legacyheaders/checkpoint.h"
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/topology/index.h"
#include "gromacs/topology/mtop_util.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
};
const char *top_fn, *frame_fn;
- t_fileio *fp;
+ struct t_fileio *fp;
ener_file_t fp_ener = NULL;
- t_trnheader head;
+ gmx_trr_header_t head;
int i;
gmx_int64_t nsteps_req, run_step, frame;
double run_t, state_t;
gmx_bool bFrame, bUse, bSel, bNeedEner, bReadEner, bScanEner, bFepState;
gmx_mtop_t mtop;
t_atoms atoms;
- t_inputrec *ir, *irnew = NULL;
- t_gromppopts *gopts;
+ t_inputrec *ir;
t_state state;
rvec *newx = NULL, *newv = NULL, *tmpx, *tmpv;
matrix newbox;
{ "-init_fep_state", FALSE, etINT, {&init_fep_state},
"fep state to initialize from" },
};
- int nerror = 0;
/* Parse the command line */
if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
if (EI_SD(ir->eI) || ir->eI == eiBD)
{
- fprintf(stderr, "\nChanging ld-seed from %"GMX_PRId64 " ", ir->ld_seed);
+ fprintf(stderr, "\nChanging ld-seed from %" GMX_PRId64 " ", ir->ld_seed);
ir->ld_seed = (gmx_int64_t)gmx_rng_make_seed();
- fprintf(stderr, "to %"GMX_PRId64 "\n\n", ir->ld_seed);
+ fprintf(stderr, "to %" GMX_PRId64 "\n\n", ir->ld_seed);
}
frame_fn = ftp2fn(efTRN, NFILE, fnm);
"\nREADING COORDS, VELS AND BOX FROM TRAJECTORY %s...\n\n",
frame_fn);
- fp = open_trn(frame_fn, "r");
+ fp = gmx_trr_open(frame_fn, "r");
if (bScanEner)
{
fp_ener = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
frame = 0;
while (bFrame)
{
- bFrame = fread_trnheader(fp, &head, &bOK);
+ bFrame = gmx_trr_read_frame_header(fp, &head, &bOK);
if (bOK && frame == 0)
{
if (mtop.natoms != head.natoms)
bFrame = bFrame && bOK;
if (bFrame)
{
- bOK = fread_htrn(fp, &head, newbox, newx, newv, NULL);
+ bOK = gmx_trr_read_frame_data(fp, &head, newbox, newx, newv, NULL);
}
bFrame = bFrame && bOK;
bUse = FALSE;
free_enxframe(fr_ener);
free_enxnms(nre, enm);
}
- close_trn(fp);
+ gmx_trr_close(fp);
fprintf(stderr, "\n");
if (!bOK)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_TOOLS_CONVERT_TPR_H
#define GMX_TOOLS_CONVERT_TPR_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
/*! \brief Implements gmx convert-tpr
*
* \param[in] argc argc value passed to main().
*/
int gmx_convert_tpr(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#include "config.h"
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
+#include <cassert>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/tngio.h"
#include "gromacs/fileio/tngio_for_tools.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trnio.h"
+#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/xtcio.h"
#include "gromacs/gmxpreprocess/gmxcpp.h"
#include "gromacs/legacyheaders/checkpoint.h"
gmx_bool bSysTop)
{
FILE *gp;
- int fp, indent, i, j, **gcount, atot;
+ int indent, i, j, **gcount, atot;
t_state state;
rvec *f = NULL;
t_inputrec ir;
if (available(stdout, &tpx, 0, fn))
{
indent = 0;
- indent = pr_title(stdout, indent, fn);
+ pr_title(stdout, indent, fn);
pr_inputrec(stdout, 0, "inputrec", tpx.bIr ? &(ir) : NULL, FALSE);
- indent = 0;
pr_header(stdout, indent, "header", &(tpx));
if (!bSysTop)
}
}
-static void list_trn(const char *fn)
+static void list_trr(const char *fn)
{
- t_fileio *fpread, *fpwrite;
- int nframe, indent;
- char buf[256];
- rvec *x, *v, *f;
- matrix box;
- t_trnheader trn;
- gmx_bool bOK;
-
- fpread = open_trn(fn, "r");
- fpwrite = open_tpx(NULL, "w");
- gmx_fio_setdebug(fpwrite, TRUE);
+ t_fileio *fpread;
+ int nframe, indent;
+ char buf[256];
+ rvec *x, *v, *f;
+ matrix box;
+ gmx_trr_header_t trrheader;
+ gmx_bool bOK;
+
+ fpread = gmx_trr_open(fn, "r");
nframe = 0;
- while (fread_trnheader(fpread, &trn, &bOK))
+ while (gmx_trr_read_frame_header(fpread, &trrheader, &bOK))
{
- snew(x, trn.natoms);
- snew(v, trn.natoms);
- snew(f, trn.natoms);
- if (fread_htrn(fpread, &trn,
- trn.box_size ? box : NULL,
- trn.x_size ? x : NULL,
- trn.v_size ? v : NULL,
- trn.f_size ? f : NULL))
+ snew(x, trrheader.natoms);
+ snew(v, trrheader.natoms);
+ snew(f, trrheader.natoms);
+ if (gmx_trr_read_frame_data(fpread, &trrheader,
+ trrheader.box_size ? box : NULL,
+ trrheader.x_size ? x : NULL,
+ trrheader.v_size ? v : NULL,
+ trrheader.f_size ? f : NULL))
{
sprintf(buf, "%s frame %d", fn, nframe);
indent = 0;
indent = pr_title(stdout, indent, buf);
pr_indent(stdout, indent);
fprintf(stdout, "natoms=%10d step=%10d time=%12.7e lambda=%10g\n",
- trn.natoms, trn.step, trn.t, trn.lambda);
- if (trn.box_size)
+ trrheader.natoms, trrheader.step, trrheader.t, trrheader.lambda);
+ if (trrheader.box_size)
{
pr_rvecs(stdout, indent, "box", box, DIM);
}
- if (trn.x_size)
+ if (trrheader.x_size)
{
- pr_rvecs(stdout, indent, "x", x, trn.natoms);
+ pr_rvecs(stdout, indent, "x", x, trrheader.natoms);
}
- if (trn.v_size)
+ if (trrheader.v_size)
{
- pr_rvecs(stdout, indent, "v", v, trn.natoms);
+ pr_rvecs(stdout, indent, "v", v, trrheader.natoms);
}
- if (trn.f_size)
+ if (trrheader.f_size)
{
- pr_rvecs(stdout, indent, "f", f, trn.natoms);
+ pr_rvecs(stdout, indent, "f", f, trrheader.natoms);
}
}
else
{
fprintf(stderr, "\nWARNING: Incomplete frame: nr %d, t=%g\n",
- nframe, trn.t);
+ nframe, trrheader.t);
}
sfree(x);
if (!bOK)
{
fprintf(stderr, "\nWARNING: Incomplete frame header: nr %d, t=%g\n",
- nframe, trn.t);
+ nframe, trrheader.t);
}
- close_tpx(fpwrite);
- close_trn(fpread);
+ gmx_trr_close(fpread);
}
void list_xtc(const char *fn)
list_xtc(fn);
break;
case efTRR:
- list_trn(fn);
+ list_trr(fn);
break;
case efTNG:
list_tng(fn);
void list_ene(const char *fn)
{
- int ndr;
ener_file_t in;
gmx_bool bCont;
gmx_enxnm_t *enm = NULL;
t_enxframe *fr;
int i, j, nre, b;
- real rav, minthird;
char buf[22];
printf("gmx dump: %s\n", fn);
printf("%5d %-24s (%s)\n", i, enm[i].name, enm[i].unit);
}
- minthird = -1.0/3.0;
snew(fr, 1);
do
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_TOOLS_DUMP_H
#define GMX_TOOLS_DUMP_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
/*! \brief Implements gmx dump
*
* \param[in] argc argc value passed to main().
*/
int gmx_dump(int argc, char *argv[]);
-#ifdef __cplusplus
-}
-#endif
-
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/types/inputrec.h"
#include "gromacs/utility/basedefinitions.h"
+/* Ugly hack to convince some compilers that returning t_topology (or other
+ * structs) from an extern "C" function is OK; can probably go when the extern
+ * "C" blocks go.
+ */
+#include "gromacs/topology/topology.h"
+
#ifdef __cplusplus
extern "C" {
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/legacyheaders/txtdump.h"
#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
void TrajectoryAnalysisModule::optionsFinished(
- Options * /*options*/,
TrajectoryAnalysisSettings * /*settings*/)
{
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
class AnalysisData;
class AnalysisDataHandle;
class AnalysisDataParallelOptions;
+class IOptionsContainer;
class Options;
class SelectionCollection;
class TopologyInformation;
* If settings depend on the option values provided by the user, see
* optionsFinished().
*/
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings) = 0;
/*! \brief
* Called after all option values have been set.
*
- * \param[in,out] options Options object in which options are stored.
* \param[in,out] settings Settings to pass to and from the module.
*
* This method is called after option values have been assigned (but
*
* The default implementation does nothing.
*/
- virtual void optionsFinished(Options *options,
- TrajectoryAnalysisSettings *settings);
+ virtual void optionsFinished(TrajectoryAnalysisSettings *settings);
/*! \brief
* Initializes the analysis.
*
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_IMPL_H
#define GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_IMPL_H
+#include <string>
+
#include "gromacs/analysisdata/modules/plot.h"
#include "gromacs/options/timeunitmanager.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
bool bRmPBC;
//! Whether to pass PBC information to the analysis module.
bool bPBC;
+
+ //! Help text for the module.
+ std::string helpText_;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/fileio/trxio.h"
#include "gromacs/math/vec.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
#include "analysissettings-impl.h"
impl_->frflags = frflags;
}
+const std::string &
+TrajectoryAnalysisSettings::helpText() const
+{
+ return impl_->helpText_;
+}
+
+void
+TrajectoryAnalysisSettings::setHelpText(const ConstArrayRef<const char *> &help)
+{
+ impl_->helpText_ = joinStrings(help, "\n");
+}
+
/********************************************************************
* TopologyInformation
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_H
#define GMX_TRAJECTORYANALYSIS_ANALYSISSETTINGS_H
+#include <string>
+
#include "gromacs/math/vectypes.h"
#include "gromacs/options/timeunitmanager.h"
#include "gromacs/utility/classhelpers.h"
namespace gmx
{
+template <typename T> class ConstArrayRef;
+
class AnalysisDataPlotSettings;
class Options;
class TrajectoryAnalysisRunnerCommon;
*/
void setFrameFlags(int frflags);
+ //! Returns the help text.
+ const std::string &helpText() const;
+ //! \copydoc ICommandLineOptionsModuleSettings::setHelpText(const std::string &)
+ void setHelpText(const ConstArrayRef<const char *> &help);
+
private:
class Impl;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/trajectoryanalysis/analysismodule.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
#include "gromacs/utility/gmxassert.h"
#include "runnercommon.h"
FileNameOptionManager fileoptManager;
SelectionOptionManager seloptManager(selections);
Options options(NULL, NULL);
- Options moduleOptions(module_->name(), module_->description());
- Options commonOptions("common", "Common analysis control");
- Options selectionOptions("selection", "Common selection control");
options.addManager(&fileoptManager);
options.addManager(&seloptManager);
- options.addSubSection(&commonOptions);
- options.addSubSection(&selectionOptions);
- options.addSubSection(&moduleOptions);
+ IOptionsContainer &commonOptions = options.addGroup();
+ IOptionsContainer &moduleOptions = options.addGroup();
module_->initOptions(&moduleOptions, settings);
common->initOptions(&commonOptions);
- selections->initOptions(&selectionOptions);
+ selections->initOptions(&commonOptions);
{
CommandLineParser parser(&options);
options.finish();
}
- common->optionsFinished(&commonOptions);
- module_->optionsFinished(&moduleOptions, settings);
+ common->optionsFinished();
+ module_->optionsFinished(settings);
common->initIndexGroups(selections, bUseDefaultGroups_);
- const bool bInteractive = File::standardInput().isInteractive();
+ const bool bInteractive = StandardInputStream::instance().isInteractive();
seloptManager.parseRequestedFromStdin(bInteractive);
common->doneIndexGroups(selections);
SelectionOptionManager seloptManager(&selections);
Options options(NULL, NULL);
- Options moduleOptions(impl_->module_->name(), impl_->module_->description());
- Options commonOptions("common", "Common analysis control");
- Options selectionOptions("selection", "Common selection control");
options.addManager(&seloptManager);
- options.addSubSection(&commonOptions);
- options.addSubSection(&selectionOptions);
- options.addSubSection(&moduleOptions);
+ IOptionsContainer &commonOptions = options.addGroup();
+ IOptionsContainer &moduleOptions = options.addGroup();
impl_->module_->initOptions(&moduleOptions, &settings);
common.initOptions(&commonOptions);
- selections.initOptions(&selectionOptions);
+ selections.initOptions(&commonOptions);
CommandLineHelpWriter(options)
- .setShowDescriptions(true)
+ .setHelpText(settings.helpText())
.setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
.writeHelp(context);
}
* \ingroup module_trajectoryanalysis
*/
class TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule
- : public CommandLineModuleInterface
+ : public ICommandLineModule
{
public:
/*! \brief
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
public:
Angle();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
- virtual void optionsFinished(Options *options,
- TrajectoryAnalysisSettings *settings);
+ virtual void optionsFinished(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
void
-Angle::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+Angle::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] computes different types of angles between vectors.",
static const char *const cGroup2TypeEnum[] =
{ "none", "vector", "plane", "t0", "z", "sphnorm" };
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("oav").filetype(eftPlot).outputFile()
.store(&fnAverage_).defaultBasename("angaver")
void
-Angle::optionsFinished(Options *options, TrajectoryAnalysisSettings * /* settings */)
+Angle::optionsFinished(TrajectoryAnalysisSettings * /* settings */)
{
const bool bSingle = (g1type_[0] == 'a' || g1type_[0] == 'd');
GMX_THROW(InconsistentInputError("Cannot use a second group (-g2) with "
"-g1 angle or dihedral"));
}
- if (bSingle && options->isSet("group2"))
+ if (bSingle && sel2info_->isSet())
{
GMX_THROW(InconsistentInputError("Cannot provide a second selection "
"(-group2) with -g1 angle or dihedral"));
default:
GMX_THROW(InternalError("invalid -g2 value"));
}
- if (natoms2_ == 0 && options->isSet("group2"))
+ if (natoms2_ == 0 && sel2info_->isSet())
{
GMX_THROW(InconsistentInputError("Cannot provide a second selection (-group2) with -g2 t0 or z"));
}
{
rvec v1, v2;
rvec c1, c2;
+
+ // v2 & c2 are conditionally set in the switch statement below, and conditionally
+ // used in a different switch statement later. Apparently the clang static analyzer
+ // thinks there are cases where they can be used uninitialzed (which I cannot find),
+ // but to avoid trouble if we ever change just one of the switch statements it
+ // makes sense to clear them outside the first switch.
+
+ clear_rvec(v2);
+ clear_rvec(c2);
+
switch (g2type_[0])
{
case 'z':
- clear_rvec(v2);
v2[ZZ] = 1.0;
- clear_rvec(c2);
break;
case 's':
copy_rvec(sel2_[g].position(0).x(), c2);
break;
+ default:
+ // do nothing
+ break;
}
+
dh.selectDataSet(g);
for (int n = 0; n < angleCount_[g]; ++n, iter1.nextValue(), iter2.nextValue())
{
rvec x[4];
+ // x[] will be assigned below based on the number of atoms used to initialize iter1,
+ // which in turn should correspond perfectly to g1type_[0] (which determines how many we read),
+ // but unsurprisingly the static analyzer chokes a bit on that.
+ clear_rvecs(4, x);
+
real angle;
// checkSelections() ensures that this reflects all the involved
// positions.
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
public:
Distance();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
void
-Distance::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+Distance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] calculates distances between pairs of positions",
"distances, use [gmx-pairdist]."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("oav").filetype(eftPlot).outputFile()
.store(&fnAverage_).defaultBasename("distave")
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/random/random.h"
#include "gromacs/selection/nbsearch.h"
class FreeVolume : public TrajectoryAnalysisModule
{
public:
- //! Constructor
FreeVolume();
-
- //! Destructor
virtual ~FreeVolume();
- //! Set the options and setting
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
-
- //! First routine called by the analysis framework
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
-
- //! Call for each frame of the trajectory
virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
TrajectoryAnalysisModuleData *pdata);
-
- //! Last routine called by the analysis framework
virtual void finishAnalysis(int nframes);
-
- //! Routine to write output, that is additional over the built-in
virtual void writeOutput();
private:
void
-FreeVolume::initOptions(Options *options,
+FreeVolume::initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"the terminal."
};
- // Add the descriptive text (program help text) to the options
- options->setDescription(desc);
+ settings->setHelpText(desc);
// Add option for optional output file
options->addOption(FileNameOption("o").filetype(eftPlot).outputFile()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/fileio/trx.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/selection/nbsearch.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
public:
PairDistance();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
void
-PairDistance::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+PairDistance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] calculates pairwise distances between one reference",
"[gmx-distance] may be a more suitable tool."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required()
.store(&fnDist_).defaultBasename("dist")
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/selection/nbsearch.h"
#include "gromacs/selection/selection.h"
public:
Rdf();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
- virtual void optionsFinished(Options *options,
- TrajectoryAnalysisSettings *settings);
+ virtual void optionsFinished(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
double cutoff_;
double rmax_;
bool bNormalize_;
+ bool bNormalizationSet_;
bool bXY_;
bool bExclusions_;
pairCounts_(new AnalysisDataSimpleHistogramModule()),
normAve_(new AnalysisDataAverageModule()),
binwidth_(0.002), cutoff_(0.0), rmax_(0.0),
- bNormalize_(true), bXY_(false), bExclusions_(false),
+ bNormalize_(true), bNormalizationSet_(false), bXY_(false),
+ bExclusions_(false),
cut2_(0.0), rmax2_(0.0), surfaceGroupCount_(0)
{
pairDist_.setMultipoint(true);
}
void
-Rdf::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+Rdf::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] calculates radial distribution functions from one",
"i.e. the average number of particles within a distance r.[PAR]"
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required()
.store(&fnRdf_).defaultBasename("rdf")
options->addOption(DoubleOption("bin").store(&binwidth_)
.description("Bin width (nm)"));
options->addOption(BooleanOption("norm").store(&bNormalize_)
+ .storeIsSet(&bNormalizationSet_)
.description("Normalize for bin volume and density"));
options->addOption(BooleanOption("xy").store(&bXY_)
.description("Use only the x and y components of the distance"));
}
void
-Rdf::optionsFinished(Options *options, TrajectoryAnalysisSettings *settings)
+Rdf::optionsFinished(TrajectoryAnalysisSettings *settings)
{
if (surface_ != "no")
{
settings->setFlag(TrajectoryAnalysisSettings::efRequireTop);
- if (options->isSet("norm") && bNormalize_)
+ if (bNormalizationSet_ && bNormalize_)
{
GMX_THROW(InconsistentInputError("-surf cannot be combined with -norm"));
}
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
public:
Sasa();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
}
void
-Sasa::initOptions(Options *options, TrajectoryAnalysisSettings *settings)
+Sasa::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] computes solvent accessible surface areas.",
"that are both too high."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required()
.store(&fnArea_).defaultBasename("area")
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/fileio/trxio.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
#include "gromacs/topology/topology.h"
public:
Select();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
- virtual void optionsFinished(Options *options,
- TrajectoryAnalysisSettings *settings);
+ virtual void optionsFinished(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
void
-Select::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+Select::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"[THISMODULE] writes out basic data about dynamic selections.",
"dynamic selections."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(FileNameOption("os").filetype(eftPlot).outputFile()
.store(&fnSize_).defaultBasename("size")
}
void
-Select::optionsFinished(Options * /*options*/,
- TrajectoryAnalysisSettings *settings)
+Select::optionsFinished(TrajectoryAnalysisSettings *settings)
{
if (!fnPDB_.empty())
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <string.h>
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/timecontrol.h"
-#include "gromacs/fileio/tpxio.h"
#include "gromacs/fileio/trx.h"
#include "gromacs/fileio/trxio.h"
#include "gromacs/legacyheaders/oenv.h"
#include "gromacs/math/vec.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/options/options.h"
#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/selection/indexutil.h"
#include "gromacs/selection/selectionfileoption.h"
#include "gromacs/topology/topology.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programcontext.h"
double startTime_;
double endTime_;
double deltaTime_;
+ bool bStartTimeSet_;
+ bool bEndTimeSet_;
+ bool bDeltaTimeSet_;
gmx_ana_indexgrps_t *grps_;
bool bTrajOpen_;
TrajectoryAnalysisRunnerCommon::Impl::Impl(TrajectoryAnalysisSettings *settings)
: settings_(*settings),
startTime_(0.0), endTime_(0.0), deltaTime_(0.0),
+ bStartTimeSet_(false), bEndTimeSet_(false), bDeltaTimeSet_(false),
grps_(NULL),
bTrajOpen_(false), fr(NULL), gpbc_(NULL), status_(NULL), oenv_(NULL)
{
void
-TrajectoryAnalysisRunnerCommon::initOptions(Options *options)
+TrajectoryAnalysisRunnerCommon::initOptions(IOptionsContainer *options)
{
TrajectoryAnalysisSettings &settings = impl_->settings_;
.description("Extra index groups"));
// Add options for trajectory time control.
- options->addOption(DoubleOption("b").store(&impl_->startTime_).timeValue()
+ options->addOption(DoubleOption("b")
+ .store(&impl_->startTime_).storeIsSet(&impl_->bStartTimeSet_)
+ .timeValue()
.description("First frame (%t) to read from trajectory"));
- options->addOption(DoubleOption("e").store(&impl_->endTime_).timeValue()
+ options->addOption(DoubleOption("e")
+ .store(&impl_->endTime_).storeIsSet(&impl_->bEndTimeSet_)
+ .timeValue()
.description("Last frame (%t) to read from trajectory"));
- options->addOption(DoubleOption("dt").store(&impl_->deltaTime_).timeValue()
+ options->addOption(DoubleOption("dt")
+ .store(&impl_->deltaTime_).storeIsSet(&impl_->bDeltaTimeSet_)
+ .timeValue()
.description("Only use frame if t MOD dt == first time (%t)"));
// Add time unit option.
settings.impl_->timeUnitManager.addTimeUnitOption(options, "tu");
// Add plot options.
- settings.impl_->plotSettings.addOptions(options);
+ settings.impl_->plotSettings.initOptions(options);
// Add common options for trajectory processing.
if (!settings.hasFlag(TrajectoryAnalysisSettings::efNoUserRmPBC))
void
-TrajectoryAnalysisRunnerCommon::optionsFinished(Options *options)
+TrajectoryAnalysisRunnerCommon::optionsFinished()
{
impl_->settings_.impl_->plotSettings.setTimeUnit(
impl_->settings_.impl_->timeUnitManager.timeUnit());
GMX_THROW(InconsistentInputError("No trajectory or topology provided, nothing to do!"));
}
- if (options->isSet("b"))
+ if (impl_->bStartTimeSet_)
{
setTimeValue(TBEGIN, impl_->startTime_);
}
- if (options->isSet("e"))
+ if (impl_->bEndTimeSet_)
{
setTimeValue(TEND, impl_->endTime_);
}
- if (options->isSet("dt"))
+ if (impl_->bDeltaTimeSet_)
{
setTimeValue(TDELTA, impl_->deltaTime_);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
+class IOptionsContainer;
class Options;
class SelectionCollection;
class TopologyInformation;
*
* \param[in,out] options Options object to add the options to.
*/
- void initOptions(Options *options);
+ void initOptions(IOptionsContainer *options);
//! Scales time option values according to the time unit set.
void scaleTimeOptions(Options *options);
- /*! \brief
- * Processes common option values after they have been parsed.
- *
- * \param[in,out] options Options object in which options are stored.
- */
- void optionsFinished(Options *options);
+ //! Processes common option values after they have been parsed.
+ void optionsFinished();
//! Initialize index groups for selections.
void initIndexGroups(SelectionCollection *selections,
bool bUseDefaults);
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="InteractiveSession">
+ <pre>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="starts-with(@Name, 'Output')">
+ <xsl:value-of select="substring(.,2)"/>
+ </xsl:when>
+ <xsl:when test="string-length(.)=1">
+ <xsl:text>►</xsl:text>
+ <xsl:text>¶</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(substring(.,2), ' ')">
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="translate(substring(.,2), ' ', '⏎')"/>
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="substring(.,2)"/>
+ <xsl:text>¶</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:text>[EOF]</xsl:text>
+ </pre>
+</xsl:template>
+
</xsl:stylesheet>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gmxpre.h"
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
#include "gromacs/trajectoryanalysis/analysismodule.h"
SelectionTester();
virtual ~SelectionTester();
- virtual void initOptions(Options *options,
+ virtual void initOptions(IOptionsContainer *options,
TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
}
void
-SelectionTester::initOptions(Options *options,
- TrajectoryAnalysisSettings * /*settings*/)
+SelectionTester::initOptions(IOptionsContainer *options,
+ TrajectoryAnalysisSettings *settings)
{
static const char *const desc[] = {
"This is a test program for selections."
};
- options->setDescription(desc);
+ settings->setHelpText(desc);
options->addOption(SelectionOption("select").storeVector(&selections_)
.required().multiValue()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* containers to simplify implementation of other code. Contents of the module
* are discussed in more details under the different headings below.
* Some of the code in installed headers in the module is intended for use
- * directly from code outside the Gromacs library, but a significant portion is
- * exposed only because other public headers depend on it.
+ * directly from code outside the \Gromacs library, but a significant portion
+ * is exposed only because other public headers depend on it.
*
* Since this module implements error handling, it should be at the lowest
* level: it should not depend on other modules. Any functionality needed by
* the error handling code should also be kept in this module.
*
- * <H3>Error Handling</H3>
+ * <H3>Error handling</H3>
*
* Exception classes used in the library are declared in the exceptions.h header
- * file. Most Gromacs-specific exceptions derive from gmx::GromacsException.
+ * file. Most \Gromacs-specific exceptions derive from gmx::GromacsException.
*
* This header also declares a ::GMX_THROW macro that should be used for
* throwing exceptions. ::GMX_THROW_WITH_ERRNO is also provided for reporting
* \endif
*
*
- * <H3>Basic %File Handling</H3>
+ * \if libapi
+ *
+ * <H3>Basic file handling and streams</H3>
*
- * The header file.h declares a gmx::File class for basic I/O support.
+ * The header textstream.h declares interfaces for simple text format streams.
+ * Headers filestream.h and stringstream.h provide implementations for these
+ * streams for reading/writing files and for writing to in-memory strings.
*
- * The header path.h declares helpers for manipulating paths and for managing
- * directories.
+ * The header fileredirector.h provides interfaces for redirecting file input
+ * and/or output to alternative streams, for use in testing, as well as default
+ * implementations for these interfaces that just use the file system.
*
- * The fate of these headers depends on what is decided in Redmine issue #950.
+ * The header textwriter.h provides gmx::TextWriter for more formatting support
+ * when writing to a text stream. Similarly, textreader.h provides more
+ * formatting support when reading from a text stream.
*
+ * The header path.h declares helpers for manipulating paths as strings and for
+ * managing directories and files.
+ * The fate of this header depends on what is decided in Redmine issue #950.
+ *
+ * \endif
*
- * <H3>Implementation Helpers</H3>
+ * <H3>Implementation helpers</H3>
*
* The header basedefinitions.h contains common definitions and macros used
* throughout \Gromacs. It includes fixed-width integer types (`gmx_int64_t`
* safety when using bit flag fields.
*
*
- * <H3>Other Functionality</H3>
+ * <H3>Other functionality</H3>
*
* The header init.h declares gmx::init() and gmx::finalize() for initializing
* and deinitializing the \Gromacs library.
* The header sysinfo.h declares gmx_getpid() for getting the current process
* id.
*
- * The header programcontext.h declares a gmx::ProgramContextInterface that is
+ * The header programcontext.h declares a gmx::IProgramContext that is
* used to
* initialize and access information about the running program, such as the
* name and path of the executable. This information is used, e.g., by the
errorcodes.h
exceptions.h
fatalerror.h
- file.h
flags.h
futil.h
gmxassert.h
#include "cstringutil.h"
-#include <assert.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+
+#include <cassert>
+#include <cctype>
+#include <cstring>
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/fatalerror.h"
void ltrim (char *str)
{
- char *tr;
int i, c;
if (NULL == str)
char *gmx_step_str(gmx_int64_t i, char *buf)
{
- sprintf(buf, "%"GMX_PRId64, i);
+ sprintf(buf, "%" GMX_PRId64, i);
return buf;
}
#include "buildinfo.h"
#include "gromacs/utility/directoryenumerator.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/stringutil.h"
fprintf(debug, "Opening library file %s\n", fn);
}
#endif
- return File::openRawHandle(filename, "r");
+ return TextInputFile::openRawHandle(filename);
}
std::string DataFileFinder::findFile(const DataFileOptions &options) const
* Constructs a default data file finder.
*
* The constructed finder searches only in the directory specified by
- * the global program context (see ProgramContextInterface), and
+ * the global program context (see IProgramContext), and
* optionally in the current directory.
*
* Does not throw.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <cstdlib>
-#include "thread_mpi/mutex.h"
+#include "gromacs/utility/mutex.h"
#include "errorformat.h"
//! Global error handler set with setFatalErrorHandler().
ErrorHandlerFunc g_errorHandler = standardErrorHandler;
//! Mutex for protecting access to ::g_errorHandler.
-tMPI::mutex handler_mutex;
+Mutex handler_mutex;
//! \}
ErrorHandlerFunc setFatalErrorHandler(ErrorHandlerFunc handler)
{
- tMPI::lock_guard<tMPI::mutex> lock(handler_mutex);
- ErrorHandlerFunc oldHandler = g_errorHandler;
+ lock_guard<Mutex> lock(handler_mutex);
+ ErrorHandlerFunc oldHandler = g_errorHandler;
g_errorHandler = handler;
return oldHandler;
}
{
ErrorHandlerFunc handler = NULL;
{
- tMPI::lock_guard<tMPI::mutex> lock(handler_mutex);
+ lock_guard<Mutex> lock(handler_mutex);
handler = g_errorHandler;
}
if (handler != NULL)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/errorcodes.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "errorformat.h"
* exceptions while still supporting output to different formats (e.g., to a
* string or to \c stderr).
*/
-class MessageWriterInterface
+class IMessageWriter
{
public:
- virtual ~MessageWriterInterface() {}
+ virtual ~IMessageWriter() {}
/*! \brief
* Writes a single line of text into the output.
* Formats the messages into the provided FILE handle without checking for
* errors in std::fprintf() calls.
*/
-class MessageWriterFileNoThrow : public MessageWriterInterface
+class MessageWriterFileNoThrow : public IMessageWriter
{
public:
//! Initializes a writer that writes to the given file handle.
FILE *fp_;
};
+/*! \brief
+ * Exception information writer to format into a TextOutputStream.
+ */
+class MessageWriterTextWriter : public IMessageWriter
+{
+ public:
+ //! Initializes a writer that writes to the given stream.
+ explicit MessageWriterTextWriter(TextWriter *writer) : writer_(writer)
+ {
+ }
+
+ virtual void writeLine(const char *text, int indent)
+ {
+ writer_->wrapperSettings().setIndent(indent);
+ writer_->writeLine(text);
+ }
+ virtual void writeErrNoInfo(int errorNumber, const char *funcName,
+ int indent)
+ {
+ writer_->wrapperSettings().setIndent(indent);
+ writer_->writeLine(formatString("Reason: %s", std::strerror(errorNumber)));
+ if (funcName != NULL)
+ {
+ writer_->writeLine(
+ formatString("(call to %s() returned error code %d)",
+ funcName, errorNumber));
+ }
+ }
+
+ private:
+ TextWriter *writer_;
+};
+
/*! \brief
* Exception information writer to format into an std::string.
*/
-class MessageWriterString : public MessageWriterInterface
+class MessageWriterString : public IMessageWriter
{
public:
//! Post-processes the output string to not end in a line feed.
*
* Does not throw unless the writer throws.
*/
-void formatExceptionMessageInternal(MessageWriterInterface *writer,
+void formatExceptionMessageInternal(IMessageWriter *writer,
const std::exception &ex, int indent)
{
const boost::exception *boostEx = dynamic_cast<const boost::exception *>(&ex);
formatExceptionMessageInternal(&writer, ex, 0);
}
+void formatExceptionMessageToWriter(TextWriter *writer,
+ const std::exception &ex)
+{
+ MessageWriterTextWriter messageWriter(writer);
+ formatExceptionMessageInternal(&messageWriter, ex, 0);
+}
+
int processExceptionAtExit(const std::exception & /*ex*/)
{
int returnCode = 1;
namespace gmx
{
+class TextWriter;
+
namespace internal
{
//! Internal container type for storing a list of nested exceptions.
* \throws std::bad_alloc if out of memory.
*/
void formatExceptionMessageToFile(FILE *fp, const std::exception &ex);
+/*! \brief
+ * Formats an error message for reporting an exception.
+ *
+ * \param writer Writer to use for writing the message.
+ * \param[in] ex Exception to format.
+ * \throws std::bad_alloc if out of memory.
+ */
+void formatExceptionMessageToWriter(TextWriter *writer,
+ const std::exception &ex);
/*! \brief
* Handles an exception that is causing the program to terminate.
*
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-/*! \internal \file
- * \brief
- * Implements gmx::File.
- *
- * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \ingroup module_utility
- */
-#include "gmxpre.h"
-
-#include "file.h"
-
-#include "config.h"
-
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/stringutil.h"
-
-namespace gmx
-{
-
-/*! \internal \brief
- * Private implementation class for File.
- *
- * \ingroup module_utility
- */
-class File::Impl
-{
- public:
- /*! \brief
- * Initialize a file object with the given handle.
- *
- * \param[in] fp %File handle to use (may be NULL).
- * \param[in] bClose Whether this object should close its file handle.
- */
- Impl(FILE *fp, bool bClose);
- ~Impl();
-
- //! File handle for this object (may be NULL).
- FILE *fp_;
- /*! \brief
- * Whether \p fp_ should be closed by this object.
- *
- * Can be true if \p fp_ is NULL.
- */
- bool bClose_;
-};
-
-File::Impl::Impl(FILE *fp, bool bClose)
- : fp_(fp), bClose_(bClose)
-{
-}
-
-File::Impl::~Impl()
-{
- if (fp_ != NULL && bClose_)
- {
- if (fclose(fp_) != 0)
- {
- // TODO: Log the error somewhere
- }
- }
-}
-
-// static
-FILE *File::openRawHandle(const char *filename, const char *mode)
-{
- FILE *fp = fopen(filename, mode);
- if (fp == NULL)
- {
- GMX_THROW_WITH_ERRNO(
- FileIOError(formatString("Could not open file '%s'", filename)),
- "fopen", errno);
- }
- return fp;
-}
-
-// static
-FILE *File::openRawHandle(const std::string &filename, const char *mode)
-{
- return openRawHandle(filename.c_str(), mode);
-}
-
-File::File(const char *filename, const char *mode)
- : impl_(new Impl(NULL, true))
-{
- open(filename, mode);
-}
-
-File::File(const std::string &filename, const char *mode)
- : impl_(new Impl(NULL, true))
-{
- open(filename, mode);
-}
-
-File::File(const FileInitializer &initializer)
- : impl_(new Impl(NULL, true))
-{
- open(initializer.filename_, initializer.mode_);
-}
-
-File::File(FILE *fp, bool bClose)
- : impl_(new Impl(fp, bClose))
-{
-}
-
-File::~File()
-{
-}
-
-void File::open(const char *filename, const char *mode)
-{
- GMX_RELEASE_ASSERT(impl_->fp_ == NULL,
- "Attempted to open the same file object twice");
- // TODO: Port all necessary functionality from gmx_ffopen() here.
- impl_->fp_ = openRawHandle(filename, mode);
-}
-
-void File::open(const std::string &filename, const char *mode)
-{
- open(filename.c_str(), mode);
-}
-
-void File::close()
-{
- GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
- "Attempted to close a file object that is not open");
- GMX_RELEASE_ASSERT(impl_->bClose_,
- "Attempted to close a file object that should not be");
- bool bOk = (fclose(impl_->fp_) == 0);
- impl_->fp_ = NULL;
- if (!bOk)
- {
- GMX_THROW_WITH_ERRNO(
- FileIOError("Error while closing file"), "fclose", errno);
- }
-}
-
-bool File::isInteractive() const
-{
- GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
- "Attempted to access a file object that is not open");
-#ifdef HAVE_UNISTD_H
- return isatty(fileno(impl_->fp_));
-#else
- return true;
-#endif
-}
-
-FILE *File::handle()
-{
- GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
- "Attempted to access a file object that is not open");
- return impl_->fp_;
-}
-
-void File::readBytes(void *buffer, size_t bytes)
-{
- errno = 0;
- FILE *fp = handle();
- // TODO: Retry based on errno or something else?
- size_t bytesRead = std::fread(buffer, 1, bytes, fp);
- if (bytesRead != bytes)
- {
- if (feof(fp))
- {
- GMX_THROW(FileIOError(
- formatString("Premature end of file\n"
- "Attempted to read: %d bytes\n"
- "Successfully read: %d bytes",
- static_cast<int>(bytes),
- static_cast<int>(bytesRead))));
- }
- else
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
- "fread", errno);
- }
- }
-}
-
-bool File::readLine(std::string *line)
-{
- if (!readLineWithTrailingSpace(line))
- {
- return false;
- }
- size_t endPos = line->find_last_not_of(" \t\r\n");
- if (endPos != std::string::npos)
- {
- line->resize(endPos + 1);
- }
- return true;
-}
-
-bool File::readLineWithTrailingSpace(std::string *line)
-{
- line->clear();
- const size_t bufsize = 256;
- std::string result;
- char buf[bufsize];
- buf[0] = '\0';
- FILE *fp = handle();
- while (fgets(buf, bufsize, fp) != NULL)
- {
- size_t length = std::strlen(buf);
- result.append(buf, length);
- if (length < bufsize - 1 || buf[length - 1] == '\n')
- {
- break;
- }
- }
- if (ferror(fp))
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
- "fgets", errno);
- }
- *line = result;
- return !result.empty() || !feof(fp);
-}
-
-void File::writeString(const char *str)
-{
- if (fprintf(handle(), "%s", str) < 0)
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"),
- "fprintf", errno);
- }
-}
-
-void File::writeLine(const char *line)
-{
- size_t length = std::strlen(line);
-
- writeString(line);
- if (length == 0 || line[length-1] != '\n')
- {
- writeString("\n");
- }
-}
-
-void File::writeLine()
-{
- writeString("\n");
-}
-
-// static
-bool File::exists(const char *filename)
-{
- if (filename == NULL)
- {
- return false;
- }
- FILE *test = fopen(filename, "r");
- if (test == NULL)
- {
- return false;
- }
- else
- {
- fclose(test);
- // Windows doesn't allow fopen of directory, so we don't need to check
- // this separately.
-#ifndef GMX_NATIVE_WINDOWS
- struct stat st_buf;
- int status = stat(filename, &st_buf);
- if (status != 0 || !S_ISREG(st_buf.st_mode))
- {
- return false;
- }
-#endif
- return true;
- }
-}
-
-// static
-bool File::exists(const std::string &filename)
-{
- return exists(filename.c_str());
-}
-
-// static
-File &File::standardInput()
-{
- static File stdinObject(stdin, false);
- return stdinObject;
-}
-
-// static
-File &File::standardOutput()
-{
- static File stdoutObject(stdout, false);
- return stdoutObject;
-}
-
-// static
-File &File::standardError()
-{
- static File stderrObject(stderr, false);
- return stderrObject;
-}
-
-// static
-std::string File::readToString(const char *filename)
-{
- // Binary mode is required on Windows to be able to determine a size
- // that can be passed to fread().
- File file(filename, "rb");
- FILE *fp = file.handle();
-
- if (std::fseek(fp, 0L, SEEK_END) != 0)
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Seeking to end of file failed"),
- "fseek", errno);
- }
- long len = std::ftell(fp);
- if (len == -1)
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Reading file length failed"),
- "ftell", errno);
- }
- if (std::fseek(fp, 0L, SEEK_SET) != 0)
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Seeking to start of file failed"),
- "fseek", errno);
- }
-
- std::vector<char> data(len);
- file.readBytes(&data[0], len);
- file.close();
-
- std::string result(&data[0], len);
- // The below is necessary on Windows to make newlines stay as '\n' on a
- // roundtrip.
- result = replaceAll(result, "\r\n", "\n");
-
- return result;
-}
-
-// static
-std::string File::readToString(const std::string &filename)
-{
- return readToString(filename.c_str());
-}
-
-// static
-void File::writeFileFromString(const std::string &filename,
- const std::string &text)
-{
- File file(filename, "w");
- file.writeString(text);
- file.close();
-}
-
-} // namespace gmx
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-/*! \file
- * \brief
- * Declares gmx::File.
- *
- * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \inpublicapi
- * \ingroup module_utility
- */
-#ifndef GMX_UTILITY_FILE_H
-#define GMX_UTILITY_FILE_H
-
-#include <cstdio>
-
-#include <string>
-
-#include "gromacs/utility/classhelpers.h"
-
-namespace gmx
-{
-
-class File;
-
-/*! \brief
- * Parameters for creating a File object.
- *
- * This class (mostly) replaces the ability to return a File object from a
- * function (since File is not copyable): returning a FileInitializer instead
- * allows the caller to construct the File object.
- *
- * \inpublicapi
- * \ingroup module_utility
- */
-class FileInitializer
-{
- public:
- /*! \brief
- * Creates the initializer with given parameters.
- *
- * The passed strings must remain valid until the initializer is used
- * to construct a File object.
- */
- FileInitializer(const char *filename, const char *mode)
- : filename_(filename), mode_(mode)
- {
- }
-
- private:
- const char *filename_;
- const char *mode_;
-
- /*! \brief
- * Needed to allow access to the parameters without otherwise
- * unnecessary accessors.
- */
- friend class File;
-};
-
-/*! \brief
- * Basic file object.
- *
- * This class provides basic file I/O functionality and uses exceptions
- * (FileIOError) for error reporting.
- *
- * \inpublicapi
- * \ingroup module_utility
- */
-class File
-{
- public:
- /*! \brief
- * Opens a file and returns a `FILE` handle.
- *
- * \param[in] filename Path of the file to open.
- * \param[in] mode Mode to open the file in (for fopen()).
- * \throws FileIOError on any I/O error.
- *
- * Instead of returning `NULL` on errors, throws an exception with
- * additional details (including the file name and `errno`).
- */
- static FILE *openRawHandle(const char *filename, const char *mode);
- //! \copydoc openRawHandle(const char *, const char *)
- static FILE *openRawHandle(const std::string &filename, const char *mode);
- /*! \brief
- * Creates a file object and opens a file.
- *
- * \param[in] filename Path of the file to open.
- * \param[in] mode Mode to open the file in (for fopen()).
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- *
- * \see open(const char *, const char *)
- */
- File(const char *filename, const char *mode);
- //! \copydoc File(const char *, const char *)
- File(const std::string &filename, const char *mode);
- /*! \brief
- * Creates a file object and opens a file.
- *
- * \param[in] initializer Parameters to open the file.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- */
- File(const FileInitializer &initializer);
- /*! \brief
- * Destroys the file object.
- *
- * If the file is still open, it is closed.
- * Any error conditions will be ignored.
- */
- ~File();
-
- /*! \brief
- * Opens a file.
- *
- * \param[in] filename Path of the file to open.
- * \param[in] mode Mode to open the file in (for fopen()).
- * \throws FileIOError on any I/O error.
- *
- * The file object must not be open.
- */
- void open(const char *filename, const char *mode);
- //! \copydoc open(const char *, const char *)
- void open(const std::string &filename, const char *mode);
- /*! \brief
- * Closes the file object.
- *
- * \throws FileIOError on any I/O error.
- *
- * The file must be open.
- */
- void close();
-
- /*! \brief
- * Returns whether the file is an interactive terminal.
- *
- * Only works on Unix, otherwise always returns true.
- * It only makes sense to call this for File::standardInput() and
- * friends.
- *
- * Thie file must be open.
- * Does not throw.
- */
- bool isInteractive() const;
- /*! \brief
- * Returns a file handle for interfacing with C functions.
- *
- * The file must be open.
- * Does not throw.
- */
- FILE *handle();
-
- /*! \brief
- * Reads given number of bytes from the file.
- *
- * \param[out] buffer Pointer to buffer that receives the bytes.
- * \param[in] bytes Number of bytes to read.
- * \throws FileIOError on any I/O error.
- *
- * The file must be open.
- */
- void readBytes(void *buffer, size_t bytes);
- /*! \brief
- * Reads a single line from the file.
- *
- * \param[out] line String to receive the line.
- * \returns false if nothing was read because the file ended.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- *
- * On error or when false is returned, \p line will be empty.
- * Trailing space will be removed from the line.
- * To loop over all lines in the file, use:
- * \code
- std::string line;
- while (file.readLine(&line))
- {
- // ...
- }
- \endcode
- */
- bool readLine(std::string *line);
- /*! \brief
- * Reads a single line from the file.
- *
- * \param[out] line String to receive the line.
- * \returns false if nothing was read because the file ended.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- *
- * On error or when false is returned, \p line will be empty.
- * Works as readLine(), except that terminating newline will be present
- * in \p line if it was present in the file.
- *
- * \see readLine()
- */
- bool readLineWithTrailingSpace(std::string *line);
-
- /*! \brief
- * Writes a string to the file.
- *
- * \param[in] str String to write.
- * \throws FileIOError on any I/O error.
- *
- * The file must be open.
- */
- void writeString(const char *str);
- //! \copydoc writeString(const char *)
- void writeString(const std::string &str) { writeString(str.c_str()); }
- /*! \brief
- * Writes a line to the file.
- *
- * \param[in] line Line to write.
- * \throws FileIOError on any I/O error.
- *
- * If \p line does not end in a newline, one newline is appended.
- * Otherwise, works as writeString().
- *
- * The file must be open.
- */
- void writeLine(const char *line);
- //! \copydoc writeLine(const char *)
- void writeLine(const std::string &line) { writeLine(line.c_str()); }
- /*! \brief
- * Writes a newline to the file.
- *
- * \throws FileIOError on any I/O error.
- */
- void writeLine();
-
- /*! \brief
- * Checks whether a file exists and is a regular file.
- *
- * \param[in] filename Path to the file to check.
- * \returns true if \p filename exists and is accessible.
- *
- * Does not throw.
- */
- static bool exists(const char *filename);
- //! \copydoc exists(const char *)
- static bool exists(const std::string &filename);
-
- /*! \brief
- * Returns a File object for accessing stdin.
- *
- * \throws std::bad_alloc if out of memory (only on first call).
- */
- static File &standardInput();
- /*! \brief
- * Returns a File object for accessing stdout.
- *
- * \throws std::bad_alloc if out of memory (only on first call).
- */
- static File &standardOutput();
- /*! \brief
- * Returns a File object for accessing stderr.
- *
- * \throws std::bad_alloc if out of memory (only on first call).
- */
- static File &standardError();
-
- /*! \brief
- * Reads contents of a file to a std::string.
- *
- * \param[in] filename Name of the file to read.
- * \returns The contents of \p filename.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- */
- static std::string readToString(const char *filename);
- //! \copydoc readToString(const char *)
- static std::string readToString(const std::string &filename);
- /*! \brief
- * Convenience method for writing a file from a string in a single call.
- *
- * \param[in] filename Name of the file to read.
- * \param[in] text String to write to \p filename.
- * \throws FileIOError on any I/O error.
- *
- * If \p filename exists, it is overwritten.
- */
- static void writeFileFromString(const std::string &filename,
- const std::string &text);
-
- private:
- /*! \brief
- * Initialize file object from an existing file handle.
- *
- * \param[in] fp %File handle to use (may be NULL).
- * \param[in] bClose Whether this object should close its file handle.
- * \throws std::bad_alloc if out of memory.
- *
- * Used internally to implement standardOutput() and standardError().
- */
- File(FILE *fp, bool bClose);
-
- class Impl;
-
- PrivateImplPointer<Impl> impl_;
-};
-
-} // namespace gmx
-
-#endif
#include "fileredirector.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
+#include "gromacs/utility/path.h"
namespace gmx
{
-FileInputRedirectorInterface::~FileInputRedirectorInterface()
+IFileInputRedirector::~IFileInputRedirector()
{
}
-FileOutputRedirectorInterface::~FileOutputRedirectorInterface()
+IFileOutputRedirector::~IFileOutputRedirector()
{
}
*
* \ingroup module_utility
*/
-class DefaultInputRedirector : public FileInputRedirectorInterface
+class DefaultInputRedirector : public IFileInputRedirector
{
public:
virtual bool fileExists(const char *filename) const
*
* \ingroup module_utility
*/
-class DefaultOutputRedirector : public FileOutputRedirectorInterface
+class DefaultOutputRedirector : public IFileOutputRedirector
{
public:
- virtual File &standardOutput()
+ virtual TextOutputStream &standardOutput()
{
- return File::standardOutput();
+ return TextOutputFile::standardOutput();
}
- virtual FileInitializer openFileForWriting(const char *filename)
+ virtual TextOutputStreamPointer openTextOutputFile(const char *filename)
{
- return FileInitializer(filename, "w");
+ return TextOutputStreamPointer(new TextOutputFile(filename));
}
};
} // namespace
//! \cond libapi
-FileInputRedirectorInterface &defaultFileInputRedirector()
+IFileInputRedirector &defaultFileInputRedirector()
{
static DefaultInputRedirector instance;
return instance;
}
-FileOutputRedirectorInterface &defaultFileOutputRedirector()
+IFileOutputRedirector &defaultFileOutputRedirector()
{
static DefaultOutputRedirector instance;
return instance;
*/
/*! \libinternal \file
* \brief
- * Declares gmx::FileOutputRedirectorInterface.
+ * Declares gmx::IFileOutputRedirector.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
#include <string>
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/textstream.h"
namespace gmx
{
*
* The calling code should take in this interface and use the methods in it
* all file system operations that need to support this redirection.
- * By default, the code can then use defaultFileInputRedirector() in case no
- * redirection is needed.
*
* This allows tests to override the file existence checks without actually
- * using the file system.
+ * using the file system. See IFileOutputRedirector for notes on
+ * a typical usage pattern.
*
* With some further refactoring of the File class, this could also support
* redirecting input files from in-memory buffers as well, but for now the
* \inlibraryapi
* \ingroup module_utility
*/
-class FileInputRedirectorInterface
+class IFileInputRedirector
{
public:
- virtual ~FileInputRedirectorInterface();
+ virtual ~IFileInputRedirector();
/*! \brief
* Checks whether the provided path exists (and is a file).
/*! \libinternal \brief
* Allows capturing `stdout` and file output from code that supports it.
*
- * The calling code should take in this interface and use the File objects
+ * The calling code should take in this interface and use the stream objects
* it returns for all output that needs to support this redirection.
- * By default, the code can then use defaultFileOutputRedirector() in case no
- * redirection is needed.
*
- * This allows tests to capture the file output without duplicating the
- * knowledge of which files are actually produced. With some further
- * refactoring of the File class, this could support capturing the output into
- * in-memory buffers as well, but for now the current capabilities are
- * sufficient.
+ * Currently, the (nearly) only purpose for this interface is for unit tests to
+ * capture the file output without duplicating the knowledge of which files are
+ * actually produced. The tests can also replace actual files with in-memory
+ * streams (e.g., a StringOutputStream), and test the output without actually
+ * accessing the file system and managing actual files.
+ *
+ * As the main user for non-default implementation of this interface is tests,
+ * code using this interface generally uses a pattern where the redirector is
+ * initialized to defaultFileOutputRedirector(), and a separate setter is
+ * provided for tests to change the default. This allows code outside the
+ * tests (and outside the code actually calling the redirector) to be written
+ * as if this interface did not exist (i.e., they do not need to pass the
+ * default instance).
+ *
+ * Also, the interface only supports text files, but can be generalized if/when
+ * there is a need for binary streams (see also TextOutputStream).
*
* \inlibraryapi
* \ingroup module_utility
*/
-class FileOutputRedirectorInterface
+class IFileOutputRedirector
{
public:
- virtual ~FileOutputRedirectorInterface();
+ virtual ~IFileOutputRedirector();
/*! \brief
- * Returns a File object to use for `stdout` output.
+ * Returns a stream to use for `stdout` output.
*/
- virtual File &standardOutput() = 0;
+ virtual TextOutputStream &standardOutput() = 0;
/*! \brief
- * Returns a File object to use for output to a given file.
+ * Returns a stream to use for output to a file at a given path.
*
* \param[in] filename Requested file name.
*/
- virtual FileInitializer openFileForWriting(const char *filename) = 0;
+ virtual TextOutputStreamPointer openTextOutputFile(const char *filename) = 0;
- //! Convenience method to open a file using an std::string path.
- FileInitializer openFileForWriting(const std::string &filename)
+ //! Convenience method to open a stream using an std::string path.
+ TextOutputStreamPointer openTextOutputFile(const std::string &filename)
{
- return openFileForWriting(filename.c_str());
+ return openTextOutputFile(filename.c_str());
}
};
//! \cond libapi
/*! \brief
- * Returns default implementation for FileInputRedirectorInterface.
+ * Returns default implementation for IFileInputRedirector.
*
* The returned implementation does not redirect anything, but just uses the
* file system normally.
*
* \ingroup module_utility
*/
-FileInputRedirectorInterface &defaultFileInputRedirector();
+IFileInputRedirector &defaultFileInputRedirector();
/*! \brief
- * Returns default implementation for FileOutputRedirectorInterface.
+ * Returns default implementation for IFileOutputRedirector.
*
* The returned implementation does not redirect anything, but just opens the
* files at requested locations.
*
* \ingroup module_utility
*/
-FileOutputRedirectorInterface &defaultFileOutputRedirector();
+IFileOutputRedirector &defaultFileOutputRedirector();
//! \endcond
} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes from filestream.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "filestream.h"
+
+#include "config.h"
+
+#include <cerrno>
+#include <cstdio>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/stringutil.h"
+
+namespace gmx
+{
+
+namespace
+{
+
+//! Helper function for implementing readLine() for input streams.
+bool readLineImpl(FILE *fp, std::string *line)
+{
+ line->clear();
+ const size_t bufsize = 256;
+ std::string result;
+ char buf[bufsize];
+ buf[0] = '\0';
+ while (std::fgets(buf, bufsize, fp) != NULL)
+ {
+ const size_t length = std::strlen(buf);
+ result.append(buf, length);
+ if (length < bufsize - 1 || buf[length - 1] == '\n')
+ {
+ break;
+ }
+ }
+ if (std::ferror(fp))
+ {
+ GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
+ "fgets", errno);
+ }
+ *line = result;
+ return !result.empty() || !std::feof(fp);
+}
+
+} // namespace
+
+namespace internal
+{
+
+/********************************************************************
+ * FileStreamImpl
+ */
+
+class FileStreamImpl
+{
+ public:
+ explicit FileStreamImpl(FILE *fp)
+ : fp_(fp), bClose_(false)
+ {
+ }
+ FileStreamImpl(const char *filename, const char *mode)
+ : fp_(NULL), bClose_(true)
+ {
+ fp_ = std::fopen(filename, mode);
+ if (fp_ == NULL)
+ {
+ GMX_THROW_WITH_ERRNO(
+ FileIOError(formatString("Could not open file '%s'", filename)),
+ "fopen", errno);
+ }
+ }
+ ~FileStreamImpl()
+ {
+ if (fp_ != NULL && bClose_)
+ {
+ if (std::fclose(fp_) != 0)
+ {
+ // TODO: Log the error somewhere
+ }
+ }
+ }
+
+ FILE *handle()
+ {
+ GMX_RELEASE_ASSERT(fp_ != NULL,
+ "Attempted to access a file object that is not open");
+ return fp_;
+ }
+
+ void close()
+ {
+ GMX_RELEASE_ASSERT(fp_ != NULL,
+ "Attempted to close a file object that is not open");
+ GMX_RELEASE_ASSERT(bClose_,
+ "Attempted to close a file object that should not be");
+ const bool bOk = (std::fclose(fp_) == 0);
+ fp_ = NULL;
+ if (!bOk)
+ {
+ GMX_THROW_WITH_ERRNO(
+ FileIOError("Error while closing file"), "fclose", errno);
+ }
+ }
+
+ private:
+ //! File handle for this object (NULL if the stream has been closed).
+ FILE *fp_;
+ //! Whether \p fp_ should be closed by this object.
+ bool bClose_;
+};
+
+} // namespace internal
+
+using internal::FileStreamImpl;
+
+/********************************************************************
+ * StandardInputStream
+ */
+
+bool StandardInputStream::isInteractive() const
+{
+#ifdef HAVE_UNISTD_H
+ return isatty(fileno(stdin));
+#else
+ return true;
+#endif
+}
+
+bool StandardInputStream::readLine(std::string *line)
+{
+ return readLineImpl(stdin, line);
+}
+
+// static
+StandardInputStream &StandardInputStream::instance()
+{
+ static StandardInputStream stdinObject;
+ return stdinObject;
+}
+
+/********************************************************************
+ * TextInputFile
+ */
+
+// static
+FILE *TextInputFile::openRawHandle(const char *filename)
+{
+ FILE *fp = fopen(filename, "r");
+ if (fp == NULL)
+ {
+ GMX_THROW_WITH_ERRNO(
+ FileIOError(formatString("Could not open file '%s'", filename)),
+ "fopen", errno);
+ }
+ return fp;
+}
+
+// static
+FILE *TextInputFile::openRawHandle(const std::string &filename)
+{
+ return openRawHandle(filename.c_str());
+}
+
+TextInputFile::TextInputFile(const std::string &filename)
+ : impl_(new FileStreamImpl(filename.c_str(), "r"))
+{
+}
+
+TextInputFile::TextInputFile(FILE *fp)
+ : impl_(new FileStreamImpl(fp))
+{
+}
+
+TextInputFile::~TextInputFile()
+{
+}
+
+FILE *TextInputFile::handle()
+{
+ return impl_->handle();
+}
+
+bool TextInputFile::readLine(std::string *line)
+{
+ return readLineImpl(impl_->handle(), line);
+}
+
+void TextInputFile::close()
+{
+ impl_->close();
+}
+
+/********************************************************************
+ * TextOutputFile
+ */
+
+TextOutputFile::TextOutputFile(const std::string &filename)
+ : impl_(new FileStreamImpl(filename.c_str(), "w"))
+{
+}
+
+TextOutputFile::TextOutputFile(FILE *fp)
+ : impl_(new FileStreamImpl(fp))
+{
+}
+
+TextOutputFile::~TextOutputFile()
+{
+}
+
+void TextOutputFile::write(const char *str)
+{
+ if (std::fprintf(impl_->handle(), "%s", str) < 0)
+ {
+ GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"),
+ "fprintf", errno);
+ }
+}
+
+void TextOutputFile::close()
+{
+ impl_->close();
+}
+
+// static
+TextOutputFile &TextOutputFile::standardOutput()
+{
+ static TextOutputFile stdoutObject(stdout);
+ return stdoutObject;
+}
+
+// static
+TextOutputFile &TextOutputFile::standardError()
+{
+ static TextOutputFile stderrObject(stderr);
+ return stderrObject;
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares implementations for textstream.h interfaces for file input/output.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_FILESTREAM_H
+#define GMX_UTILITY_FILESTREAM_H
+
+#include <cstdio>
+
+#include <string>
+
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+namespace internal
+{
+class FileStreamImpl;
+}
+
+/*! \libinternal \brief
+ * Text input stream implementation for reading from `stdin`.
+ *
+ * Implementations for the TextInputStream methods throw FileIOError on any
+ * I/O error.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class StandardInputStream : public TextInputStream
+{
+ public:
+ /*! \brief
+ * Returns whether `stdin` is an interactive terminal.
+ *
+ * Only works on Unix, otherwise always returns true.
+ *
+ * Does not throw.
+ */
+ bool isInteractive() const;
+
+ // From TextInputStream
+ virtual bool readLine(std::string *line);
+ virtual void close() {}
+
+ /*! \brief
+ * Returns a stream for accessing `stdin`.
+ *
+ * Does not throw.
+ */
+ static StandardInputStream &instance();
+};
+
+/*! \libinternal \brief
+ * Text input stream implementation for reading from a file.
+ *
+ * Implementations for the TextInputStream methods throw FileIOError on any
+ * I/O error.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextInputFile : public TextInputStream
+{
+ public:
+ /*! \brief
+ * Opens a file and returns a `FILE` handle.
+ *
+ * \param[in] filename Path of the file to open.
+ * \throws FileIOError on any I/O error.
+ *
+ * Instead of returning `NULL` on errors, throws an exception with
+ * additional details (including the file name and `errno`).
+ */
+ static FILE *openRawHandle(const char *filename);
+ //! \copydoc openRawHandle(const char *, const char *)
+ static FILE *openRawHandle(const std::string &filename);
+
+ /*! \brief
+ * Opens a text file as a stream.
+ *
+ * \param[in] filename Path to the file to open.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ */
+ explicit TextInputFile(const std::string &filename);
+ /*! \brief
+ * Initializes file object from an existing file handle.
+ *
+ * \param[in] fp File handle to use.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The caller is responsible of closing the file; close() does nothing
+ * for an object constructed this way.
+ */
+ explicit TextInputFile(FILE *fp);
+ virtual ~TextInputFile();
+
+ /*! \brief
+ * Returns a raw handle to the input file.
+ *
+ * This is provided for interoperability with older C-like code.
+ */
+ FILE *handle();
+
+ // From TextInputStream
+ virtual bool readLine(std::string *line);
+ virtual void close();
+
+ private:
+ PrivateImplPointer<internal::FileStreamImpl> impl_;
+};
+
+/*! \libinternal \brief
+ * Text output stream implementation for writing to a file.
+ *
+ * Implementations for the TextOutputStream methods throw FileIOError on any
+ * I/O error.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextOutputFile : public TextOutputStream
+{
+ public:
+ //! \copydoc TextInputFile::TextInputFile(const std::string &)
+ explicit TextOutputFile(const std::string &filename);
+ //! \copydoc TextInputFile::TextInputFile(FILE *)
+ explicit TextOutputFile(FILE *fp);
+ virtual ~TextOutputFile();
+
+ // From TextOutputStream
+ virtual void write(const char *text);
+ virtual void close();
+
+ /*! \brief
+ * Returns a stream for accessing `stdout`.
+ *
+ * \throws std::bad_alloc if out of memory (only on first call).
+ */
+ static TextOutputFile &standardOutput();
+ /*! \brief
+ * Returns a stream for accessing `stderr`.
+ *
+ * \throws std::bad_alloc if out of memory (only on first call).
+ */
+ static TextOutputFile &standardError();
+
+ private:
+ PrivateImplPointer<internal::FileStreamImpl> impl_;
+};
+
+} // namespace gmx
+
+#endif
#ifdef gmx_ffclose
#undef gmx_ffclose
#endif
-#if (!defined(HAVE_PIPES) && !defined(__native_client__))
+#if (!HAVE_PIPES && !defined(__native_client__))
static FILE *popen(const char *nm, const char *mode)
{
gmx_impl("Sorry no pipes...");
return 0;
}
-#endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
+#endif /* !HAVE_PIPES && !defined(__native_client__) */
#endif /* GMX_FAHCORE */
int gmx_ffclose(FILE *fp)
#include "config.h"
-#if defined(HAVE_POSIX_REGEX)
-#include <sys/types.h>
+#if HAVE_POSIX_REGEX
+# include <sys/types.h>
// old Mac needs sys/types.h before regex.h
-#include <regex.h>
-#define USE_POSIX_REGEX
-#elif defined(HAVE_CXX11_REGEX)
-#include <regex>
-#define USE_CXX11_REGEX
+# include <regex.h>
+#elif HAVE_CXX11_REGEX
+# include <regex>
#endif
#include "gromacs/utility/exceptions.h"
// static
bool Regex::isSupported()
{
-#if defined(USE_POSIX_REGEX) || defined(USE_CXX11_REGEX)
+#if HAVE_POSIX_REGEX || HAVE_CXX11_REGEX
return true;
#else
return false;
#endif
}
-#if defined(USE_POSIX_REGEX)
+#if HAVE_POSIX_REGEX
class Regex::Impl
{
public:
regex_t regex_;
};
-#elif defined(USE_CXX11_REGEX)
+#elif HAVE_CXX11_REGEX
class Regex::Impl
{
public:
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifndef _genborn_sse2_double_h
-#define _genborn_sse2_double_h
+/*! \libinternal \file
+ * \brief
+ * Declares C++11-style basic threading primitives
+ * (gmx::Mutex, gmx::lock_guard).
+ *
+ * For now, the implementation is imported from thread-MPI.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_THREADING_MUTEX_H
+#define GMX_THREADING_MUTEX_H
-#include "gromacs/legacyheaders/typedefs.h"
+#include "thread_mpi/mutex.h"
-int
-calc_gb_rad_still_sse2_double(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
- double *x, t_nblist *nl, gmx_genborn_t *born);
+namespace gmx
+{
-int
-calc_gb_chainrule_sse2_double(int natoms, t_nblist *nl, double *dadx, double *dvda, double *xd, double *f,
- double *fshift, double *shift_vec, int gb_algorithm,
- gmx_genborn_t *born, t_mdatoms *md);
+//! \cond libapi
+/*! \libinternal \brief
+ * C++11-compatible basic mutex.
+ */
+typedef tMPI::mutex Mutex;
+//! \endcond
+using tMPI::lock_guard;
-int
-calc_gb_rad_hct_obc_sse2_double(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
- double *x, t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, int gb_algorithm);
+} // namespace gmx
-#endif /* _genborn_sse2_double_h */
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares no_delete deleter for boost::shared_ptr.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_NODELETE_H
+#define GMX_UTILITY_NODELETE_H
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Deleter for boost::shared_ptr that does nothing.
+ *
+ * This is useful for cases where a class needs to keep a reference to another
+ * class, and optionally also manage the lifetime of that other class.
+ * The simplest construct (that does not force all callers to use heap
+ * allocation and boost::shared_ptr for the referenced class) is to use a
+ * single boost::shared_ptr to hold that reference, and use no_delete as the
+ * deleter if the lifetime is managed externally.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+template <class T>
+struct no_delete
+{
+ //! Deleter that does nothing.
+ void operator()(T *) {}
+};
+
+} // namespace gmx
+
+#endif
#include <cctype>
#include <cerrno>
+#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
+#include <string>
#include <sys/stat.h>
return result;
}
+/********************************************************************
+ * File
+ */
+
+// static
+bool File::exists(const char *filename)
+{
+ if (filename == NULL)
+ {
+ return false;
+ }
+ FILE *test = std::fopen(filename, "r");
+ if (test == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ std::fclose(test);
+ // Windows doesn't allow fopen of directory, so we don't need to check
+ // this separately.
+#ifndef GMX_NATIVE_WINDOWS
+ struct stat st_buf;
+ int status = stat(filename, &st_buf);
+ if (status != 0 || !S_ISREG(st_buf.st_mode))
+ {
+ return false;
+ }
+#endif
+ return true;
+ }
+}
+
+// static
+bool File::exists(const std::string &filename)
+{
+ return exists(filename.c_str());
+}
/********************************************************************
* Directory
Path();
};
+class File
+{
+ public:
+ /*! \brief
+ * Checks whether a file exists and is a regular file.
+ *
+ * \param[in] filename Path to the file to check.
+ * \returns `true` if \p filename exists and is accessible.
+ *
+ * Does not throw.
+ */
+ static bool exists(const char *filename);
+ //! \copydoc exists(const char *)
+ static bool exists(const std::string &filename);
+
+ private:
+ // Disallow instantiation.
+ File();
+};
class Directory
{
*/
/*! \internal \file
* \brief
- * Implements gmx::ProgramContextInterface and related methods.
+ * Implements gmx::IProgramContext and related methods.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_utility
//! \{
/*! \brief
- * Default implementation of ProgramContextInterface.
+ * Default implementation of IProgramContext.
*
* This implementation is used if nothing has been set with
* setProgramContext().
*
* Since it is constructed using a global initializer, it should not throw.
*/
-class DefaultProgramContext : public ProgramContextInterface
+class DefaultProgramContext : public IProgramContext
{
public:
DefaultProgramContext() {}
};
//! Global program info; stores the object set with setProgramContext().
-const ProgramContextInterface *g_programContext;
+const IProgramContext *g_programContext;
//! Default program context if nothing is set.
const DefaultProgramContext g_defaultContext;
} // namespace
-const ProgramContextInterface &getProgramContext()
+const IProgramContext &getProgramContext()
{
if (g_programContext != NULL)
{
return g_defaultContext;
}
-void setProgramContext(const ProgramContextInterface *programContext)
+void setProgramContext(const IProgramContext *programContext)
{
g_programContext = programContext;
}
*/
/*! \file
* \brief
- * Declares gmx::ProgramContextInterface and related methods.
+ * Declares gmx::IProgramContext and related methods.
*
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \inpublicapi
/*! \brief
* Provides information about installation prefix (see
- * ProgramContextInterface::installationPrefix()).
+ * IProgramContext::installationPrefix()).
*
* \inpublicapi
*/
* \see setProgramContext()
* \inpublicapi
*/
-class ProgramContextInterface
+class IProgramContext
{
public:
/*! \brief
virtual const char *commandLine() const = 0;
protected:
- virtual ~ProgramContextInterface() {}
+ virtual ~IProgramContext() {}
};
/*! \brief
- * Returns the global ProgramContextInterface instance.
+ * Returns the global IProgramContext instance.
*
* \returns The context set with setProgramContext().
*
* the presence of such calls. For example, initForCommandLine() assumes that
* such calls do not exist to be able to free the context before exiting.
*
- * \see ProgramContextInterface
+ * \see IProgramContext
*/
-const ProgramContextInterface &getProgramContext();
+const IProgramContext &getProgramContext();
/*! \brief
- * Sets the global ProgramContextInterface instance.
+ * Sets the global IProgramContext instance.
*
* \param[in] context Program context to set
* (can be NULL to restore the default context).
*
* Does not throw.
*
- * \see ProgramContextInterface
+ * \see IProgramContext
*/
-void setProgramContext(const ProgramContextInterface *context);
+void setProgramContext(const IProgramContext *context);
//! \}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
int t, v;
size_t s, st;
+ if (size == 0)
+ {
+ return;
+ }
+
cbase = (char *)base;
swaptype = (size_t)(cbase - (char *)0) % sizeof(int) || size % sizeof(int) ? 2 : size == sizeof(int) ? 0 : 1;
}
else
{
- pv = (char*)(void*)&v;
v = *(int *)pm;
+ pv = (char*)(void*)&v;
}
pa = pb = cbase;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
//! Returns the stored pointer.
T *get() const { return ptr_; }
//! Check for non-null pointer in boolean context.
-#ifdef GMX_CXX11
+#if GMX_CXX11
explicit
#endif
operator bool () const { return ptr_ != 0; }
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#include <malloc.h>
#endif
+#include <cstring>
+
#include "thread_mpi/threads.h"
#include "gromacs/utility/dir_separator.h"
if ((p = malloc(size)) == NULL)
{
gmx_fatal(errno, __FILE__, __LINE__,
- "Not enough memory. Failed to malloc %"GMX_PRId64 " bytes for %s\n"
+ "Not enough memory. Failed to malloc %" GMX_PRId64 " bytes for %s\n"
"(called from file %s, line %d)",
(gmx_int64_t)size, name, file, line);
}
if ((p = malloc((size_t)nelem*(size_t)elsize)) == NULL)
{
gmx_fatal(errno, __FILE__, __LINE__,
- "Not enough memory. Failed to calloc %"GMX_PRId64
- " elements of size %"GMX_PRId64
+ "Not enough memory. Failed to calloc %" GMX_PRId64
+ " elements of size %" GMX_PRId64
" for %s\n(called from file %s, line %d)",
(gmx_int64_t)nelem, (gmx_int64_t)elsize,
name, file, line);
if ((p = calloc((size_t)nelem, (size_t)elsize)) == NULL)
{
gmx_fatal(errno, __FILE__, __LINE__,
- "Not enough memory. Failed to calloc %"GMX_PRId64
- " elements of size %"GMX_PRId64
+ "Not enough memory. Failed to calloc %" GMX_PRId64
+ " elements of size %" GMX_PRId64
" for %s\n(called from file %s, line %d)",
(gmx_int64_t)nelem, (gmx_int64_t)elsize, name, file, line);
}
if (p == NULL)
{
gmx_fatal(errno, __FILE__, __LINE__,
- "Not enough memory. Failed to realloc %"GMX_PRId64 " bytes for %s, %s=%x\n"
+ "Not enough memory. Failed to realloc %" GMX_PRId64 " bytes for %s, %s=%x\n"
"(called from file %s, line %d)",
(gmx_int64_t)size, name, name, ptr, file, line);
}
/* This routine can NOT be called with any pointer */
void save_free_aligned(const char gmx_unused *name, const char gmx_unused *file, int gmx_unused line, void *ptr)
{
- int i, j;
void *free = ptr;
if (NULL != ptr)
{
if (g_bOverAllocDD)
{
- return OVER_ALLOC_FAC*n + 100;
+ return static_cast<int>(OVER_ALLOC_FAC*n + 100);
}
else
{
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes from stringstream.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "stringstream.h"
+
+#include <string>
+
+namespace gmx
+{
+
+void StringOutputStream::write(const char *str)
+{
+ str_.append(str);
+}
+
+void StringOutputStream::close()
+{
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares implementations for textstream.h interfaces for input/output to
+ * in-memory strings.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_STRINGSTREAM_H
+#define GMX_UTILITY_STRINGSTREAM_H
+
+#include <string>
+
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Text output stream implementation for writing to an in-memory string.
+ *
+ * Implementations for the TextOutputStream methods throw std::bad_alloc if
+ * reallocation of the string fails.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class StringOutputStream : public TextOutputStream
+{
+ public:
+ //! Returns the text written to the stream so far.
+ const std::string &toString() const { return str_; }
+
+ // From TextOutputStream
+ virtual void write(const char *text);
+ virtual void close();
+
+ private:
+ std::string str_;
+};
+
+} // namespace gmx
+
+#endif
namespace gmx
{
-bool endsWith(const std::string &str, const char *suffix)
+bool endsWith(const char *str, const char *suffix)
{
- if (suffix == NULL || suffix[0] == '\0')
+ if (isNullOrEmpty(suffix))
{
return true;
}
- size_t length = std::strlen(suffix);
- return (str.length() >= length
- && str.compare(str.length() - length, length, suffix) == 0);
+ const size_t strLength = std::strlen(str);
+ const size_t suffixLength = std::strlen(suffix);
+ return (strLength >= suffixLength
+ && std::strcmp(&str[strLength - suffixLength], suffix) == 0);
}
std::string stripSuffixIfPresent(const std::string &str, const char *suffix)
TextLineWrapperSettings::TextLineWrapperSettings()
: maxLength_(0), indent_(0), firstLineIndent_(-1),
- bStripLeadingWhitespace_(false), continuationChar_('\0')
+ bKeepFinalSpaces_(false), continuationChar_('\0')
{
}
* TextLineWrapper
*/
+bool TextLineWrapper::isTrivial() const
+{
+ return settings_.lineLength() == 0 && settings_.indent() == 0
+ && settings_.firstLineIndent_ <= 0;
+}
+
size_t
TextLineWrapper::findNextLine(const char *input, size_t lineStart) const
{
size_t inputLength = std::strlen(input);
bool bFirstLine = (lineStart == 0 || input[lineStart - 1] == '\n');
// Ignore leading whitespace if necessary.
- if (!bFirstLine || settings_.bStripLeadingWhitespace_)
+ if (!bFirstLine)
{
lineStart += std::strspn(input + lineStart, " ");
if (lineStart >= inputLength)
size_t inputLength = input.length();
bool bFirstLine = (lineStart == 0 || input[lineStart - 1] == '\n');
// Strip leading whitespace if necessary.
- if (!bFirstLine || settings_.bStripLeadingWhitespace_)
+ if (!bFirstLine)
{
lineStart = input.find_first_not_of(' ', lineStart);
if (lineStart >= inputLength)
int indent = (bFirstLine ? settings_.firstLineIndent() : settings_.indent());
bool bContinuation = (lineEnd < inputLength && input[lineEnd - 1] != '\n');
// Strip trailing whitespace.
- while (lineEnd > lineStart && std::isspace(input[lineEnd - 1]))
+ if (!settings_.bKeepFinalSpaces_ || lineEnd < inputLength || input[inputLength - 1] == '\n')
{
- --lineEnd;
+ while (lineEnd > lineStart && std::isspace(input[lineEnd - 1]))
+ {
+ --lineEnd;
+ }
}
const size_t lineLength = lineEnd - lineStart;
*
* Does not throw.
*/
-bool inline isNullOrEmpty(const char *str)
+static inline bool isNullOrEmpty(const char *str)
{
return str == NULL || str[0] == '\0';
}
* Returns true if \p prefix is empty.
* Does not throw.
*/
-bool inline startsWith(const std::string &str, const std::string &prefix)
+static inline bool startsWith(const std::string &str, const std::string &prefix)
{
return str.compare(0, prefix.length(), prefix) == 0;
}
//! \copydoc startsWith(const std::string &, const std::string &)
-bool inline startsWith(const char *str, const char *prefix)
+static inline bool startsWith(const char *str, const char *prefix)
{
return std::strncmp(str, prefix, std::strlen(prefix)) == 0;
}
* Returns true if \p suffix is NULL or empty.
* Does not throw.
*/
-bool endsWith(const std::string &str, const char *suffix);
+bool endsWith(const char *str, const char *suffix);
+//! \copydoc endsWith(const char *, const char *)
+static inline bool endsWith(const std::string &str, const char *suffix)
+{
+ return endsWith(str.c_str(), suffix);
+}
/*! \brief
* Removes a suffix from a string.
* - No maximum line width (only explicit line breaks).
* - No indentation.
* - No continuation characters.
- * - Ignore whitespace after an explicit newline.
+ * - Do not keep final spaces in input strings.
*/
TextLineWrapperSettings();
*/
void setFirstLineIndent(int indent) { firstLineIndent_ = indent; }
/*! \brief
- * Sets whether to remove spaces after an explicit newline.
+ * Sets whether final spaces in input should be kept.
*
- * \param[in] bStrip If true, spaces after newline are ignored.
+ * \param[in] bKeep Whether to keep spaces at the end of the input.
*
- * If not removed, the space is added to the indentation set with
- * setIndent().
- * The default is to not strip such whitespace.
+ * This means that wrapping a string that ends in spaces also keeps
+ * those spaces in the output. This allows using the wrapper for
+ * partial lines where the initial part of the line may end in a space.
+ * By default, all trailing whitespace is removed. Note that this
+ * option does not affect spaces before an explicit newline: those are
+ * always removed.
*/
- void setStripLeadingWhitespace(bool bStrip)
- {
- bStripLeadingWhitespace_ = bStrip;
- }
+ void setKeepFinalSpaces(bool bKeep) { bKeepFinalSpaces_ = bKeep; }
/*! \brief
* Sets a continuation marker for wrapped lines.
*
* If -1, \a indent_ is used.
*/
int firstLineIndent_;
- //! Whether to ignore or preserve space after a newline.
- bool bStripLeadingWhitespace_;
+ //! Whether to keep spaces at end of input.
+ bool bKeepFinalSpaces_;
//! If not \c '\0', mark each wrapping point with this character.
char continuationChar_;
*/
TextLineWrapperSettings &settings() { return settings_; }
+ //! Returns true if the wrapper would not modify the input string.
+ bool isTrivial() const;
+
/*! \brief
* Finds the next line to be wrapped.
*
gmx_add_unit_test(UtilityUnitTests utility-test
arrayref.cpp
bitmask32.cpp bitmask64.cpp bitmask128.cpp
- stringutil.cpp)
+ stringutil.cpp
+ textwriter.cpp
+ )
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
<ReferenceData>
- <String Name="WrappedAt14StripLeading"><![CDATA[
-A quick brown
-fox jumps
-over the lazy
-dog]]></String>
- <String Name="WrappedAt14PreserveLeading"><![CDATA[
+ <String Name="WrappedAt14"><![CDATA[
A quick brown
fox jumps
over the lazy
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="Output"><![CDATA[
+Explicit newline
+Implicit newline
+Explicit newline
+Implicit newline
+
+]]></String>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="Output"><![CDATA[
+Partial spaced line
+Partial spaced line
+]]></String>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="Output"><![CDATA[
+Partial spaced line
+Partial spaced line
+]]></String>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="Output"><![CDATA[
+ Wrapped and
+ indented text
+ Wrapped and
+ indented text
+
+]]></String>
+</ReferenceData>
EXPECT_EQ("", wrapper.wrapToString(""));
EXPECT_EQ("", wrapper.wrapToString(" "));
EXPECT_TRUE(wrapper.wrapToVector("").empty());
- EXPECT_TRUE(wrapper.wrapToString(" ").empty());
+ {
+ std::vector<std::string> wrapped(wrapper.wrapToVector(" "));
+ ASSERT_EQ(1U, wrapped.size());
+ EXPECT_EQ("", wrapped[0]);
+ }
+}
+
+TEST_F(TextLineWrapperTest, HandlesTrailingWhitespace)
+{
+ gmx::TextLineWrapper wrapper;
+
+ EXPECT_EQ("line", wrapper.wrapToString("line "));
+ EXPECT_EQ("line\n", wrapper.wrapToString("line \n"));
+
+ wrapper.settings().setKeepFinalSpaces(true);
+ EXPECT_EQ("line ", wrapper.wrapToString("line "));
+ EXPECT_EQ("line\n", wrapper.wrapToString("line \n"));
}
TEST_F(TextLineWrapperTest, HandlesTrailingNewlines)
TEST_F(TextLineWrapperTest, WrapsCorrectlyWithExtraWhitespace)
{
gmx::TextLineWrapper wrapper;
-
wrapper.settings().setLineLength(14);
- wrapper.settings().setStripLeadingWhitespace(true);
- checkText(wrapper.wrapToString(g_wrapTextWhitespace),
- "WrappedAt14StripLeading");
- wrapper.settings().setStripLeadingWhitespace(false);
+
checkText(wrapper.wrapToString(g_wrapTextWhitespace),
- "WrappedAt14PreserveLeading");
+ "WrappedAt14");
}
} // namespace
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Tests for gmx::TextWriter.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "gromacs/utility/textwriter.h"
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include "gromacs/utility/stringstream.h"
+#include "gromacs/utility/stringutil.h"
+
+#include "testutils/stringtest.h"
+
+namespace
+{
+
+class TextWriterTest : public gmx::test::StringTestBase
+{
+ public:
+ TextWriterTest() : writer_(&stream_)
+ {
+ }
+
+ void checkOutput()
+ {
+ checkText(stream_.toString(), "Output");
+ }
+
+ gmx::StringOutputStream stream_;
+ gmx::TextWriter writer_;
+};
+
+TEST_F(TextWriterTest, WritesLines)
+{
+ writer_.writeLine("Explicit newline\n");
+ writer_.writeLine("Implicit newline");
+ writer_.writeLine(std::string("Explicit newline\n"));
+ writer_.writeLine(std::string("Implicit newline"));
+ writer_.writeLine();
+ checkOutput();
+}
+
+TEST_F(TextWriterTest, WritesLinesInParts)
+{
+ writer_.writeString("Partial ");
+ writer_.writeString("spaced");
+ writer_.writeString(" line");
+ writer_.writeLine();
+ writer_.writeString(std::string("Partial "));
+ writer_.writeString(std::string("spaced"));
+ writer_.writeString(std::string(" line"));
+ writer_.writeLine();
+ checkOutput();
+}
+
+TEST_F(TextWriterTest, WritesWrappedLines)
+{
+ writer_.wrapperSettings().setIndent(2);
+ writer_.wrapperSettings().setLineLength(15);
+ writer_.writeLine("Wrapped and indented text");
+ writer_.writeLine(std::string("Wrapped and indented text"));
+ writer_.writeLine();
+ checkOutput();
+}
+
+TEST_F(TextWriterTest, WritesLinesInPartsWithWrapper)
+{
+ writer_.wrapperSettings().setLineLength(50);
+ writer_.writeString("Partial ");
+ writer_.writeString("spaced");
+ writer_.writeString(" line");
+ writer_.writeLine();
+ writer_.writeString(std::string("Partial "));
+ writer_.writeString(std::string("spaced"));
+ writer_.writeString(std::string(" line"));
+ writer_.writeLine();
+ checkOutput();
+}
+
+} // namespace
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements gmx::TextReader.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "textreader.h"
+
+#include "gromacs/utility/filestream.h"
+#include "gromacs/utility/nodelete.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+// static
+std::string TextReader::readFileToString(const char *filename)
+{
+ std::string result;
+ TextReader reader(filename);
+ std::string line;
+ while (reader.readLine(&line))
+ {
+ result.append(line);
+ }
+ reader.close();
+ return result;
+}
+
+// static
+std::string TextReader::readFileToString(const std::string &filename)
+{
+ return readFileToString(filename.c_str());
+}
+
+class TextReader::Impl
+{
+ public:
+ explicit Impl(const TextInputStreamPointer &stream)
+ : stream_(stream)
+ {
+ }
+
+ TextInputStreamPointer stream_;
+};
+
+TextReader::TextReader(const std::string &filename)
+ : impl_(new Impl(TextInputStreamPointer(new TextInputFile(filename))))
+{
+}
+
+TextReader::TextReader(TextInputStream *stream)
+ : impl_(new Impl(TextInputStreamPointer(stream, no_delete<TextInputStream>())))
+{
+}
+
+TextReader::TextReader(const TextInputStreamPointer &stream)
+ : impl_(new Impl(stream))
+{
+}
+
+TextReader::~TextReader()
+{
+}
+
+bool TextReader::readLine(std::string *line)
+{
+ return impl_->stream_->readLine(line);
+}
+
+bool TextReader::readLineTrimmed(std::string *line)
+{
+ if (!readLine(line))
+ {
+ return false;
+ }
+ const size_t endPos = line->find_last_not_of(" \t\r\n");
+ if (endPos != std::string::npos)
+ {
+ line->resize(endPos + 1);
+ }
+ return true;
+}
+
+void TextReader::close()
+{
+ impl_->stream_->close();
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares gmx::TextReader.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_TEXTREADER_H
+#define GMX_UTILITY_TEXTREADER_H
+
+#include <string>
+
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Reads text from a TextInputStream.
+ *
+ * This class provides more formatted reading capabilities than reading raw
+ * lines from the stream (and a natural place to implement more such
+ * capabilities).
+ *
+ * All methods that read from the stream can throw any exceptions that the
+ * underlying stream throws.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextReader
+{
+ public:
+ /*! \brief
+ * Reads contents of a file to a std::string.
+ *
+ * \param[in] filename Name of the file to read.
+ * \returns The contents of \p filename.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ */
+ static std::string readFileToString(const char *filename);
+ //! \copydoc readFileToString(const char *)
+ static std::string readFileToString(const std::string &filename);
+
+ /*! \brief
+ * Creates a reader that reads from specified file.
+ *
+ * \param[in] filename Path to the file to open.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ *
+ * This constructor is provided for convenience for reading directly
+ * from a file, without the need to construct multiple objects.
+ */
+ explicit TextReader(const std::string &filename);
+ /*! \brief
+ * Creates a reader that reads from specified stream.
+ *
+ * \param[in] stream Stream to read from.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The caller is responsible of the lifetime of the stream (should
+ * remain in existence as long as the reader exists).
+ *
+ * This constructor is provided for convenience for cases where the
+ * stream is not allocated with `new` and/or not managed by a
+ * boost::shared_ptr (e.g., if the stream is an object on the stack).
+ */
+ explicit TextReader(TextInputStream *stream);
+ /*! \brief
+ * Creates a reader that reads from specified stream.
+ *
+ * \param[in] stream Stream to read from.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The reader keeps a reference to the stream, so the caller can pass
+ * in a temporary if necessary.
+ */
+ explicit TextReader(const TextInputStreamPointer &stream);
+ ~TextReader();
+
+ /*! \brief
+ * Reads a single line (including newline) from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns `false` if nothing was read because the file ended.
+ *
+ * On error or when false is returned, \p line will be empty.
+ * Newlines will be returned as part of \p line if it was present in
+ * the stream.
+ * To loop over all lines in the stream, use:
+ * \code
+ std::string line;
+ while (reader.readLine(&line))
+ {
+ // ...
+ }
+ \endcode
+ */
+ bool readLine(std::string *line);
+ /*! \brief
+ * Reads a single line from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns false if nothing was read because the file ended.
+ *
+ * On error or when false is returned, \p line will be empty.
+ * Works as readLine(), except that trailing whitespace will be removed
+ * from \p line.
+ *
+ * \see readLine()
+ */
+ bool readLineTrimmed(std::string *line);
+
+ /*! \brief
+ * Closes the underlying stream.
+ */
+ void close();
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares interfaces for simple input/output streams.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_TEXTSTREAM_H
+#define GMX_UTILITY_TEXTSTREAM_H
+
+#include <boost/shared_ptr.hpp>
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Interface for reading text.
+ *
+ * Concrete implementations can read the text from, e.g., a file or an in-memory
+ * string. The main use is to allow unit tests to inject in-memory buffers
+ * instead of writing files to be read by the code under test, but there are
+ * also use cases outside the tests where it is useful to abstract out whether
+ * the input is from a real file or something else.
+ *
+ * To use more advanced formatting than reading raw lines, use TextReader.
+ *
+ * Both methods in the interface can throw std::bad_alloc or other exceptions
+ * that indicate failures to read from the stream.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextInputStream
+{
+ public:
+ virtual ~TextInputStream() {}
+
+ /*! \brief
+ * Reads a line (with newline included) from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns `false` if nothing was read because the stream ended.
+ *
+ * On error or when `false` is returned, \p line will be empty.
+ */
+ virtual bool readLine(std::string *line) = 0;
+ /*! \brief
+ * Closes the stream.
+ *
+ * It is not allowed to read from a stream after it has been closed.
+ * See TextOutputStream::close() for rationale for a close() method
+ * separate from the destructor. For input, failures during close
+ * should be rare, but it is clearer to keep the interface symmetric.
+ */
+ virtual void close() = 0;
+};
+
+/*! \libinternal \brief
+ * Interface for writing text.
+ *
+ * Concrete implementations can write the text to, e.g., a file or an in-memory
+ * string. The main use is to allow unit tests to inject in-memory buffers
+ * instead of reading in files produced by the code under test, but there are
+ * also use cases outside the tests where it is useful to abstract out whether
+ * the output is into a real file or something else.
+ *
+ * To use more advanced formatting than writing plain strings, use TextWriter.
+ *
+ * The current implementation assumes text-only output in several places, but
+ * this interface could possibly be generalized also for binary files.
+ * However, since all binary files currently written by \Gromacs are either
+ * XDR- or TNG-based, they may require a different approach. Also, it is worth
+ * keeping the distinction between text and binary files clear, since Windows
+ * does transparent `LF`-`CRLF` newline translation for text files, so mixing
+ * modes when reading and/or writing the same file can cause subtle issues.
+ *
+ * Both methods in the interface can throw std::bad_alloc or other exceptions
+ * that indicate failures to write to the stream.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextOutputStream
+{
+ public:
+ virtual ~TextOutputStream() {}
+
+ /*! \brief
+ * Writes a given string to the stream.
+ */
+ virtual void write(const char *text) = 0;
+ /*! \brief
+ * Closes the stream.
+ *
+ * It is not allowed to write to a stream after it has been closed.
+ * A method separate from the destructor is provided such that errors
+ * that occur while closing the stream (e.g., when closing the file)
+ * can be handled using exceptions.
+ * The destructor is not allowed to throw, so code that wants to
+ * observe such errors needs to call close() after it has finished
+ * writing to the stream.
+ */
+ virtual void close() = 0;
+};
+
+//! Shorthand for a smart pointer to a TextInputStream.
+typedef boost::shared_ptr<TextInputStream> TextInputStreamPointer;
+//! Shorthand for a smart pointer to a TextOutputStream.
+typedef boost::shared_ptr<TextOutputStream> TextOutputStreamPointer;
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements gmx::TextWriter.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "textwriter.h"
+
+#include <cstring>
+
+#include "gromacs/utility/filestream.h"
+#include "gromacs/utility/nodelete.h"
+#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+class TextWriter::Impl
+{
+ public:
+ explicit Impl(const TextOutputStreamPointer &stream)
+ : stream_(stream)
+ {
+ wrapper_.settings().setKeepFinalSpaces(true);
+ }
+
+ void writeWrappedString(const std::string &str)
+ {
+ stream_->write(wrapper_.wrapToString(str).c_str());
+ }
+
+ TextOutputStreamPointer stream_;
+ TextLineWrapper wrapper_;
+};
+
+// static
+void TextWriter::writeFileFromString(const std::string &filename,
+ const std::string &text)
+{
+ TextWriter file(filename);
+ file.writeString(text);
+ file.close();
+}
+
+TextWriter::TextWriter(const std::string &filename)
+ : impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(filename))))
+{
+}
+
+TextWriter::TextWriter(FILE *fp)
+ : impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(fp))))
+{
+}
+
+TextWriter::TextWriter(TextOutputStream *stream)
+ : impl_(new Impl(TextOutputStreamPointer(stream, no_delete<TextOutputStream>())))
+{
+}
+
+TextWriter::TextWriter(const TextOutputStreamPointer &stream)
+ : impl_(new Impl(stream))
+{
+}
+
+TextWriter::~TextWriter()
+{
+}
+
+TextOutputStream &TextWriter::stream()
+{
+ return *impl_->stream_;
+}
+
+TextLineWrapperSettings &TextWriter::wrapperSettings()
+{
+ return impl_->wrapper_.settings();
+}
+
+void TextWriter::writeString(const char *str)
+{
+ if (impl_->wrapper_.isTrivial())
+ {
+ impl_->stream_->write(str);
+ }
+ else
+ {
+ impl_->writeWrappedString(str);
+ }
+}
+
+void TextWriter::writeString(const std::string &str)
+{
+ impl_->writeWrappedString(str);
+}
+
+void TextWriter::writeLine(const char *line)
+{
+ writeString(line);
+ if (!endsWith(line, "\n"))
+ {
+ writeLine();
+ }
+}
+
+void TextWriter::writeLine(const std::string &line)
+{
+ writeString(line);
+ if (!endsWith(line, "\n"))
+ {
+ writeLine();
+ }
+}
+
+void TextWriter::writeLine()
+{
+ writeString("\n");
+}
+
+void TextWriter::close()
+{
+ impl_->stream_->close();
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares gmx::TextWriter.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_TEXTWRITER_H
+#define GMX_UTILITY_TEXTWRITER_H
+
+#include <cstdio>
+
+#include <string>
+
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+class TextLineWrapperSettings;
+
+/*! \libinternal \brief
+ * Writes text into a TextOutputStream.
+ *
+ * This class provides more formatting and line-oriented writing capabilities
+ * than writing raw strings into the stream.
+ *
+ * All methods that write to the stream can throw any exceptions that the
+ * underlying stream throws.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextWriter
+{
+ public:
+ /*! \brief
+ * Convenience method for writing a file from a string in a single call.
+ *
+ * \param[in] filename Name of the file to read.
+ * \param[in] text String to write to \p filename.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ *
+ * If \p filename exists, it is overwritten.
+ */
+ static void writeFileFromString(const std::string &filename,
+ const std::string &text);
+
+ /*! \brief
+ * Creates a writer that writes to specified file.
+ *
+ * \param[in] filename Path to the file to open.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ *
+ * This constructor is provided for convenience for writing directly to
+ * a file, without the need to construct multiple objects.
+ */
+ explicit TextWriter(const std::string &filename);
+ /*! \brief
+ * Creates a writer that writes to specified file.
+ *
+ * \param[in] fp File handle to write to.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ *
+ * This constructor is provided for interoperability with C-like code
+ * for writing directly to an already opened file, without the need to
+ * construct multiple objects.
+ *
+ * The caller is responsible of closing \p fp; it is not allowed to
+ * call close() on the writer.
+ */
+ explicit TextWriter(FILE *fp);
+ /*! \brief
+ * Creates a writer that writes to specified stream.
+ *
+ * \param[in] stream Stream to write to.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The caller is responsible of the lifetime of the stream (should
+ * remain in existence as long as the writer exists).
+ *
+ * This constructor is provided for convenience for cases where the
+ * stream is not allocated with `new` and/or not managed by a
+ * boost::shared_ptr (e.g., if the stream is an object on the stack).
+ */
+ explicit TextWriter(TextOutputStream *stream);
+ /*! \brief
+ * Creates a writer that writes to specified stream.
+ *
+ * \param[in] stream Stream to write to.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The writer keeps a reference to the stream, so the caller can pass
+ * in a temporary if necessary.
+ */
+ explicit TextWriter(const TextOutputStreamPointer &stream);
+ ~TextWriter();
+
+ //! Returns the underlying stream for this writer.
+ TextOutputStream &stream();
+
+ /*! \brief
+ * Allows adjusting wrapping settings for the writer.
+ *
+ * \todo
+ * Wrapping is not currently implemented for code that writes partial
+ * lines with writeString().
+ */
+ TextLineWrapperSettings &wrapperSettings();
+
+ /*! \brief
+ * Writes a string to the stream.
+ *
+ * \param[in] str String to write.
+ */
+ void writeString(const char *str);
+ //! \copydoc writeString(const char *)
+ void writeString(const std::string &str);
+ /*! \brief
+ * Writes a line to the stream.
+ *
+ * \param[in] line Line to write.
+ *
+ * If \p line does not end in a newline, one newline is appended.
+ * Otherwise, works as writeString().
+ */
+ void writeLine(const char *line);
+ //! \copydoc writeLine(const char *)
+ void writeLine(const std::string &line);
+ //! Writes a newline to the stream.
+ void writeLine();
+
+ /*! \brief
+ * Closes the underlying stream.
+ */
+ void close();
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
+} // namespace gmx
+
+#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "config.h"
-#ifdef GMX_CXX11 // C++11 Compiler
+#if GMX_CXX11 // C++11 Compiler
#include <memory> // IWYU pragma: export
#include <utility> // IWYU pragma: export
#else // C++03 Compiler
* \brief The smart pointer type.
* Work-around for the non-existence of template typedefs in C++03.
*/
-#ifdef GMX_CXX11 // C++11 Compiler
+#if GMX_CXX11 // C++11 Compiler
using std::move;
template<typename T>
struct gmx_unique_ptr
* Prints a message directing the user to a wiki page describing replacement
* options.
*/
-class ObsoleteToolModule : public gmx::CommandLineModuleInterface
+class ObsoleteToolModule : public gmx::ICommandLineModule
{
public:
//! Creates an obsolete tool module for a tool with the given name.
// TODO: Consider removing duplication with CMainCommandLineModule from
// cmdlinemodulemanager.cpp.
-class NoNiceModule : public gmx::CommandLineModuleInterface
+class NoNiceModule : public gmx::ICommandLineModule
{
public:
//! \copydoc gmx::CommandLineModuleManager::CMainFunction
registerModuleNoNice(manager, &gmx_mdrun, "mdrun",
"Perform a simulation, do a normal mode analysis or an energy minimization");
- gmx::CommandLineOptionsModuleInterface::registerModule(
+ gmx::ICommandLineOptionsModule::registerModule(
manager, gmx::InsertMoleculesInfo::name,
gmx::InsertMoleculesInfo::shortDescription,
&gmx::InsertMoleculesInfo::create);
#include "gromacs/domdec/domdec.h"
#include "gromacs/domdec/domdec_network.h"
-#include "gromacs/ewald/pme-load-balancing.h"
#include "gromacs/ewald/pme.h"
+#include "gromacs/ewald/pme-load-balancing.h"
#include "gromacs/fileio/filenm.h"
#include "gromacs/fileio/mdoutf.h"
#include "gromacs/fileio/trajectory_writing.h"
#include "gromacs/swap/swapcoords.h"
#include "gromacs/timing/wallcycle.h"
#include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/gmxmpi.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/gmxpreprocess/grompp.h"
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/basenetwork.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxmpi.h"
+#include "gromacs/utility/textwriter.h"
#include "programs/mdrun/mdrun_main.h"
#include "testutils/cmdlinetest.h"
void
SimulationRunner::useStringAsMdpFile(const std::string &mdpString)
{
- gmx::File::writeFileFromString(mdpInputFileName_, mdpString);
+ gmx::TextWriter::writeFileFromString(mdpInputFileName_, mdpString);
}
void
SimulationRunner::useStringAsNdxFile(const char *ndxString)
{
- gmx::File::writeFileFromString(ndxFileName_, ndxString);
+ gmx::TextWriter::writeFileFromString(ndxFileName_, ndxString);
}
void
* version. */
const char *trajectoryFileNames[] = {
"../../../gromacs/gmxana/legacytests/spc2-traj.trr",
-#if defined GMX_USE_TNG && defined HAVE_ZLIB
+#if defined GMX_USE_TNG && HAVE_ZLIB
"../../../gromacs/gmxana/legacytests/spc2-traj.tng",
#endif
"../../../gromacs/gmxana/legacytests/spc2-traj.xtc",
*/
#include "gmxpre.h"
-#include <string.h>
+#include <cstring>
#include <algorithm>
#include "gromacs/legacyheaders/macros.h"
#include "gromacs/topology/index.h"
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/dir_separator.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
char tmpfile[STRLEN];
int i, j, k, len, tlen, ht, ncol, nrow, x0;
- len = strlen(title);
+ len = std::strlen(title);
for (i = 0; (i < (int)gmx->filter->grps->nr); i++)
{
- len = std::max(len, (int)strlen(gmx->filter->grpnames[i]));
+ len = std::max(len, static_cast<int>(std::strlen(gmx->filter->grpnames[i])));
}
len += 2;
{
ht = 1+(gmx->filter->grps->nr+1)*2+3;
}
- strcpy(tmpfile, "filterXXXXXX");
+ std::strcpy(tmpfile, "filterXXXXXX");
gmx_tmpnam(tmpfile);
#ifdef DEBUG
fprintf(stderr, "file: %s\n", tmpfile);
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
-#ifdef GMX_X11
+#if GMX_X11
#include "gromacs/fileio/writeps.h"
if (parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm,
0, NULL, asize(desc), desc, asize(bugs), bugs, &oenv))
{
-#ifndef GMX_X11
+#if !GMX_X11
fprintf(stderr, "Compiled without X-Windows - can not run viewer.\n");
#else
t_x11 *x11;
set(TESTUTILS_SOURCES
cmdlinetest.cpp
integrationtests.cpp
+ interactivetest.cpp
mpi-printer.cpp
refdata.cpp
stringtest.cpp
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/commandline/cmdlineoptionsmodule.h"
#include "gromacs/commandline/cmdlineprogramcontext.h"
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textreader.h"
+#include "gromacs/utility/textwriter.h"
#include "testutils/refdata.h"
#include "testutils/testfilemanager.h"
// static
int CommandLineTestHelper::runModule(
- CommandLineModuleInterface *module, CommandLine *commandLine)
+ ICommandLineModule *module, CommandLine *commandLine)
{
CommandLineModuleSettings settings;
module->init(&settings);
// static
int CommandLineTestHelper::runModule(
- CommandLineOptionsModuleInterface::FactoryMethod factory,
+ ICommandLineOptionsModule::FactoryMethod factory,
CommandLine *commandLine)
{
// The name and description are not used in the tests, so they can be NULL.
- boost::scoped_ptr<CommandLineModuleInterface> module(
- CommandLineOptionsModuleInterface::createModule(NULL, NULL, factory));
+ boost::scoped_ptr<ICommandLineModule> module(
+ ICommandLineOptionsModule::createModule(NULL, NULL, factory));
return runModule(module.get(), commandLine);
}
GMX_ASSERT(extension[0] != '.', "Extension should not contain a dot");
std::string fullFilename = impl_->fileManager_.getTemporaryFilePath(
formatString("%d.%s", args->argc(), extension));
- File::writeFileFromString(fullFilename, contents);
+ TextWriter::writeFileFromString(fullFilename, contents);
args->addOption(option, fullFilename);
}
GMX_ASSERT(extension[0] != '.', "Extension should not contain a dot");
std::string fullFilename = impl_->fileManager_.getTemporaryFilePath(
formatString("%d.%s", args->argc(), extension));
- File file(fullFilename, "w");
+ TextWriter file(fullFilename);
ConstArrayRef<const char *>::const_iterator i;
for (i = contents.begin(); i != contents.end(); ++i)
{
outfile != impl_->outputFiles_.end();
++outfile)
{
- std::string output = File::readToString(outfile->path);
+ std::string output = TextReader::readFileToString(outfile->path);
outputChecker.checkStringBlock(output, outfile->option.c_str());
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
namespace gmx
{
-class CommandLineModuleInterface;
-class CommandLineOptionsModuleInterface;
+class ICommandLineModule;
+class ICommandLineOptionsModule;
namespace test
{
{
public:
/*! \brief
- * Runs a command-line program that implements CommandLineModuleInterface.
+ * Runs a command-line program that implements ICommandLineModule.
*
* \param[in,out] module Module to run.
* The function does not take ownership.
* \throws unspecified Any exception thrown by the module.
*/
static int
- runModule(CommandLineModuleInterface *module, CommandLine *commandLine);
+ runModule(ICommandLineModule *module, CommandLine *commandLine);
/*! \brief
* Runs a command-line program that implements
- * CommandLineOptionsModuleInterface.
+ * ICommandLineOptionsModule.
*
* \param[in] factory Factory method for the module to run.
* \param[in,out] commandLine Command line parameters to pass.
* module.
*/
static int
- runModule(CommandLineOptionsModuleInterface *(*factory)(),
+ runModule(ICommandLineOptionsModule *(*factory)(),
CommandLine *commandLine);
/*! \brief
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="InteractiveSession">
+ <pre>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="starts-with(@Name, 'Output')">
+ <xsl:value-of select="substring(.,2)"/>
+ </xsl:when>
+ <xsl:when test="string-length(.)=1">
+ <xsl:text>►</xsl:text>
+ <xsl:text>¶</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(substring(.,2), ' ')">
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="translate(substring(.,2), ' ', '⏎')"/>
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>►</xsl:text>
+ <xsl:value-of select="substring(.,2)"/>
+ <xsl:text>¶</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:text>[EOF]</xsl:text>
+ </pre>
+</xsl:template>
+
</xsl:stylesheet>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <stdio.h>
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/textwriter.h"
namespace gmx
{
IntegrationTestFixture::redirectStringToStdin(const char* theString)
{
std::string fakeStdin("fake-stdin");
- gmx::File::writeFileFromString(fakeStdin, theString);
+ gmx::TextWriter::writeFileFromString(fakeStdin, theString);
if (NULL == std::freopen(fakeStdin.c_str(), "r", stdin))
{
GMX_THROW_WITH_ERRNO(FileIOError("Failed to redirect a string to stdin"),
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes from interactivetest.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_testutils
+ */
+#include "gmxpre.h"
+
+#include "interactivetest.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textstream.h"
+
+#include "testutils/refdata.h"
+#include "testutils/stringtest.h"
+
+namespace gmx
+{
+namespace test
+{
+
+// These two classes cannot be in an unnamed namespace (easily), since
+// then their use as members below would trigger warnings.
+// But if anyone needs these outside this file, they can easily be moved to a
+// separate header.
+
+class MockTextInputStream : public TextInputStream
+{
+ public:
+ MOCK_METHOD1(readLine, bool(std::string *));
+ MOCK_METHOD0(close, void());
+};
+
+class MockTextOutputStream : public TextOutputStream
+{
+ public:
+ MOCK_METHOD1(write, void(const char *));
+ MOCK_METHOD0(close, void());
+};
+
+class InteractiveTestHelper::Impl
+{
+ public:
+ explicit Impl(TestReferenceChecker checker)
+ : checker_(checker), bLastNewline_(true),
+ currentLine_(0), bHasOutput_(false)
+ {
+ using ::testing::_;
+ using ::testing::Invoke;
+ EXPECT_CALL(inputStream_, readLine(_))
+ .WillRepeatedly(Invoke(this, &Impl::readInputLine));
+ EXPECT_CALL(inputStream_, close()).Times(0);
+ EXPECT_CALL(outputStream_, write(_))
+ .WillRepeatedly(Invoke(this, &Impl::addOutput));
+ EXPECT_CALL(outputStream_, close()).Times(0);
+ }
+
+ bool readInputLine(std::string *line)
+ {
+ checkOutput();
+ line->clear();
+ const bool bPresent = (currentLine_ < inputLines_.size());
+ if (bPresent)
+ {
+ line->assign(inputLines_[currentLine_]);
+ if (bLastNewline_ || currentLine_ + 1 < inputLines_.size())
+ {
+ line->append("\n");
+ }
+ }
+ ++currentLine_;
+ const std::string id = formatString("Input%d", static_cast<int>(currentLine_));
+ StringTestBase::checkText(&checker_, *line, id.c_str());
+ return bPresent;
+ }
+ void addOutput(const char *str)
+ {
+ bHasOutput_ = true;
+ currentOutput_.append(str);
+ }
+
+ void checkOutput()
+ {
+ const std::string id = formatString("Output%d", static_cast<int>(currentLine_));
+ if (checker_.checkPresent(bHasOutput_, id.c_str()))
+ {
+ StringTestBase::checkText(&checker_, currentOutput_, id.c_str());
+ }
+ bHasOutput_ = false;
+ currentOutput_.clear();
+ }
+ void checkPendingInput()
+ {
+ const std::string id = formatString("Input%d", static_cast<int>(currentLine_+1));
+ checker_.checkPresent(false, id.c_str());
+ }
+
+ TestReferenceChecker checker_;
+ ConstArrayRef<const char *> inputLines_;
+ bool bLastNewline_;
+ size_t currentLine_;
+ bool bHasOutput_;
+ std::string currentOutput_;
+ MockTextInputStream inputStream_;
+ MockTextOutputStream outputStream_;
+};
+
+InteractiveTestHelper::InteractiveTestHelper(TestReferenceChecker checker)
+ : impl_(new Impl(checker.checkCompound("InteractiveSession", "Interactive")))
+{
+}
+
+InteractiveTestHelper::~InteractiveTestHelper()
+{
+}
+
+void InteractiveTestHelper::setLastNewline(bool bInclude)
+{
+ impl_->bLastNewline_ = bInclude;
+}
+
+void InteractiveTestHelper::setInputLines(
+ const ConstArrayRef<const char *> &inputLines)
+{
+ impl_->inputLines_ = inputLines;
+ impl_->currentLine_ = 0;
+}
+
+TextInputStream &InteractiveTestHelper::inputStream()
+{
+ return impl_->inputStream_;
+}
+
+TextOutputStream &InteractiveTestHelper::outputStream()
+{
+ return impl_->outputStream_;
+}
+
+void InteractiveTestHelper::checkSession()
+{
+ impl_->checkOutput();
+ impl_->checkPendingInput();
+}
+
+} // namespace test
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Provides helper classes for testing interactive prompts.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+#ifndef GMX_TESTUTILS_INTERACTIVETEST_H
+#define GMX_TESTUTILS_INTERACTIVETEST_H
+
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/classhelpers.h"
+
+namespace gmx
+{
+
+class TextInputStream;
+class TextOutputStream;
+
+namespace test
+{
+
+class TestReferenceChecker;
+
+/*! \libinternal \brief
+ * Helper class for testing interactive sessions.
+ *
+ * The calling test can set the user input using setInputLines() (and possibly
+ * setLastNewline()), pass the streams from inputStream() and outputStream() to
+ * the code that executes the interactive session, and then call checkSession()
+ * after the session is finished.
+ * The input is provided from the array set with setInputLines(), and all
+ * output is checked using the reference data framework.
+ * The reference XML data can be viewed with the XSLT stylesheet to show
+ * exactly how the session went.
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+class InteractiveTestHelper
+{
+ public:
+ /*! \brief
+ * Initializes the helper.
+ *
+ * \param[in] checker Parent reference checker to use.
+ *
+ * The helper creates a compound item under \p checker for the
+ * interactive session it tests.
+ */
+ explicit InteractiveTestHelper(gmx::test::TestReferenceChecker checker);
+ ~InteractiveTestHelper();
+
+ //! Sets whether the last input line contains a newline (by default, it does).
+ void setLastNewline(bool bInclude);
+ /*! \brief
+ * Sets the input lines for the interactive session.
+ *
+ * Calls to TextInputStream::readLine() will return strings from this
+ * array in sequence.
+ * Newlines are added at the end automatically (except for the last
+ * line if `setLastNewLine(false)` has been called).
+ * If there are more `readLine()` calls than there are input lines,
+ * the remaining calls return end-of-input.
+ */
+ void setInputLines(const ConstArrayRef<const char *> &inputLines);
+
+ //! Returns the input stream for the session.
+ TextInputStream &inputStream();
+ //! Returns the output stream for the session.
+ TextOutputStream &outputStream();
+
+ /*! \brief
+ * Finalizes the checking for the session.
+ *
+ * This must be called after all input and output from a session has
+ * occurred, as the helper will not otherwise know when output after
+ * the last input has finished. This method also checks that the
+ * required number of input lines were read in the session.
+ */
+ void checkSession();
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+} // namespace test
+} // namespace gmx
+
+#endif
#include <libxml/xmlmemory.h>
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/path.h"
namespace test
{
-void initReferenceData(Options *options)
+void initReferenceData(IOptionsContainer *options)
{
// Needs to correspond to the enum order in refdata.h.
const char *const refDataEnum[] = { "check", "create", "update" };
namespace gmx
{
-class Options;
+class IOptionsContainer;
namespace test
{
*
* \ingroup module_testutils
*/
-void initReferenceData(Options *options);
+void initReferenceData(IOptionsContainer *options);
class TestReferenceChecker;
#include "stringtest.h"
-#include <algorithm>
#include <string>
-#include <utility>
-#include <vector>
#include <boost/scoped_ptr.hpp>
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
-#include "gromacs/utility/fileredirector.h"
+#include "gromacs/options/ioptionscontainer.h"
+#include "gromacs/utility/textreader.h"
#include "testutils/refdata.h"
-#include "testutils/testexceptions.h"
-#include "testutils/testfilemanager.h"
#include "testutils/testoptions.h"
namespace gmx
{
//! Stores the -stdout flag value to print out values instead of checking them.
bool g_bWriteToStdOut = false;
-
-/*! \brief
- * Helper for checking a block of text, e.g., implementing the `-stdout`
- * option.
- *
- * \ingroup module_testutils
- */
-void checkTextImpl(TestReferenceChecker *checker, const std::string &text,
- const char *id)
-{
- if (g_bWriteToStdOut)
- {
- printf("%s:\n", id);
- printf("%s[END]\n", text.c_str());
- }
- else
- {
- checker->checkStringBlock(text, id);
- }
-}
-
}
// TODO: Only add this option to those test binaries that actually need it
}
//! \endcond
-/********************************************************************
- * TestFileOutputRedirector
- */
-
-/*! \internal
- * \brief
- * Implementation of FileOutputRedirectorInterface for tests.
- *
- * This class redirects all output files to temporary files managed by a
- * TestFileManager, and supports checking the contents of these files using the
- * reference data framework.
- *
- * \ingroup module_testutils
- */
-class TestFileOutputRedirector : public FileOutputRedirectorInterface
-{
- public:
- //! Initializes the redirector with the given file manager.
- explicit TestFileOutputRedirector(TestFileManager *fileManager)
- : fileManager_(*fileManager)
- {
- }
-
- virtual File &standardOutput()
- {
- if (!stdoutFile_)
- {
- const std::string path = fileManager_.getTemporaryFilePath("stdout.txt");
- stdoutFile_.reset(new File(path, "w"));
- fileList_.push_back(FileListEntry("<stdout>", path));
- }
- return *stdoutFile_;
- }
- virtual FileInitializer openFileForWriting(const char *filename)
- {
- std::string suffix = filename;
- std::replace(suffix.begin(), suffix.end(), '/', '_');
- const std::string path = fileManager_.getTemporaryFilePath(suffix);
- fileList_.push_back(FileListEntry(filename, path));
- return FileInitializer(fileList_.back().second.c_str(), "w");
- }
-
- /*! \brief
- * Checks the contents of all redirected files.
- */
- void checkRedirectedFiles(TestReferenceChecker *checker)
- {
- if (stdoutFile_)
- {
- stdoutFile_->close();
- stdoutFile_.reset();
- }
- std::vector<FileListEntry>::const_iterator i;
- for (i = fileList_.begin(); i != fileList_.end(); ++i)
- {
- const std::string text = File::readToString(i->second);
- checkTextImpl(checker, text, i->first.c_str());
- }
- }
-
- private:
- typedef std::pair<std::string, std::string> FileListEntry;
-
- TestFileManager &fileManager_;
- boost::scoped_ptr<File> stdoutFile_;
- std::vector<FileListEntry> fileList_;
-};
-
/********************************************************************
* StringTestBase::Impl
*/
public:
TestReferenceData data_;
boost::scoped_ptr<TestReferenceChecker> checker_;
- boost::scoped_ptr<TestFileOutputRedirector> redirector_;
};
/********************************************************************
* StringTestBase
*/
-StringTestBase::StringTestBase()
- : impl_(new Impl)
+// static
+void StringTestBase::checkText(TestReferenceChecker *checker,
+ const std::string &text, const char *id)
{
+ if (g_bWriteToStdOut)
+ {
+ printf("%s:\n", id);
+ printf("%s[END]\n", text.c_str());
+ }
+ else
+ {
+ checker->checkStringBlock(text, id);
+ }
}
-StringTestBase::~StringTestBase()
+StringTestBase::StringTestBase()
+ : impl_(new Impl)
{
}
-FileOutputRedirectorInterface &
-StringTestBase::initOutputRedirector(TestFileManager *fileManager)
+StringTestBase::~StringTestBase()
{
- if (impl_->redirector_)
- {
- GMX_THROW(TestException("initOutputRedirector() called more than once"));
- }
- impl_->redirector_.reset(new TestFileOutputRedirector(fileManager));
- return *impl_->redirector_;
}
TestReferenceChecker &
void
StringTestBase::checkText(const std::string &text, const char *id)
{
- checkTextImpl(&checker(), text, id);
+ checkText(&checker(), text, id);
}
void
StringTestBase::checkFileContents(const std::string &filename, const char *id)
{
- const std::string text = File::readToString(filename);
+ const std::string text = TextReader::readFileToString(filename);
checkText(text, id);
}
void
-StringTestBase::checkRedirectedOutputFiles()
+StringTestBase::testFilesEqual(const std::string &refFilename,
+ const std::string &testFilename)
{
- if (!impl_->redirector_)
+ const std::string expectedContents = TextReader::readFileToString(refFilename);
+ const std::string contents = TextReader::readFileToString(testFilename);
+ if (g_bWriteToStdOut)
{
- GMX_THROW(TestException("initOutputRedirector() not called"));
+ printf("%s[END]\n", contents.c_str());
}
- impl_->redirector_->checkRedirectedFiles(&checker());
+ EXPECT_EQ(expectedContents, contents);
}
} // namespace test
namespace gmx
{
-class FileOutputRedirectorInterface;
-
namespace test
{
-class TestFileManager;
class TestReferenceChecker;
/*! \libinternal \brief
class StringTestBase : public ::testing::Test
{
public:
- StringTestBase();
- ~StringTestBase();
-
/*! \brief
- * Creates a redirector that directs all output to temporary files.
- *
- * \param[in] fileManager File manager to use for temporary files.
- *
- * Can only be called once in a test.
+ * Checks a block of text.
*
- * \see checkRedirectedOutputFiles()
+ * This static method is provided for code that does not derive from
+ * StringTestBase to use the same functionality, e.g., implementing the
+ * `-stdout` option.
*/
- FileOutputRedirectorInterface &
- initOutputRedirector(TestFileManager *fileManager);
+ static void checkText(TestReferenceChecker *checker,
+ const std::string &text, const char *id);
+
+ StringTestBase();
+ ~StringTestBase();
/*! \brief
* Returns the root checker for this test's reference data.
* single string and calls checkText().
*/
void checkFileContents(const std::string &filename, const char *id);
+
/*! \brief
- * Checks contents of all files redirected with initOutputRedirector().
- *
- * Uses the same logic as checkFileContents() to check each file
- * (including `stdout`) that has been created using the redirector
- * returned by initOutputRedirector().
+ * Tests that contents of two files are equal.
*
- * initOutputRedirector() must have been called.
- * This method should not be called if the redirector will still be
- * used for further output in the test. Behavior is not designed for
- * checking in the middle of the test, although that could potentially
- * be changed if necessary.
+ * \param[in] refFilename File with the expected contents.
+ * \param[in] testFilename File with the contents to be tested.
*/
- void checkRedirectedOutputFiles();
+ void testFilesEqual(const std::string &refFilename,
+ const std::string &testFilename);
private:
class Impl;
#include <gtest/gtest.h>
#include "gromacs/options/basicoptions.h"
-#include "gromacs/options/options.h"
+#include "gromacs/options/ioptionscontainer.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/path.h"
#include <set>
#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+
+#include "gromacs/utility/stringstream.h"
+
+#include "testutils/stringtest.h"
namespace gmx
{
namespace test
{
+/********************************************************************
+ * TestFileInputRedirector
+ */
+
TestFileInputRedirector::TestFileInputRedirector()
{
}
return existingFiles_.count(filename) > 0;
}
+/********************************************************************
+ * TestFileOutputRedirector::Impl
+ */
+
+class TestFileOutputRedirector::Impl
+{
+ public:
+ typedef boost::shared_ptr<StringOutputStream> StringStreamPointer;
+ typedef std::pair<std::string, StringStreamPointer> FileListEntry;
+
+ StringStreamPointer stdoutStream_;
+ std::vector<FileListEntry> fileList_;
+};
+
+/********************************************************************
+ * TestFileOutputRedirector
+ */
+
+TestFileOutputRedirector::TestFileOutputRedirector()
+ : impl_(new Impl)
+{
+}
+
+TestFileOutputRedirector::~TestFileOutputRedirector()
+{
+}
+
+TextOutputStream &TestFileOutputRedirector::standardOutput()
+{
+ if (!impl_->stdoutStream_)
+ {
+ impl_->stdoutStream_.reset(new StringOutputStream);
+ impl_->fileList_.push_back(Impl::FileListEntry("<stdout>", impl_->stdoutStream_));
+ }
+ return *impl_->stdoutStream_;
+}
+
+TextOutputStreamPointer
+TestFileOutputRedirector::openTextOutputFile(const char *filename)
+{
+ Impl::StringStreamPointer stream(new StringOutputStream);
+ impl_->fileList_.push_back(Impl::FileListEntry(filename, stream));
+ return stream;
+}
+
+void TestFileOutputRedirector::checkRedirectedFiles(TestReferenceChecker *checker)
+{
+ std::vector<Impl::FileListEntry>::const_iterator i;
+ for (i = impl_->fileList_.begin(); i != impl_->fileList_.end(); ++i)
+ {
+ StringTestBase::checkText(checker, i->second->toString(), i->first.c_str());
+ }
+}
+
} // namespace test
} // namespace gmx
namespace test
{
+class TestReferenceChecker;
+
/*! \libinternal \brief
- * In-memory implementation for FileInputRedirectorInterface for tests.
+ * In-memory implementation for IFileInputRedirector for tests.
*
* By default, this implementation will return `false` for all file existence
* checks. To return `true` for a specific path, use addExistingFile().
* \inlibraryapi
* \ingroup module_testutils
*/
-class TestFileInputRedirector : public FileInputRedirectorInterface
+class TestFileInputRedirector : public IFileInputRedirector
{
public:
TestFileInputRedirector();
*/
void addExistingFile(const char *filename);
- // From FileInputRedirectorInterface
+ // From IFileInputRedirector
virtual bool fileExists(const char *filename) const;
private:
GMX_DISALLOW_COPY_AND_ASSIGN(TestFileInputRedirector);
};
+/*! \libinternal \brief
+ * In-memory implementation of IFileOutputRedirector for tests.
+ *
+ * This class redirects all output files to in-memory buffers, and supports
+ * checking the contents of these files using the reference data framework.
+ *
+ * \ingroup module_testutils
+ */
+class TestFileOutputRedirector : public IFileOutputRedirector
+{
+ public:
+ TestFileOutputRedirector();
+ virtual ~TestFileOutputRedirector();
+
+ /*! \brief
+ * Checks contents of all redirected files (including stdout).
+ *
+ * This method should not be called if the redirector will still be
+ * used for further output in the test. Behavior is not designed for
+ * checking in the middle of the test, although that could potentially
+ * be changed if necessary.
+ */
+ void checkRedirectedFiles(TestReferenceChecker *checker);
+
+ // From IFileOutputRedirector
+ virtual TextOutputStream &standardOutput();
+ virtual TextOutputStreamPointer openTextOutputFile(const char *filename);
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
} // namespace test
} // namespace gmx
#include "gromacs/options/options.h"
#include "gromacs/utility/errorcodes.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/path.h"
#include "gromacs/utility/programcontext.h"
*
* \ingroup module_testutils
*/
-class TestProgramContext : public ProgramContextInterface
+class TestProgramContext : public IProgramContext
{
public:
/*! \brief
*
* \param[in] context Current \Gromacs program context.
*/
- explicit TestProgramContext(const ProgramContextInterface &context)
+ explicit TestProgramContext(const IProgramContext &context)
: context_(context), dataPath_(CMAKE_SOURCE_DIR)
{
}
}
private:
- const ProgramContextInterface &context_;
+ const IProgramContext &context_;
std::string dataPath_;
};
std::fprintf(stderr,
"\nYou can use the following GROMACS-specific command-line flags\n"
"to control the behavior of the tests:\n\n");
- CommandLineHelpContext context(&File::standardError(),
+ CommandLineHelpContext context(&TextOutputFile::standardError(),
eHelpOutputFormat_Console, NULL, program);
context.setModuleDisplayName(program);
CommandLineHelpWriter(options).writeHelp(context);
#include <list>
-#include "thread_mpi/mutex.h"
-
#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/mutex.h"
namespace gmx
{
//! Adds a provider into the registry.
void add(const char * /*name*/, TestOptionsProvider *provider)
{
- tMPI::lock_guard<tMPI::mutex> lock(listMutex_);
+ lock_guard<Mutex> lock(listMutex_);
providerList_.push_back(provider);
}
//! Initializes the options from all the provides.
- void initOptions(Options *options);
+ void initOptions(IOptionsContainer *options);
private:
TestOptionsRegistry() {}
typedef std::list<TestOptionsProvider *> ProviderList;
- tMPI::mutex listMutex_;
+ Mutex listMutex_;
ProviderList providerList_;
GMX_DISALLOW_COPY_AND_ASSIGN(TestOptionsRegistry);
};
-void TestOptionsRegistry::initOptions(Options *options)
+void TestOptionsRegistry::initOptions(IOptionsContainer *options)
{
// TODO: Have some deterministic order for the options; now it depends on
// the order in which the global initializers are run.
- tMPI::lock_guard<tMPI::mutex> lock(listMutex_);
+ lock_guard<Mutex> lock(listMutex_);
ProviderList::const_iterator i;
for (i = providerList_.begin(); i != providerList_.end(); ++i)
{
TestOptionsRegistry::getInstance().add(name, provider);
}
-void initTestOptions(Options *options)
+void initTestOptions(IOptionsContainer *options)
{
TestOptionsRegistry::getInstance().initOptions(options);
}
namespace gmx
{
-class Options;
+class IOptionsContainer;
namespace test
{
*
* \param options The options need to be added here.
*/
- virtual void initOptions(Options *options) = 0;
+ virtual void initOptions(IOptionsContainer *options) = 0;
protected:
virtual ~TestOptionsProvider() {}
*
* \ingroup module_testutils
*/
-void initTestOptions(Options *options);
+void initTestOptions(IOptionsContainer *options);
// Uncrustify screws up the indentation for the example otherwise.
/* *INDENT-OFF* */
* Typical usage:
* \code
#include "gromacs/options/basicoptions.h"
- #include "gromacs/options/options.h"
+ #include "gromacs/options/ioptionscontainer.h"
#include "testutils/testoptions.h"
{ \
::gmx::test::registerTestOptions(#name, this); \
} \
- virtual void initOptions(::gmx::Options *options); \
+ virtual void initOptions(::gmx::IOptionsContainer *options); \
}; \
\
static name s_ ## name ## Instance; \
\
- void name::initOptions(::gmx::Options *options)
+ void name::initOptions(::gmx::IOptionsContainer *options)
} // namespace test
} // namespace gmx
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2011,2012,2014, by the GROMACS development team, led by
+# Copyright (c) 2011,2012,2014,2015, by the GROMACS development team, led by
# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
# and including many others, as listed in the AUTHORS file in the
# top-level source directory and at http://www.gromacs.org.
# the research papers on the package. Check out http://www.gromacs.org.
gmx_add_unit_test(TestUtilsUnitTests testutils-test
+ interactivetest.cpp
refdata_tests.cpp
testasserts_tests.cpp)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Self-tests for interactive test helpers.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_testutils
+ */
+#include "gmxpre.h"
+
+#include "testutils/interactivetest.h"
+
+#include <vector>
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+#include "gromacs/utility/textstream.h"
+
+#include "testutils/refdata.h"
+
+namespace
+{
+
+class InteractiveSession
+{
+ public:
+ InteractiveSession(gmx::test::ReferenceDataMode mode)
+ : data_(mode), helper_(data_.rootChecker()), nextInputLine_(0)
+ {
+ }
+
+ void addOutput(const char *output)
+ {
+ events_.push_back(Event(WriteOutput, output));
+ }
+ void addInputLine(const char *inputLine)
+ {
+ inputLines_.push_back(inputLine);
+ }
+ void addReadInput()
+ {
+ events_.push_back(Event(ReadInput, ""));
+ }
+ void addInput(const char *inputLine)
+ {
+ addInputLine(inputLine);
+ addReadInput();
+ }
+ void addInputNoNewline(const char *inputLine)
+ {
+ addInputLine(inputLine);
+ helper_.setLastNewline(false);
+ events_.push_back(Event(ReadInputNoNewline, ""));
+ }
+
+ void run()
+ {
+ gmx::TextInputStream &input = helper_.inputStream();
+ gmx::TextOutputStream &output = helper_.outputStream();
+ helper_.setInputLines(inputLines_);
+ std::vector<Event>::const_iterator event;
+ for (event = events_.begin(); event != events_.end(); ++event)
+ {
+ if (event->first == WriteOutput)
+ {
+ output.write(event->second);
+ }
+ else
+ {
+ std::string expectedLine;
+ const bool bInputRemaining = (nextInputLine_ < inputLines_.size());
+ if (bInputRemaining)
+ {
+ expectedLine = inputLines_[nextInputLine_];
+ if (event->first != ReadInputNoNewline)
+ {
+ expectedLine.append("\n");
+ }
+ }
+ ++nextInputLine_;
+ std::string line;
+ EXPECT_EQ(bInputRemaining, input.readLine(&line));
+ EXPECT_EQ(expectedLine, line);
+ }
+ }
+ helper_.checkSession();
+ }
+
+ private:
+ enum EventType
+ {
+ ReadInput,
+ ReadInputNoNewline,
+ WriteOutput
+ };
+ // The latter is the output string.
+ typedef std::pair<EventType, const char *> Event;
+
+ gmx::test::TestReferenceData data_;
+ gmx::test::InteractiveTestHelper helper_;
+ std::vector<const char *> inputLines_;
+ size_t nextInputLine_;
+ std::vector<Event> events_;
+};
+
+TEST(InteractiveTestHelperTest, ChecksSimpleSession)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n");
+ session.addOutput("> ");
+ session.addInput("input");
+ session.addOutput("Second line\n");
+ session.addOutput("> ");
+ session.addReadInput();
+ session.addOutput("\n");
+ session.addOutput(".\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n");
+ session.addOutput("> ");
+ session.addInput("input");
+ session.addOutput("Second line\n");
+ session.addOutput("> ");
+ session.addReadInput();
+ session.addOutput("\n");
+ session.addOutput(".\n");
+ session.run();
+ }
+}
+
+TEST(InteractiveTestHelperTest, ChecksSessionWithoutLastNewline)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n");
+ session.addOutput("> ");
+ session.addInput("input");
+ session.addOutput("Second line\n");
+ session.addOutput("> ");
+ session.addInputNoNewline("input2");
+ session.addOutput("\n");
+ session.addOutput(".\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n");
+ session.addOutput("> ");
+ session.addInput("input");
+ session.addOutput("Second line\n");
+ session.addOutput("> ");
+ session.addInputNoNewline("input2");
+ session.addOutput("\n");
+ session.addOutput(".\n");
+ session.run();
+ }
+}
+
+TEST(InteractiveTestHelperTest, ChecksSessionWithMissingOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addInput("input2");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addInput("input2");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+}
+
+TEST(InteractiveTestHelperTest, ChecksSessionWithEquivalentOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n");
+ session.addOutput("> ");
+ session.addInput("input");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ session.addOutput("\n");
+ session.addOutput(".\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Second line\n");
+ session.addOutput("> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsIncorrectOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Incorrect line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsMissingOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Second line\n> ");
+ session.addInput("input2");
+ session.addOutput("Third line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addInput("input2");
+ session.addOutput("Third line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsMissingFinalOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Second line\n> ");
+ session.addReadInput();
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsExtraOutput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addInput("input2");
+ session.addOutput("More output\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addOutput("First line\n> ");
+ session.addInput("input");
+ session.addOutput("Extra output\n> ");
+ session.addInput("input2");
+ session.addOutput("More output\n> ");
+ session.addReadInput();
+ session.addOutput("\n.\n");
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsMissingInput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addInput("input");
+ session.addInput("input2");
+ session.addReadInput();
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addInputLine("input");
+ session.addInputLine("input2");
+ session.addReadInput();
+ session.addReadInput();
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+TEST(InteractiveTestHelperTest, DetectsExtraInput)
+{
+ {
+ InteractiveSession session(gmx::test::erefdataUpdateAll);
+ session.addInput("input");
+ session.addInput("input2");
+ session.addReadInput();
+ session.run();
+ }
+ {
+ InteractiveSession session(gmx::test::erefdataCompare);
+ session.addInputLine("input");
+ session.addInputLine("input2");
+ session.addReadInput();
+ session.addReadInput();
+ session.addReadInput();
+ session.addReadInput();
+ EXPECT_NONFATAL_FAILURE(session.run(), "");
+ }
+}
+
+} // namespace
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <vector>
-#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
namespace
{
* temporary files that need to be created during the test.
* - gmx::test::TestFileInputRedirector (in testfileredirector.h) provides
* functionality for capturing file existence checks in code that uses
- * gmx::FileInputRedirectorInterface.
+ * gmx::IFileInputRedirector.
+ * - gmx::test::TestFileOutputRedirector (in testfileredirector.h) provides
+ * functionality for capturing file output (including `stdout`) from code
+ * that uses gmx::IFileOutputRedirector, and checking that output
+ * against reference data.
+ * - gmx::test::InteractiveTestHelper (in interactivetest.h) provides
+ * a helper class for testing an interactive session that uses
+ * gmx::TextInputStream and gmx::TextOutputStream for prompting input and
+ * printing status messages.
* - #GMX_TEST_OPTIONS macro provides facilities for adding custom command
* line options for the test binary.
* - testasserts.h provides several custom test assertions for better