From 9f0b7ff922a9dbc20ee8d3f1f1498ec91fd3f15f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:03:02 -0400 Subject: [PATCH 001/218] Start EnergyDecomposer class --- src/CMakeLists.txt | 1 + src/Energy/CMakeLists.txt | 4 ++++ src/Energy/EnergyDecomposer.cpp | 8 ++++++++ src/Energy/EnergyDecomposer.h | 16 ++++++++++++++++ src/Energy/Makefile | 26 ++++++++++++++++++++++++++ src/Energy/energydepend | 1 + src/Energy/energyfiles | 3 +++ src/Makefile | 9 +++++++-- src/cpptrajfiles | 2 +- 9 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/Energy/CMakeLists.txt create mode 100644 src/Energy/EnergyDecomposer.cpp create mode 100644 src/Energy/EnergyDecomposer.h create mode 100644 src/Energy/Makefile create mode 100644 src/Energy/energydepend create mode 100644 src/Energy/energyfiles diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4977c05e15..70c8e644c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,6 +115,7 @@ endif() add_library(cpptraj_common_obj OBJECT ${CPPTRAJ_COMMON_SOURCES}) add_subdirectory(Cluster) add_subdirectory(Structure) +add_subdirectory(Energy) make_pic_if_needed(cpptraj_common_obj) #normally this would be applied by target_link_libraries, but since we use that intermediary object library, we have to apply it manually diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt new file mode 100644 index 0000000000..8bbb85ca17 --- /dev/null +++ b/src/Energy/CMakeLists.txt @@ -0,0 +1,4 @@ +#CMake buildfile for CPPTRAJ Energy subdirectory. +target_sources(cpptraj_common_obj PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp +) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp new file mode 100644 index 0000000000..486cf65713 --- /dev/null +++ b/src/Energy/EnergyDecomposer.cpp @@ -0,0 +1,8 @@ +#include "EnergyDecomposer.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR */ +EnergyDecomposer::EnergyDecomposer() +{ } + diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h new file mode 100644 index 0000000000..dfa20fca60 --- /dev/null +++ b/src/Energy/EnergyDecomposer.h @@ -0,0 +1,16 @@ +#ifndef INC_ENERGY_ENERGYDECOMPOSER_H +#define INC_ENERGY_ENERGYDECOMPOSER_H +#include "../CharMask.h" +namespace Cpptraj { +namespace Energy { +/// Used to break down pairwise-additive energy by atom or residue +class EnergyDecomposer { + public: + /// CONSTRUCTOR + EnergyDecomposer(); + private: + CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. +}; +} +} +#endif diff --git a/src/Energy/Makefile b/src/Energy/Makefile new file mode 100644 index 0000000000..c08a17fdc2 --- /dev/null +++ b/src/Energy/Makefile @@ -0,0 +1,26 @@ +# Energy Makefile +include ../../config.h + +include energyfiles + +DEL_FILE = /bin/rm -f + +# Objects +OBJECTS=$(ENERGY_SOURCES:.cpp=.o) + +# Default target: objects +all: $(OBJECTS) + +clean: + $(DEL_FILE) *.o + +uninstall: clean + +# Dependency targets +../findDepend: + cd ../ && $(MAKE) findDepend + +depend: ../findDepend + ../findDepend $(ENERGY_SOURCES) > energydepend + +include energydepend diff --git a/src/Energy/energydepend b/src/Energy/energydepend new file mode 100644 index 0000000000..567e870783 --- /dev/null +++ b/src/Energy/energydepend @@ -0,0 +1 @@ +EnergyDecomposer.o : EnergyDecomposer.cpp ../Atom.h ../CharMask.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles new file mode 100644 index 0000000000..f3a3b6c905 --- /dev/null +++ b/src/Energy/energyfiles @@ -0,0 +1,3 @@ +# Files for Energy subdirectory. +ENERGY_SOURCES= \ + EnergyDecomposer.cpp diff --git a/src/Makefile b/src/Makefile index 625e87e043..4c7d82db76 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,9 +8,11 @@ include Cluster/clusterfiles CLUSTER_SOURCEFILES=$(CLUSTER_SOURCES:%.cpp=Cluster/%.cpp) include Structure/structurefiles STRUCTURE_SOURCEFILES=$(STRUCTURE_SOURCES:%.cpp=Structure/%.cpp) +include Energy/energyfiles +ENERGY_SOURCEFILES=$(ENERGY_SOURCES:%.cpp=Energy/%.cpp) # All object files -OBJECTS=$(SOURCES:.cpp=.o) $(CSOURCES:.c=.o) $(CLUSTER_SOURCEFILES:.cpp=.o) $(STRUCTURE_SOURCEFILES:.cpp=.o) +OBJECTS=$(SOURCES:.cpp=.o) $(CSOURCES:.c=.o) $(CLUSTER_SOURCEFILES:.cpp=.o) $(STRUCTURE_SOURCEFILES:.cpp=.o) $(ENERGY_SOURCEFILES:.cpp=.o) # General rules .cpp.o: @@ -27,6 +29,7 @@ DEL_FILE = /bin/rm -f showsources: @echo $(CLUSTER_SOURCEFILES) @echo $(STRUCTURE_SOURCEFILES) + @echo $(ENERGY_SOURCEFILES) showobjects: @echo $(OBJECTS) @@ -137,7 +140,7 @@ findDepend: FindDepend.cpp FindDepend.o $(CXX) -o findDepend FindDepend.o depend: findDepend - ./findDepend $(SOURCES) $(CSOURCES) $(CLUSTER_SOURCEFILES) $(STRUCTURE_SOURCEFILES) > cpptrajdepend + ./findDepend $(SOURCES) $(CSOURCES) $(CLUSTER_SOURCEFILES) $(STRUCTURE_SOURCEFILES) $(ENERGY_SOURCEFILES) > cpptrajdepend dependclean: $(DEL_FILE) FindDepend.o findDepend @@ -151,6 +154,7 @@ clean: cd cuda_kernels && $(MAKE) clean cd Cluster && $(MAKE) clean cd Structure && $(MAKE) clean + cd Energy && $(MAKE) clean cd tng && $(MAKE) clean uninstall_lib: @@ -174,6 +178,7 @@ uninstall: uninstall_lib uninstall_inc cd cuda_kernels && $(MAKE) uninstall cd Cluster && $(MAKE) uninstall cd Structure && $(MAKE) uninstall + cd Energy && $(MAKE) uninstall # Header dependencies include cpptrajdepend diff --git a/src/cpptrajfiles b/src/cpptrajfiles index 493089d055..0b9e351356 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -479,7 +479,7 @@ SOURCES=$(COMMON_SOURCES) \ # by libcpptraj. They MUST have the '.LIBCPPTRAJ.o' extension and will be # compiled with the '-DLIBCPPTRAJ' define. # NOTE: This variable MUST be in cpptrajfiles as the cmake build expects it. -LIBCPPTRAJ_OBJECTS=$(COMMON_SOURCES:.cpp=.o) $(CSOURCES:.c=.o) $(CLUSTER_SOURCEFILES:.cpp=.o) $(STRUCTURE_SOURCEFILES:.cpp=.o) \ +LIBCPPTRAJ_OBJECTS=$(COMMON_SOURCES:.cpp=.o) $(CSOURCES:.c=.o) $(CLUSTER_SOURCEFILES:.cpp=.o) $(STRUCTURE_SOURCEFILES:.cpp=.o) $(ENERGY_SOURCEFILES:.cpp=.o) \ Action_Esander.LIBCPPTRAJ.o \ Command.LIBCPPTRAJ.o \ Cpptraj.LIBCPPTRAJ.o \ From aaeb9a791c427f939b808af9ae02fce8d239d187 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:03:23 -0400 Subject: [PATCH 002/218] Update dependencies --- src/cpptrajdepend | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 300a19680d..7218a38f4f 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -275,6 +275,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp Atom.h CharMask.h Energy/EnergyDecomposer.h MaskToken.h Molecule.h NameType.h Residue.h Segment.h SymbolExporting.h Unit.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From f55d1e763b88dfdbc3f6f8511c022d1268babf53 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:06:17 -0400 Subject: [PATCH 003/218] Start init routine --- src/Energy/EnergyDecomposer.cpp | 8 ++++++++ src/Energy/EnergyDecomposer.h | 4 ++++ src/Energy/energydepend | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 486cf65713..4f0d5cfaa9 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,4 +1,5 @@ #include "EnergyDecomposer.h" +#include "../ArgList.h" using namespace Cpptraj::Energy; @@ -6,3 +7,10 @@ using namespace Cpptraj::Energy; EnergyDecomposer::EnergyDecomposer() { } +/** Initialize decomposer. */ +int EnergyDecomposer::InitDecomposer(ArgList&, int debugIn) +{ + debug_ = debugIn; + + return 0; +} diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index dfa20fca60..e0404d3680 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -1,6 +1,7 @@ #ifndef INC_ENERGY_ENERGYDECOMPOSER_H #define INC_ENERGY_ENERGYDECOMPOSER_H #include "../CharMask.h" +class ArgList; namespace Cpptraj { namespace Energy { /// Used to break down pairwise-additive energy by atom or residue @@ -8,8 +9,11 @@ class EnergyDecomposer { public: /// CONSTRUCTOR EnergyDecomposer(); + /// Initialize with arguments + int InitDecomposer(ArgList&, int); private: CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. + int debug_; ///< Debug level }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 567e870783..69bb0bc047 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../Atom.h ../CharMask.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../Atom.h ../CharMask.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h From 60d2060699c965b54d9a9bd2e0f50f00fdd34f0e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:09:52 -0400 Subject: [PATCH 004/218] Add mask and options print --- src/Energy/EnergyDecomposer.cpp | 12 +++++++++++- src/Energy/EnergyDecomposer.h | 2 ++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 4f0d5cfaa9..8da9cdf182 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,5 +1,6 @@ #include "EnergyDecomposer.h" #include "../ArgList.h" +#include "../CpptrajStdio.h" using namespace Cpptraj::Energy; @@ -8,9 +9,18 @@ EnergyDecomposer::EnergyDecomposer() { } /** Initialize decomposer. */ -int EnergyDecomposer::InitDecomposer(ArgList&, int debugIn) +int EnergyDecomposer::InitDecomposer(ArgList& argIn, int debugIn) { debug_ = debugIn; + // Get atom mask + if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) + return 1; + return 0; } + +/** Print options to stdout. */ +void EnergyDecomposer::PrintOpts() const { + mprintf("\tCalculating for atoms selected by mask: %s\n", selectedAtoms_.MaskString()); +} diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index e0404d3680..851f44ce73 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -11,6 +11,8 @@ class EnergyDecomposer { EnergyDecomposer(); /// Initialize with arguments int InitDecomposer(ArgList&, int); + /// Print options to stdout + void PrintOpts() const; private: CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. int debug_; ///< Debug level diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 69bb0bc047..f035fcf5c1 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../Atom.h ../CharMask.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../Atom.h ../CharMask.h ../CpptrajStdio.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 7218a38f4f..2e1d63c89a 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -275,7 +275,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp Atom.h CharMask.h Energy/EnergyDecomposer.h MaskToken.h Molecule.h NameType.h Residue.h Segment.h SymbolExporting.h Unit.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h Atom.h CharMask.h CpptrajStdio.h Energy/EnergyDecomposer.h MaskToken.h Molecule.h NameType.h Residue.h Segment.h SymbolExporting.h Unit.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From 1d66d29500006991037319e8772483849122f928 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:12:50 -0400 Subject: [PATCH 005/218] Start energy decomp action --- src/Action_EneDecomp.cpp | 25 +++++++++++++++++++++++++ src/Action_EneDecomp.h | 26 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/Action_EneDecomp.cpp create mode 100644 src/Action_EneDecomp.h diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp new file mode 100644 index 0000000000..0716345c79 --- /dev/null +++ b/src/Action_EneDecomp.cpp @@ -0,0 +1,25 @@ +#include "Action_EneDecomp.h" +#include "CpptrajStdio.h" + +// Action_EneDecomp::Help() +void Action_EneDecomp::Help() const { + +} + +// Action_EneDecomp::Init() +Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, int debugIn) +{ + +} + +// Action_EneDecomp::Setup() +Action::RetType Action_EneDecomp::Setup(ActionSetup& setup) +{ + +} + +// Action_EneDecomp::DoAction() +Action::RetType Action_EneDecomp::DoAction(int frameNum, ActionFrame& frm) +{ + +} diff --git a/src/Action_EneDecomp.h b/src/Action_EneDecomp.h new file mode 100644 index 0000000000..1d1db6feba --- /dev/null +++ b/src/Action_EneDecomp.h @@ -0,0 +1,26 @@ +#ifndef INC_ACTION_ENEDECOMP_H +#define INC_ACTION_ENEDECOMP_H +#include "Action.h" +#include "Energy/EnergyDecomposer.h" +/// Used to decompose the pairwise additive energy of a system +class Action_EneDecomp : public Action { + public: + /// CONSTRUCTOR + Action_EneDecomp() {} + /// Allocator + DispatchObject* Alloc() const { return (DispatchObject*)new Action_EneDecomp(); } + /// Help text + void Help() const; + private: + /// Initialization + Action::RetType Init(ArgList&, ActionInit&, int); + /// Topology-based setup + Action::RetType Setup(ActionSetup&); + /// Do the action + Action::RetType DoAction(int, ActionFrame&); + /// Print results/finish calculations + void Print() {} + + Cpptraj::Energy::EnergyDecomposer eneDecomp_; ///< Do the actual decomposition +}; +#endif From cc5648b9896305276de72a35a41f35d45f8b9c02 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:28:56 -0400 Subject: [PATCH 006/218] Start adding the enedecomp command, start initialization --- src/Action_EneDecomp.cpp | 9 +++++++-- src/Command.cpp | 2 ++ src/Energy/EnergyDecomposer.cpp | 20 ++++++++++++++++++-- src/Energy/EnergyDecomposer.h | 10 +++++++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 5 +++-- src/cpptrajfiles | 1 + 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index 0716345c79..f408ea41ae 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -9,17 +9,22 @@ void Action_EneDecomp::Help() const { // Action_EneDecomp::Init() Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { + if (eneDecomp_.InitDecomposer( actionArgs, init.DSL(), debugIn )) + return Action::ERR; + mprintf(" ENEDECOMP: Decomposing energy for selected atoms.\n"); + eneDecomp_.PrintOpts(); + return Action::OK; } // Action_EneDecomp::Setup() Action::RetType Action_EneDecomp::Setup(ActionSetup& setup) { - + return Action::ERR; // FIXME } // Action_EneDecomp::DoAction() Action::RetType Action_EneDecomp::DoAction(int frameNum, ActionFrame& frm) { - + return Action::ERR; // FIXME } diff --git a/src/Command.cpp b/src/Command.cpp index 545514dea5..b4c6b91013 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -164,6 +164,7 @@ #include "Action_ToroidalDiffusion.h" #include "Action_MinMaxDist.h" #include "Action_AddAtom.h" +#include "Action_EneDecomp.h" // ----- ANALYSIS -------------------------------------------------------------- #include "Analysis_Hist.h" #include "Analysis_Corr.h" @@ -347,6 +348,7 @@ void Command::Init() { Command::AddCmd( new Action_DNAionTracker(), Cmd::ACT, 1, "dnaiontracker" ); // hidden Command::AddCmd( new Action_DistRmsd(), Cmd::ACT, 2, "drms", "drmsd" ); Command::AddCmd( new Action_DSSP(), Cmd::ACT, 2, "dssp", "secstruct" ); + Command::AddCmd( new Action_EneDecomp(), Cmd::ACT, 1, "enedecomp" ); Command::AddCmd( new Action_Energy(), Cmd::ACT, 1, "energy" ); Command::AddCmd( new Action_Esander(), Cmd::ACT, 1, "esander" ); Command::AddCmd( new Action_FilterByData(), Cmd::ACT, 1, "filter" ); diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 8da9cdf182..a64b8ffeff 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,26 +1,42 @@ #include "EnergyDecomposer.h" #include "../ArgList.h" #include "../CpptrajStdio.h" +#include "../DataSetList.h" using namespace Cpptraj::Energy; /** CONSTRUCTOR */ -EnergyDecomposer::EnergyDecomposer() +EnergyDecomposer::EnergyDecomposer() : + eneOut_(0) { } /** Initialize decomposer. */ -int EnergyDecomposer::InitDecomposer(ArgList& argIn, int debugIn) +int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, int debugIn) { debug_ = debugIn; // Get atom mask if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) return 1; + // Output DataSet + std::string setname = argIn.GetStringNext(); + if (setname.empty()) + setname = DSLin.GenerateDefaultName("DECOMP"); + eneOut_ = DSLin.AddSet(DataSet::XYMESH, MetaData(setname)); + if (eneOut_ == 0) { + mprinterr("Error: Could not allocate decomp. output set '%s'\n", setname.c_str()); + return 1; + } return 0; } /** Print options to stdout. */ void EnergyDecomposer::PrintOpts() const { + if (eneOut_ == 0) { + mprinterr("Internal Error: EnergyDecomposer::PrintOpts() called before initialization.\n"); + return; + } mprintf("\tCalculating for atoms selected by mask: %s\n", selectedAtoms_.MaskString()); + mprintf("\tData set name: %s\n", eneOut_->legend()); } diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 851f44ce73..16cf0521f8 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -1,7 +1,11 @@ #ifndef INC_ENERGY_ENERGYDECOMPOSER_H #define INC_ENERGY_ENERGYDECOMPOSER_H +#include #include "../CharMask.h" +#include "../OnlineVarT.h" class ArgList; +class DataSet; +class DataSetList; namespace Cpptraj { namespace Energy { /// Used to break down pairwise-additive energy by atom or residue @@ -10,11 +14,15 @@ class EnergyDecomposer { /// CONSTRUCTOR EnergyDecomposer(); /// Initialize with arguments - int InitDecomposer(ArgList&, int); + int InitDecomposer(ArgList&, DataSetList&, int); /// Print options to stdout void PrintOpts() const; private: + typedef std::vector< Stats > EneArrayType; + CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. + DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. + EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. int debug_; ///< Debug level }; } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index f035fcf5c1..933fb8d5a0 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../Atom.h ../CharMask.h ../CpptrajStdio.h ../MaskToken.h ../Molecule.h ../NameType.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h EnergyDecomposer.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataSet.h ../DataSetList.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../Dimension.h ../FileIO.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h EnergyDecomposer.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 2e1d63c89a..fbcc790754 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,6 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/EnergyDecomposer.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -189,7 +190,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -275,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h Atom.h CharMask.h CpptrajStdio.h Energy/EnergyDecomposer.h MaskToken.h Molecule.h NameType.h Residue.h Segment.h SymbolExporting.h Unit.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h Energy/EnergyDecomposer.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index 0b9e351356..bdb04fd255 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -35,6 +35,7 @@ COMMON_SOURCES= \ Action_Dipole.cpp \ Action_Distance.cpp \ Action_DistRmsd.cpp \ + Action_EneDecomp.cpp \ Action_Energy.cpp \ Action_FilterByData.cpp \ Action_FixAtomOrder.cpp \ From d868e8dff5fa7c37c5f2268d522570c575301d4f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:36:20 -0400 Subject: [PATCH 007/218] Start doing setup --- src/Action_EneDecomp.cpp | 7 ++++++- src/Energy/EnergyDecomposer.cpp | 19 +++++++++++++++++++ src/Energy/EnergyDecomposer.h | 7 +++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index f408ea41ae..e2bc4ae5d6 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -20,7 +20,12 @@ Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, in // Action_EneDecomp::Setup() Action::RetType Action_EneDecomp::Setup(ActionSetup& setup) { - return Action::ERR; // FIXME + int ret = eneDecomp_.SetupDecomposer( setup.Top() ); + if (ret == -1) + return Action::SKIP; + else if (ret == 1) + return Action::ERR; + return Action::OK; } // Action_EneDecomp::DoAction() diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index a64b8ffeff..9a3af101c1 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -2,6 +2,7 @@ #include "../ArgList.h" #include "../CpptrajStdio.h" #include "../DataSetList.h" +#include "../ParameterTypes.h" using namespace Cpptraj::Energy; @@ -40,3 +41,21 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tCalculating for atoms selected by mask: %s\n", selectedAtoms_.MaskString()); mprintf("\tData set name: %s\n", eneOut_->legend()); } + +/** Topology-based setup. + * \return 0 if setup OK, 1 if error, -1 if nothing selected. + */ +int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { + // First set up the mask + if (topIn.SetupCharMask( selectedAtoms_ )) { + mprinterr("Error: Could not set up mask '%s'\n", selectedAtoms_.MaskString()); + return 1; + } + selectedAtoms_.MaskInfo(); + if (selectedAtoms_.None()) { + mprintf("Warning: Nothing selected by mask '%s'\n", selectedAtoms_.MaskString()); + return -1; + } + + return 0; +} diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 16cf0521f8..d6cf28607c 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -4,8 +4,10 @@ #include "../CharMask.h" #include "../OnlineVarT.h" class ArgList; +class BondType; class DataSet; class DataSetList; +class Topology; namespace Cpptraj { namespace Energy { /// Used to break down pairwise-additive energy by atom or residue @@ -17,6 +19,8 @@ class EnergyDecomposer { int InitDecomposer(ArgList&, DataSetList&, int); /// Print options to stdout void PrintOpts() const; + /// Topology-based setup + int SetupDecomposer(Topology const&); private: typedef std::vector< Stats > EneArrayType; @@ -24,6 +28,9 @@ class EnergyDecomposer { DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. int debug_; ///< Debug level + + typedef std::vector BndArrayType; + BndArrayType bonds_; ///< Hold all bonds to be calculated }; } } From edb9c8bc01ec0005a00213b18dd8faf0d9a0a6f3 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:43:20 -0400 Subject: [PATCH 008/218] Bond setup --- src/Energy/EnergyDecomposer.cpp | 21 +++++++++++++++++++++ src/Energy/EnergyDecomposer.h | 5 ++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 9a3af101c1..5e6befc32a 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -3,6 +3,7 @@ #include "../CpptrajStdio.h" #include "../DataSetList.h" #include "../ParameterTypes.h" +#include //std::sort using namespace Cpptraj::Energy; @@ -42,6 +43,18 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); } +/** Set up bonds. */ +void EnergyDecomposer::setupBonds(BndArrayType const& bondsIn) { + for (BndArrayType::const_iterator bnd = bondsIn.begin(); bnd != bondsIn.end(); ++bnd) + { + if ( selectedAtoms_.AtomInCharMask( bnd->A1() ) || + selectedAtoms_.AtomInCharMask( bnd->A2() ) ) + { + bonds_.push_back( *bnd ); + } + } +} + /** Topology-based setup. * \return 0 if setup OK, 1 if error, -1 if nothing selected. */ @@ -56,6 +69,14 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { mprintf("Warning: Nothing selected by mask '%s'\n", selectedAtoms_.MaskString()); return -1; } + // Set up bonds + bonds_.clear(); + setupBonds( topIn.Bonds() ); + setupBonds( topIn.BondsH() ); + std::sort( bonds_.begin(), bonds_.end() ); + mprintf("DEBUG: Bonds:\n"); + for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) + mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); return 0; } diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index d6cf28607c..3d1928f95d 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -23,13 +23,16 @@ class EnergyDecomposer { int SetupDecomposer(Topology const&); private: typedef std::vector< Stats > EneArrayType; + typedef std::vector BndArrayType; + + /// Set up selected bonds + void setupBonds(BndArrayType const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. int debug_; ///< Debug level - typedef std::vector BndArrayType; BndArrayType bonds_; ///< Hold all bonds to be calculated }; } From e015e5998271809473796218e7e1b850905481c9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:52:13 -0400 Subject: [PATCH 009/218] Setup output arrays --- src/Energy/EnergyDecomposer.cpp | 20 ++++++++++++++++++++ src/Energy/EnergyDecomposer.h | 6 ++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 5e6befc32a..8151d4af2d 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -43,6 +43,7 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); } +// ----------------------------------------------------------------------------- /** Set up bonds. */ void EnergyDecomposer::setupBonds(BndArrayType const& bondsIn) { for (BndArrayType::const_iterator bnd = bondsIn.begin(); bnd != bondsIn.end(); ++bnd) @@ -69,6 +70,23 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { mprintf("Warning: Nothing selected by mask '%s'\n", selectedAtoms_.MaskString()); return -1; } + // Set up calculation arrays + if (indices_.empty()) { + // First time setup + indices_.reserve( selectedAtoms_.Nselected() ); + for (int idx = 0; idx != topIn.Natom(); idx++) + if (selectedAtoms_.AtomInCharMask( idx )) + indices_.push_back( idx ); + energies_.resize( selectedAtoms_.Nselected() ); + } else { + // Already setup. Warn if indices have changed. + if ((unsigned int)selectedAtoms_.Nselected() != indices_.size()) { + // FIXME implement this + mprinterr("Error: Number of selected atoms has changed in topology '%s'\n", topIn.c_str()); + mprinterr("Error: Not yet supported by energy decomposition.\n"); + return 1; + } + } // Set up bonds bonds_.clear(); setupBonds( topIn.Bonds() ); @@ -80,3 +98,5 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { return 0; } + +// ----------------------------------------------------------------------------- diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 3d1928f95d..f1aff6e13c 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -24,16 +24,18 @@ class EnergyDecomposer { private: typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; + typedef std::vector Iarray; /// Set up selected bonds void setupBonds(BndArrayType const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. - EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. int debug_; ///< Debug level - BndArrayType bonds_; ///< Hold all bonds to be calculated + BndArrayType bonds_; ///< Hold all bonds to be calculated + Iarray indices_; ///< Hold indices of each selected entity. + EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. }; } } From 8e836d005c5512dcff5fd1fe7dbad2f79b00cac8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 11:57:18 -0400 Subject: [PATCH 010/218] Print atoms that energy will be saved for --- src/Energy/EnergyDecomposer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 8151d4af2d..36aa7bddb4 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -92,6 +92,11 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { setupBonds( topIn.Bonds() ); setupBonds( topIn.BondsH() ); std::sort( bonds_.begin(), bonds_.end() ); + + // DEBUG + mprintf("DEBUG: Saving energy for atoms:\n"); + for (Iarray::const_iterator it = indices_.begin(); it != indices_.end(); ++it) + mprintf("\t%s\n", topIn.AtomMaskName( *it ).c_str()); mprintf("DEBUG: Bonds:\n"); for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); From f2f48b749cfc81d9fa699840e80b079765752896 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 12:09:12 -0400 Subject: [PATCH 011/218] Just allocate an energy for each atom, will make bookkeeping easier --- src/Energy/EnergyDecomposer.cpp | 58 +++++++++++++++++++++++++-------- src/Energy/EnergyDecomposer.h | 10 ++++-- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 36aa7bddb4..44f62a97a4 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -9,7 +9,9 @@ using namespace Cpptraj::Energy; /** CONSTRUCTOR */ EnergyDecomposer::EnergyDecomposer() : - eneOut_(0) + eneOut_(0), + debug_(0), + currentTop_(0) { } /** Initialize decomposer. */ @@ -45,15 +47,21 @@ void EnergyDecomposer::PrintOpts() const { // ----------------------------------------------------------------------------- /** Set up bonds. */ -void EnergyDecomposer::setupBonds(BndArrayType const& bondsIn) { +int EnergyDecomposer::setupBonds(BndArrayType const& bondsIn) { for (BndArrayType::const_iterator bnd = bondsIn.begin(); bnd != bondsIn.end(); ++bnd) { if ( selectedAtoms_.AtomInCharMask( bnd->A1() ) || selectedAtoms_.AtomInCharMask( bnd->A2() ) ) { + if (bnd->Idx() < 0) { + mprinterr("Error: Bond %i - %i does not have parameters, cannot calculate energy.\n", + bnd->A1()+1, bnd->A2()+1); + return 1; + } bonds_.push_back( *bnd ); } } + return 0; } /** Topology-based setup. @@ -71,37 +79,59 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { return -1; } // Set up calculation arrays - if (indices_.empty()) { + if (energies_.empty()) { // First time setup - indices_.reserve( selectedAtoms_.Nselected() ); - for (int idx = 0; idx != topIn.Natom(); idx++) - if (selectedAtoms_.AtomInCharMask( idx )) - indices_.push_back( idx ); - energies_.resize( selectedAtoms_.Nselected() ); +// indices_.reserve( selectedAtoms_.Nselected() ); +// for (int idx = 0; idx != topIn.Natom(); idx++) +// if (selectedAtoms_.AtomInCharMask( idx )) +// indices_.push_back( idx ); + energies_.resize( topIn.Natom() ); } else { // Already setup. Warn if indices have changed. - if ((unsigned int)selectedAtoms_.Nselected() != indices_.size()) { + //if ((unsigned int)selectedAtoms_.Nselected() != indices_.size()) + if ((unsigned int)topIn.Natom() != energies_.size()) + { // FIXME implement this - mprinterr("Error: Number of selected atoms has changed in topology '%s'\n", topIn.c_str()); + mprinterr("Error: Number of atoms has changed in topology '%s'\n", topIn.c_str()); + mprinterr("Error: Now %i atoms, expected %zu\n", topIn.Natom(), energies_.size()); mprinterr("Error: Not yet supported by energy decomposition.\n"); return 1; } } // Set up bonds bonds_.clear(); - setupBonds( topIn.Bonds() ); - setupBonds( topIn.BondsH() ); + if (setupBonds( topIn.Bonds() )) return 1; + if (setupBonds( topIn.BondsH() )) return 1; std::sort( bonds_.begin(), bonds_.end() ); // DEBUG mprintf("DEBUG: Saving energy for atoms:\n"); - for (Iarray::const_iterator it = indices_.begin(); it != indices_.end(); ++it) - mprintf("\t%s\n", topIn.AtomMaskName( *it ).c_str()); + for (int idx = 0; idx != topIn.Natom(); idx++) + if (selectedAtoms_.AtomInCharMask( idx )) + mprintf("\t%s\n", topIn.AtomMaskName( idx ).c_str()); mprintf("DEBUG: Bonds:\n"); for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); + currentTop_ = &topIn; + return 0; } // ----------------------------------------------------------------------------- +/** Calculate bond energies. */ +void EnergyDecomposer::calcBonds( Frame const& frameIn ) { + //for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) +} + +/** Calculate and decompose energies. */ +int EnergyDecomposer::CalcEne(Frame const& frameIn) { + if (currentTop_ == 0) { + mprinterr("Internal Error: EnergyDecomposer::CalcEne() called before setup.\n"); + return 1; + } + // Bonds + calcBonds(frameIn); + + return 0; +} diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index f1aff6e13c..5039d0683d 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -7,6 +7,7 @@ class ArgList; class BondType; class DataSet; class DataSetList; +class Frame; class Topology; namespace Cpptraj { namespace Energy { @@ -21,21 +22,24 @@ class EnergyDecomposer { void PrintOpts() const; /// Topology-based setup int SetupDecomposer(Topology const&); + /// Calculate and decompose energies for given frame. + int CalcEne(Frame const&); private: typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; - typedef std::vector Iarray; /// Set up selected bonds - void setupBonds(BndArrayType const&); + int setupBonds(BndArrayType const&); + /// Calculate bond energies + void calcBonds(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. int debug_; ///< Debug level BndArrayType bonds_; ///< Hold all bonds to be calculated - Iarray indices_; ///< Hold indices of each selected entity. EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. + Topology const* currentTop_; }; } } From 915d75d7b3cfa9c53354d2b21ddf22fe671edac9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 12:34:20 -0400 Subject: [PATCH 012/218] Fix up the dataset dimension labels. Add calculation --- src/Action_EneDecomp.cpp | 9 ++++++- src/Action_EneDecomp.h | 2 +- src/DataSet_Mesh.h | 1 + src/Energy/EnergyDecomposer.cpp | 44 ++++++++++++++++++++++++++++++++- src/Energy/EnergyDecomposer.h | 7 +++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index e2bc4ae5d6..4e15ee838b 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -31,5 +31,12 @@ Action::RetType Action_EneDecomp::Setup(ActionSetup& setup) // Action_EneDecomp::DoAction() Action::RetType Action_EneDecomp::DoAction(int frameNum, ActionFrame& frm) { - return Action::ERR; // FIXME + if (eneDecomp_.CalcEne( frm.Frm() )) + return Action::ERR; + return Action::OK; +} + +// Action_EneDecomp::Print() +void Action_EneDecomp::Print() { + eneDecomp_.FinishCalc(); } diff --git a/src/Action_EneDecomp.h b/src/Action_EneDecomp.h index 1d1db6feba..c0e1cc840b 100644 --- a/src/Action_EneDecomp.h +++ b/src/Action_EneDecomp.h @@ -19,7 +19,7 @@ class Action_EneDecomp : public Action { /// Do the action Action::RetType DoAction(int, ActionFrame&); /// Print results/finish calculations - void Print() {} + void Print(); Cpptraj::Energy::EnergyDecomposer eneDecomp_; ///< Do the actual decomposition }; diff --git a/src/DataSet_Mesh.h b/src/DataSet_Mesh.h index 48613cf8c9..a8888364e6 100644 --- a/src/DataSet_Mesh.h +++ b/src/DataSet_Mesh.h @@ -13,6 +13,7 @@ class DataSet_Mesh : public DataSet_1D { DataSet_Mesh(int,double,double); static DataSet* Alloc() { return (DataSet*)new DataSet_Mesh(); } void Resize(size_t n) { mesh_x_.resize(n, 0.0); mesh_y_.resize(n, 0.0); } + void Clear() { mesh_x_.clear(); mesh_y_.clear(); } // ----- DataSet functions ------------------- size_t Size() const { return mesh_x_.size(); } # ifdef MPI diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 44f62a97a4..c23b714f68 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,6 +1,9 @@ #include "EnergyDecomposer.h" +#include // sqrt for Ene_Bond etc +#include "Ene_Bond.h" #include "../ArgList.h" #include "../CpptrajStdio.h" +#include "../DataSet_Mesh.h" #include "../DataSetList.h" #include "../ParameterTypes.h" #include //std::sort @@ -31,6 +34,10 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, int deb mprinterr("Error: Could not allocate decomp. output set '%s'\n", setname.c_str()); return 1; } +# ifdef MPI + eneOut_->SetNeedsSync( false ); // Not a time series +# endif + eneOut_->ModifyDim(Dimension::X).SetLabel("Atom"); return 0; } @@ -119,9 +126,25 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { } // ----------------------------------------------------------------------------- +/** Save energy contribution to atom if it is selected. */ +void EnergyDecomposer::saveEne(int idx, double ene_cont) { + if (selectedAtoms_.AtomInCharMask( idx )) + energies_[ idx ].accumulate( ene_cont ); +} + /** Calculate bond energies. */ void EnergyDecomposer::calcBonds( Frame const& frameIn ) { - //for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) + for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) + { + BondParmType const& BP = currentTop_->BondParm()[ bnd->Idx() ]; + double ene = Ene_Bond( frameIn.XYZ( bnd->A1() ), + frameIn.XYZ( bnd->A2() ), + BP.Req(), BP.Rk() ); + // Divide the energy equally between the two atoms. + double ene_half = ene * 0.5; + saveEne( bnd->A1(), ene_half ); + saveEne( bnd->A2(), ene_half ); + } } /** Calculate and decompose energies. */ @@ -135,3 +158,22 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { return 0; } + +// ----------------------------------------------------------------------------- +/** Finish the calculation by putting the results into the output DataSet. */ +int EnergyDecomposer::FinishCalc() { + if (energies_.empty() || eneOut_ == 0) { + mprinterr("Internal Error: EnergyDecomposer::FinishCalc() called before setup.\n"); + return 1; + } + // Only add entities that have data. + DataSet_Mesh& set = static_cast( *eneOut_ ); + set.Clear(); + // TODO allocate? + for (unsigned int idx = 0; idx != energies_.size(); idx++) { + if ( energies_[idx].nData() > 0 ) { + set.AddXY( idx+1, energies_[idx].mean() ); + } + } + return 0; +} diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 5039d0683d..4b69dbf9aa 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -11,7 +11,7 @@ class Frame; class Topology; namespace Cpptraj { namespace Energy { -/// Used to break down pairwise-additive energy by atom or residue +/// Used to break down pairwise-additive energy by atom class EnergyDecomposer { public: /// CONSTRUCTOR @@ -24,12 +24,17 @@ class EnergyDecomposer { int SetupDecomposer(Topology const&); /// Calculate and decompose energies for given frame. int CalcEne(Frame const&); + /// Finish the calculation by putting energies in output DataSet + int FinishCalc(); private: typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; /// Set up selected bonds int setupBonds(BndArrayType const&); + + /// Save energy contribution for atom if it is selected + inline void saveEne(int, double); /// Calculate bond energies void calcBonds(Frame const&); diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 933fb8d5a0..864ecf45ab 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataSet.h ../DataSetList.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../Dimension.h ../FileIO.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h EnergyDecomposer.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index fbcc790754..69cc363421 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h Energy/EnergyDecomposer.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From 3289056d0777673cd1b96e759ab1692f17d01434 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 12:39:37 -0400 Subject: [PATCH 013/218] Add output file --- src/Action_EneDecomp.cpp | 2 +- src/Energy/EnergyDecomposer.cpp | 12 ++++++++++-- src/Energy/EnergyDecomposer.h | 5 ++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index 4e15ee838b..32e162a909 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -9,7 +9,7 @@ void Action_EneDecomp::Help() const { // Action_EneDecomp::Init() Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { - if (eneDecomp_.InitDecomposer( actionArgs, init.DSL(), debugIn )) + if (eneDecomp_.InitDecomposer( actionArgs, init.DSL(), init.DFL(), debugIn )) return Action::ERR; mprintf(" ENEDECOMP: Decomposing energy for selected atoms.\n"); eneDecomp_.PrintOpts(); diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index c23b714f68..ea26b5fbf7 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -3,6 +3,7 @@ #include "Ene_Bond.h" #include "../ArgList.h" #include "../CpptrajStdio.h" +#include "../DataFileList.h" #include "../DataSet_Mesh.h" #include "../DataSetList.h" #include "../ParameterTypes.h" @@ -13,15 +14,18 @@ using namespace Cpptraj::Energy; /** CONSTRUCTOR */ EnergyDecomposer::EnergyDecomposer() : eneOut_(0), + outfile_(0), debug_(0), currentTop_(0) { } /** Initialize decomposer. */ -int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, int debugIn) +int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFileList& DFLin, + int debugIn) { debug_ = debugIn; - + // Process keywords + outfile_ = DFLin.AddDataFile( argIn.GetStringKey("out"), argIn ); // Get atom mask if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) return 1; @@ -38,6 +42,8 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, int deb eneOut_->SetNeedsSync( false ); // Not a time series # endif eneOut_->ModifyDim(Dimension::X).SetLabel("Atom"); + if (outfile_ != 0) + outfile_->AddDataSet( eneOut_ ); return 0; } @@ -50,6 +56,8 @@ void EnergyDecomposer::PrintOpts() const { } mprintf("\tCalculating for atoms selected by mask: %s\n", selectedAtoms_.MaskString()); mprintf("\tData set name: %s\n", eneOut_->legend()); + if (outfile_ != 0) + mprintf("\tOutput file: %s\n", outfile_->DataFilename().full()); } // ----------------------------------------------------------------------------- diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 4b69dbf9aa..43c7ddb47f 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -5,6 +5,8 @@ #include "../OnlineVarT.h" class ArgList; class BondType; +class DataFile; +class DataFileList; class DataSet; class DataSetList; class Frame; @@ -17,7 +19,7 @@ class EnergyDecomposer { /// CONSTRUCTOR EnergyDecomposer(); /// Initialize with arguments - int InitDecomposer(ArgList&, DataSetList&, int); + int InitDecomposer(ArgList&, DataSetList&, DataFileList&, int); /// Print options to stdout void PrintOpts() const; /// Topology-based setup @@ -40,6 +42,7 @@ class EnergyDecomposer { CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. + DataFile* outfile_; ///< Output file int debug_; ///< Debug level BndArrayType bonds_; ///< Hold all bonds to be calculated diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 864ecf45ab..bda68b9112 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 69cc363421..d2c1d37c81 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From 692c65d610ed0ac9164bde7ac9c0f549c584d693 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 14:55:17 -0400 Subject: [PATCH 014/218] Add angle term. Need to sum before accumulation --- src/Energy/EnergyDecomposer.cpp | 58 ++++++++++++++++++++++++++++++++- src/Energy/EnergyDecomposer.h | 10 ++++++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index ea26b5fbf7..199d82856f 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,6 +1,7 @@ #include "EnergyDecomposer.h" #include // sqrt for Ene_Bond etc #include "Ene_Bond.h" +#include "Ene_Angle.h" #include "../ArgList.h" #include "../CpptrajStdio.h" #include "../DataFileList.h" @@ -79,6 +80,25 @@ int EnergyDecomposer::setupBonds(BndArrayType const& bondsIn) { return 0; } +/** Set up angles. */ +int EnergyDecomposer::setupAngles(AngArrayType const& anglesIn) { + for (AngArrayType::const_iterator ang = anglesIn.begin(); ang != anglesIn.end(); ++ang) + { + if ( selectedAtoms_.AtomInCharMask( ang->A1() ) || + selectedAtoms_.AtomInCharMask( ang->A2() ) || + selectedAtoms_.AtomInCharMask( ang->A3() ) ) + { + if (ang->Idx() < 0) { + mprinterr("Error: Angle %i - %i - %i does not have parameters, cannot calculate energy.\n", + ang->A1()+1, ang->A2()+1, ang->A3()+1); + return 1; + } + angles_.push_back( *ang ); + } + } + return 0; +} + /** Topology-based setup. * \return 0 if setup OK, 1 if error, -1 if nothing selected. */ @@ -118,6 +138,11 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { if (setupBonds( topIn.Bonds() )) return 1; if (setupBonds( topIn.BondsH() )) return 1; std::sort( bonds_.begin(), bonds_.end() ); + // Set up angles + angles_.clear(); + if (setupAngles( topIn.Angles() )) return 1; + if (setupAngles( topIn.AnglesH() )) return 1; + std::sort( angles_.begin(), angles_.end() ); // DEBUG mprintf("DEBUG: Saving energy for atoms:\n"); @@ -127,6 +152,9 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { mprintf("DEBUG: Bonds:\n"); for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); + mprintf("DEBUG: Angles:\n"); + for (AngArrayType::const_iterator ang = angles_.begin(); ang != angles_.end(); ++ang) + mprintf("\t%s - %s - %s\n", topIn.AtomMaskName(ang->A1()).c_str(), topIn.AtomMaskName(ang->A2()).c_str(), topIn.AtomMaskName(ang->A3()).c_str()); currentTop_ = &topIn; @@ -137,7 +165,7 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { /** Save energy contribution to atom if it is selected. */ void EnergyDecomposer::saveEne(int idx, double ene_cont) { if (selectedAtoms_.AtomInCharMask( idx )) - energies_[ idx ].accumulate( ene_cont ); + currentEne_[ idx ] += ene_cont; } /** Calculate bond energies. */ @@ -148,6 +176,7 @@ void EnergyDecomposer::calcBonds( Frame const& frameIn ) { double ene = Ene_Bond( frameIn.XYZ( bnd->A1() ), frameIn.XYZ( bnd->A2() ), BP.Req(), BP.Rk() ); + mprintf("DEBUG: BND %f\n", ene); // Divide the energy equally between the two atoms. double ene_half = ene * 0.5; saveEne( bnd->A1(), ene_half ); @@ -155,14 +184,41 @@ void EnergyDecomposer::calcBonds( Frame const& frameIn ) { } } +/** Calculate angle energies. */ +void EnergyDecomposer::calcAngles( Frame const& frameIn ) { + for (AngArrayType::const_iterator ang = angles_.begin(); ang != angles_.end(); ++ang) + { + AngleParmType const& AP = currentTop_->AngleParm()[ ang->Idx() ]; + double ene = Ene_Angle( frameIn.XYZ( ang->A1() ), + frameIn.XYZ( ang->A2() ), + frameIn.XYZ( ang->A3() ), + AP.Teq(), AP.Tk() ); + mprintf("DEBUG: ANG %f\n", ene); + // Divide the energy equally between the three atoms. + double ene_third = ene / 3.0; + saveEne( ang->A1(), ene_third ); + saveEne( ang->A2(), ene_third ); + saveEne( ang->A3(), ene_third ); + } +} + /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { if (currentTop_ == 0) { mprinterr("Internal Error: EnergyDecomposer::CalcEne() called before setup.\n"); return 1; } + currentEne_.assign( energies_.size(), 0.0 ); // Bonds calcBonds(frameIn); + // Angles + calcAngles(frameIn); + + // Accumulate the energies + for (unsigned int idx = 0; idx != energies_.size(); idx++) { + if (selectedAtoms_.AtomInCharMask( idx )) + energies_[idx].accumulate( currentEne_[idx] ); + } return 0; } diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 43c7ddb47f..f9cae570a3 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -3,6 +3,7 @@ #include #include "../CharMask.h" #include "../OnlineVarT.h" +class AngleType; class ArgList; class BondType; class DataFile; @@ -29,16 +30,22 @@ class EnergyDecomposer { /// Finish the calculation by putting energies in output DataSet int FinishCalc(); private: + typedef std::vector Darray; typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; + typedef std::vector AngArrayType; /// Set up selected bonds int setupBonds(BndArrayType const&); + /// Set up selected angles + int setupAngles(AngArrayType const&); /// Save energy contribution for atom if it is selected inline void saveEne(int, double); /// Calculate bond energies void calcBonds(Frame const&); + /// Calculate angle energies + void calcAngles(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. @@ -46,8 +53,11 @@ class EnergyDecomposer { int debug_; ///< Debug level BndArrayType bonds_; ///< Hold all bonds to be calculated + AngArrayType angles_; ///< Hold all angles to be calculated EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. Topology const* currentTop_; + + Darray currentEne_; ///< Hold the total energy of each atom for the current frame }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index bda68b9112..46f3c85a5a 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index d2c1d37c81..8424525cd7 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From 05a3eab02fd629302f328fb263d227bbfa783bb5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 15:20:33 -0400 Subject: [PATCH 015/218] Decompose dihedrals --- src/Energy/EnergyDecomposer.cpp | 54 +++++++++++++++++++++++++++++++++ src/Energy/EnergyDecomposer.h | 7 +++++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 199d82856f..708d46489a 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -2,12 +2,14 @@ #include // sqrt for Ene_Bond etc #include "Ene_Bond.h" #include "Ene_Angle.h" +#include "Kernel_Fourier.h" #include "../ArgList.h" #include "../CpptrajStdio.h" #include "../DataFileList.h" #include "../DataSet_Mesh.h" #include "../DataSetList.h" #include "../ParameterTypes.h" +#include "../TorsionRoutines.h" #include //std::sort using namespace Cpptraj::Energy; @@ -99,6 +101,26 @@ int EnergyDecomposer::setupAngles(AngArrayType const& anglesIn) { return 0; } +/** Set up dihedrals. */ +int EnergyDecomposer::setupDihedrals(DihArrayType const& dihedralsIn) { + for (DihArrayType::const_iterator dih = dihedralsIn.begin(); dih != dihedralsIn.end(); ++dih) + { + if ( selectedAtoms_.AtomInCharMask( dih->A1() ) || + selectedAtoms_.AtomInCharMask( dih->A2() ) || + selectedAtoms_.AtomInCharMask( dih->A3() ) || + selectedAtoms_.AtomInCharMask( dih->A4() ) ) + { + if (dih->Idx() < 0) { + mprinterr("Error: Dihedral %i - %i - %i - %i does not have parameters, cannot calculate energy.\n", + dih->A1()+1, dih->A2()+1, dih->A3()+1, dih->A4()+1); + return 1; + } + dihedrals_.push_back( *dih ); + } + } + return 0; +} + /** Topology-based setup. * \return 0 if setup OK, 1 if error, -1 if nothing selected. */ @@ -143,6 +165,11 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { if (setupAngles( topIn.Angles() )) return 1; if (setupAngles( topIn.AnglesH() )) return 1; std::sort( angles_.begin(), angles_.end() ); + // Set up dihedrals + dihedrals_.clear(); + if (setupDihedrals( topIn.Dihedrals() )) return 1; + if (setupDihedrals( topIn.DihedralsH() )) return 1; + std::sort( dihedrals_.begin(), dihedrals_.end() ); // DEBUG mprintf("DEBUG: Saving energy for atoms:\n"); @@ -155,6 +182,9 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { mprintf("DEBUG: Angles:\n"); for (AngArrayType::const_iterator ang = angles_.begin(); ang != angles_.end(); ++ang) mprintf("\t%s - %s - %s\n", topIn.AtomMaskName(ang->A1()).c_str(), topIn.AtomMaskName(ang->A2()).c_str(), topIn.AtomMaskName(ang->A3()).c_str()); + mprintf("DEBUG: Dihedrals:\n"); + for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) + mprintf("\t%s - %s - %s - %s\n", topIn.AtomMaskName(dih->A1()).c_str(), topIn.AtomMaskName(dih->A2()).c_str(), topIn.AtomMaskName(dih->A3()).c_str(), topIn.AtomMaskName(dih->A4()).c_str()); currentTop_ = &topIn; @@ -202,6 +232,28 @@ void EnergyDecomposer::calcAngles( Frame const& frameIn ) { } } +/** Calculate dihedral energies. */ +void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { + for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) + { + DihedralParmType const& DP = currentTop_->DihedralParm()[ dih->Idx() ]; + + double theta = Torsion( frameIn.XYZ(dih->A1()), + frameIn.XYZ(dih->A2()), + frameIn.XYZ(dih->A3()), + frameIn.XYZ(dih->A4()) ); + double ene = Kernel_Fourier( theta, DP.Pk(), DP.Pn(), DP.Phase() ); + + mprintf("DEBUG: DIH %f\n", ene); + // Divide the energy equally between the four atoms. + double ene_fourth = ene / 4.0; + saveEne( dih->A1(), ene_fourth ); + saveEne( dih->A2(), ene_fourth ); + saveEne( dih->A3(), ene_fourth ); + saveEne( dih->A4(), ene_fourth ); + } +} + /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { if (currentTop_ == 0) { @@ -213,6 +265,8 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { calcBonds(frameIn); // Angles calcAngles(frameIn); + // Dihedrals + calcDihedrals(frameIn); // Accumulate the energies for (unsigned int idx = 0; idx != energies_.size(); idx++) { diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index f9cae570a3..faaad7a813 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -10,6 +10,7 @@ class DataFile; class DataFileList; class DataSet; class DataSetList; +class DihedralType; class Frame; class Topology; namespace Cpptraj { @@ -34,11 +35,14 @@ class EnergyDecomposer { typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; typedef std::vector AngArrayType; + typedef std::vector DihArrayType; /// Set up selected bonds int setupBonds(BndArrayType const&); /// Set up selected angles int setupAngles(AngArrayType const&); + /// Set up selected dihedrals + int setupDihedrals(DihArrayType const&); /// Save energy contribution for atom if it is selected inline void saveEne(int, double); @@ -46,6 +50,8 @@ class EnergyDecomposer { void calcBonds(Frame const&); /// Calculate angle energies void calcAngles(Frame const&); + /// Calculate dihedral energies + void calcDihedrals(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. @@ -54,6 +60,7 @@ class EnergyDecomposer { BndArrayType bonds_; ///< Hold all bonds to be calculated AngArrayType angles_; ///< Hold all angles to be calculated + DihArrayType dihedrals_; ///< Hold all dihedrals to be calculated EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. Topology const* currentTop_; diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 46f3c85a5a..77f4b737e4 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h EnergyDecomposer.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 8424525cd7..8f4279a77d 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From e2919b59c3a035d8bad4a981798aecdc9c844da7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 15:35:49 -0400 Subject: [PATCH 016/218] LJ 6-12 energy template --- src/Energy/Ene_LJ_6_12.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/Energy/Ene_LJ_6_12.h diff --git a/src/Energy/Ene_LJ_6_12.h b/src/Energy/Ene_LJ_6_12.h new file mode 100644 index 0000000000..6b00334960 --- /dev/null +++ b/src/Energy/Ene_LJ_6_12.h @@ -0,0 +1,20 @@ +#ifndef INC_ENERGY_ENE_LJ_6_12_H +#define INC_ENERGY_ENE_LJ_6_12_H +#include "Kernel_Harmonic.h" +namespace Cpptraj { +namespace Energy { +/// \return LJ 6-12 energy +template +T Ene_LJ_6_12(T const& rij2, T const& LJA, T const& LJB) +{ + T r2 = 1.0 / rij2; + T r6 = r2 * r2 * r2; + T r12 = r6 * r6; + T f12 = LJA * r12; // A/r^12 + T f6 = LJB * r6; // B/r^6 + T e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + return e_vdw; +} +} +} +#endif From 9375be0a2a971fe98e81edca5785971c559751b5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 15:41:53 -0400 Subject: [PATCH 017/218] Create and use an LJ 6-12 template --- src/Energy.cpp | 16 ++++++++++------ src/cpptrajdepend | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Energy.cpp b/src/Energy.cpp index 936414ecd0..44f6386bb0 100644 --- a/src/Energy.cpp +++ b/src/Energy.cpp @@ -9,6 +9,7 @@ #include "ExclusionArray.h" #include "Energy/Ene_Angle.h" #include "Energy/Ene_Bond.h" +#include "Energy/Ene_LJ_6_12.h" const double Energy_Amber::QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; @@ -176,12 +177,13 @@ double Energy_Amber::Calc_14_Energy(Frame const& fIn, DihedralArray const& Dihed double rij = sqrt( rij2 ); // VDW NonbondType const& LJ = tIn.GetLJparam(d->A1(), d->A4()); - double r2 = 1.0 / rij2; + double e_vdw = Cpptraj::Energy::Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); +/* double r2 = 1.0 / rij2; double r6 = r2 * r2 * r2; double r12 = r6 * r6; double f12 = LJ.A() * r12; // A/r^12 double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + double e_vdw = f12 - f6; // (A/r^12)-(B/r^6)*/ e_vdw /= dp.SCNB(); Evdw14 += e_vdw; // Coulomb @@ -235,12 +237,13 @@ double Energy_Amber::E_Nonbond(Frame const& fIn, Topology const& tIn, AtomMask c double rij = sqrt( rij2 ); // VDW NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); - double r2 = 1.0 / rij2; + double e_vdw = Cpptraj::Energy::Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + /*double r2 = 1.0 / rij2; double r6 = r2 * r2 * r2; double r12 = r6 * r6; double f12 = LJ.A() * r12; // A/r^12 double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + double e_vdw = f12 - f6; // (A/r^12)-(B/r^6)*/ Evdw += e_vdw; // Coulomb double qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); @@ -294,12 +297,13 @@ double Energy_Amber::E_VDW(Frame const& fIn, Topology const& tIn, AtomMask const double rij2 = DIST2_NoImage( crd1, fIn.XYZ( atom2 ) ); // VDW NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); - double r2 = 1.0 / rij2; + double e_vdw = Cpptraj::Energy::Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + /*double r2 = 1.0 / rij2; double r6 = r2 * r2 * r2; double r12 = r6 * r6; double f12 = LJ.A() * r12; // A/r^12 double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + double e_vdw = f12 - f6; // (A/r^12)-(B/r^6)*/ Evdw += e_vdw; # ifdef DEBUG_ENERGY mprintf("\tEVDW %4i -- %4i: A= %12.5e B= %12.5e r2= %12.5f E= %12.5e\n", diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 8f4279a77d..59a261658b 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -275,7 +275,7 @@ Deprecated.o : Deprecated.cpp CpptrajStdio.h Deprecated.h DispatchObject.h DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DiffusionResults.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h -Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 53a3c2f4b4afac33d4a1df1d05ce1b122cb78747 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 15:47:51 -0400 Subject: [PATCH 018/218] Start adding the 1-4 energy --- src/Energy/EnergyDecomposer.cpp | 11 ++++++++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 708d46489a..a10e3ee3ac 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -1,13 +1,15 @@ #include "EnergyDecomposer.h" #include // sqrt for Ene_Bond etc -#include "Ene_Bond.h" #include "Ene_Angle.h" +#include "Ene_Bond.h" +#include "Ene_LJ_6_12.h" #include "Kernel_Fourier.h" #include "../ArgList.h" #include "../CpptrajStdio.h" #include "../DataFileList.h" #include "../DataSet_Mesh.h" #include "../DataSetList.h" +#include "../DistRoutines.h" #include "../ParameterTypes.h" #include "../TorsionRoutines.h" #include //std::sort @@ -251,6 +253,13 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { saveEne( dih->A2(), ene_fourth ); saveEne( dih->A3(), ene_fourth ); saveEne( dih->A4(), ene_fourth ); + // 1-4 energy + double rij2 = DIST2_NoImage( frameIn.XYZ(dih->A1()), frameIn.XYZ(dih->A4()) ); + NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); + double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + double ene_half = e_vdw * 0.5; + saveEne( dih->A1(), ene_half ); + saveEne( dih->A4(), ene_half ); } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 77f4b737e4..85f471bd88 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 59a261658b..171c07ef7a 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From c5df682dfbca42ec9ea540bd7e2192812f9c3725 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 13 Sep 2024 15:54:02 -0400 Subject: [PATCH 019/218] Add 1-4 elec --- src/Energy/EnergyDecomposer.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index a10e3ee3ac..83a6471776 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -236,6 +236,7 @@ void EnergyDecomposer::calcAngles( Frame const& frameIn ) { /** Calculate dihedral energies. */ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { + static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) { DihedralParmType const& DP = currentTop_->DihedralParm()[ dih->Idx() ]; @@ -253,13 +254,22 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { saveEne( dih->A2(), ene_fourth ); saveEne( dih->A3(), ene_fourth ); saveEne( dih->A4(), ene_fourth ); - // 1-4 energy + // 1-4 vdw energy double rij2 = DIST2_NoImage( frameIn.XYZ(dih->A1()), frameIn.XYZ(dih->A4()) ); NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + e_vdw /= DP.SCNB(); double ene_half = e_vdw * 0.5; saveEne( dih->A1(), ene_half ); saveEne( dih->A4(), ene_half ); + // 1-4 coulomb energy + double rij = sqrt(rij2); + double qiqj = QFAC * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); + double e_elec = qiqj / rij; + e_elec /= DP.SCEE(); + ene_half = e_elec * 0.5; + saveEne( dih->A1(), ene_half ); + saveEne( dih->A4(), ene_half ); } } From 383e73e415fa3a1b384c6f24a594efc0de4ba722 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 16 Sep 2024 11:01:18 -0400 Subject: [PATCH 020/218] Add debug for the 1-4 terms --- src/Energy/EnergyDecomposer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 83a6471776..2f8235deb4 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -259,6 +259,7 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); e_vdw /= DP.SCNB(); + mprintf("DEBUG: V14 %f\n", e_vdw); double ene_half = e_vdw * 0.5; saveEne( dih->A1(), ene_half ); saveEne( dih->A4(), ene_half ); @@ -267,6 +268,7 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { double qiqj = QFAC * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); double e_elec = qiqj / rij; e_elec /= DP.SCEE(); + mprintf("DEBUG: E14 %f\n", e_elec); ene_half = e_elec * 0.5; saveEne( dih->A1(), ene_half ); saveEne( dih->A4(), ene_half ); From 63efd03b448e3b900adb53fac0d2aec684dc2fd9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 16 Sep 2024 13:33:29 -0400 Subject: [PATCH 021/218] Start adding nonbond decomp --- src/Energy/EnergyDecomposer.cpp | 54 +++++++++++++++++++++++++++++++-- src/Energy/EnergyDecomposer.h | 18 ++++++++--- src/Energy/energydepend | 2 +- src/cpptrajdepend | 4 +-- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 2f8235deb4..3088b8a963 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -16,6 +16,8 @@ using namespace Cpptraj::Energy; +const double EnergyDecomposer::QFAC_ = Constants::ELECTOAMBER * Constants::ELECTOAMBER; + /** CONSTRUCTOR */ EnergyDecomposer::EnergyDecomposer() : eneOut_(0), @@ -172,6 +174,18 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { if (setupDihedrals( topIn.Dihedrals() )) return 1; if (setupDihedrals( topIn.DihedralsH() )) return 1; std::sort( dihedrals_.begin(), dihedrals_.end() ); + // For nonbonds, set up all selected atoms in an integer atom mask. + //mask_ = AtomMask( selectedAtoms_.ConvertToIntMask(), selectedAtoms_.Natom() ); + // Need to set up ex + // TODO if using pairlist, needs to be EXCLUDE_SELF and FULL + //if (Excluded_.SetupExcludedForAtoms( topIn.Atoms(), mask_, 4 )) + if (Excluded_.SetupExcluded( topIn.Atoms(), 4, + ExclusionArray::NO_EXCLUDE_SELF, + ExclusionArray::ONLY_GREATER_IDX )) + { + mprinterr("Error: Could not set up atom exclusion list for energy decomposition.\n"); + return 1; + } // DEBUG mprintf("DEBUG: Saving energy for atoms:\n"); @@ -234,9 +248,8 @@ void EnergyDecomposer::calcAngles( Frame const& frameIn ) { } } -/** Calculate dihedral energies. */ +/** Calculate dihedral and LJ 1-4 energies. */ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { - static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) { DihedralParmType const& DP = currentTop_->DihedralParm()[ dih->Idx() ]; @@ -265,7 +278,7 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { saveEne( dih->A4(), ene_half ); // 1-4 coulomb energy double rij = sqrt(rij2); - double qiqj = QFAC * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); + double qiqj = QFAC_ * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); double e_elec = qiqj / rij; e_elec /= DP.SCEE(); mprintf("DEBUG: E14 %f\n", e_elec); @@ -275,6 +288,39 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { } } +/** Simple nonbonded energy calculation with no cutoff. */ +void EnergyDecomposer::calcNB_simple(Frame const& frameIn) { + for (int atom1 = 0; atom1 < currentTop_->Natom(); atom1++) { + bool atom1_is_selected = selectedAtoms_.AtomInCharMask( atom1 ); + ExclusionArray::ExListType const& excludedAtoms = Excluded_[atom1]; + for (int atom2 = atom1 + 1; atom2 < currentTop_->Natom(); atom2++) { + bool atom2_is_selected = selectedAtoms_.AtomInCharMask( atom2 ); + if (atom1_is_selected || atom2_is_selected) { + ExclusionArray::ExListType::const_iterator it = excludedAtoms.find( atom2 ); + if (it == excludedAtoms.end()) { + // Either atom1 or atom2 is selected and the interaction is not excluded. + // vdw energy TODO image distances? + double rij2 = DIST2_NoImage( frameIn.XYZ(atom1), frameIn.XYZ(atom2) ); + NonbondType const& LJ = currentTop_->GetLJparam(atom1, atom2); + double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + mprintf("DEBUG: VDW %f\n", e_vdw); + double ene_half = e_vdw * 0.5; + saveEne( atom1, ene_half ); + saveEne( atom2, ene_half ); + // Coulomb energy + double rij = sqrt(rij2); + double qiqj = QFAC_ * (*currentTop_)[atom1].Charge() * (*currentTop_)[atom2].Charge(); + double e_elec = qiqj / rij; + mprintf("DEBUG: ELE %f\n", e_elec); + ene_half = e_elec * 0.5; + saveEne( atom1, ene_half ); + saveEne( atom2, ene_half ); + } // END atom2 not excluded from atom1 + } // END atom1 or atom2 is selected + } // END inner loop over atoms + } // END outer loop over atoms +} + /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { if (currentTop_ == 0) { @@ -288,6 +334,8 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { calcAngles(frameIn); // Dihedrals calcDihedrals(frameIn); + // Nonbonds + calcNB_simple(frameIn); // Accumulate the energies for (unsigned int idx = 0; idx != energies_.size(); idx++) { diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index faaad7a813..6d82c77490 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -1,7 +1,9 @@ #ifndef INC_ENERGY_ENERGYDECOMPOSER_H #define INC_ENERGY_ENERGYDECOMPOSER_H #include +#include "../AtomMask.h" #include "../CharMask.h" +#include "../ExclusionArray.h" #include "../OnlineVarT.h" class AngleType; class ArgList; @@ -31,6 +33,8 @@ class EnergyDecomposer { /// Finish the calculation by putting energies in output DataSet int FinishCalc(); private: + static const double QFAC_; ///< Coulomb prefactor + typedef std::vector Darray; typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; @@ -52,17 +56,21 @@ class EnergyDecomposer { void calcAngles(Frame const&); /// Calculate dihedral energies void calcDihedrals(Frame const&); + /// Calculate simple nonbonded energies, no cutoff + void calcNB_simple(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. DataFile* outfile_; ///< Output file int debug_; ///< Debug level - BndArrayType bonds_; ///< Hold all bonds to be calculated - AngArrayType angles_; ///< Hold all angles to be calculated - DihArrayType dihedrals_; ///< Hold all dihedrals to be calculated - EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. - Topology const* currentTop_; + BndArrayType bonds_; ///< Hold all bonds to be calculated + AngArrayType angles_; ///< Hold all angles to be calculated + DihArrayType dihedrals_; ///< Hold all dihedrals to be calculated + //AtomMask mask_; ///< Atom mask for nonbonded calculations + ExclusionArray Excluded_; ///< Hold excluded atoms lists for each selected atom + EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. + Topology const* currentTop_; ///< Current topology from Setup Darray currentEne_; ///< Hold the total energy of each atom for the current frame }; diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 85f471bd88..e34de55540 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 171c07ef7a..a47ea37562 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,7 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/EnergyDecomposer.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/EnergyDecomposer.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -276,7 +276,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h From bef1e317c9aa3e110dd9f6a4357c326efe1312eb Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 16 Sep 2024 14:46:06 -0400 Subject: [PATCH 022/218] Only do 1-4 calculation for NORMAL dihedrals --- src/Energy/EnergyDecomposer.cpp | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 3088b8a963..0c27ff3479 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -267,24 +267,26 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { saveEne( dih->A2(), ene_fourth ); saveEne( dih->A3(), ene_fourth ); saveEne( dih->A4(), ene_fourth ); - // 1-4 vdw energy - double rij2 = DIST2_NoImage( frameIn.XYZ(dih->A1()), frameIn.XYZ(dih->A4()) ); - NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); - double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); - e_vdw /= DP.SCNB(); - mprintf("DEBUG: V14 %f\n", e_vdw); - double ene_half = e_vdw * 0.5; - saveEne( dih->A1(), ene_half ); - saveEne( dih->A4(), ene_half ); - // 1-4 coulomb energy - double rij = sqrt(rij2); - double qiqj = QFAC_ * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); - double e_elec = qiqj / rij; - e_elec /= DP.SCEE(); - mprintf("DEBUG: E14 %f\n", e_elec); - ene_half = e_elec * 0.5; - saveEne( dih->A1(), ene_half ); - saveEne( dih->A4(), ene_half ); + if (dih->Type() == DihedralType::NORMAL) { + // 1-4 vdw energy + double rij2 = DIST2_NoImage( frameIn.XYZ(dih->A1()), frameIn.XYZ(dih->A4()) ); + NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); + double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + e_vdw /= DP.SCNB(); + mprintf("DEBUG: V14 %f\n", e_vdw); + double ene_half = e_vdw * 0.5; + saveEne( dih->A1(), ene_half ); + saveEne( dih->A4(), ene_half ); + // 1-4 coulomb energy + double rij = sqrt(rij2); + double qiqj = QFAC_ * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); + double e_elec = qiqj / rij; + e_elec /= DP.SCEE(); + mprintf("DEBUG: E14 %f\n", e_elec); + ene_half = e_elec * 0.5; + saveEne( dih->A1(), ene_half ); + saveEne( dih->A4(), ene_half ); + } } } From cc5018709e682c503510aeec23716a1ae04b98c0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 17 Sep 2024 10:26:32 -0400 Subject: [PATCH 023/218] Start trying to template the pairlist loop --- src/Kernel_LJswitch.h | 30 ++++++++++ src/PairListEngine_Nonbond.h | 75 +++++++++++++++++++++++ src/PairListTemplate.h | 113 +++++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 src/Kernel_LJswitch.h create mode 100644 src/PairListEngine_Nonbond.h create mode 100644 src/PairListTemplate.h diff --git a/src/Kernel_LJswitch.h b/src/Kernel_LJswitch.h new file mode 100644 index 0000000000..016492f829 --- /dev/null +++ b/src/Kernel_LJswitch.h @@ -0,0 +1,30 @@ +#ifndef INC_KERNEL_LJSWITCH_H +#define INC_KERNEL_LJSWITCH_H +/** Switching function for Lennard-Jones. */ +template class Kernel_LJswitch { + public: + /// CONSTRUCTOR + Kernel_LJswitch() : cut2_0_(0), cut2_1_(0) {} + /// Setup + void setup_switch(T const& cut2_0in, T const& cut2_1in) { + cut2_0_ = cut2_0in; + cut2_1_ = cut2_1in; + } + /// Calculate switched value + T switch_fn(T const& rij2) + { + if (rij2 <= cut2_0_) + return 1.0; + else if (rij2 > cut2_1_) + return 0.0; + else { + T xoff_m_x = cut2_1_ - rij2; + T fac = 1.0 / (cut2_1_ - cut2_0_); + return (xoff_m_x*xoff_m_x) * (cut2_1_ + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); + } + } + private: + T cut2_0_; + T cut2_1_; +}; +#endif diff --git a/src/PairListEngine_Nonbond.h b/src/PairListEngine_Nonbond.h new file mode 100644 index 0000000000..8efe965b78 --- /dev/null +++ b/src/PairListEngine_Nonbond.h @@ -0,0 +1,75 @@ +#ifndef INC_PAIRLISTENGINE_NONBOND_H +#define INC_PAIRLISTENGINE_NONBOND_H +#include "Kernel_LJswitch.h" +#include "PairList.h" +#include "ParameterTypes.h" +#include "SplineFxnTable.h" +#include +template +class PairListEngine_Nonbond { + typedef std::vector Iarray; + public: + PairListEngine_Nonbond() {} + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = Charge_[atom0.Idx()]; + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = Charge_[atom1.Idx()]; + } + /// Call when cutoff is satisfied + void CutoffSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + double rij = sqrt( rij2 ); + double qiqj = q0_ * q1_; +# ifndef _OPENMP + t_erfc_.Start(); +# endif + //double erfc = erfc_func(ew_coeff_ * rij); + double erfc = ERFC(ew_coeff_ * rij); +# ifndef _OPENMP + t_erfc_.Stop(); +# endif + double e_elec = qiqj * erfc / rij; + Eelec += e_elec; + //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", + //int ta0, ta1; + //if (it0->Idx() < it1->Idx()) { + // ta0=it0->Idx(); ta1=it1->Idx(); + //} else { + // ta1=it0->Idx(); ta0=it1->Idx(); + //} + //mprintf("PELEC %6i%6i%12.5f%12.5f%12.5f\n", ta0, ta1, rij, erfc, e_elec); + int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], + TypeIndices_[atom1.Idx()]); + if (nbindex > -1) { + double vswitch = ljswitch.switch_fn(rij2); + NonbondType const& LJ = NB_->NBarray()[ nbindex ]; + double r2 = 1.0 / rij2; + double r6 = r2 * r2 * r2; + double r12 = r6 * r6; + double f12 = LJ.A() * r12; // A/r^12 + double f6 = LJ.B() * r6; // B/r^6 + double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + Evdw += (e_vdw * vswitch); + //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); + } + } + private: + double ERFC(double xIn) const { + return table_.Yval( xIn); + } + + T q0_; ///< Charge on atom 0 + T q1_; ///< Charge on atom 1 + + SplineFxnTable table_; ///< Hold spline interpolation for erfc + std::vector Charge_; ///< Array of charges + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + Kernel_LJswitch ljswitch_; ///< LJ switching function +}; +#endif diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h new file mode 100644 index 0000000000..4b3a82deb6 --- /dev/null +++ b/src/PairListTemplate.h @@ -0,0 +1,113 @@ +#ifndef INC_PAIRLISTTEMPLATE_H +#define INC_PAIRLISTTEMPLATE_H +#include "PairList.h" +#include "ExclusionArray.h" +namespace Cpptraj { +/// Template for doing pair list calculations +template class EngineClass> +void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double cut2, + EngineClass& engine) +{ + int cidx; + + for (cidx = 0; cidx < PL.NGridMax(); cidx++) + { + PairList::CellType const& thisCell = PL.Cell( cidx ); + if (thisCell.NatomsInGrid() > 0) + { + // cellList contains this cell index and all neighbors. + PairList::Iarray const& cellList = thisCell.CellList(); + // transList contains index to translation for the neighbor. + PairList::Iarray const& transList = thisCell.TransList(); + // Loop over all atoms of thisCell. + for (PairList::CellType::const_iterator it0 = thisCell.begin(); + it0 != thisCell.end(); ++it0) + { + engine.SetupAtom0( *it0 ); + Vec3 const& xyz0 = it0->ImageCoords(); + //double q0 = Charge_[it0->Idx()]; +# ifdef DEBUG_PAIRLIST + mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); +# endif + // Exclusion list for this atom + ExclusionArray::ExListType const& excluded = Excluded[it0->Idx()]; + // Calc interaction of atom to all other atoms in thisCell. + for (PairList::CellType::const_iterator it1 = it0 + 1; + it1 != thisCell.end(); ++it1) + { + engine.SetupAtom1( *it1 ); + Vec3 const& xyz1 = it1->ImageCoords(); + //double q1 = Charge_[it1->Idx()]; + Vec3 dxyz = xyz1 - xyz0; + double rij2 = dxyz.Magnitude2(); +# ifdef DEBUG_PAIRLIST + mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + // If atom excluded, calc adjustment, otherwise calc elec. energy. + if (excluded.find( it1->Idx() ) == excluded.end()) + { + + if ( rij2 < cut2 ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif + engine.CutoffSatisfied(rij2, *it0, *it1); + } + } else { +# include "EnergyKernel_Adjust.h" + } + } // END loop over other atoms in thisCell + // Loop over all neighbor cells + for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) + { + PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); +# endif + // Translate vector for neighbor cell + Vec3 const& tVec = PL.TransVec( transList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); +# endif + //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); + // Loop over every atom in nbrCell + for (PairList::CellType::const_iterator it1 = nbrCell.begin(); + it1 != nbrCell.end(); ++it1) + { + Vec3 const& xyz1 = it1->ImageCoords(); + double q1 = Charge_[it1->Idx()]; + Vec3 dxyz = xyz1 + tVec - xyz0; + double rij2 = dxyz.Magnitude2(); + //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); +# ifdef DEBUG_PAIRLIST + mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + //mprintf("\t\tNbrAtom %06i\n",atnum1); + // If atom excluded, calc adjustment, otherwise calc elec. energy. + // TODO Is there better way of checking this? + if (excluded.find( it1->Idx() ) == excluded.end()) + { + + //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); + if ( rij2 < cut2 ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif +# include "EnergyKernel_Nonbond.h" + } + } else { +# include "EnergyKernel_Adjust.h" + } + } // END loop over neighbor cell atoms + } // END Loop over neighbor cells + } // Loop over thisCell atoms + } // END if thisCell is not empty + } // Loop over cells +} // END PairListTemplate +#endif From 31c3e9e68351fad775647aa7aec4de533bd13dfb Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 17 Sep 2024 10:52:41 -0400 Subject: [PATCH 024/218] Add wrapper around Erfc --- src/ErfcFxn.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++ src/ErfcFxn.h | 21 +++++++++++++++ src/cpptrajdepend | 1 + src/cpptrajfiles | 1 + 4 files changed, 92 insertions(+) create mode 100644 src/ErfcFxn.cpp create mode 100644 src/ErfcFxn.h diff --git a/src/ErfcFxn.cpp b/src/ErfcFxn.cpp new file mode 100644 index 0000000000..8ea7ec7509 --- /dev/null +++ b/src/ErfcFxn.cpp @@ -0,0 +1,69 @@ +#include "ErfcFxn.h" +#include "CpptrajStdio.h" +#include + +static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } + +/** Complimentary error function: 2/sqrt(PI) * SUM[exp(-t^2)*dt] + * Original code: SANDER: erfcfun.F90 + */ +double ErfcFxn::erfc_func(double xIn) { + double erfc; + double absx = DABS( xIn ); + + if (xIn > 26.0) + erfc = 0.0; + else if (xIn < -5.5) + erfc = 2.0; + else if (absx <= 0.5) { + double cval = xIn * xIn; + double pval = ((-0.356098437018154E-1*cval+0.699638348861914E1)*cval + 0.219792616182942E2) * + cval + 0.242667955230532E3; + double qval = ((cval+0.150827976304078E2)*cval+0.911649054045149E2)*cval + 0.215058875869861E3; + double erf = xIn * pval/qval; + erfc = 1.0 - erf; + } else if (absx < 4.0) { + double cval = absx; + double pval=((((((-0.136864857382717E-6*cval+0.564195517478974)*cval+ + 0.721175825088309E1)*cval+0.431622272220567E2)*cval+ + 0.152989285046940E3)*cval+0.339320816734344E3)*cval+ + 0.451918953711873E3)*cval+0.300459261020162E3; + double qval=((((((cval+0.127827273196294E2)*cval+0.770001529352295E2)*cval+ + 0.277585444743988E3)*cval+0.638980264465631E3)*cval+ + 0.931354094850610E3)*cval+0.790950925327898E3)*cval+ + 0.300459260956983E3; + double nonexperfc; + if ( xIn > 0.0 ) + nonexperfc = pval/qval; + else + nonexperfc = 2.0*exp(xIn*xIn) - pval/qval; + erfc = exp(-absx*absx)*nonexperfc; + } else { + double cval = 1.0/(xIn*xIn); + double pval = (((0.223192459734185E-1*cval+0.278661308609648)*cval+ + 0.226956593539687)*cval+0.494730910623251E-1)*cval+ + 0.299610707703542E-2; + double qval = (((cval+0.198733201817135E1)*cval+0.105167510706793E1)*cval+ + 0.191308926107830)*cval+0.106209230528468E-1; + cval = (-cval*pval/qval + 0.564189583547756)/absx; + double nonexperfc; + if ( xIn > 0.0 ) + nonexperfc = cval; + else + nonexperfc = 2.0*exp(xIn*xIn) - cval; + erfc = exp(-absx*absx)*nonexperfc; + } + return erfc; +} + +/** Fill table with values. */ +int ErfcFxn::FillErfcTable( double erfcTableDx, double beg, double end ) +{ + if (table_.FillTable( erfc_func, erfcTableDx, beg, end )) { + mprinterr("Error: Could not set up spline table for ERFC\n"); + return 1; + } + table_.PrintMemUsage("\t"); + table_.PrintTableInfo("\t"); + return 0; +} diff --git a/src/ErfcFxn.h b/src/ErfcFxn.h new file mode 100644 index 0000000000..da09f024df --- /dev/null +++ b/src/ErfcFxn.h @@ -0,0 +1,21 @@ +#ifndef INC_ERFCFXN_H +#define INC_ERFCFXN_H +#include "SplineFxnTable.h" +/// Complimentary error function +class ErfcFxn { + public: + ErfcFxn() {} + /// Fill table with ERFC values using given spacing, begin, and end + int FillErfcTable(double, double, double); + /// \return Interpolated erfc value + double ERFC(double xIn) const { + return table_.Yval( xIn); + } + + private: + /// ERFC function from sander + static double erfc_func(double); + + SplineFxnTable table_; +}; +#endif diff --git a/src/cpptrajdepend b/src/cpptrajdepend index a47ea37562..dadb7125a1 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -287,6 +287,7 @@ EnsembleOut.o : EnsembleOut.cpp ActionFrameCounter.h BaseIOtype.h Box.h Coordina EnsembleOutList.o : EnsembleOutList.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOutList.h EnsembleOut_Multi.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Multi.o : EnsembleOut_Multi.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Multi.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Single.o : EnsembleOut_Single.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h +ErfcFxn.o : ErfcFxn.cpp CpptrajStdio.h ErfcFxn.h SplineFxnTable.h Ewald.o : Ewald.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h Ewald.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListLoop.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h StringRoutines.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EwaldOptions.o : EwaldOptions.cpp ArgList.h CpptrajStdio.h EwaldOptions.h Ewald_ParticleMesh.o : Ewald_ParticleMesh.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index bdb04fd255..fd3d904b33 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -256,6 +256,7 @@ COMMON_SOURCES= \ EnsembleOut_Multi.cpp \ EnsembleOut_Single.cpp \ EnsembleOutList.cpp \ + ErfcFxn.cpp \ Ewald.cpp \ Ewald_ParticleMesh.cpp \ Ewald_Regular.cpp \ From 96556d87eb8428708f5245183c90f6ab0294061a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 17 Sep 2024 14:25:17 -0400 Subject: [PATCH 025/218] Add Ewald adjust kernel --- src/Kernel_EwaldAdjust.h | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/Kernel_EwaldAdjust.h diff --git a/src/Kernel_EwaldAdjust.h b/src/Kernel_EwaldAdjust.h new file mode 100644 index 0000000000..2d1a52248b --- /dev/null +++ b/src/Kernel_EwaldAdjust.h @@ -0,0 +1,11 @@ +#ifndef INC_KERNEL_EWALDADJUST_H +#define INC_KERNEL_EWALDADJUST_H +// NOTE: ERFC is not const so that timing data can be obtained +template T Kernel_EwaldAdjust(T const& q0, T const& q1, T const& rij, + T const& ew_coeff, ErfcFxn& ERFC) +{ + T erfc = ERFC.ERFC(ew_coeff * rij); + T d0 = (erfc - 1.0) / rij; + return (q0 * q1 * d0); +} +#endif From 1cc44dd461c00f3d13a0d0eeec68fbf5b64bf063 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 17 Sep 2024 14:26:42 -0400 Subject: [PATCH 026/218] Finish initial incarnation of the Ewald pairlist nonbond kernel. Make ERFC non-const and put timing tracking directly into ErfcFxn --- src/ErfcFxn.h | 12 +++++-- src/PairListEngine_Nonbond.h | 61 +++++++++++++++++------------------- src/PairListTemplate.h | 13 +++++--- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/ErfcFxn.h b/src/ErfcFxn.h index da09f024df..7e1501c22b 100644 --- a/src/ErfcFxn.h +++ b/src/ErfcFxn.h @@ -1,6 +1,7 @@ #ifndef INC_ERFCFXN_H #define INC_ERFCFXN_H #include "SplineFxnTable.h" +#include "Timer.h" /// Complimentary error function class ErfcFxn { public: @@ -8,14 +9,21 @@ class ErfcFxn { /// Fill table with ERFC values using given spacing, begin, and end int FillErfcTable(double, double, double); /// \return Interpolated erfc value - double ERFC(double xIn) const { + double ERFC(double xIn) { +# ifdef _OPENMP return table_.Yval( xIn); +# else + t_erfc_.Start(); + double erfcval = table_.Yval(xIn); + t_erfc_.Stop(); + return erfcval; +# endif } - private: /// ERFC function from sander static double erfc_func(double); SplineFxnTable table_; + Timer t_erfc_; ///< For recording how much time is spent doing erfc lookup }; #endif diff --git a/src/PairListEngine_Nonbond.h b/src/PairListEngine_Nonbond.h index 8efe965b78..236166790f 100644 --- a/src/PairListEngine_Nonbond.h +++ b/src/PairListEngine_Nonbond.h @@ -1,15 +1,19 @@ #ifndef INC_PAIRLISTENGINE_NONBOND_H #define INC_PAIRLISTENGINE_NONBOND_H +#include "Energy/Ene_LJ_6_12.h" +#include "ErfcFxn.h" +#include "Kernel_EwaldAdjust.h" #include "Kernel_LJswitch.h" #include "PairList.h" #include "ParameterTypes.h" -#include "SplineFxnTable.h" #include +namespace Cpptraj { +/// Nonbond calculation for pairlist with Ewald and VDW LR correction template class PairListEngine_Nonbond { typedef std::vector Iarray; public: - PairListEngine_Nonbond() {} + PairListEngine_Nonbond() : NB_(0) {} /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { q0_ = Charge_[atom0.Idx()]; @@ -18,6 +22,8 @@ class PairListEngine_Nonbond { void SetupAtom1( PairList::AtmType const& atom1 ) { q1_ = Charge_[atom1.Idx()]; } + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } /// Call when cutoff is satisfied void CutoffSatisfied(T const& rij2, PairList::AtmType const& atom0, @@ -25,51 +31,42 @@ class PairListEngine_Nonbond { { double rij = sqrt( rij2 ); double qiqj = q0_ * q1_; -# ifndef _OPENMP - t_erfc_.Start(); -# endif //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(ew_coeff_ * rij); -# ifndef _OPENMP - t_erfc_.Stop(); -# endif + double erfc = erfc_.ERFC(ew_coeff_ * rij); double e_elec = qiqj * erfc / rij; - Eelec += e_elec; - //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", - //int ta0, ta1; - //if (it0->Idx() < it1->Idx()) { - // ta0=it0->Idx(); ta1=it1->Idx(); - //} else { - // ta1=it0->Idx(); ta0=it1->Idx(); - //} - //mprintf("PELEC %6i%6i%12.5f%12.5f%12.5f\n", ta0, ta1, rij, erfc, e_elec); + Eelec_ += e_elec; + int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], TypeIndices_[atom1.Idx()]); if (nbindex > -1) { - double vswitch = ljswitch.switch_fn(rij2); + double vswitch = ljswitch_.switch_fn(rij2); NonbondType const& LJ = NB_->NBarray()[ nbindex ]; - double r2 = 1.0 / rij2; - double r6 = r2 * r2 * r2; - double r12 = r6 * r6; - double f12 = LJ.A() * r12; // A/r^12 - double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) - Evdw += (e_vdw * vswitch); - //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); + T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); + Evdw_ += (e_vdw * vswitch); } } - private: - double ERFC(double xIn) const { - return table_.Yval( xIn); + /// Call when cutoff is not satisfied + void CutoffNotSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + Eadjust_ += Kernel_EwaldAdjust( q0_, q1_, sqrt(rij2), ew_coeff_, erfc_ ); } - + private: + T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 + T Evdw_; ///< VDW sum for current frame + T Eelec_; ///< Coulomb sum for current frame + T Eadjust_; ///< Adjust energy sum for current frame + + T ew_coeff_; ///< Ewald coefficient - SplineFxnTable table_; ///< Hold spline interpolation for erfc + ErfcFxn erfc_; ///< Hold spline interpolation for erfc std::vector Charge_; ///< Array of charges Iarray TypeIndices_; ///< Hold atom type indices for selected atoms NonbondParmType const* NB_; ///< Pointer to nonbonded parameters Kernel_LJswitch ljswitch_; ///< LJ switching function }; +} // END namespace Cpptraj #endif diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h index 4b3a82deb6..eecdff5e65 100644 --- a/src/PairListTemplate.h +++ b/src/PairListTemplate.h @@ -8,6 +8,8 @@ template class EngineClass> void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double cut2, EngineClass& engine) { + engine.FrameBeginCalc(); + int cidx; for (cidx = 0; cidx < PL.NGridMax(); cidx++) @@ -46,7 +48,6 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double // If atom excluded, calc adjustment, otherwise calc elec. energy. if (excluded.find( it1->Idx() ) == excluded.end()) { - if ( rij2 < cut2 ) { # ifdef NBDBG if (it0->Idx() < it1->Idx()) @@ -57,7 +58,7 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double engine.CutoffSatisfied(rij2, *it0, *it1); } } else { -# include "EnergyKernel_Adjust.h" + engine.CutoffNotSatisfied(rij2, *it0, *it1); } } // END loop over other atoms in thisCell // Loop over all neighbor cells @@ -77,8 +78,9 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double for (PairList::CellType::const_iterator it1 = nbrCell.begin(); it1 != nbrCell.end(); ++it1) { + engine.SetupAtom1( *it1 ); Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; + //double q1 = Charge_[it1->Idx()]; Vec3 dxyz = xyz1 + tVec - xyz0; double rij2 = dxyz.Magnitude2(); //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); @@ -99,10 +101,10 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double else mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); # endif -# include "EnergyKernel_Nonbond.h" + engine.CutoffSatisfied(rij2, *it0, *it1); } } else { -# include "EnergyKernel_Adjust.h" + engine.CutoffNotSatisfied(rij2, *it0, *it1); } } // END loop over neighbor cell atoms } // END Loop over neighbor cells @@ -110,4 +112,5 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double } // END if thisCell is not empty } // Loop over cells } // END PairListTemplate +} // END namespace Cpptraj #endif From e2a5b5267622aca7f60153c5bacf7b941a0a4b26 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 08:18:32 -0400 Subject: [PATCH 027/218] Some cleanup --- src/PairListEngine_Nonbond.h | 12 +++++------- src/PairListTemplate.h | 9 +++------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/PairListEngine_Nonbond.h b/src/PairListEngine_Nonbond.h index 236166790f..083fe5c72c 100644 --- a/src/PairListEngine_Nonbond.h +++ b/src/PairListEngine_Nonbond.h @@ -53,19 +53,17 @@ class PairListEngine_Nonbond { Eadjust_ += Kernel_EwaldAdjust( q0_, q1_, sqrt(rij2), ew_coeff_, erfc_ ); } private: - T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 T Evdw_; ///< VDW sum for current frame T Eelec_; ///< Coulomb sum for current frame T Eadjust_; ///< Adjust energy sum for current frame - T ew_coeff_; ///< Ewald coefficient - - ErfcFxn erfc_; ///< Hold spline interpolation for erfc - std::vector Charge_; ///< Array of charges - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + T ew_coeff_; ///< Ewald coefficient + ErfcFxn erfc_; ///< Hold spline interpolation for erfc + std::vector Charge_; ///< Array of charges + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters Kernel_LJswitch ljswitch_; ///< LJ switching function }; } // END namespace Cpptraj diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h index eecdff5e65..31571ec423 100644 --- a/src/PairListTemplate.h +++ b/src/PairListTemplate.h @@ -5,7 +5,7 @@ namespace Cpptraj { /// Template for doing pair list calculations template class EngineClass> -void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double cut2, +void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2, EngineClass& engine) { engine.FrameBeginCalc(); @@ -27,7 +27,6 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double { engine.SetupAtom0( *it0 ); Vec3 const& xyz0 = it0->ImageCoords(); - //double q0 = Charge_[it0->Idx()]; # ifdef DEBUG_PAIRLIST mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); # endif @@ -39,9 +38,8 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double { engine.SetupAtom1( *it1 ); Vec3 const& xyz1 = it1->ImageCoords(); - //double q1 = Charge_[it1->Idx()]; Vec3 dxyz = xyz1 - xyz0; - double rij2 = dxyz.Magnitude2(); + T rij2 = dxyz.Magnitude2(); # ifdef DEBUG_PAIRLIST mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); # endif @@ -80,9 +78,8 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, double { engine.SetupAtom1( *it1 ); Vec3 const& xyz1 = it1->ImageCoords(); - //double q1 = Charge_[it1->Idx()]; Vec3 dxyz = xyz1 + tVec - xyz0; - double rij2 = dxyz.Magnitude2(); + T rij2 = dxyz.Magnitude2(); //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); # ifdef DEBUG_PAIRLIST mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); From b540bb2bd62f9a86ffb67095d9a8d3916e0e7823 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 08:21:31 -0400 Subject: [PATCH 028/218] Add code comments --- src/PairListEngine_Nonbond.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PairListEngine_Nonbond.h b/src/PairListEngine_Nonbond.h index 083fe5c72c..378a3c827e 100644 --- a/src/PairListEngine_Nonbond.h +++ b/src/PairListEngine_Nonbond.h @@ -14,6 +14,7 @@ class PairListEngine_Nonbond { typedef std::vector Iarray; public: PairListEngine_Nonbond() : NB_(0) {} + // ------------------------------------------- /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { q0_ = Charge_[atom0.Idx()]; @@ -52,6 +53,7 @@ class PairListEngine_Nonbond { { Eadjust_ += Kernel_EwaldAdjust( q0_, q1_, sqrt(rij2), ew_coeff_, erfc_ ); } + // ------------------------------------------- private: T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 From 52b94da8eff77a00e5b67bada139af54d9858ce4 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 08:23:38 -0400 Subject: [PATCH 029/218] Change name --- src/{PairListEngine_Nonbond.h => PairListEngine_Ewald_LJLR.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{PairListEngine_Nonbond.h => PairListEngine_Ewald_LJLR.h} (100%) diff --git a/src/PairListEngine_Nonbond.h b/src/PairListEngine_Ewald_LJLR.h similarity index 100% rename from src/PairListEngine_Nonbond.h rename to src/PairListEngine_Ewald_LJLR.h From baeb4842377a4234c5d039a90f148a380df9338a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 08:25:36 -0400 Subject: [PATCH 030/218] Change class name --- src/PairListEngine_Ewald_LJLR.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 378a3c827e..1e00269121 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -1,5 +1,5 @@ -#ifndef INC_PAIRLISTENGINE_NONBOND_H -#define INC_PAIRLISTENGINE_NONBOND_H +#ifndef INC_PAIRLISTENGINE_EWALD_LJLR_H +#define INC_PAIRLISTENGINE_EWALD_LJLR_H #include "Energy/Ene_LJ_6_12.h" #include "ErfcFxn.h" #include "Kernel_EwaldAdjust.h" @@ -8,12 +8,12 @@ #include "ParameterTypes.h" #include namespace Cpptraj { -/// Nonbond calculation for pairlist with Ewald and VDW LR correction +/// Direct space nonbond calculation using pairlist with Ewald and VDW LR correction template -class PairListEngine_Nonbond { +class PairListEngine_Ewald_LJLR { typedef std::vector Iarray; public: - PairListEngine_Nonbond() : NB_(0) {} + PairListEngine_Ewald_LJLR() : NB_(0) {} // ------------------------------------------- /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { From a3af47eb86079e4c202cda1f47e2d98f47b53241 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 08:59:28 -0400 Subject: [PATCH 031/218] Reorder --- src/PairListEngine_Ewald_LJLR.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 1e00269121..36701f95d0 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -15,6 +15,8 @@ class PairListEngine_Ewald_LJLR { public: PairListEngine_Ewald_LJLR() : NB_(0) {} // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { q0_ = Charge_[atom0.Idx()]; @@ -23,8 +25,6 @@ class PairListEngine_Ewald_LJLR { void SetupAtom1( PairList::AtmType const& atom1 ) { q1_ = Charge_[atom1.Idx()]; } - /// Call at the beginning of the frame calculation - void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } /// Call when cutoff is satisfied void CutoffSatisfied(T const& rij2, PairList::AtmType const& atom0, From e00caf11ed60e58d5c39b308bf149bb9e6156572 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 09:23:46 -0400 Subject: [PATCH 032/218] Try as a separate class --- src/PairListEngine.h | 25 +++++++++++++++++++++ src/PairListEngine_Ewald.h | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/PairListEngine.h create mode 100644 src/PairListEngine_Ewald.h diff --git a/src/PairListEngine.h b/src/PairListEngine.h new file mode 100644 index 0000000000..092f6e6c4d --- /dev/null +++ b/src/PairListEngine.h @@ -0,0 +1,25 @@ +#ifndef INC_PAIRLISTENGINE_H +#define INC_PAIRLISTENGINE_H +#include "PairList.h" +class Topology; +class AtomMask; +namespace Cpptraj { +class EngineOpts; +/// Abstract base class for Pairlist engines +class PairListEngine { + public: + PairListEngine() {} + // Virtual since inherited + virtual ~PairListEngine() {} + + virtual int InitEngine(Box const&, EngineOpts const&, int) = 0; + virtual int SetupEngine(Topology const&, AtomMask const&) = 0; + + virtual void FrameBeginCalc() = 0; + virtual void SetupAtom0(PairList::AtmType const&) = 0; + virtual void SetupAtom1(PairList::AtmType const&) = 0; + virtual void CutoffSatisfied(double, PairList::AtmType const&, PairList::AtmType const&) = 0; + virtual void CutoffNotSatisfied(double, PairList::AtmType const&, PairList::AtmType const&) = 0; +}; +} +#endif diff --git a/src/PairListEngine_Ewald.h b/src/PairListEngine_Ewald.h new file mode 100644 index 0000000000..5e417fe357 --- /dev/null +++ b/src/PairListEngine_Ewald.h @@ -0,0 +1,45 @@ +#ifndef INC_PAIRLISTENGINE_EWALD_H +#define INC_PAIRLISTENGINE_EWALD_H +#include "ErfcFxn.h" +#include "Kernel_LJswitch.h" +#include "PairList.h" +#include +class NonbondParmType; +namespace Cpptraj { +/// Base class for direct space nonbond calculation using pairlist with Ewald +class PairListEngine_Ewald : public PairListEngine { + typedef std::vector Iarray; + public: + PairListEngine_Ewald() : NB_(0) {} + // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = Charge_[atom0.Idx()]; + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = Charge_[atom1.Idx()]; + } + // ------------------------------------------- + int CheckInput(Box const&, int, double, double, + double, double, double, + double, double); + + private: + double q0_; ///< Charge on atom 0 + double q1_; ///< Charge on atom 1 + double Evdw_; ///< VDW sum for current frame + double Eelec_; ///< Coulomb sum for current frame + double Eadjust_; ///< Adjust energy sum for current frame + + double ew_coeff_; ///< Ewald coefficient + ErfcFxn erfc_; ///< Hold spline interpolation for erfc + std::vector Charge_; ///< Array of charges + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + Kernel_LJswitch ljswitch_; ///< LJ switching function +}; +} // END namespace Cpptraj +#endif From 623f4945a0ae5b308508f033aff9008e0f7b9c56 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 09:24:34 -0400 Subject: [PATCH 033/218] Remove for now --- src/PairListEngine.h | 25 --------------------- src/PairListEngine_Ewald.h | 45 -------------------------------------- 2 files changed, 70 deletions(-) delete mode 100644 src/PairListEngine.h delete mode 100644 src/PairListEngine_Ewald.h diff --git a/src/PairListEngine.h b/src/PairListEngine.h deleted file mode 100644 index 092f6e6c4d..0000000000 --- a/src/PairListEngine.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef INC_PAIRLISTENGINE_H -#define INC_PAIRLISTENGINE_H -#include "PairList.h" -class Topology; -class AtomMask; -namespace Cpptraj { -class EngineOpts; -/// Abstract base class for Pairlist engines -class PairListEngine { - public: - PairListEngine() {} - // Virtual since inherited - virtual ~PairListEngine() {} - - virtual int InitEngine(Box const&, EngineOpts const&, int) = 0; - virtual int SetupEngine(Topology const&, AtomMask const&) = 0; - - virtual void FrameBeginCalc() = 0; - virtual void SetupAtom0(PairList::AtmType const&) = 0; - virtual void SetupAtom1(PairList::AtmType const&) = 0; - virtual void CutoffSatisfied(double, PairList::AtmType const&, PairList::AtmType const&) = 0; - virtual void CutoffNotSatisfied(double, PairList::AtmType const&, PairList::AtmType const&) = 0; -}; -} -#endif diff --git a/src/PairListEngine_Ewald.h b/src/PairListEngine_Ewald.h deleted file mode 100644 index 5e417fe357..0000000000 --- a/src/PairListEngine_Ewald.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef INC_PAIRLISTENGINE_EWALD_H -#define INC_PAIRLISTENGINE_EWALD_H -#include "ErfcFxn.h" -#include "Kernel_LJswitch.h" -#include "PairList.h" -#include -class NonbondParmType; -namespace Cpptraj { -/// Base class for direct space nonbond calculation using pairlist with Ewald -class PairListEngine_Ewald : public PairListEngine { - typedef std::vector Iarray; - public: - PairListEngine_Ewald() : NB_(0) {} - // ------------------------------------------- - /// Call at the beginning of the frame calculation - void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } - /// Call for atom 0 when looping over atoms of thisCell - void SetupAtom0( PairList::AtmType const& atom0 ) { - q0_ = Charge_[atom0.Idx()]; - } - /// Call for atom 1 when looping over interaction atoms of this/other cell - void SetupAtom1( PairList::AtmType const& atom1 ) { - q1_ = Charge_[atom1.Idx()]; - } - // ------------------------------------------- - int CheckInput(Box const&, int, double, double, - double, double, double, - double, double); - - private: - double q0_; ///< Charge on atom 0 - double q1_; ///< Charge on atom 1 - double Evdw_; ///< VDW sum for current frame - double Eelec_; ///< Coulomb sum for current frame - double Eadjust_; ///< Adjust energy sum for current frame - - double ew_coeff_; ///< Ewald coefficient - ErfcFxn erfc_; ///< Hold spline interpolation for erfc - std::vector Charge_; ///< Array of charges - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - Kernel_LJswitch ljswitch_; ///< LJ switching function -}; -} // END namespace Cpptraj -#endif From 2cb1d5335aa33d4b0d023be8752bfa84ca5bb913 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 09:28:22 -0400 Subject: [PATCH 034/218] Rename --- src/{Kernel_LJswitch.h => LJswitch.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{Kernel_LJswitch.h => LJswitch.h} (100%) diff --git a/src/Kernel_LJswitch.h b/src/LJswitch.h similarity index 100% rename from src/Kernel_LJswitch.h rename to src/LJswitch.h From 91893e05fdc559adc7e18c226da080adb0cf587f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 09:28:28 -0400 Subject: [PATCH 035/218] Finish renaming --- src/LJswitch.h | 8 ++++---- src/PairListEngine_Ewald_LJLR.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/LJswitch.h b/src/LJswitch.h index 016492f829..984ae0b24f 100644 --- a/src/LJswitch.h +++ b/src/LJswitch.h @@ -1,10 +1,10 @@ -#ifndef INC_KERNEL_LJSWITCH_H -#define INC_KERNEL_LJSWITCH_H +#ifndef INC_LJSWITCH_H +#define INC_LJSWITCH_H /** Switching function for Lennard-Jones. */ -template class Kernel_LJswitch { +template class LJswitch { public: /// CONSTRUCTOR - Kernel_LJswitch() : cut2_0_(0), cut2_1_(0) {} + LJswitch() : cut2_0_(0), cut2_1_(0) {} /// Setup void setup_switch(T const& cut2_0in, T const& cut2_1in) { cut2_0_ = cut2_0in; diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 36701f95d0..73aa862310 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -3,7 +3,7 @@ #include "Energy/Ene_LJ_6_12.h" #include "ErfcFxn.h" #include "Kernel_EwaldAdjust.h" -#include "Kernel_LJswitch.h" +#include "LJswitch.h" #include "PairList.h" #include "ParameterTypes.h" #include @@ -66,7 +66,7 @@ class PairListEngine_Ewald_LJLR { std::vector Charge_; ///< Array of charges Iarray TypeIndices_; ///< Hold atom type indices for selected atoms NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - Kernel_LJswitch ljswitch_; ///< LJ switching function + LJswitch ljswitch_; ///< LJ switching function }; } // END namespace Cpptraj #endif From 43eaf885ef4bff51a03474c10d27f992f72a16f2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 10:37:57 -0400 Subject: [PATCH 036/218] Remove unneeded depend. --- src/Energy/Ene_LJ_6_12.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Energy/Ene_LJ_6_12.h b/src/Energy/Ene_LJ_6_12.h index 6b00334960..a8bd1d31b4 100644 --- a/src/Energy/Ene_LJ_6_12.h +++ b/src/Energy/Ene_LJ_6_12.h @@ -1,6 +1,5 @@ #ifndef INC_ENERGY_ENE_LJ_6_12_H #define INC_ENERGY_ENE_LJ_6_12_H -#include "Kernel_Harmonic.h" namespace Cpptraj { namespace Energy { /// \return LJ 6-12 energy From 5535ef01806d5a86af77c7230dda11eaab38b2e1 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 10:45:40 -0400 Subject: [PATCH 037/218] Rip out the new framework. Its really not at all ready for further development until i come up with a plan --- src/ErfcFxn.cpp | 69 ------------------- src/ErfcFxn.h | 29 -------- src/Kernel_EwaldAdjust.h | 11 ---- src/LJswitch.h | 30 --------- src/PairListEngine_Ewald_LJLR.h | 72 -------------------- src/PairListTemplate.h | 113 -------------------------------- src/cpptrajdepend | 1 - src/cpptrajfiles | 1 - 8 files changed, 326 deletions(-) delete mode 100644 src/ErfcFxn.cpp delete mode 100644 src/ErfcFxn.h delete mode 100644 src/Kernel_EwaldAdjust.h delete mode 100644 src/LJswitch.h delete mode 100644 src/PairListEngine_Ewald_LJLR.h delete mode 100644 src/PairListTemplate.h diff --git a/src/ErfcFxn.cpp b/src/ErfcFxn.cpp deleted file mode 100644 index 8ea7ec7509..0000000000 --- a/src/ErfcFxn.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "ErfcFxn.h" -#include "CpptrajStdio.h" -#include - -static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } - -/** Complimentary error function: 2/sqrt(PI) * SUM[exp(-t^2)*dt] - * Original code: SANDER: erfcfun.F90 - */ -double ErfcFxn::erfc_func(double xIn) { - double erfc; - double absx = DABS( xIn ); - - if (xIn > 26.0) - erfc = 0.0; - else if (xIn < -5.5) - erfc = 2.0; - else if (absx <= 0.5) { - double cval = xIn * xIn; - double pval = ((-0.356098437018154E-1*cval+0.699638348861914E1)*cval + 0.219792616182942E2) * - cval + 0.242667955230532E3; - double qval = ((cval+0.150827976304078E2)*cval+0.911649054045149E2)*cval + 0.215058875869861E3; - double erf = xIn * pval/qval; - erfc = 1.0 - erf; - } else if (absx < 4.0) { - double cval = absx; - double pval=((((((-0.136864857382717E-6*cval+0.564195517478974)*cval+ - 0.721175825088309E1)*cval+0.431622272220567E2)*cval+ - 0.152989285046940E3)*cval+0.339320816734344E3)*cval+ - 0.451918953711873E3)*cval+0.300459261020162E3; - double qval=((((((cval+0.127827273196294E2)*cval+0.770001529352295E2)*cval+ - 0.277585444743988E3)*cval+0.638980264465631E3)*cval+ - 0.931354094850610E3)*cval+0.790950925327898E3)*cval+ - 0.300459260956983E3; - double nonexperfc; - if ( xIn > 0.0 ) - nonexperfc = pval/qval; - else - nonexperfc = 2.0*exp(xIn*xIn) - pval/qval; - erfc = exp(-absx*absx)*nonexperfc; - } else { - double cval = 1.0/(xIn*xIn); - double pval = (((0.223192459734185E-1*cval+0.278661308609648)*cval+ - 0.226956593539687)*cval+0.494730910623251E-1)*cval+ - 0.299610707703542E-2; - double qval = (((cval+0.198733201817135E1)*cval+0.105167510706793E1)*cval+ - 0.191308926107830)*cval+0.106209230528468E-1; - cval = (-cval*pval/qval + 0.564189583547756)/absx; - double nonexperfc; - if ( xIn > 0.0 ) - nonexperfc = cval; - else - nonexperfc = 2.0*exp(xIn*xIn) - cval; - erfc = exp(-absx*absx)*nonexperfc; - } - return erfc; -} - -/** Fill table with values. */ -int ErfcFxn::FillErfcTable( double erfcTableDx, double beg, double end ) -{ - if (table_.FillTable( erfc_func, erfcTableDx, beg, end )) { - mprinterr("Error: Could not set up spline table for ERFC\n"); - return 1; - } - table_.PrintMemUsage("\t"); - table_.PrintTableInfo("\t"); - return 0; -} diff --git a/src/ErfcFxn.h b/src/ErfcFxn.h deleted file mode 100644 index 7e1501c22b..0000000000 --- a/src/ErfcFxn.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef INC_ERFCFXN_H -#define INC_ERFCFXN_H -#include "SplineFxnTable.h" -#include "Timer.h" -/// Complimentary error function -class ErfcFxn { - public: - ErfcFxn() {} - /// Fill table with ERFC values using given spacing, begin, and end - int FillErfcTable(double, double, double); - /// \return Interpolated erfc value - double ERFC(double xIn) { -# ifdef _OPENMP - return table_.Yval( xIn); -# else - t_erfc_.Start(); - double erfcval = table_.Yval(xIn); - t_erfc_.Stop(); - return erfcval; -# endif - } - private: - /// ERFC function from sander - static double erfc_func(double); - - SplineFxnTable table_; - Timer t_erfc_; ///< For recording how much time is spent doing erfc lookup -}; -#endif diff --git a/src/Kernel_EwaldAdjust.h b/src/Kernel_EwaldAdjust.h deleted file mode 100644 index 2d1a52248b..0000000000 --- a/src/Kernel_EwaldAdjust.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef INC_KERNEL_EWALDADJUST_H -#define INC_KERNEL_EWALDADJUST_H -// NOTE: ERFC is not const so that timing data can be obtained -template T Kernel_EwaldAdjust(T const& q0, T const& q1, T const& rij, - T const& ew_coeff, ErfcFxn& ERFC) -{ - T erfc = ERFC.ERFC(ew_coeff * rij); - T d0 = (erfc - 1.0) / rij; - return (q0 * q1 * d0); -} -#endif diff --git a/src/LJswitch.h b/src/LJswitch.h deleted file mode 100644 index 984ae0b24f..0000000000 --- a/src/LJswitch.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef INC_LJSWITCH_H -#define INC_LJSWITCH_H -/** Switching function for Lennard-Jones. */ -template class LJswitch { - public: - /// CONSTRUCTOR - LJswitch() : cut2_0_(0), cut2_1_(0) {} - /// Setup - void setup_switch(T const& cut2_0in, T const& cut2_1in) { - cut2_0_ = cut2_0in; - cut2_1_ = cut2_1in; - } - /// Calculate switched value - T switch_fn(T const& rij2) - { - if (rij2 <= cut2_0_) - return 1.0; - else if (rij2 > cut2_1_) - return 0.0; - else { - T xoff_m_x = cut2_1_ - rij2; - T fac = 1.0 / (cut2_1_ - cut2_0_); - return (xoff_m_x*xoff_m_x) * (cut2_1_ + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); - } - } - private: - T cut2_0_; - T cut2_1_; -}; -#endif diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h deleted file mode 100644 index 73aa862310..0000000000 --- a/src/PairListEngine_Ewald_LJLR.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef INC_PAIRLISTENGINE_EWALD_LJLR_H -#define INC_PAIRLISTENGINE_EWALD_LJLR_H -#include "Energy/Ene_LJ_6_12.h" -#include "ErfcFxn.h" -#include "Kernel_EwaldAdjust.h" -#include "LJswitch.h" -#include "PairList.h" -#include "ParameterTypes.h" -#include -namespace Cpptraj { -/// Direct space nonbond calculation using pairlist with Ewald and VDW LR correction -template -class PairListEngine_Ewald_LJLR { - typedef std::vector Iarray; - public: - PairListEngine_Ewald_LJLR() : NB_(0) {} - // ------------------------------------------- - /// Call at the beginning of the frame calculation - void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } - /// Call for atom 0 when looping over atoms of thisCell - void SetupAtom0( PairList::AtmType const& atom0 ) { - q0_ = Charge_[atom0.Idx()]; - } - /// Call for atom 1 when looping over interaction atoms of this/other cell - void SetupAtom1( PairList::AtmType const& atom1 ) { - q1_ = Charge_[atom1.Idx()]; - } - /// Call when cutoff is satisfied - void CutoffSatisfied(T const& rij2, - PairList::AtmType const& atom0, - PairList::AtmType const& atom1) - { - double rij = sqrt( rij2 ); - double qiqj = q0_ * q1_; - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = erfc_.ERFC(ew_coeff_ * rij); - double e_elec = qiqj * erfc / rij; - Eelec_ += e_elec; - - int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], - TypeIndices_[atom1.Idx()]); - if (nbindex > -1) { - double vswitch = ljswitch_.switch_fn(rij2); - NonbondType const& LJ = NB_->NBarray()[ nbindex ]; - T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); - Evdw_ += (e_vdw * vswitch); - } - } - /// Call when cutoff is not satisfied - void CutoffNotSatisfied(T const& rij2, - PairList::AtmType const& atom0, - PairList::AtmType const& atom1) - { - Eadjust_ += Kernel_EwaldAdjust( q0_, q1_, sqrt(rij2), ew_coeff_, erfc_ ); - } - // ------------------------------------------- - private: - T q0_; ///< Charge on atom 0 - T q1_; ///< Charge on atom 1 - T Evdw_; ///< VDW sum for current frame - T Eelec_; ///< Coulomb sum for current frame - T Eadjust_; ///< Adjust energy sum for current frame - - T ew_coeff_; ///< Ewald coefficient - ErfcFxn erfc_; ///< Hold spline interpolation for erfc - std::vector Charge_; ///< Array of charges - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - LJswitch ljswitch_; ///< LJ switching function -}; -} // END namespace Cpptraj -#endif diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h deleted file mode 100644 index 31571ec423..0000000000 --- a/src/PairListTemplate.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef INC_PAIRLISTTEMPLATE_H -#define INC_PAIRLISTTEMPLATE_H -#include "PairList.h" -#include "ExclusionArray.h" -namespace Cpptraj { -/// Template for doing pair list calculations -template class EngineClass> -void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2, - EngineClass& engine) -{ - engine.FrameBeginCalc(); - - int cidx; - - for (cidx = 0; cidx < PL.NGridMax(); cidx++) - { - PairList::CellType const& thisCell = PL.Cell( cidx ); - if (thisCell.NatomsInGrid() > 0) - { - // cellList contains this cell index and all neighbors. - PairList::Iarray const& cellList = thisCell.CellList(); - // transList contains index to translation for the neighbor. - PairList::Iarray const& transList = thisCell.TransList(); - // Loop over all atoms of thisCell. - for (PairList::CellType::const_iterator it0 = thisCell.begin(); - it0 != thisCell.end(); ++it0) - { - engine.SetupAtom0( *it0 ); - Vec3 const& xyz0 = it0->ImageCoords(); -# ifdef DEBUG_PAIRLIST - mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); -# endif - // Exclusion list for this atom - ExclusionArray::ExListType const& excluded = Excluded[it0->Idx()]; - // Calc interaction of atom to all other atoms in thisCell. - for (PairList::CellType::const_iterator it1 = it0 + 1; - it1 != thisCell.end(); ++it1) - { - engine.SetupAtom1( *it1 ); - Vec3 const& xyz1 = it1->ImageCoords(); - Vec3 dxyz = xyz1 - xyz0; - T rij2 = dxyz.Magnitude2(); -# ifdef DEBUG_PAIRLIST - mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - // If atom excluded, calc adjustment, otherwise calc elec. energy. - if (excluded.find( it1->Idx() ) == excluded.end()) - { - if ( rij2 < cut2 ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif - engine.CutoffSatisfied(rij2, *it0, *it1); - } - } else { - engine.CutoffNotSatisfied(rij2, *it0, *it1); - } - } // END loop over other atoms in thisCell - // Loop over all neighbor cells - for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) - { - PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); -# endif - // Translate vector for neighbor cell - Vec3 const& tVec = PL.TransVec( transList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); -# endif - //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); - // Loop over every atom in nbrCell - for (PairList::CellType::const_iterator it1 = nbrCell.begin(); - it1 != nbrCell.end(); ++it1) - { - engine.SetupAtom1( *it1 ); - Vec3 const& xyz1 = it1->ImageCoords(); - Vec3 dxyz = xyz1 + tVec - xyz0; - T rij2 = dxyz.Magnitude2(); - //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); -# ifdef DEBUG_PAIRLIST - mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - //mprintf("\t\tNbrAtom %06i\n",atnum1); - // If atom excluded, calc adjustment, otherwise calc elec. energy. - // TODO Is there better way of checking this? - if (excluded.find( it1->Idx() ) == excluded.end()) - { - - //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); - if ( rij2 < cut2 ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif - engine.CutoffSatisfied(rij2, *it0, *it1); - } - } else { - engine.CutoffNotSatisfied(rij2, *it0, *it1); - } - } // END loop over neighbor cell atoms - } // END Loop over neighbor cells - } // Loop over thisCell atoms - } // END if thisCell is not empty - } // Loop over cells -} // END PairListTemplate -} // END namespace Cpptraj -#endif diff --git a/src/cpptrajdepend b/src/cpptrajdepend index dadb7125a1..a47ea37562 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -287,7 +287,6 @@ EnsembleOut.o : EnsembleOut.cpp ActionFrameCounter.h BaseIOtype.h Box.h Coordina EnsembleOutList.o : EnsembleOutList.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOutList.h EnsembleOut_Multi.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Multi.o : EnsembleOut_Multi.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Multi.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Single.o : EnsembleOut_Single.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h -ErfcFxn.o : ErfcFxn.cpp CpptrajStdio.h ErfcFxn.h SplineFxnTable.h Ewald.o : Ewald.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h Ewald.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListLoop.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h StringRoutines.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EwaldOptions.o : EwaldOptions.cpp ArgList.h CpptrajStdio.h EwaldOptions.h Ewald_ParticleMesh.o : Ewald_ParticleMesh.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index fd3d904b33..bdb04fd255 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -256,7 +256,6 @@ COMMON_SOURCES= \ EnsembleOut_Multi.cpp \ EnsembleOut_Single.cpp \ EnsembleOutList.cpp \ - ErfcFxn.cpp \ Ewald.cpp \ Ewald_ParticleMesh.cpp \ Ewald_Regular.cpp \ From 85ca9d34feb1a8289cebdd6e483477377dd1cc34 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 13:55:28 -0400 Subject: [PATCH 038/218] Start a separate class for decomposing ewald energies. Bring back ErfcFxn and LJswitch --- src/Energy/EnergyDecomp_Ewald.cpp | 208 ++++++++++++++++++++++++++++++ src/Energy/ErfcFxn.cpp | 69 ++++++++++ src/Energy/ErfcFxn.h | 29 +++++ src/Energy/LJswitch.h | 30 +++++ 4 files changed, 336 insertions(+) create mode 100644 src/Energy/EnergyDecomp_Ewald.cpp create mode 100644 src/Energy/ErfcFxn.cpp create mode 100644 src/Energy/ErfcFxn.h create mode 100644 src/Energy/LJswitch.h diff --git a/src/Energy/EnergyDecomp_Ewald.cpp b/src/Energy/EnergyDecomp_Ewald.cpp new file mode 100644 index 0000000000..2da26852fb --- /dev/null +++ b/src/Energy/EnergyDecomp_Ewald.cpp @@ -0,0 +1,208 @@ +#include "EnergyDecomp_Ewald.h" +#include "../ParameterTypes.h" +#include + +using namespace Cpptraj::Energy; + +EnergyDecomp_Ewald::EnergyDecomp_Ewald() {} + +double EnergyDecomp_Ewald::adjust(double q0, double q1, double rij) { + t_adjust_.Start(); + //double erfc = erfc_func(ew_coeff_ * rij); + double erfc = erfc_.ERFC(ew_coeff_ * rij); + double d0 = (erfc - 1.0) / rij; + t_adjust_.Stop(); + return (q0 * q1 * d0); +} + +void EnergyDecomp_Ewald::calcAdjust(double& e_adjust, double& Eljpme_correction_excl, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1, + double q0, double q1, double rij2) +{ + e_adjust += adjust(q0, q1, sqrt(rij2)); + if (lw_coeff_ > 0.0) { + // LJ PME direct space exclusion correction + // NOTE: Assuming excluded pair is within cutoff + double kr2 = lw_coeff_ * lw_coeff_ * rij2; + double kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + double expterm = exp(-kr2); + double r4 = rij2 * rij2; + double r6 = rij2 * r4; + double Cij = Cparam_[atom0.Idx()] * Cparam_[atom1.Idx()]; + Eljpme_correction_excl += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; + } +} + +/** Nonbonded energy */ +void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_correction, + double rij2, double q0, double q1, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) +{ + double rij = sqrt( rij2 ); + double qiqj = q0 * q1; + //double erfc = erfc_func(ew_coeff_ * rij); + double erfc = erfc_.ERFC(ew_coeff_ * rij); + double e_elec = qiqj * erfc / rij; + Eelec += e_elec; + //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", + //int ta0, ta1; + //if (it0->Idx() < it1->Idx()) { + // ta0=it0->Idx(); ta1=it1->Idx(); + //} else { + // ta1=it0->Idx(); ta0=it1->Idx(); + //} + //mprintf("PELEC %6i%6i%12.5f%12.5f%12.5f\n", ta0, ta1, rij, erfc, e_elec); + int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], + TypeIndices_[atom1.Idx()]); + if (nbindex > -1) { + double vswitch = ljswitch_.switch_fn(rij2); + NonbondType const& LJ = NB_->NBarray()[ nbindex ]; + double r2 = 1.0 / rij2; + double r6 = r2 * r2 * r2; + double r12 = r6 * r6; + double f12 = LJ.A() * r12; // A/r^12 + double f6 = LJ.B() * r6; // B/r^6 + double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + Evdw += (e_vdw * vswitch); + //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); + if (lw_coeff_ > 0.0) { + // LJ PME direct space correction + double kr2 = lw_coeff_ * lw_coeff_ * rij2; + double kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + double expterm = exp(-kr2); + double Cij = Cparam_[atom0.Idx()] * Cparam_[atom1.Idx()]; + Eljpme_correction += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; + } + } +} + +/** Direct space nonbonded energy calculation for Ewald */ +void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, double& eadjust_out, + Frame const& frameIn) +{ + t_direct_.Start(); + Eelec = 0.0; + double e_adjust = 0.0; + double Evdw = 0.0; + double Eljpme_correction = 0.0; + double Eljpme_correction_excl = 0.0; + int cidx; +# ifdef _OPENMP +# pragma omp parallel private(cidx) reduction(+: Eelec, Evdw, e_adjust, Eljpme_correction,Eljpme_correction_excl) + { +# pragma omp for +# endif + for (cidx = 0; cidx < PL_.NGridMax(); cidx++) + { + PairList::CellType const& thisCell = PL_.Cell( cidx ); + if (thisCell.NatomsInGrid() > 0) + { + // cellList contains this cell index and all neighbors. + PairList::Iarray const& cellList = thisCell.CellList(); + // transList contains index to translation for the neighbor. + PairList::Iarray const& transList = thisCell.TransList(); + // Loop over all atoms of thisCell. + for (PairList::CellType::const_iterator it0 = thisCell.begin(); + it0 != thisCell.end(); ++it0) + { + Vec3 const& xyz0 = it0->ImageCoords(); + double q0 = Charge_[it0->Idx()]; +# ifdef DEBUG_PAIRLIST + mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); +# endif + // Exclusion list for this atom + ExclusionArray::ExListType const& excluded = Excluded_[it0->Idx()]; + // Calc interaction of atom to all other atoms in thisCell. + for (PairList::CellType::const_iterator it1 = it0 + 1; + it1 != thisCell.end(); ++it1) + { + Vec3 const& xyz1 = it1->ImageCoords(); + double q1 = Charge_[it1->Idx()]; + Vec3 dxyz = xyz1 - xyz0; + double rij2 = dxyz.Magnitude2(); +# ifdef DEBUG_PAIRLIST + mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + // If atom excluded, calc adjustment, otherwise calc elec. energy. + if (excluded.find( it1->Idx() ) == excluded.end()) + { + + if ( rij2 < cut2_ ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif + ene_nb(Eelec, Evdw, Eljpme_correction, rij2, q0, q1, *it0, *it1); // FIXME + } + } else { + calcAdjust(e_adjust, Eljpme_correction_excl, *it0, *it1, q0, q1, rij2); //FIXME + } + } // END loop over other atoms in thisCell + // Loop over all neighbor cells + for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) + { + PairList::CellType const& nbrCell = PL_.Cell( cellList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); +# endif + // Translate vector for neighbor cell + Vec3 const& tVec = PL_.TransVec( transList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); +# endif + //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); + // Loop over every atom in nbrCell + for (PairList::CellType::const_iterator it1 = nbrCell.begin(); + it1 != nbrCell.end(); ++it1) + { + Vec3 const& xyz1 = it1->ImageCoords(); + double q1 = Charge_[it1->Idx()]; + Vec3 dxyz = xyz1 + tVec - xyz0; + double rij2 = dxyz.Magnitude2(); + //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); +# ifdef DEBUG_PAIRLIST + mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + //mprintf("\t\tNbrAtom %06i\n",atnum1); + // If atom excluded, calc adjustment, otherwise calc elec. energy. + // TODO Is there better way of checking this? + if (excluded.find( it1->Idx() ) == excluded.end()) + { + + //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); + if ( rij2 < cut2_ ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif + ene_nb(Eelec, Evdw, Eljpme_correction, rij2, q0, q1, *it0, *it1); // FIXME + } + } else { + calcAdjust(e_adjust, Eljpme_correction_excl, *it0, *it1, q0, q1, rij2); //FIXME + } + } // END loop over neighbor cell atoms + } // END Loop over neighbor cells + } // Loop over thisCell atoms + } // END if thisCell is not empty + } // Loop over cells + t_direct_.Stop(); +# ifdef DEBUG_PAIRLIST + mprintf("DEBUG: Elec = %16.8f\n", Eelec); + mprintf("DEBUG: Eadjust = %16.8f\n", e_adjust); + mprintf("DEBUG: LJ vdw = %16.8f\n", Evdw); + mprintf("DEBUG: LJ vdw PME correction = %16.8f\n", Eljpme_correction); + mprintf("DEBUG: LJ vdw PME correction (excluded) = %16.8f\n", Eljpme_correction_excl); +# endif + evdw_out = Evdw + Eljpme_correction + Eljpme_correction_excl; + eadjust_out = e_adjust; +} // END nb ewald + + diff --git a/src/Energy/ErfcFxn.cpp b/src/Energy/ErfcFxn.cpp new file mode 100644 index 0000000000..8ea7ec7509 --- /dev/null +++ b/src/Energy/ErfcFxn.cpp @@ -0,0 +1,69 @@ +#include "ErfcFxn.h" +#include "CpptrajStdio.h" +#include + +static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } + +/** Complimentary error function: 2/sqrt(PI) * SUM[exp(-t^2)*dt] + * Original code: SANDER: erfcfun.F90 + */ +double ErfcFxn::erfc_func(double xIn) { + double erfc; + double absx = DABS( xIn ); + + if (xIn > 26.0) + erfc = 0.0; + else if (xIn < -5.5) + erfc = 2.0; + else if (absx <= 0.5) { + double cval = xIn * xIn; + double pval = ((-0.356098437018154E-1*cval+0.699638348861914E1)*cval + 0.219792616182942E2) * + cval + 0.242667955230532E3; + double qval = ((cval+0.150827976304078E2)*cval+0.911649054045149E2)*cval + 0.215058875869861E3; + double erf = xIn * pval/qval; + erfc = 1.0 - erf; + } else if (absx < 4.0) { + double cval = absx; + double pval=((((((-0.136864857382717E-6*cval+0.564195517478974)*cval+ + 0.721175825088309E1)*cval+0.431622272220567E2)*cval+ + 0.152989285046940E3)*cval+0.339320816734344E3)*cval+ + 0.451918953711873E3)*cval+0.300459261020162E3; + double qval=((((((cval+0.127827273196294E2)*cval+0.770001529352295E2)*cval+ + 0.277585444743988E3)*cval+0.638980264465631E3)*cval+ + 0.931354094850610E3)*cval+0.790950925327898E3)*cval+ + 0.300459260956983E3; + double nonexperfc; + if ( xIn > 0.0 ) + nonexperfc = pval/qval; + else + nonexperfc = 2.0*exp(xIn*xIn) - pval/qval; + erfc = exp(-absx*absx)*nonexperfc; + } else { + double cval = 1.0/(xIn*xIn); + double pval = (((0.223192459734185E-1*cval+0.278661308609648)*cval+ + 0.226956593539687)*cval+0.494730910623251E-1)*cval+ + 0.299610707703542E-2; + double qval = (((cval+0.198733201817135E1)*cval+0.105167510706793E1)*cval+ + 0.191308926107830)*cval+0.106209230528468E-1; + cval = (-cval*pval/qval + 0.564189583547756)/absx; + double nonexperfc; + if ( xIn > 0.0 ) + nonexperfc = cval; + else + nonexperfc = 2.0*exp(xIn*xIn) - cval; + erfc = exp(-absx*absx)*nonexperfc; + } + return erfc; +} + +/** Fill table with values. */ +int ErfcFxn::FillErfcTable( double erfcTableDx, double beg, double end ) +{ + if (table_.FillTable( erfc_func, erfcTableDx, beg, end )) { + mprinterr("Error: Could not set up spline table for ERFC\n"); + return 1; + } + table_.PrintMemUsage("\t"); + table_.PrintTableInfo("\t"); + return 0; +} diff --git a/src/Energy/ErfcFxn.h b/src/Energy/ErfcFxn.h new file mode 100644 index 0000000000..666a596d25 --- /dev/null +++ b/src/Energy/ErfcFxn.h @@ -0,0 +1,29 @@ +#ifndef INC_ERFCFXN_H +#define INC_ERFCFXN_H +#include "../SplineFxnTable.h" +#include "../Timer.h" +/// Complimentary error function +class ErfcFxn { + public: + ErfcFxn() {} + /// Fill table with ERFC values using given spacing, begin, and end + int FillErfcTable(double, double, double); + /// \return Interpolated erfc value + double ERFC(double xIn) { +# ifdef _OPENMP + return table_.Yval( xIn); +# else + t_erfc_.Start(); + double erfcval = table_.Yval(xIn); + t_erfc_.Stop(); + return erfcval; +# endif + } + private: + /// ERFC function from sander + static double erfc_func(double); + + SplineFxnTable table_; + Timer t_erfc_; ///< For recording how much time is spent doing erfc lookup +}; +#endif diff --git a/src/Energy/LJswitch.h b/src/Energy/LJswitch.h new file mode 100644 index 0000000000..984ae0b24f --- /dev/null +++ b/src/Energy/LJswitch.h @@ -0,0 +1,30 @@ +#ifndef INC_LJSWITCH_H +#define INC_LJSWITCH_H +/** Switching function for Lennard-Jones. */ +template class LJswitch { + public: + /// CONSTRUCTOR + LJswitch() : cut2_0_(0), cut2_1_(0) {} + /// Setup + void setup_switch(T const& cut2_0in, T const& cut2_1in) { + cut2_0_ = cut2_0in; + cut2_1_ = cut2_1in; + } + /// Calculate switched value + T switch_fn(T const& rij2) + { + if (rij2 <= cut2_0_) + return 1.0; + else if (rij2 > cut2_1_) + return 0.0; + else { + T xoff_m_x = cut2_1_ - rij2; + T fac = 1.0 / (cut2_1_ - cut2_0_); + return (xoff_m_x*xoff_m_x) * (cut2_1_ + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); + } + } + private: + T cut2_0_; + T cut2_1_; +}; +#endif From e3e13b9834f895fb1d034d6f88f2af2551b4e7f6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 14:41:48 -0400 Subject: [PATCH 039/218] Start splitting out the Ewald parameters --- src/Energy/EnergyDecomp_Ewald.h | 43 +++++++++++++ src/Energy/EwaldParams.cpp | 106 ++++++++++++++++++++++++++++++++ src/Energy/EwaldParams.h | 31 ++++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/Energy/EnergyDecomp_Ewald.h create mode 100644 src/Energy/EwaldParams.cpp create mode 100644 src/Energy/EwaldParams.h diff --git a/src/Energy/EnergyDecomp_Ewald.h b/src/Energy/EnergyDecomp_Ewald.h new file mode 100644 index 0000000000..84897316b6 --- /dev/null +++ b/src/Energy/EnergyDecomp_Ewald.h @@ -0,0 +1,43 @@ +#ifndef INC_ENERGY_ENERGYDECOMP_EWALD_H +#define INC_ENERGY_ENERGYDECOMP_EWALD_H +#include +#include "ErfcFxn.h" +#include "LJswitch.h" +#include "../PairList.h" // For AtmType +class ExclusionArray; +class Frame; +class NonbondParmType; +namespace Cpptraj { +namespace Energy { +class EnergyDecomp_Ewald { + public: + EnergyDecomp_Ewald(); + private: + typedef std::vector Iarray; + typedef std::vector Darray; + + double adjust(double, double, double); + void calcAdjust(double&, double&, PairList::AtmType const&, PairList::AtmType const&, + double, double, double); + void ene_nb(double&, double&, double&, + double, double, double, PairList::AtmType const&, PairList::AtmType const&); + void ene_ewald_direct(double&, double&, double&, Frame const&, + PairList const&, ExclusionArray const&); + + double cut2_; ///< Direct space cutoff + double ew_coeff_; ///< Ewald coefficient + double lw_coeff_; ///< LJ Ewald coefficient + ErfcFxn erfc_; ///< Hold spline interpolation for erfc + Darray Charge_; ///< Array of charges + Darray Cparam_; ///< Array of C6 coefficients for LJPME + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + LJswitch ljswitch_; ///< LJ switching function + + Timer t_direct_; + Timer t_adjust_; + +}; +} +} +#endif diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp new file mode 100644 index 0000000000..f684e782aa --- /dev/null +++ b/src/Energy/EwaldParams.cpp @@ -0,0 +1,106 @@ +#include "EwaldParams.h" +#include "../Box.h" +#include "../Constants.h" +#include "../CpptrajStdio.h" + +using namespace Cpptraj::Energy; + +static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } + +/** Determine Ewald coefficient from cutoff and direct sum tolerance. + * Original Code: SANDER: findewaldcof + */ +double EwaldParams::FindEwaldCoefficient(double cutoff, double dsum_tol) +{ + // First get direct sum tolerance. How big must the Ewald coefficient be to + // get terms outside the cutoff below tolerance? + double xval = 0.5; + int nloop = 0; + double term = 0.0; + do { + xval = 2.0 * xval; + nloop++; + double yval = xval * cutoff; + term = ErfcFxn::erfc_func(yval) / cutoff; + } while (term >= dsum_tol); + + // Binary search tolerance is 2^-50 + int ntimes = nloop + 50; + double xlo = 0.0; + double xhi = xval; + for (int i = 0; i != ntimes; i++) { + xval = (xlo + xhi) / 2.0; + double yval = xval * cutoff; + double term = ErfcFxn::erfc_func(yval) / cutoff; + if (term >= dsum_tol) + xlo = xval; + else + xhi = xval; + } + mprintf("\tEwald coefficient for cut=%g, direct sum tol=%g is %g\n", + cutoff, dsum_tol, xval); + return xval; +} + +/** Check some common input. */ +int EwaldParams::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, double dsumTolIn, + double ew_coeffIn, double lw_coeffIn, double switch_widthIn, + double erfcTableDxIn, double skinnbIn) +{ + debug_ = debugIn; + cutoff_ = cutoffIn; + dsumTol_ = dsumTolIn; + ew_coeff_ = ew_coeffIn; + lw_coeff_ = lw_coeffIn; + switch_width_ = switch_widthIn; + double erfcTableDx = erfcTableDxIn; + // Check input + if (cutoff_ < Constants::SMALL) { + mprinterr("Error: Direct space cutoff (%g) is too small.\n", cutoff_); + return 1; + } + char dir[3] = {'X', 'Y', 'Z'}; + // NOTE: First 3 box parameters are X Y Z + for (int i = 0; i < 3; i++) { + if (cutoff_ > boxIn.Param((Box::ParamType)i)/2.0) { + mprinterr("Error: Cutoff must be less than half the box length (%g > %g, %c)\n", + cutoff_, boxIn.Param((Box::ParamType)i)/2.0, dir[i]); + return 1; + } + } + if (skinnbIn < 0.0) { + mprinterr("Error: skinnb is less than 0.0\n"); + return 1; + } + if (switch_width_ < 0.0) switch_width_ = 0.0; + if (switch_width_ > cutoff_) { + mprinterr("Error: Switch width must be less than the cutoff.\n"); + return 1; + } + + // Set defaults if necessary + if (dsumTol_ < Constants::SMALL) + dsumTol_ = 1E-5; + if (DABS(ew_coeff_) < Constants::SMALL) + ew_coeff_ = FindEwaldCoefficient( cutoff_, dsumTol_ ); + if (erfcTableDx <= 0.0) erfcTableDx = 1.0 / 5000; + // TODO make this optional + if (erfc_.FillErfcTable( erfcTableDx, 0.0, cutoff_*ew_coeff_*1.5 )) { + mprinterr("Error: Could not set up spline table for ERFC\n"); + return 1; + } + // TODO do for C6 as well + // TODO for C6 correction term + if (lw_coeff_ < 0.0) + lw_coeff_ = 0.0; + else if (DABS(lw_coeff_) < Constants::SMALL) + lw_coeff_ = ew_coeff_; + + // Calculate some common factors. + cut2_ = cutoff_ * cutoff_; + double cut0 = cutoff_ - switch_width_; + cut2_0_ = cut0 * cut0; + + return 0; +} + diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h new file mode 100644 index 0000000000..95685142da --- /dev/null +++ b/src/Energy/EwaldParams.h @@ -0,0 +1,31 @@ +#ifndef INC_ENERGY_EWALDPARAMS_H +#define INC_ENERGY_EWALDPARAMS_H +#include "ErfcFxn.h" +class Box; +namespace Cpptraj { +namespace Energy { +class EwaldParams { + public: + EwaldParams(); + + int CheckInput(Box const&, int, double, double, + double, double, double, + double, double); + + private: + double FindEwaldCoefficient(double, double); + + double ew_coeff_; ///< Ewald coefficient + double lw_coeff_; ///< LJ Ewald coefficient + double switch_width_; ///< Switching window size for LJ switch if active + double cutoff_; ///< Direct space cutoff + double cut2_; ///< Direct space cutoff squared. + double cut2_0_; ///< Direct space cutoff minus switch width, squared. + double dsumTol_; ///< Direct space sum tolerance. + int debug_; + + ErfcFxn erfc_; ///< Hold spline interpolation for erfc +}; +} +} +#endif From 837ca73f66d8a922e5f66005acdf28593b2ed838 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 14:42:31 -0400 Subject: [PATCH 040/218] Update build files --- src/Energy/CMakeLists.txt | 3 +++ src/Energy/energydepend | 3 +++ src/Energy/energyfiles | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 8bbb85ca17..7f4e87877c 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,4 +1,7 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomp_Ewald.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp + ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ) diff --git a/src/Energy/energydepend b/src/Energy/energydepend index e34de55540..08495b6c56 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1 +1,4 @@ +EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h LJswitch.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h +ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ../Timer.h ErfcFxn.h +EwaldParams.o : EwaldParams.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../SplineFxnTable.h ../Timer.h ../Vec3.h ErfcFxn.h EwaldParams.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index f3a3b6c905..3538ecbe8b 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,3 +1,6 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ - EnergyDecomposer.cpp + EnergyDecomp_Ewald.cpp \ + EnergyDecomposer.cpp \ + ErfcFxn.cpp \ + EwaldParams.cpp From b32ef0dfd5dd82b9ec25b5158fd1723fa2dd01d0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 14:42:46 -0400 Subject: [PATCH 041/218] Just make a function template again --- src/Energy/LJswitch.h | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/src/Energy/LJswitch.h b/src/Energy/LJswitch.h index 984ae0b24f..e5fae804cd 100644 --- a/src/Energy/LJswitch.h +++ b/src/Energy/LJswitch.h @@ -1,30 +1,20 @@ #ifndef INC_LJSWITCH_H #define INC_LJSWITCH_H +namespace Cpptraj { +namespace Energy { /** Switching function for Lennard-Jones. */ -template class LJswitch { - public: - /// CONSTRUCTOR - LJswitch() : cut2_0_(0), cut2_1_(0) {} - /// Setup - void setup_switch(T const& cut2_0in, T const& cut2_1in) { - cut2_0_ = cut2_0in; - cut2_1_ = cut2_1in; - } - /// Calculate switched value - T switch_fn(T const& rij2) - { - if (rij2 <= cut2_0_) - return 1.0; - else if (rij2 > cut2_1_) - return 0.0; - else { - T xoff_m_x = cut2_1_ - rij2; - T fac = 1.0 / (cut2_1_ - cut2_0_); - return (xoff_m_x*xoff_m_x) * (cut2_1_ + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); - } - } - private: - T cut2_0_; - T cut2_1_; -}; +template T LJswitch(T rij2, T cut2_0, T cut2_1) +{ + if (rij2 <= cut2_0) + return 1.0; + else if (rij2 > cut2_1) + return 0.0; + else { + T xoff_m_x = cut2_1 - rij2; + T fac = 1.0 / (cut2_1 - cut2_0); + return (xoff_m_x*xoff_m_x) * (cut2_1 + 2.0*rij2 - 3.0*cut2_0) * (fac*fac*fac); + } +} +} +} #endif From 0fda331df793ccd35e084150da6de346c8763aae Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 14:43:04 -0400 Subject: [PATCH 042/218] Put in energy namespace and make erfc_func available --- src/Energy/ErfcFxn.cpp | 4 +++- src/Energy/ErfcFxn.h | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Energy/ErfcFxn.cpp b/src/Energy/ErfcFxn.cpp index 8ea7ec7509..cb3a1e953f 100644 --- a/src/Energy/ErfcFxn.cpp +++ b/src/Energy/ErfcFxn.cpp @@ -1,7 +1,9 @@ #include "ErfcFxn.h" -#include "CpptrajStdio.h" +#include "../CpptrajStdio.h" #include +using namespace Cpptraj::Energy; + static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } /** Complimentary error function: 2/sqrt(PI) * SUM[exp(-t^2)*dt] diff --git a/src/Energy/ErfcFxn.h b/src/Energy/ErfcFxn.h index 666a596d25..73fe5b8144 100644 --- a/src/Energy/ErfcFxn.h +++ b/src/Energy/ErfcFxn.h @@ -2,6 +2,8 @@ #define INC_ERFCFXN_H #include "../SplineFxnTable.h" #include "../Timer.h" +namespace Cpptraj { +namespace Energy { /// Complimentary error function class ErfcFxn { public: @@ -19,11 +21,13 @@ class ErfcFxn { return erfcval; # endif } - private: /// ERFC function from sander static double erfc_func(double); + private: SplineFxnTable table_; Timer t_erfc_; ///< For recording how much time is spent doing erfc lookup }; +} +} #endif From 1534b5d594f680a4cf7ce5217c6b393a5df961a9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 15:02:22 -0400 Subject: [PATCH 043/218] Put Erfc and switching functions through the EwaldParams class --- src/Energy/EnergyDecomp_Ewald.cpp | 45 ++++++++++++++++++++----------- src/Energy/EnergyDecomp_Ewald.h | 11 +++----- src/Energy/ErfcFxn.h | 14 +--------- src/Energy/EwaldParams.h | 19 +++++++++++++ src/Energy/LJswitch.h | 20 -------------- src/Energy/energydepend | 6 ++--- 6 files changed, 57 insertions(+), 58 deletions(-) delete mode 100644 src/Energy/LJswitch.h diff --git a/src/Energy/EnergyDecomp_Ewald.cpp b/src/Energy/EnergyDecomp_Ewald.cpp index 2da26852fb..7b7841091a 100644 --- a/src/Energy/EnergyDecomp_Ewald.cpp +++ b/src/Energy/EnergyDecomp_Ewald.cpp @@ -1,4 +1,5 @@ #include "EnergyDecomp_Ewald.h" +#include "../ExclusionArray.h" #include "../ParameterTypes.h" #include @@ -6,10 +7,23 @@ using namespace Cpptraj::Energy; EnergyDecomp_Ewald::EnergyDecomp_Ewald() {} +// ----------------------------------------------------------------------------- + +double EnergyDecomp_Ewald::ERFC(double rIn) { +# ifdef _OPENMP + return EW_.ErfcEW( rIn ); +# else + t_erfc_.Start(); + double erfcval = EW_.ErfcEW( rIn ); + t_erfc_.Stop(); + return erfcval; +# endif +} + double EnergyDecomp_Ewald::adjust(double q0, double q1, double rij) { t_adjust_.Start(); //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = erfc_.ERFC(ew_coeff_ * rij); + double erfc = ERFC(rij); double d0 = (erfc - 1.0) / rij; t_adjust_.Stop(); return (q0 * q1 * d0); @@ -21,10 +35,10 @@ void EnergyDecomp_Ewald::calcAdjust(double& e_adjust, double& Eljpme_correction_ double q0, double q1, double rij2) { e_adjust += adjust(q0, q1, sqrt(rij2)); - if (lw_coeff_ > 0.0) { + if (EW_.LW_Coeff() > 0.0) { // LJ PME direct space exclusion correction // NOTE: Assuming excluded pair is within cutoff - double kr2 = lw_coeff_ * lw_coeff_ * rij2; + double kr2 = EW_.LW_Coeff() * EW_.LW_Coeff() * rij2; double kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; double expterm = exp(-kr2); @@ -44,7 +58,7 @@ void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_corr double rij = sqrt( rij2 ); double qiqj = q0 * q1; //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = erfc_.ERFC(ew_coeff_ * rij); + double erfc = ERFC(rij); double e_elec = qiqj * erfc / rij; Eelec += e_elec; //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", @@ -58,7 +72,7 @@ void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_corr int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], TypeIndices_[atom1.Idx()]); if (nbindex > -1) { - double vswitch = ljswitch_.switch_fn(rij2); + double vswitch = EW_.Switch_Fn(rij2); NonbondType const& LJ = NB_->NBarray()[ nbindex ]; double r2 = 1.0 / rij2; double r6 = r2 * r2 * r2; @@ -68,9 +82,9 @@ void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_corr double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) Evdw += (e_vdw * vswitch); //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); - if (lw_coeff_ > 0.0) { + if (EW_.LW_Coeff() > 0.0) { // LJ PME direct space correction - double kr2 = lw_coeff_ * lw_coeff_ * rij2; + double kr2 = EW_.LW_Coeff() * EW_.LW_Coeff() * rij2; double kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; double expterm = exp(-kr2); @@ -82,7 +96,8 @@ void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_corr /** Direct space nonbonded energy calculation for Ewald */ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, double& eadjust_out, - Frame const& frameIn) + Frame const& frameIn, PairList const& PL, + ExclusionArray const& Excluded) { t_direct_.Start(); Eelec = 0.0; @@ -96,9 +111,9 @@ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, doubl { # pragma omp for # endif - for (cidx = 0; cidx < PL_.NGridMax(); cidx++) + for (cidx = 0; cidx < PL.NGridMax(); cidx++) { - PairList::CellType const& thisCell = PL_.Cell( cidx ); + PairList::CellType const& thisCell = PL.Cell( cidx ); if (thisCell.NatomsInGrid() > 0) { // cellList contains this cell index and all neighbors. @@ -115,7 +130,7 @@ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, doubl mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); # endif // Exclusion list for this atom - ExclusionArray::ExListType const& excluded = Excluded_[it0->Idx()]; + ExclusionArray::ExListType const& excluded = Excluded[it0->Idx()]; // Calc interaction of atom to all other atoms in thisCell. for (PairList::CellType::const_iterator it1 = it0 + 1; it1 != thisCell.end(); ++it1) @@ -131,7 +146,7 @@ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, doubl if (excluded.find( it1->Idx() ) == excluded.end()) { - if ( rij2 < cut2_ ) { + if ( rij2 < EW_.Cut2() ) { # ifdef NBDBG if (it0->Idx() < it1->Idx()) mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); @@ -147,12 +162,12 @@ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, doubl // Loop over all neighbor cells for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) { - PairList::CellType const& nbrCell = PL_.Cell( cellList[nidx] ); + PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); # ifdef DEBUG_PAIRLIST if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); # endif // Translate vector for neighbor cell - Vec3 const& tVec = PL_.TransVec( transList[nidx] ); + Vec3 const& tVec = PL.TransVec( transList[nidx] ); # ifdef DEBUG_PAIRLIST if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); # endif @@ -176,7 +191,7 @@ void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, doubl { //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); - if ( rij2 < cut2_ ) { + if ( rij2 < EW_.Cut2() ) { # ifdef NBDBG if (it0->Idx() < it1->Idx()) mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); diff --git a/src/Energy/EnergyDecomp_Ewald.h b/src/Energy/EnergyDecomp_Ewald.h index 84897316b6..18aac82a5b 100644 --- a/src/Energy/EnergyDecomp_Ewald.h +++ b/src/Energy/EnergyDecomp_Ewald.h @@ -1,8 +1,7 @@ #ifndef INC_ENERGY_ENERGYDECOMP_EWALD_H #define INC_ENERGY_ENERGYDECOMP_EWALD_H #include -#include "ErfcFxn.h" -#include "LJswitch.h" +#include "EwaldParams.h" #include "../PairList.h" // For AtmType class ExclusionArray; class Frame; @@ -16,6 +15,7 @@ class EnergyDecomp_Ewald { typedef std::vector Iarray; typedef std::vector Darray; + double ERFC(double); double adjust(double, double, double); void calcAdjust(double&, double&, PairList::AtmType const&, PairList::AtmType const&, double, double, double); @@ -24,18 +24,15 @@ class EnergyDecomp_Ewald { void ene_ewald_direct(double&, double&, double&, Frame const&, PairList const&, ExclusionArray const&); - double cut2_; ///< Direct space cutoff - double ew_coeff_; ///< Ewald coefficient - double lw_coeff_; ///< LJ Ewald coefficient - ErfcFxn erfc_; ///< Hold spline interpolation for erfc + EwaldParams EW_; Darray Charge_; ///< Array of charges Darray Cparam_; ///< Array of C6 coefficients for LJPME Iarray TypeIndices_; ///< Hold atom type indices for selected atoms NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - LJswitch ljswitch_; ///< LJ switching function Timer t_direct_; Timer t_adjust_; + Timer t_erfc_; }; } diff --git a/src/Energy/ErfcFxn.h b/src/Energy/ErfcFxn.h index 73fe5b8144..d9d709fe31 100644 --- a/src/Energy/ErfcFxn.h +++ b/src/Energy/ErfcFxn.h @@ -1,7 +1,6 @@ #ifndef INC_ERFCFXN_H #define INC_ERFCFXN_H #include "../SplineFxnTable.h" -#include "../Timer.h" namespace Cpptraj { namespace Energy { /// Complimentary error function @@ -11,22 +10,11 @@ class ErfcFxn { /// Fill table with ERFC values using given spacing, begin, and end int FillErfcTable(double, double, double); /// \return Interpolated erfc value - double ERFC(double xIn) { -# ifdef _OPENMP - return table_.Yval( xIn); -# else - t_erfc_.Start(); - double erfcval = table_.Yval(xIn); - t_erfc_.Stop(); - return erfcval; -# endif - } + double ErfcInterpolated(double xIn) const { return table_.Yval( xIn); } /// ERFC function from sander static double erfc_func(double); private: - SplineFxnTable table_; - Timer t_erfc_; ///< For recording how much time is spent doing erfc lookup }; } } diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 95685142da..cb22b097f6 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -11,7 +11,26 @@ class EwaldParams { int CheckInput(Box const&, int, double, double, double, double, double, double, double); + /// \return ERFC value of given distance times the Ewald coefficient + double ErfcEW(double rIn) const { return erfc_.ErfcInterpolated( ew_coeff_*rIn ); } + /// \return LJ switch fn value + double Switch_Fn(double rij2) const { + double cut2_1 = cut2_; + if (rij2 <= cut2_0_) + return 1.0; + else if (rij2 > cut2_1) + return 0.0; + else { + double xoff_m_x = cut2_1 - rij2; + double fac = 1.0 / (cut2_1 - cut2_0_); + return (xoff_m_x*xoff_m_x) * (cut2_1 + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); + } + } + /// \return LJ PME coefficient + double LW_Coeff() const { return lw_coeff_; } + /// \return Direct space cutoff (in Ang squared) + double Cut2() const { return cut2_; } private: double FindEwaldCoefficient(double, double); diff --git a/src/Energy/LJswitch.h b/src/Energy/LJswitch.h deleted file mode 100644 index e5fae804cd..0000000000 --- a/src/Energy/LJswitch.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef INC_LJSWITCH_H -#define INC_LJSWITCH_H -namespace Cpptraj { -namespace Energy { -/** Switching function for Lennard-Jones. */ -template T LJswitch(T rij2, T cut2_0, T cut2_1) -{ - if (rij2 <= cut2_0) - return 1.0; - else if (rij2 > cut2_1) - return 0.0; - else { - T xoff_m_x = cut2_1 - rij2; - T fac = 1.0 / (cut2_1 - cut2_0); - return (xoff_m_x*xoff_m_x) * (cut2_1 + 2.0*rij2 - 3.0*cut2_0) * (fac*fac*fac); - } -} -} -} -#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 08495b6c56..48f6a20003 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h LJswitch.h +EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h -ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ../Timer.h ErfcFxn.h -EwaldParams.o : EwaldParams.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../SplineFxnTable.h ../Timer.h ../Vec3.h ErfcFxn.h EwaldParams.h +ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h +EwaldParams.o : EwaldParams.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../SplineFxnTable.h ../Vec3.h ErfcFxn.h EwaldParams.h From f2dc7b3e1124662a5a463d9e925645b848fdc9a6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 18 Sep 2024 15:56:27 -0400 Subject: [PATCH 044/218] Init class vars --- src/Energy/EwaldParams.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index f684e782aa..f4117a8381 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -5,6 +5,18 @@ using namespace Cpptraj::Energy; +/** CONSTRUCTOR */ +EwaldParams::EwaldParams() : + ew_coeff_(0.0), + lw_coeff_(0.0), + switch_width_(0.0), + cutoff_(0.0), + cut2_(0.0), + cut2_0_(0.0), + dsumTol_(0.0), + debug_(0) +{} + static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } /** Determine Ewald coefficient from cutoff and direct sum tolerance. From b27e445a5624822f2f600fef55ee427cc3c87fce Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 08:38:05 -0400 Subject: [PATCH 045/218] Add params for PME --- src/Energy/CMakeLists.txt | 1 + src/Energy/EwaldParams.h | 19 ++++++++++++++++++- src/Energy/EwaldParams_PME.h | 16 ++++++++++++++++ src/Energy/energydepend | 1 + src/Energy/energyfiles | 3 ++- 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/Energy/EwaldParams_PME.h diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 7f4e87877c..07749a04ec 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -4,4 +4,5 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp ) diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index cb22b097f6..51e91fd92f 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -2,12 +2,18 @@ #define INC_ENERGY_EWALDPARAMS_H #include "ErfcFxn.h" class Box; +class EwaldOptions; namespace Cpptraj { namespace Energy { class EwaldParams { public: EwaldParams(); - + // Virtual since inherited + virtual ~EwaldParams() {} + // ------------------------------------------- + virtual int InitEwald(Box const&, EwaldOptions const&, int) = 0; + // ------------------------------------------- + // TODO make protected? int CheckInput(Box const&, int, double, double, double, double, double, double, double); @@ -31,6 +37,17 @@ class EwaldParams { double LW_Coeff() const { return lw_coeff_; } /// \return Direct space cutoff (in Ang squared) double Cut2() const { return cut2_; } + + /// \return Direct space cutoff (in Ang) + double Cutoff() const { return cutoff_; } + /// \return Direct sum tolerance + double DirectSumTol() const { return dsumTol_; } + /// \return Ewald coefficient + double EwaldCoeff() const { return ew_coeff_; } + /// \return LJ Ewald coefficient + double LJ_EwaldCoeff() const { return lw_coeff_; } + /// \return LJ switch width (in Ang.) + double LJ_SwitchWidth() const { return switch_width_; } private: double FindEwaldCoefficient(double, double); diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h new file mode 100644 index 0000000000..2b90fbd0b2 --- /dev/null +++ b/src/Energy/EwaldParams_PME.h @@ -0,0 +1,16 @@ +#ifndef INC_ENERGY_EWALDPARAMS_PME_H +#define INC_ENERGY_EWALDPARAMS_PME_H +#include "EwaldParams.h" +namespace Cpptraj { +namespace Energy { +class EwaldParams_PME : public EwaldParams { + public: + EwaldParams_PME(); + int InitEwald(Box const&, EwaldOptions const&, int); + private: + int nfft_[3]; ///< Number of FFT grid points in each direction + int order_; ///< PME B spline order +}; +} +} +#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 48f6a20003..18d680ddd9 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -2,3 +2,4 @@ EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../Exclusi EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../SplineFxnTable.h ../Vec3.h ErfcFxn.h EwaldParams.h +EwaldParams_PME.o : EwaldParams_PME.cpp ../CpptrajStdio.h ../EwaldOptions.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 3538ecbe8b..a1cfcc1e60 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -3,4 +3,5 @@ ENERGY_SOURCES= \ EnergyDecomp_Ewald.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ - EwaldParams.cpp + EwaldParams.cpp \ + EwaldParams_PME.cpp From b01d0ea17b4513ff76a7525f193be84e06e0bfe0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 09:00:42 -0400 Subject: [PATCH 046/218] Second try for using pairlist template/engine model --- src/Energy/EwaldParams_PME.cpp | 58 ++++++++++++++++ src/Energy/Kernel_EwaldAdjust.h | 13 ++++ src/PairListEngine_Ewald_LJLR.h | 71 ++++++++++++++++++++ src/PairListTemplate.h | 113 ++++++++++++++++++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 src/Energy/EwaldParams_PME.cpp create mode 100644 src/Energy/Kernel_EwaldAdjust.h create mode 100644 src/PairListEngine_Ewald_LJLR.h create mode 100644 src/PairListTemplate.h diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp new file mode 100644 index 0000000000..b0138bdd7f --- /dev/null +++ b/src/Energy/EwaldParams_PME.cpp @@ -0,0 +1,58 @@ +#include "EwaldParams_PME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR */ +EwaldParams_PME::EwaldParams_PME() : + order_(6) +{ + nfft_[0] = -1; + nfft_[1] = -1; + nfft_[2] = -1; +} + +/** Set up PME parameters. */ +int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + if (CheckInput(boxIn, debugIn, pmeOpts.Cutoff(), pmeOpts.DsumTol(), pmeOpts.EwCoeff(), + pmeOpts.LwCoeff(), pmeOpts.LJ_SwWidth(), + pmeOpts.ErfcDx(), pmeOpts.SkinNB())) + return 1; + nfft_[0] = pmeOpts.Nfft1(); + nfft_[1] = pmeOpts.Nfft2(); + nfft_[2] = pmeOpts.Nfft3(); + order_ = pmeOpts.SplineOrder(); + + // Set defaults if necessary + if (order_ < 1) order_ = 6; + + mprintf("\tParticle Mesh Ewald params:\n"); + mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", + Cutoff(), DirectSumTol(), EwaldCoeff(), pmeOpts.SkinNB()); + if (LJ_EwaldCoeff() > 0.0) + mprintf("\t LJ Ewald coeff.= %g\n", LJ_EwaldCoeff()); + if (LJ_SwitchWidth() > 0.0) + mprintf("\t LJ switch width= %g\n", LJ_SwitchWidth()); + mprintf("\t Bspline order= %i\n", order_); + //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); + mprintf("\t "); + for (int i = 0; i != 3; i++) + if (nfft_[i] == -1) + mprintf(" NFFT%i=auto", i+1); + else + mprintf(" NFFT%i=%i", i+1, nfft_[i]); + mprintf("\n"); + + // Set up pair list + //if (Setup_Pairlist(boxIn, pmeOpts.SkinNB())) return 1; + + return 0; +} + diff --git a/src/Energy/Kernel_EwaldAdjust.h b/src/Energy/Kernel_EwaldAdjust.h new file mode 100644 index 0000000000..f4f51ab4ef --- /dev/null +++ b/src/Energy/Kernel_EwaldAdjust.h @@ -0,0 +1,13 @@ +#ifndef INC_KERNEL_EWALDADJUST_H +#define INC_KERNEL_EWALDADJUST_H +namespace Cpptraj { +namespace Energy { +/// Used to adjust Ewald energy for excluded atoms +template T Kernel_EwaldAdjust(T const& q0, T const& q1, T const& rij, T const& erfcval) +{ + T d0 = (erfcval - 1.0) / rij; + return (q0 * q1 * d0); +} +} +} +#endif diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h new file mode 100644 index 0000000000..fa4cad71ae --- /dev/null +++ b/src/PairListEngine_Ewald_LJLR.h @@ -0,0 +1,71 @@ +#ifndef INC_PAIRLISTENGINE_EWALD_LJLR_H +#define INC_PAIRLISTENGINE_EWALD_LJLR_H +#include "Energy/Ene_LJ_6_12.h" +#include "Energy/EwaldParams_PME.h" +#include "Energy/Kernel_EwaldAdjust.h" +#include "PairList.h" +#include "ParameterTypes.h" +#include +namespace Cpptraj { +/// Direct space nonbond calculation using pairlist with Ewald and VDW LR correction +template +class PairListEngine_Ewald_LJLR { + typedef std::vector Iarray; + public: + PairListEngine_Ewald_LJLR() : NB_(0) {} + // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = Charge_[atom0.Idx()]; + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = Charge_[atom1.Idx()]; + } + /// Call when cutoff is satisfied + void CutoffSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt( rij2 ); + T qiqj = q0_ * q1_; + //double erfc = erfc_func(ew_coeff_ * rij); + T erfcval = EW_.ErfcEW( rij ); + T e_elec = qiqj * erfcval / rij; + Eelec_ += e_elec; + + int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], + TypeIndices_[atom1.Idx()]); + if (nbindex > -1) { + double vswitch = EW_.Switch_Fn(rij2); + NonbondType const& LJ = NB_->NBarray()[ nbindex ]; + T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); + Evdw_ += (e_vdw * vswitch); + } + } + /// Call when cutoff is not satisfied + void CutoffNotSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt(rij2); + T erfcval = EW_.ErfcEW( rij ); + Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + } + // ------------------------------------------- + private: + T q0_; ///< Charge on atom 0 + T q1_; ///< Charge on atom 1 + T Evdw_; ///< VDW sum for current frame + T Eelec_; ///< Coulomb sum for current frame + T Eadjust_; ///< Adjust energy sum for current frame + + std::vector Charge_; ///< Array of charges + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME +}; +} // END namespace Cpptraj +#endif diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h new file mode 100644 index 0000000000..31571ec423 --- /dev/null +++ b/src/PairListTemplate.h @@ -0,0 +1,113 @@ +#ifndef INC_PAIRLISTTEMPLATE_H +#define INC_PAIRLISTTEMPLATE_H +#include "PairList.h" +#include "ExclusionArray.h" +namespace Cpptraj { +/// Template for doing pair list calculations +template class EngineClass> +void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2, + EngineClass& engine) +{ + engine.FrameBeginCalc(); + + int cidx; + + for (cidx = 0; cidx < PL.NGridMax(); cidx++) + { + PairList::CellType const& thisCell = PL.Cell( cidx ); + if (thisCell.NatomsInGrid() > 0) + { + // cellList contains this cell index and all neighbors. + PairList::Iarray const& cellList = thisCell.CellList(); + // transList contains index to translation for the neighbor. + PairList::Iarray const& transList = thisCell.TransList(); + // Loop over all atoms of thisCell. + for (PairList::CellType::const_iterator it0 = thisCell.begin(); + it0 != thisCell.end(); ++it0) + { + engine.SetupAtom0( *it0 ); + Vec3 const& xyz0 = it0->ImageCoords(); +# ifdef DEBUG_PAIRLIST + mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); +# endif + // Exclusion list for this atom + ExclusionArray::ExListType const& excluded = Excluded[it0->Idx()]; + // Calc interaction of atom to all other atoms in thisCell. + for (PairList::CellType::const_iterator it1 = it0 + 1; + it1 != thisCell.end(); ++it1) + { + engine.SetupAtom1( *it1 ); + Vec3 const& xyz1 = it1->ImageCoords(); + Vec3 dxyz = xyz1 - xyz0; + T rij2 = dxyz.Magnitude2(); +# ifdef DEBUG_PAIRLIST + mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + // If atom excluded, calc adjustment, otherwise calc elec. energy. + if (excluded.find( it1->Idx() ) == excluded.end()) + { + if ( rij2 < cut2 ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif + engine.CutoffSatisfied(rij2, *it0, *it1); + } + } else { + engine.CutoffNotSatisfied(rij2, *it0, *it1); + } + } // END loop over other atoms in thisCell + // Loop over all neighbor cells + for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) + { + PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); +# endif + // Translate vector for neighbor cell + Vec3 const& tVec = PL.TransVec( transList[nidx] ); +# ifdef DEBUG_PAIRLIST + if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); +# endif + //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); + // Loop over every atom in nbrCell + for (PairList::CellType::const_iterator it1 = nbrCell.begin(); + it1 != nbrCell.end(); ++it1) + { + engine.SetupAtom1( *it1 ); + Vec3 const& xyz1 = it1->ImageCoords(); + Vec3 dxyz = xyz1 + tVec - xyz0; + T rij2 = dxyz.Magnitude2(); + //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); +# ifdef DEBUG_PAIRLIST + mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); +# endif + //mprintf("\t\tNbrAtom %06i\n",atnum1); + // If atom excluded, calc adjustment, otherwise calc elec. energy. + // TODO Is there better way of checking this? + if (excluded.find( it1->Idx() ) == excluded.end()) + { + + //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); + if ( rij2 < cut2 ) { +# ifdef NBDBG + if (it0->Idx() < it1->Idx()) + mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); + else + mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); +# endif + engine.CutoffSatisfied(rij2, *it0, *it1); + } + } else { + engine.CutoffNotSatisfied(rij2, *it0, *it1); + } + } // END loop over neighbor cell atoms + } // END Loop over neighbor cells + } // Loop over thisCell atoms + } // END if thisCell is not empty + } // Loop over cells +} // END PairListTemplate +} // END namespace Cpptraj +#endif From cad410146c95d52eddbbfe93476b5a2e61e3c206 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 09:30:38 -0400 Subject: [PATCH 047/218] Do some Ewald setup --- src/Energy/EwaldParams.cpp | 25 ++++++++++++++++++++++- src/Energy/EwaldParams.h | 36 ++++++++++++++++++++++++++------- src/Energy/EwaldParams_PME.cpp | 13 ++++++++++++ src/Energy/EwaldParams_PME.h | 2 ++ src/Energy/energydepend | 2 +- src/PairListEngine_Ewald_LJLR.h | 15 +++++--------- 6 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index f4117a8381..5c53809063 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -2,6 +2,7 @@ #include "../Box.h" #include "../Constants.h" #include "../CpptrajStdio.h" +#include "../Topology.h" using namespace Cpptraj::Energy; @@ -14,7 +15,10 @@ EwaldParams::EwaldParams() : cut2_(0.0), cut2_0_(0.0), dsumTol_(0.0), - debug_(0) + debug_(0), + NB_(0), + sumq_(0), + sumq2_(0) {} static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } @@ -115,4 +119,23 @@ int EwaldParams::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, doub return 0; } +/** Convert charges to Amber units. Calculate sum of charges and squared charges. */ +void EwaldParams::CalculateCharges(Topology const& topIn, AtomMask const& maskIn) { + NB_ = static_cast( &(topIn.Nonbond()) ); + + sumq_ = 0.0; + sumq2_ = 0.0; + Charge_.clear(); + TypeIndices_.clear(); + for (AtomMask::const_iterator atom = maskIn.begin(); atom != maskIn.end(); ++atom) { + double qi = topIn[*atom].Charge() * Constants::ELECTOAMBER; + Charge_.push_back(qi); + sumq_ += qi; + sumq2_ += (qi * qi); + // Store atom type indices for selected atoms. + TypeIndices_.push_back( topIn[*atom].TypeIndex() ); + } + //mprintf("DEBUG: sumq= %20.10f sumq2= %20.10f\n", sumq_, sumq2_); + //Setup_VDW_Correction( topIn, maskIn ); +} diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 51e91fd92f..de2b42136a 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -1,8 +1,11 @@ #ifndef INC_ENERGY_EWALDPARAMS_H #define INC_ENERGY_EWALDPARAMS_H #include "ErfcFxn.h" +#include "../ParameterTypes.h" // NonbondParmType +class AtomMask; class Box; class EwaldOptions; +class Topology; namespace Cpptraj { namespace Energy { class EwaldParams { @@ -12,11 +15,9 @@ class EwaldParams { virtual ~EwaldParams() {} // ------------------------------------------- virtual int InitEwald(Box const&, EwaldOptions const&, int) = 0; + virtual int SetupEwald(Topology const&, AtomMask const&) = 0; // ------------------------------------------- - // TODO make protected? - int CheckInput(Box const&, int, double, double, - double, double, double, - double, double); + /// \return ERFC value of given distance times the Ewald coefficient double ErfcEW(double rIn) const { return erfc_.ErfcInterpolated( ew_coeff_*rIn ); } /// \return LJ switch fn value @@ -33,10 +34,14 @@ class EwaldParams { } } - /// \return LJ PME coefficient - double LW_Coeff() const { return lw_coeff_; } /// \return Direct space cutoff (in Ang squared) double Cut2() const { return cut2_; } + /// \return Charge for given atom index + double Charge(int idx) { return Charge_[idx]; } + /// \return Nonbonded index for given atom indices + int NbIndex(int idx0, int idx1) { return NB_->GetLJindex(TypeIndices_[idx0], TypeIndices_[idx1]); } + /// \return Nonbonded parameter at nonobonded parameter index + NonbondType const& GetLJ(int nbindex) const { return NB_->NBarray()[ nbindex ]; } /// \return Direct space cutoff (in Ang) double Cutoff() const { return cutoff_; } @@ -48,7 +53,18 @@ class EwaldParams { double LJ_EwaldCoeff() const { return lw_coeff_; } /// \return LJ switch width (in Ang.) double LJ_SwitchWidth() const { return switch_width_; } + protected: + typedef std::vector Iarray; + typedef std::vector Darray; + + /// Set Ewald parametsr, check them and set defaults if needed. + int CheckInput(Box const&, int, double, double, + double, double, double, + double, double); + /// Calculate sum q, sum q^2. + void CalculateCharges(Topology const&, AtomMask const&); private: + double FindEwaldCoefficient(double, double); double ew_coeff_; ///< Ewald coefficient @@ -60,7 +76,13 @@ class EwaldParams { double dsumTol_; ///< Direct space sum tolerance. int debug_; - ErfcFxn erfc_; ///< Hold spline interpolation for erfc + ErfcFxn erfc_; ///< Hold spline interpolation for erfc + + Darray Charge_; ///< Hold charges for selected atoms + Iarray TypeIndices_; ///< Hold atom type indices for selected atoms + NonbondParmType const* NB_; ///< Pointer to nonbonded parameters + double sumq_; ///< Sum of charges + double sumq2_; ///< Sum of charges squared }; } } diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp index b0138bdd7f..dbb51f8b2c 100644 --- a/src/Energy/EwaldParams_PME.cpp +++ b/src/Energy/EwaldParams_PME.cpp @@ -1,4 +1,5 @@ #include "EwaldParams_PME.h" +#include "../AtomMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" @@ -56,3 +57,15 @@ int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, in return 0; } +/** Setup PME calculation. */ +int EwaldParams_PME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { + CalculateCharges(topIn, maskIn); + // NOTE: These dont need to actually be calculated if the lj ewald coeff + // is 0.0, but do it here anyway to avoid segfaults. + //CalculateC6params( topIn, maskIn ); + coordsD_.clear(); + coordsD_.reserve( maskIn.Nselected() * 3); + //SetupExclusionList(topIn, maskIn); + return 0; +} + diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h index 2b90fbd0b2..0c2f776f88 100644 --- a/src/Energy/EwaldParams_PME.h +++ b/src/Energy/EwaldParams_PME.h @@ -7,9 +7,11 @@ class EwaldParams_PME : public EwaldParams { public: EwaldParams_PME(); int InitEwald(Box const&, EwaldOptions const&, int); + int SetupEwald(Topology const&, AtomMask const&); private: int nfft_[3]; ///< Number of FFT grid points in each direction int order_; ///< PME B spline order + Darray coordsD_; ///< Hold coordinates for selected atoms }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 18d680ddd9..d86ae8ba1e 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,5 @@ EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h -EwaldParams.o : EwaldParams.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../SplineFxnTable.h ../Vec3.h ErfcFxn.h EwaldParams.h +EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.o : EwaldParams_PME.cpp ../CpptrajStdio.h ../EwaldOptions.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index fa4cad71ae..a44e6442e5 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -4,7 +4,6 @@ #include "Energy/EwaldParams_PME.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" -#include "ParameterTypes.h" #include namespace Cpptraj { /// Direct space nonbond calculation using pairlist with Ewald and VDW LR correction @@ -12,17 +11,17 @@ template class PairListEngine_Ewald_LJLR { typedef std::vector Iarray; public: - PairListEngine_Ewald_LJLR() : NB_(0) {} + PairListEngine_Ewald_LJLR() {} // ------------------------------------------- /// Call at the beginning of the frame calculation void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { - q0_ = Charge_[atom0.Idx()]; + q0_ = EW_.Charge(atom0.Idx()); } /// Call for atom 1 when looping over interaction atoms of this/other cell void SetupAtom1( PairList::AtmType const& atom1 ) { - q1_ = Charge_[atom1.Idx()]; + q1_ = EW_.Charge(atom1.Idx()); } /// Call when cutoff is satisfied void CutoffSatisfied(T const& rij2, @@ -36,11 +35,10 @@ class PairListEngine_Ewald_LJLR { T e_elec = qiqj * erfcval / rij; Eelec_ += e_elec; - int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], - TypeIndices_[atom1.Idx()]); + int nbindex = EW_.NbIndex(atom0.Idx(), atom1.Idx()); if (nbindex > -1) { double vswitch = EW_.Switch_Fn(rij2); - NonbondType const& LJ = NB_->NBarray()[ nbindex ]; + NonbondType const& LJ = EW_.GetLJ( nbindex ); T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); Evdw_ += (e_vdw * vswitch); } @@ -62,9 +60,6 @@ class PairListEngine_Ewald_LJLR { T Eelec_; ///< Coulomb sum for current frame T Eadjust_; ///< Adjust energy sum for current frame - std::vector Charge_; ///< Array of charges - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME }; } // END namespace Cpptraj From 142e806aad601561e1ab421cdb5f028f5b396661 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 12:33:43 -0400 Subject: [PATCH 048/218] Add routines to access Ewald parameters to the engine --- src/Energy/EwaldParams.h | 1 + src/PairListEngine_Ewald_LJLR.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index de2b42136a..330e7cdd5c 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -8,6 +8,7 @@ class EwaldOptions; class Topology; namespace Cpptraj { namespace Energy { +/// Parameters common to all Ewald methods class EwaldParams { public: EwaldParams(); diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index a44e6442e5..5af009fd24 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -53,6 +53,8 @@ class PairListEngine_Ewald_LJLR { Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); } // ------------------------------------------- + Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams_PME const& EwaldParams() const { return EW_; } private: T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 From 84e8addd4d242cba01c79284364b0175cb3dd442 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 12:35:46 -0400 Subject: [PATCH 049/218] Start PME calc wrapper --- src/Energy/Calc_PME.cpp | 24 ++++++++++++++++++++++++ src/Energy/Calc_PME.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Energy/Calc_PME.cpp create mode 100644 src/Energy/Calc_PME.h diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp new file mode 100644 index 0000000000..374a94a9ef --- /dev/null +++ b/src/Energy/Calc_PME.cpp @@ -0,0 +1,24 @@ +#include "Calc_PME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +Calc_PME::Calc_PME() {} + +/** Set up PME parameters. */ +int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: PME calculation init failed.\n"); + return 1; + } + if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + + return 0; +} + + diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h new file mode 100644 index 0000000000..aad2d64179 --- /dev/null +++ b/src/Energy/Calc_PME.h @@ -0,0 +1,30 @@ +#ifndef INC_ENERGY_CALC_PME_H +#define INC_ENERGY_CALC_PME_H +#include "../ExclusionArray.h" +#include "../helpme_standalone.h" +#include "../PairList.h" +#include "../PairListEngine_Ewald_LJLR.h" +class AtomMask; +class Box; +class EwaldOptions; +class Frame; +class Topology; +namespace Cpptraj { +namespace Energy { +class Calc_PME { + public: + Calc_PME(); + /// Init with Box, EwaldOptions and debug level + int Init(Box const&, EwaldOptions const&, int); + int Setup(Topology const&, AtomMask const&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); + + private: + PairListEngine_Ewald_LJLR NBengine_; + PMEInstanceD pme_object_; + PairList pairList_; + ExclusionArray Excluded_; +}; +} +} +#endif From ed8a923b6e6aece913fa324c664bdba1d7baa235 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 13:41:01 -0400 Subject: [PATCH 050/218] Add class for calculating long range VDW --- src/Energy/VDW_LongRange_Correction.cpp | 57 +++++++++++++++++++++++++ src/Energy/VDW_LongRange_Correction.h | 28 ++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/Energy/VDW_LongRange_Correction.cpp create mode 100644 src/Energy/VDW_LongRange_Correction.h diff --git a/src/Energy/VDW_LongRange_Correction.cpp b/src/Energy/VDW_LongRange_Correction.cpp new file mode 100644 index 0000000000..cdc688ee5e --- /dev/null +++ b/src/Energy/VDW_LongRange_Correction.cpp @@ -0,0 +1,57 @@ +#include "VDW_LongRange_Correction.h" +#include "../CpptrajStdio.h" +#include "../Topology.h" + +using namespace Cpptraj::Energy; + +VDW_LongRange_Correction::VDW_LongRange_Correction() : + Vdw_Recip_term_(0), + debug_(0) +{} + +void VDW_LongRange_Correction::SetDebug(int debugIn) { debug_ = debugIn; } + +/** Determine VDW long range correction prefactor. */ +void VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, + AtomMask const& maskIn) +{ + Vdw_Recip_term_ = 0.0; + NonbondParmType const* NB_ = static_cast( &(topIn.Nonbond()) ); + if (!NB_->HasNonbond()) { + mprintf("Warning: '%s' has no nonbonded parameters. Cannot calculate VDW correction.\n", + topIn.c_str()); + return; + } + Iarray N_vdw_type_; + // Count the number of each unique nonbonded type. + N_vdw_type_.assign( NB_->Ntypes(), 0 ); + //vdw_type_.clear(); + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) + { + N_vdw_type_[ topIn[*atm].TypeIndex() ]++; + //vdw_type_.push_back( topIn[*atm].TypeIndex() ); + } + if (debug_ > 0) { + mprintf("DEBUG: %zu VDW types.\n", N_vdw_type_.size()); + for (Iarray::const_iterator it = N_vdw_type_.begin(); it != N_vdw_type_.end(); ++it) + mprintf("\tType %li = %i\n", it-N_vdw_type_.begin(), *it); + } + // Determine correction term from types and LJ B parameters + for (unsigned int itype = 0; itype != N_vdw_type_.size(); itype++) + { + double atype_vdw_term = 0.0; // term for each nonbond atom type + unsigned int offset = N_vdw_type_.size() * itype; + for (unsigned int jtype = 0; jtype != N_vdw_type_.size(); jtype++) + { + unsigned int idx = offset + jtype; + int nbidx = NB_->NBindex()[ idx ]; + if (nbidx > -1) { + atype_vdw_term += N_vdw_type_[itype] * N_vdw_type_[jtype] * NB_->NBarray()[ nbidx ].B(); + + Vdw_Recip_term_ += N_vdw_type_[itype] * N_vdw_type_[jtype] * NB_->NBarray()[ nbidx ].B(); + } + } + //atype_vdw_recip_terms_.push_back(atype_vdw_term); // the nonbond interaction for each atom type + } +} + diff --git a/src/Energy/VDW_LongRange_Correction.h b/src/Energy/VDW_LongRange_Correction.h new file mode 100644 index 0000000000..efec37ceed --- /dev/null +++ b/src/Energy/VDW_LongRange_Correction.h @@ -0,0 +1,28 @@ +#ifndef INC_ENERGY_VDW_LONGRANGE_CORRECTION_H +#define INC_ENERGY_VDW_LONGRANGE_CORRECTION_H +#include +#include "../Constants.h" +class AtomMask; +class Topology; +namespace Cpptraj { +namespace Energy { +class VDW_LongRange_Correction { + public: + VDW_LongRange_Correction(); + void SetDebug(int); + void Setup_VDW_Correction(Topology const&, AtomMask const&); + /// \return Full VDW long range correction from cutoff and volume + double Vdw_Correction(double cutoff_, double volume) const { + double prefac = Constants::TWOPI / (3.0*volume*cutoff_*cutoff_*cutoff_); + double e_vdwr = -prefac * Vdw_Recip_term_; + //if (debug_ > 0) mprintf("DEBUG: Vdw correction %20.10f\n", e_vdwr); + return e_vdwr; + } + private: + typedef std::vector Iarray; + double Vdw_Recip_term_; + int debug_; +}; +} +} +#endif From 2f2e2a83723dae408efaeadd23f0aa10401251b9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 13:41:20 -0400 Subject: [PATCH 051/218] Use long range VDW calc --- src/Energy/CMakeLists.txt | 2 ++ src/Energy/Calc_PME.cpp | 1 + src/Energy/Calc_PME.h | 2 ++ src/Energy/energydepend | 4 +++- src/Energy/energyfiles | 4 +++- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 07749a04ec..98b79cdc1c 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,8 +1,10 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/Calc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomp_Ewald.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp + ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 374a94a9ef..26dcb35abb 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -17,6 +17,7 @@ int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) return 1; if (pairList_.SetupPairList( boxIn )) return 1; + VDW_LR_.SetDebug( debugIn ); return 0; } diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h index aad2d64179..3f152ef459 100644 --- a/src/Energy/Calc_PME.h +++ b/src/Energy/Calc_PME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_CALC_PME_H #define INC_ENERGY_CALC_PME_H +#include "VDW_LongRange_Correction.h" #include "../ExclusionArray.h" #include "../helpme_standalone.h" #include "../PairList.h" @@ -24,6 +25,7 @@ class Calc_PME { PMEInstanceD pme_object_; PairList pairList_; ExclusionArray Excluded_; + VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index d86ae8ba1e..4f1c341dbd 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,7 @@ +Calc_PME.o : Calc_PME.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_PME.h VDW_LongRange_Correction.h EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h -EwaldParams_PME.o : EwaldParams_PME.cpp ../CpptrajStdio.h ../EwaldOptions.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h +EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Constants.h ../CpptrajStdio.h ../EwaldOptions.h ../MaskToken.h ../Molecule.h ../NameType.h ../ParameterTypes.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h +VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index a1cfcc1e60..dd90da206b 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,7 +1,9 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ + Calc_PME.cpp \ EnergyDecomp_Ewald.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ EwaldParams.cpp \ - EwaldParams_PME.cpp + EwaldParams_PME.cpp \ + VDW_LongRange_Correction.cpp From 8e3b60f1d450de653061cadab8b7179559a35461 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 14:22:53 -0400 Subject: [PATCH 052/218] PME calculation setup --- src/Energy/Calc_PME.cpp | 26 +++++++++++++++++++++++++ src/Energy/Calc_PME.h | 4 ++++ src/Energy/EwaldParams_PME.cpp | 7 ------- src/Energy/EwaldParams_PME.h | 1 - src/Energy/VDW_LongRange_Correction.cpp | 8 ++++---- src/Energy/VDW_LongRange_Correction.h | 2 +- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 26dcb35abb..d50c2db84a 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -1,6 +1,7 @@ #include "Calc_PME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Topology.h" using namespace Cpptraj::Energy; @@ -22,4 +23,29 @@ int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) return 0; } +/** Setup PME calculation. */ +int Calc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { + if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { + mprinterr("Error: PME calculation setup failed.\n"); + return 1; + } + if (VDW_LR_.Setup_VDW_Correction( topIn, maskIn )) { + mprinterr("Error: PME calculation long range VDW correction setup failed.\n"); + return 1; + } + // Reserve space for coords for the reciprocal part of the calculation + coordsD_.clear(); + coordsD_.reserve( maskIn.Nselected() * 3); + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for PME calculation.\n"); + return 1; + } + + return 0; +} diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h index 3f152ef459..966dfda80b 100644 --- a/src/Energy/Calc_PME.h +++ b/src/Energy/Calc_PME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_CALC_PME_H #define INC_ENERGY_CALC_PME_H +#include #include "VDW_LongRange_Correction.h" #include "../ExclusionArray.h" #include "../helpme_standalone.h" @@ -21,11 +22,14 @@ class Calc_PME { int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); private: + typedef std::vector Darray; + PairListEngine_Ewald_LJLR NBengine_; PMEInstanceD pme_object_; PairList pairList_; ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction + Darray coordsD_; ///< Hold selected coords for recip calc }; } } diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp index dbb51f8b2c..d2dbec7fa6 100644 --- a/src/Energy/EwaldParams_PME.cpp +++ b/src/Energy/EwaldParams_PME.cpp @@ -60,12 +60,5 @@ int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, in /** Setup PME calculation. */ int EwaldParams_PME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { CalculateCharges(topIn, maskIn); - // NOTE: These dont need to actually be calculated if the lj ewald coeff - // is 0.0, but do it here anyway to avoid segfaults. - //CalculateC6params( topIn, maskIn ); - coordsD_.clear(); - coordsD_.reserve( maskIn.Nselected() * 3); - //SetupExclusionList(topIn, maskIn); return 0; } - diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h index 0c2f776f88..8f52057a00 100644 --- a/src/Energy/EwaldParams_PME.h +++ b/src/Energy/EwaldParams_PME.h @@ -11,7 +11,6 @@ class EwaldParams_PME : public EwaldParams { private: int nfft_[3]; ///< Number of FFT grid points in each direction int order_; ///< PME B spline order - Darray coordsD_; ///< Hold coordinates for selected atoms }; } } diff --git a/src/Energy/VDW_LongRange_Correction.cpp b/src/Energy/VDW_LongRange_Correction.cpp index cdc688ee5e..deb5855f94 100644 --- a/src/Energy/VDW_LongRange_Correction.cpp +++ b/src/Energy/VDW_LongRange_Correction.cpp @@ -12,15 +12,15 @@ VDW_LongRange_Correction::VDW_LongRange_Correction() : void VDW_LongRange_Correction::SetDebug(int debugIn) { debug_ = debugIn; } /** Determine VDW long range correction prefactor. */ -void VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, +int VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, AtomMask const& maskIn) { Vdw_Recip_term_ = 0.0; NonbondParmType const* NB_ = static_cast( &(topIn.Nonbond()) ); if (!NB_->HasNonbond()) { - mprintf("Warning: '%s' has no nonbonded parameters. Cannot calculate VDW correction.\n", + mprinterr("Error: '%s' has no nonbonded parameters. Cannot calculate VDW correction.\n", topIn.c_str()); - return; + return 1; } Iarray N_vdw_type_; // Count the number of each unique nonbonded type. @@ -53,5 +53,5 @@ void VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, } //atype_vdw_recip_terms_.push_back(atype_vdw_term); // the nonbond interaction for each atom type } + return 0; } - diff --git a/src/Energy/VDW_LongRange_Correction.h b/src/Energy/VDW_LongRange_Correction.h index efec37ceed..2cfe11048e 100644 --- a/src/Energy/VDW_LongRange_Correction.h +++ b/src/Energy/VDW_LongRange_Correction.h @@ -10,7 +10,7 @@ class VDW_LongRange_Correction { public: VDW_LongRange_Correction(); void SetDebug(int); - void Setup_VDW_Correction(Topology const&, AtomMask const&); + int Setup_VDW_Correction(Topology const&, AtomMask const&); /// \return Full VDW long range correction from cutoff and volume double Vdw_Correction(double cutoff_, double volume) const { double prefac = Constants::TWOPI / (3.0*volume*cutoff_*cutoff_*cutoff_); From 4fcdf6f3826d89ca4a60d14bc4467bcb802dc8d8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 14:51:25 -0400 Subject: [PATCH 053/218] Add PME recip calc wrapper class --- src/Energy/PME_Recip.cpp | 154 +++++++++++++++++++++++++++++++++++++++ src/Energy/PME_Recip.h | 30 ++++++++ 2 files changed, 184 insertions(+) create mode 100644 src/Energy/PME_Recip.cpp create mode 100644 src/Energy/PME_Recip.h diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp new file mode 100644 index 0000000000..60d548f86d --- /dev/null +++ b/src/Energy/PME_Recip.cpp @@ -0,0 +1,154 @@ +#include "PME_Recip.h" +#include "../AtomMask.h" +#include "../Box.h" +#include "../CpptrajStdio.h" +#include "../Frame.h" + +typedef helpme::Matrix Mat; + +using namespace Cpptraj::Energy; + +PME_Recip::PME_Recip() : + debug_(0) +{} + +void PME_Recip::SetDebug(int d) { debug_ = d; } + +/** \return true if given number is a product of powers of 2, 3, or 5. */ +bool PME_Recip::check_prime_factors(int nIn) { + if (nIn == 1) return true; + int NL = nIn; + int NQ; + // First divide down by 2 + while (NL > 0) { + NQ = NL / 2; + if (NQ * 2 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + // Next try 3 + while (NL > 0) { + NQ = NL / 3; + if (NQ * 3 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + // Last try 5 + while (NL > 0) { + NQ = NL / 5; + if (NQ * 5 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + return false; +} + +/** Compute the ceiling of len that is also a product of powers of 2, 3, 5. + * Use check_prime_factors to get the smallest integer greater or equal + * than len which is decomposable into powers of 2, 3, 5. + */ +int PME_Recip::ComputeNFFT(double len) { + int mval = (int)len - 1; + for (int i = 0; i < 100; i++) { + mval += 1; + // Sanity check + if (mval < 1) { + mprinterr("Error: Bad box length %g, cannot get NFFT value.\n", len); + return 0; + } + if (check_prime_factors(mval)) + return mval; + } + mprinterr("Error: Failed to get good FFT array size for length %g Ang.\n", len); + return 0; +} + +/** Given a box, determine number of FFT grid points in each dimension. */ +int PME_Recip::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxIn) const +{ + if (nfft1 < 1) { + // Need even dimension for X direction + nfft1 = ComputeNFFT( (boxIn.Param(Box::X) + 1.0) * 0.5 ); + nfft1 *= 2; + } + if (nfft2 < 1) + nfft2 = ComputeNFFT( boxIn.Param(Box::Y) ); + if (nfft3 < 1) + nfft3 = ComputeNFFT( boxIn.Param(Box::Z) ); + + if (nfft1 < 1 || nfft2 < 1 || nfft3 < 1) { + mprinterr("Error: Bad NFFT values: %i %i %i\n", nfft1, nfft2, nfft3); + return 1; + } + if (debug_ > 0) mprintf("DEBUG: NFFTs: %i %i %i\n", nfft1, nfft2, nfft3); + + return 0; +} + +/** \return Reciprocal space part of PME energy calc. */ +// TODO currently helPME needs the charge array to be non-const, need to fix that +double PME_Recip::Recip_ParticleMesh(Frame const& frameIn, AtomMask const& maskIn, + Box const& boxIn, Darray& ChargeIn, + const int* nfftIn, double ew_coeffIn, int orderIn) +{ + // Sanity check + if (ChargeIn.size() != (unsigned int)maskIn.Nselected()) { + mprinterr("Internal Error: PME_Recip::Recip_ParticleMesh: Charge/coords size mismatch (%zu vs %i\n", ChargeIn.size(), maskIn.Nselected()); + return 0; + } + + coordsD_.clear(); + coordsD_.reserve( maskIn.Nselected()*3 ); + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { + const double* XYZ = frameIn.XYZ( *atm ); + coordsD_.push_back( XYZ[0] ); + coordsD_.push_back( XYZ[1] ); + coordsD_.push_back( XYZ[2] ); + } + + t_recip_.Start(); + // This essentially makes coordsD and chargesD point to arrays. + Mat coordsD(&coordsD_[0], ChargeIn.size(), 3); + Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); + int nfft1 = -1; + int nfft2 = -1; + int nfft3 = -1; + if (nfftIn != 0) { + nfft1 = nfftIn[0]; + nfft2 = nfftIn[1]; + nfft3 = nfftIn[2]; + } + if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + mprinterr("Error: Could not determine FFT grid spacing.\n"); + return 0.0; + } + // Instantiate double precision PME object + // Args: 1 = Exponent of the distance kernel: 1 for Coulomb + // 2 = Kappa + // 3 = Spline order + // 4 = nfft1 + // 5 = nfft2 + // 6 = nfft3 + // 7 = scale factor to be applied to all computed energies and derivatives thereof + // 8 = max # threads to use for each MPI instance; 0 = all available threads used. + // NOTE: Scale factor for Charmm is 332.0716 + // NOTE: The electrostatic constant has been baked into the Charge_ array already. + //auto pme_object = std::unique_ptr(new PMEInstanceD()); + pme_object_.setup(1, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, 1.0, 0); + // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. + // Args: 1 = the A lattice parameter in units consistent with the coordinates. + // 2 = the B lattice parameter in units consistent with the coordinates. + // 3 = the C lattice parameter in units consistent with the coordinates. + // 4 = the alpha lattice parameter in degrees. + // 5 = the beta lattice parameter in degrees. + // 6 = the gamma lattice parameter in degrees. + // 7 = lattice type + pme_object_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), + boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), + PMEInstanceD::LatticeType::XAligned); + double erecip = pme_object_.computeERec(0, chargesD, coordsD); + + t_recip_.Stop(); + return erecip; +} + diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h new file mode 100644 index 0000000000..2d0087a8b4 --- /dev/null +++ b/src/Energy/PME_Recip.h @@ -0,0 +1,30 @@ +#ifndef INC_ENERGY_PME_RECIP_H +#define INC_ENERGY_PME_RECIP_H +#include "../helpme_standalone.h" +#include "../Timer.h" +class AtomMask; +class Box; +class Frame; +namespace Cpptraj { +namespace Energy { +/// Do the reciprocal part of a PME calculation +class PME_Recip { + typedef std::vector Darray; + public: + PME_Recip(); + void SetDebug(int); + double Recip_ParticleMesh(Frame const&, AtomMask const&, Box const&, + Darray&, const int*, double, int); + private: + static bool check_prime_factors(int); + static int ComputeNFFT(double); + int DetermineNfft(int&, int&, int&, Box const&) const; + + PMEInstanceD pme_object_; + Darray coordsD_; + Timer t_recip_; ///< Recip calc timer + int debug_; +}; +} +} +#endif From a7a6951e6445632df7bc68d6240dad9af03eca9d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 14:51:41 -0400 Subject: [PATCH 054/218] Start using PME_Recip --- src/Energy/CMakeLists.txt | 1 + src/Energy/Calc_PME.cpp | 4 +--- src/Energy/Calc_PME.h | 8 ++------ src/Energy/energydepend | 3 ++- src/Energy/energyfiles | 1 + 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 98b79cdc1c..5b06b676c1 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -6,5 +6,6 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp + ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index d50c2db84a..f369ebf705 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -19,6 +19,7 @@ int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) if (pairList_.SetupPairList( boxIn )) return 1; VDW_LR_.SetDebug( debugIn ); + Recip_.SetDebug( debugIn ); return 0; } @@ -33,9 +34,6 @@ int Calc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { mprinterr("Error: PME calculation long range VDW correction setup failed.\n"); return 1; } - // Reserve space for coords for the reciprocal part of the calculation - coordsD_.clear(); - coordsD_.reserve( maskIn.Nselected() * 3); // Setup exclusion list // Use distance of 4 (up to dihedrals) if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h index 966dfda80b..0007519c26 100644 --- a/src/Energy/Calc_PME.h +++ b/src/Energy/Calc_PME.h @@ -1,9 +1,8 @@ #ifndef INC_ENERGY_CALC_PME_H #define INC_ENERGY_CALC_PME_H -#include +#include "PME_Recip.h" #include "VDW_LongRange_Correction.h" #include "../ExclusionArray.h" -#include "../helpme_standalone.h" #include "../PairList.h" #include "../PairListEngine_Ewald_LJLR.h" class AtomMask; @@ -22,14 +21,11 @@ class Calc_PME { int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); private: - typedef std::vector Darray; - PairListEngine_Ewald_LJLR NBengine_; - PMEInstanceD pme_object_; + PME_Recip Recip_; PairList pairList_; ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction - Darray coordsD_; ///< Hold selected coords for recip calc }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 4f1c341dbd..2ba4f984ff 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,7 +1,8 @@ -Calc_PME.o : Calc_PME.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_PME.h VDW_LongRange_Correction.h +Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Constants.h ../CpptrajStdio.h ../EwaldOptions.h ../MaskToken.h ../Molecule.h ../NameType.h ../ParameterTypes.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h +PME_Recip.o : PME_Recip.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index dd90da206b..40aa8cb5b2 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -6,4 +6,5 @@ ENERGY_SOURCES= \ ErfcFxn.cpp \ EwaldParams.cpp \ EwaldParams_PME.cpp \ + PME_Recip.cpp \ VDW_LongRange_Correction.cpp From 14d90062cea98bc0634e020f5c147ac5572b0a1a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 15:04:48 -0400 Subject: [PATCH 055/218] Allow PME_Recip to be used for coulomb or LJ --- src/Energy/PME_Recip.cpp | 17 ++++++++++++++--- src/Energy/PME_Recip.h | 6 +++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 60d548f86d..db175258de 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -8,9 +8,20 @@ typedef helpme::Matrix Mat; using namespace Cpptraj::Energy; -PME_Recip::PME_Recip() : +PME_Recip::PME_Recip(Type typeIn) : debug_(0) -{} +{ + switch (typeIn) { + case COULOMB: + distKernelExponent_ = 1; + scaleFac_ = 1.0; + break; + case LJ: + distKernelExponent_ = 6; + scaleFac_ = -1.0; + break; + } +} void PME_Recip::SetDebug(int d) { debug_ = d; } @@ -134,7 +145,7 @@ double PME_Recip::Recip_ParticleMesh(Frame const& frameIn, AtomMask const& maskI // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(1, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, 1.0, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. // Args: 1 = the A lattice parameter in units consistent with the coordinates. // 2 = the B lattice parameter in units consistent with the coordinates. diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 2d0087a8b4..54ed3bc381 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -11,7 +11,9 @@ namespace Energy { class PME_Recip { typedef std::vector Darray; public: - PME_Recip(); + enum Type { COULOMB = 0, LJ }; + + PME_Recip(Type); void SetDebug(int); double Recip_ParticleMesh(Frame const&, AtomMask const&, Box const&, Darray&, const int*, double, int); @@ -24,6 +26,8 @@ class PME_Recip { Darray coordsD_; Timer t_recip_; ///< Recip calc timer int debug_; + int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ + double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof }; } } From 392df78a721dcec9704cdd58af744febb0e9ed42 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 15:05:40 -0400 Subject: [PATCH 056/218] Use COULOMB recip --- src/Energy/Calc_PME.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index f369ebf705..5bae7e9fe3 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -5,7 +5,9 @@ using namespace Cpptraj::Energy; -Calc_PME::Calc_PME() {} +Calc_PME::Calc_PME() : + Recip_(PME_Recip::COULOMB) +{} /** Set up PME parameters. */ int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) From d42e02d4638c66f62259b85061a72104c647d32e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 19 Sep 2024 15:10:50 -0400 Subject: [PATCH 057/218] Add self energy calc --- src/Energy/EwaldParams.cpp | 14 ++++++++++++++ src/Energy/EwaldParams.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index 5c53809063..e1709fa235 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -139,3 +139,17 @@ void EwaldParams::CalculateCharges(Topology const& topIn, AtomMask const& maskIn //Setup_VDW_Correction( topIn, maskIn ); } +/** Electrostatic self energy. This is the cancelling Gaussian plus the "neutralizing plasma". */ +double EwaldParams::SelfEnergy(double volume) const { + static const double INVSQRTPI = 1.0 / sqrt(Constants::PI); +// t_self_.Start(); + double d0 = -ew_coeff_ * INVSQRTPI; + double ene = sumq2_ * d0; +// mprintf("DEBUG: d0= %20.10f ene= %20.10f\n", d0, ene); + double factor = Constants::PI / (ew_coeff_ * ew_coeff_ * volume); + double ee_plasma = -0.5 * factor * sumq_ * sumq_; + ene += ee_plasma; +// t_self_.Stop(); + return ene; +} + diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 330e7cdd5c..a0130078bc 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -34,6 +34,8 @@ class EwaldParams { return (xoff_m_x*xoff_m_x) * (cut2_1 + 2.0*rij2 - 3.0*cut2_0_) * (fac*fac*fac); } } + /// \return Self energy for the given volume + double SelfEnergy(double) const; /// \return Direct space cutoff (in Ang squared) double Cut2() const { return cut2_; } From 2e80c2c159f413c94485384f591536700e58e698 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 08:15:40 -0400 Subject: [PATCH 058/218] Save recip coords in EwaldParams_PME so it can be used for multiple recip objects. Start the nonbonded calc --- src/Energy/Calc_PME.cpp | 68 ++++++++++++++++++++++++++++++++++ src/Energy/EwaldParams.h | 2 + src/Energy/EwaldParams_PME.cpp | 21 +++++++++++ src/Energy/EwaldParams_PME.h | 4 ++ src/Energy/PME_Recip.cpp | 22 ++--------- src/Energy/PME_Recip.h | 4 +- 6 files changed, 99 insertions(+), 22 deletions(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 5bae7e9fe3..c298d54d8c 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -49,3 +49,71 @@ int Calc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +/** Calculate full nonbonded energy with PME */ +int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + double& e_elec, double& e_vdw) +{ + t_total_.Start(); + double volume = frameIn.BoxCrd().CellVolume(); + double e_self = Self( volume ); + double e_vdw_lr_correction; + + int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); + if (retVal != 0) { + mprinterr("Error: Grid setup failed.\n"); + return 1; + } + + // TODO make more efficient + int idx = 0; + coordsD_.clear(); + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm, ++idx) { + const double* XYZ = frameIn.XYZ( *atm ); + coordsD_.push_back( XYZ[0] ); + coordsD_.push_back( XYZ[1] ); + coordsD_.push_back( XYZ[2] ); + } + +// MapCoords(frameIn, ucell, recip, maskIn); + double e_recip = Recip_ParticleMesh( frameIn.BoxCrd() ); + + // TODO branch + double e_vdw6self, e_vdw6recip; + if (lw_coeff_ > 0.0) { + e_vdw6self = Self6(); + e_vdw6recip = LJ_Recip_ParticleMesh( frameIn.BoxCrd() ); + if (debug_ > 0) { + mprintf("DEBUG: e_vdw6self = %16.8f\n", e_vdw6self); + mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); + } + e_vdw_lr_correction = 0.0; + } else { + e_vdw6self = 0.0; + e_vdw6recip = 0.0; + e_vdw_lr_correction = Vdw_Correction( volume ); + } + + e_vdw = 0.0; + double e_adjust = 0.0; + double e_direct = Direct( pairList_, e_vdw, e_adjust ); + if (debug_ > 0) { + mprintf("DEBUG: Nonbond energy components:\n"); + mprintf(" Evdw = %24.12f\n", e_vdw + e_vdw_lr_correction + e_vdw6self + e_vdw6recip); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + e_direct + e_adjust); + mprintf("\n"); + mprintf(" E electrostatic (self) = %24.12f\n", e_self); + mprintf(" (rec) = %24.12f\n", e_recip); + mprintf(" (dir) = %24.12f\n", e_direct); + mprintf(" (adj) = %24.12f\n", e_adjust); + mprintf(" E vanDerWaals (dir) = %24.12f\n", e_vdw); + mprintf(" (LR) = %24.12f\n", e_vdw_lr_correction); + mprintf(" (6slf) = %24.12f\n", e_vdw6self); + mprintf(" (6rcp) = %24.12f\n", e_vdw6recip); + } + e_vdw += (e_vdw_lr_correction + e_vdw6self + e_vdw6recip); + t_total_.Stop(); + e_elec = e_self + e_recip + e_direct + e_adjust; + return 0; +} + + diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index a0130078bc..2da52b01cb 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -60,6 +60,8 @@ class EwaldParams { typedef std::vector Iarray; typedef std::vector Darray; + /// \return Charge array + Darray const& Charge() const { return Charge_; } /// Set Ewald parametsr, check them and set defaults if needed. int CheckInput(Box const&, int, double, double, double, double, double, diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp index d2dbec7fa6..5af5d6ade5 100644 --- a/src/Energy/EwaldParams_PME.cpp +++ b/src/Energy/EwaldParams_PME.cpp @@ -2,6 +2,7 @@ #include "../AtomMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Frame.h" using namespace Cpptraj::Energy; @@ -60,5 +61,25 @@ int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, in /** Setup PME calculation. */ int EwaldParams_PME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { CalculateCharges(topIn, maskIn); + // Sanity check + if (Charge().size() != (unsigned int)maskIn.Nselected()) { + mprinterr("Internal Error: EwaldParams_PME::SetupEwald(): Charge/coords size mismatch (%zu vs %i\n", + Charge().size(), maskIn.Nselected()); + return 1; + } + + coordsD_.clear(); + coordsD_.reserve( maskIn.Nselected()*3 ); return 0; } + +/** Put selected coords in separate array for recip calc. */ +void EwaldParams_PME::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) +{ + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { + const double* XYZ = frameIn.XYZ( *atm ); + coordsD_.push_back( XYZ[0] ); + coordsD_.push_back( XYZ[1] ); + coordsD_.push_back( XYZ[2] ); + } +} diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h index 8f52057a00..c2e05ad03e 100644 --- a/src/Energy/EwaldParams_PME.h +++ b/src/Energy/EwaldParams_PME.h @@ -1,6 +1,7 @@ #ifndef INC_ENERGY_EWALDPARAMS_PME_H #define INC_ENERGY_EWALDPARAMS_PME_H #include "EwaldParams.h" +class Frame; namespace Cpptraj { namespace Energy { class EwaldParams_PME : public EwaldParams { @@ -8,7 +9,10 @@ class EwaldParams_PME : public EwaldParams { EwaldParams_PME(); int InitEwald(Box const&, EwaldOptions const&, int); int SetupEwald(Topology const&, AtomMask const&); + + void FillRecipCoords(Frame const&, AtomMask const&); private: + Darray coordsD_; ///< Hold coords for selected atoms (for recip. calc) int nfft_[3]; ///< Number of FFT grid points in each direction int order_; ///< PME B spline order }; diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index db175258de..23c7c04853 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -97,29 +97,13 @@ int PME_Recip::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxI } /** \return Reciprocal space part of PME energy calc. */ -// TODO currently helPME needs the charge array to be non-const, need to fix that -double PME_Recip::Recip_ParticleMesh(Frame const& frameIn, AtomMask const& maskIn, - Box const& boxIn, Darray& ChargeIn, +// TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that +double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, const int* nfftIn, double ew_coeffIn, int orderIn) { - // Sanity check - if (ChargeIn.size() != (unsigned int)maskIn.Nselected()) { - mprinterr("Internal Error: PME_Recip::Recip_ParticleMesh: Charge/coords size mismatch (%zu vs %i\n", ChargeIn.size(), maskIn.Nselected()); - return 0; - } - - coordsD_.clear(); - coordsD_.reserve( maskIn.Nselected()*3 ); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { - const double* XYZ = frameIn.XYZ( *atm ); - coordsD_.push_back( XYZ[0] ); - coordsD_.push_back( XYZ[1] ); - coordsD_.push_back( XYZ[2] ); - } - t_recip_.Start(); // This essentially makes coordsD and chargesD point to arrays. - Mat coordsD(&coordsD_[0], ChargeIn.size(), 3); + Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); int nfft1 = -1; int nfft2 = -1; diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 54ed3bc381..0c729ac02e 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -15,15 +15,13 @@ class PME_Recip { PME_Recip(Type); void SetDebug(int); - double Recip_ParticleMesh(Frame const&, AtomMask const&, Box const&, - Darray&, const int*, double, int); + double Recip_ParticleMesh(Darray&, Box const&, Darray&, const int*, double, int); private: static bool check_prime_factors(int); static int ComputeNFFT(double); int DetermineNfft(int&, int&, int&, Box const&) const; PMEInstanceD pme_object_; - Darray coordsD_; Timer t_recip_; ///< Recip calc timer int debug_; int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ From 564be0eba0fa5d02823dc74c629f337e3767552e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 11:19:47 -0400 Subject: [PATCH 059/218] Finish up nonbonded pme calc with template --- src/Energy/Calc_PME.cpp | 83 +++++++++++++++++---------------- src/Energy/Calc_PME.h | 1 + src/Energy/EwaldParams.h | 7 ++- src/Energy/EwaldParams_PME.h | 7 +++ src/Energy/energydepend | 4 +- src/PairListEngine_Ewald_LJLR.h | 4 ++ 6 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index c298d54d8c..503f80a9de 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -1,6 +1,7 @@ #include "Calc_PME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../PairListTemplate.h" #include "../Topology.h" using namespace Cpptraj::Energy; @@ -55,64 +56,64 @@ int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, { t_total_.Start(); double volume = frameIn.BoxCrd().CellVolume(); - double e_self = Self( volume ); - double e_vdw_lr_correction; + double e_self = NBengine_.EwaldParams().SelfEnergy( volume ); - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); + int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn); if (retVal != 0) { - mprinterr("Error: Grid setup failed.\n"); + mprinterr("Error: Pairlist creation failed for PME calc.\n"); return 1; } // TODO make more efficient - int idx = 0; - coordsD_.clear(); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm, ++idx) { - const double* XYZ = frameIn.XYZ( *atm ); - coordsD_.push_back( XYZ[0] ); - coordsD_.push_back( XYZ[1] ); - coordsD_.push_back( XYZ[2] ); - } + NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); -// MapCoords(frameIn, ucell, recip, maskIn); - double e_recip = Recip_ParticleMesh( frameIn.BoxCrd() ); + // MapCoords(frameIn, ucell, recip, maskIn); + // FIXME helPME requires coords and charge arrays to be non-const + double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); // TODO branch - double e_vdw6self, e_vdw6recip; - if (lw_coeff_ > 0.0) { - e_vdw6self = Self6(); - e_vdw6recip = LJ_Recip_ParticleMesh( frameIn.BoxCrd() ); - if (debug_ > 0) { - mprintf("DEBUG: e_vdw6self = %16.8f\n", e_vdw6self); - mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); - } - e_vdw_lr_correction = 0.0; - } else { - e_vdw6self = 0.0; - e_vdw6recip = 0.0; - e_vdw_lr_correction = Vdw_Correction( volume ); - } + //double e_vdw6self, e_vdw6recip; + //if (lw_coeff_ > 0.0) { + // e_vdw6self = Self6(); + // e_vdw6recip = LJ_Recip_ParticleMesh( frameIn.BoxCrd() ); + // if (debug_ > 0) { + // mprintf("DEBUG: e_vdw6self = %16.8f\n", e_vdw6self); + // mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); + // } + // e_vdw_lr_correction = 0.0; + //} else { + // e_vdw6self = 0.0; + // e_vdw6recip = 0.0; + double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); + //} + + Cpptraj::PairListTemplate(pairList_, Excluded_, + NBengine_.EwaldParams().Cut2(), NBengine_); - e_vdw = 0.0; - double e_adjust = 0.0; - double e_direct = Direct( pairList_, e_vdw, e_adjust ); - if (debug_ > 0) { + if (NBengine_.EwaldParams().Debug() > 0) { mprintf("DEBUG: Nonbond energy components:\n"); - mprintf(" Evdw = %24.12f\n", e_vdw + e_vdw_lr_correction + e_vdw6self + e_vdw6recip); - mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + e_direct + e_adjust); + mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + e_vdw_lr_correction ); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + + NBengine_.Eelec() + + NBengine_.Eadjust()); mprintf("\n"); mprintf(" E electrostatic (self) = %24.12f\n", e_self); mprintf(" (rec) = %24.12f\n", e_recip); - mprintf(" (dir) = %24.12f\n", e_direct); - mprintf(" (adj) = %24.12f\n", e_adjust); - mprintf(" E vanDerWaals (dir) = %24.12f\n", e_vdw); + mprintf(" (dir) = %24.12f\n", NBengine_.Eelec()); + mprintf(" (adj) = %24.12f\n", NBengine_.Eadjust()); + mprintf(" E vanDerWaals (dir) = %24.12f\n", NBengine_.Evdw()); mprintf(" (LR) = %24.12f\n", e_vdw_lr_correction); - mprintf(" (6slf) = %24.12f\n", e_vdw6self); - mprintf(" (6rcp) = %24.12f\n", e_vdw6recip); } - e_vdw += (e_vdw_lr_correction + e_vdw6self + e_vdw6recip); + e_vdw = NBengine_.Evdw() + e_vdw_lr_correction; + e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); t_total_.Stop(); - e_elec = e_self + e_recip + e_direct + e_adjust; return 0; } diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h index 0007519c26..7aa84adf7d 100644 --- a/src/Energy/Calc_PME.h +++ b/src/Energy/Calc_PME.h @@ -26,6 +26,7 @@ class Calc_PME { PairList pairList_; ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction + Timer t_total_; }; } } diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 2da52b01cb..07c56c8410 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -46,6 +46,8 @@ class EwaldParams { /// \return Nonbonded parameter at nonobonded parameter index NonbondType const& GetLJ(int nbindex) const { return NB_->NBarray()[ nbindex ]; } + /// \return Debug level + int Debug() const { return debug_; } /// \return Direct space cutoff (in Ang) double Cutoff() const { return cutoff_; } /// \return Direct sum tolerance @@ -56,9 +58,12 @@ class EwaldParams { double LJ_EwaldCoeff() const { return lw_coeff_; } /// \return LJ switch width (in Ang.) double LJ_SwitchWidth() const { return switch_width_; } + + // FIXME do not return const because helPME needs the array to be non-const. Should be fixed + std::vector& SelectedCharges() { return Charge_; } protected: - typedef std::vector Iarray; typedef std::vector Darray; + typedef std::vector Iarray; /// \return Charge array Darray const& Charge() const { return Charge_; } diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h index c2e05ad03e..5f58b40fe1 100644 --- a/src/Energy/EwaldParams_PME.h +++ b/src/Energy/EwaldParams_PME.h @@ -11,6 +11,13 @@ class EwaldParams_PME : public EwaldParams { int SetupEwald(Topology const&, AtomMask const&); void FillRecipCoords(Frame const&, AtomMask const&); + + // FIXME do not return const because helPME needs the array to be non-const. Should be fixed + Darray& SelectedCoords() { return coordsD_; } + /// \return NFFT array pointer + const int* NFFT() const { return nfft_; } + /// \return B-spline order + int Order() const { return order_; } private: Darray coordsD_; ///< Hold coords for selected atoms (for recip. calc) int nfft_[3]; ///< Number of FFT grid points in each direction diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 2ba4f984ff..8ad8d588c9 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,8 +1,8 @@ -Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h +Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h -EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Constants.h ../CpptrajStdio.h ../EwaldOptions.h ../MaskToken.h ../Molecule.h ../NameType.h ../ParameterTypes.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h +EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h PME_Recip.o : PME_Recip.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 5af009fd24..ea22da83f4 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -55,6 +55,10 @@ class PairListEngine_Ewald_LJLR { // ------------------------------------------- Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } Cpptraj::Energy::EwaldParams_PME const& EwaldParams() const { return EW_; } + + T Evdw() const { return Evdw_; } + T Eelec() const { return Eelec_; } + T Eadjust() const { return Eadjust_; } private: T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 From c3bc274a1397fe63d3758ce032d3f4767f88d9d4 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 13:43:28 -0400 Subject: [PATCH 060/218] Remove separate EwaldDecomp for now --- src/Energy/EnergyDecomp_Ewald.cpp | 223 ------------------------------ src/Energy/EnergyDecomp_Ewald.h | 40 ------ src/Energy/energydepend | 1 - src/Energy/energyfiles | 1 - 4 files changed, 265 deletions(-) delete mode 100644 src/Energy/EnergyDecomp_Ewald.cpp delete mode 100644 src/Energy/EnergyDecomp_Ewald.h diff --git a/src/Energy/EnergyDecomp_Ewald.cpp b/src/Energy/EnergyDecomp_Ewald.cpp deleted file mode 100644 index 7b7841091a..0000000000 --- a/src/Energy/EnergyDecomp_Ewald.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include "EnergyDecomp_Ewald.h" -#include "../ExclusionArray.h" -#include "../ParameterTypes.h" -#include - -using namespace Cpptraj::Energy; - -EnergyDecomp_Ewald::EnergyDecomp_Ewald() {} - -// ----------------------------------------------------------------------------- - -double EnergyDecomp_Ewald::ERFC(double rIn) { -# ifdef _OPENMP - return EW_.ErfcEW( rIn ); -# else - t_erfc_.Start(); - double erfcval = EW_.ErfcEW( rIn ); - t_erfc_.Stop(); - return erfcval; -# endif -} - -double EnergyDecomp_Ewald::adjust(double q0, double q1, double rij) { - t_adjust_.Start(); - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(rij); - double d0 = (erfc - 1.0) / rij; - t_adjust_.Stop(); - return (q0 * q1 * d0); -} - -void EnergyDecomp_Ewald::calcAdjust(double& e_adjust, double& Eljpme_correction_excl, - PairList::AtmType const& atom0, - PairList::AtmType const& atom1, - double q0, double q1, double rij2) -{ - e_adjust += adjust(q0, q1, sqrt(rij2)); - if (EW_.LW_Coeff() > 0.0) { - // LJ PME direct space exclusion correction - // NOTE: Assuming excluded pair is within cutoff - double kr2 = EW_.LW_Coeff() * EW_.LW_Coeff() * rij2; - double kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - double expterm = exp(-kr2); - double r4 = rij2 * rij2; - double r6 = rij2 * r4; - double Cij = Cparam_[atom0.Idx()] * Cparam_[atom1.Idx()]; - Eljpme_correction_excl += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; - } -} - -/** Nonbonded energy */ -void EnergyDecomp_Ewald::ene_nb(double& Eelec, double& Evdw, double& Eljpme_correction, - double rij2, double q0, double q1, - PairList::AtmType const& atom0, - PairList::AtmType const& atom1) -{ - double rij = sqrt( rij2 ); - double qiqj = q0 * q1; - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(rij); - double e_elec = qiqj * erfc / rij; - Eelec += e_elec; - //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", - //int ta0, ta1; - //if (it0->Idx() < it1->Idx()) { - // ta0=it0->Idx(); ta1=it1->Idx(); - //} else { - // ta1=it0->Idx(); ta0=it1->Idx(); - //} - //mprintf("PELEC %6i%6i%12.5f%12.5f%12.5f\n", ta0, ta1, rij, erfc, e_elec); - int nbindex = NB_->GetLJindex(TypeIndices_[atom0.Idx()], - TypeIndices_[atom1.Idx()]); - if (nbindex > -1) { - double vswitch = EW_.Switch_Fn(rij2); - NonbondType const& LJ = NB_->NBarray()[ nbindex ]; - double r2 = 1.0 / rij2; - double r6 = r2 * r2 * r2; - double r12 = r6 * r6; - double f12 = LJ.A() * r12; // A/r^12 - double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) - Evdw += (e_vdw * vswitch); - //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); - if (EW_.LW_Coeff() > 0.0) { - // LJ PME direct space correction - double kr2 = EW_.LW_Coeff() * EW_.LW_Coeff() * rij2; - double kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - double expterm = exp(-kr2); - double Cij = Cparam_[atom0.Idx()] * Cparam_[atom1.Idx()]; - Eljpme_correction += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; - } - } -} - -/** Direct space nonbonded energy calculation for Ewald */ -void EnergyDecomp_Ewald::ene_ewald_direct(double& Eelec, double& evdw_out, double& eadjust_out, - Frame const& frameIn, PairList const& PL, - ExclusionArray const& Excluded) -{ - t_direct_.Start(); - Eelec = 0.0; - double e_adjust = 0.0; - double Evdw = 0.0; - double Eljpme_correction = 0.0; - double Eljpme_correction_excl = 0.0; - int cidx; -# ifdef _OPENMP -# pragma omp parallel private(cidx) reduction(+: Eelec, Evdw, e_adjust, Eljpme_correction,Eljpme_correction_excl) - { -# pragma omp for -# endif - for (cidx = 0; cidx < PL.NGridMax(); cidx++) - { - PairList::CellType const& thisCell = PL.Cell( cidx ); - if (thisCell.NatomsInGrid() > 0) - { - // cellList contains this cell index and all neighbors. - PairList::Iarray const& cellList = thisCell.CellList(); - // transList contains index to translation for the neighbor. - PairList::Iarray const& transList = thisCell.TransList(); - // Loop over all atoms of thisCell. - for (PairList::CellType::const_iterator it0 = thisCell.begin(); - it0 != thisCell.end(); ++it0) - { - Vec3 const& xyz0 = it0->ImageCoords(); - double q0 = Charge_[it0->Idx()]; -# ifdef DEBUG_PAIRLIST - mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); -# endif - // Exclusion list for this atom - ExclusionArray::ExListType const& excluded = Excluded[it0->Idx()]; - // Calc interaction of atom to all other atoms in thisCell. - for (PairList::CellType::const_iterator it1 = it0 + 1; - it1 != thisCell.end(); ++it1) - { - Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; - Vec3 dxyz = xyz1 - xyz0; - double rij2 = dxyz.Magnitude2(); -# ifdef DEBUG_PAIRLIST - mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - // If atom excluded, calc adjustment, otherwise calc elec. energy. - if (excluded.find( it1->Idx() ) == excluded.end()) - { - - if ( rij2 < EW_.Cut2() ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif - ene_nb(Eelec, Evdw, Eljpme_correction, rij2, q0, q1, *it0, *it1); // FIXME - } - } else { - calcAdjust(e_adjust, Eljpme_correction_excl, *it0, *it1, q0, q1, rij2); //FIXME - } - } // END loop over other atoms in thisCell - // Loop over all neighbor cells - for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) - { - PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); -# endif - // Translate vector for neighbor cell - Vec3 const& tVec = PL.TransVec( transList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); -# endif - //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); - // Loop over every atom in nbrCell - for (PairList::CellType::const_iterator it1 = nbrCell.begin(); - it1 != nbrCell.end(); ++it1) - { - Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; - Vec3 dxyz = xyz1 + tVec - xyz0; - double rij2 = dxyz.Magnitude2(); - //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); -# ifdef DEBUG_PAIRLIST - mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - //mprintf("\t\tNbrAtom %06i\n",atnum1); - // If atom excluded, calc adjustment, otherwise calc elec. energy. - // TODO Is there better way of checking this? - if (excluded.find( it1->Idx() ) == excluded.end()) - { - - //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); - if ( rij2 < EW_.Cut2() ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif - ene_nb(Eelec, Evdw, Eljpme_correction, rij2, q0, q1, *it0, *it1); // FIXME - } - } else { - calcAdjust(e_adjust, Eljpme_correction_excl, *it0, *it1, q0, q1, rij2); //FIXME - } - } // END loop over neighbor cell atoms - } // END Loop over neighbor cells - } // Loop over thisCell atoms - } // END if thisCell is not empty - } // Loop over cells - t_direct_.Stop(); -# ifdef DEBUG_PAIRLIST - mprintf("DEBUG: Elec = %16.8f\n", Eelec); - mprintf("DEBUG: Eadjust = %16.8f\n", e_adjust); - mprintf("DEBUG: LJ vdw = %16.8f\n", Evdw); - mprintf("DEBUG: LJ vdw PME correction = %16.8f\n", Eljpme_correction); - mprintf("DEBUG: LJ vdw PME correction (excluded) = %16.8f\n", Eljpme_correction_excl); -# endif - evdw_out = Evdw + Eljpme_correction + Eljpme_correction_excl; - eadjust_out = e_adjust; -} // END nb ewald - - diff --git a/src/Energy/EnergyDecomp_Ewald.h b/src/Energy/EnergyDecomp_Ewald.h deleted file mode 100644 index 18aac82a5b..0000000000 --- a/src/Energy/EnergyDecomp_Ewald.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef INC_ENERGY_ENERGYDECOMP_EWALD_H -#define INC_ENERGY_ENERGYDECOMP_EWALD_H -#include -#include "EwaldParams.h" -#include "../PairList.h" // For AtmType -class ExclusionArray; -class Frame; -class NonbondParmType; -namespace Cpptraj { -namespace Energy { -class EnergyDecomp_Ewald { - public: - EnergyDecomp_Ewald(); - private: - typedef std::vector Iarray; - typedef std::vector Darray; - - double ERFC(double); - double adjust(double, double, double); - void calcAdjust(double&, double&, PairList::AtmType const&, PairList::AtmType const&, - double, double, double); - void ene_nb(double&, double&, double&, - double, double, double, PairList::AtmType const&, PairList::AtmType const&); - void ene_ewald_direct(double&, double&, double&, Frame const&, - PairList const&, ExclusionArray const&); - - EwaldParams EW_; - Darray Charge_; ///< Array of charges - Darray Cparam_; ///< Array of C6 coefficients for LJPME - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - - Timer t_direct_; - Timer t_adjust_; - Timer t_erfc_; - -}; -} -} -#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 8ad8d588c9..a58f74e113 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,4 @@ Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h -EnergyDecomp_Ewald.o : EnergyDecomp_Ewald.cpp ../Box.h ../Constants.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../Timer.h ../Vec3.h EnergyDecomp_Ewald.h ErfcFxn.h EwaldParams.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 40aa8cb5b2..501a0a522f 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,7 +1,6 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ Calc_PME.cpp \ - EnergyDecomp_Ewald.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ EwaldParams.cpp \ From 071e732cdfb5320c643944748cf575346dcf4a65 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 14:00:53 -0400 Subject: [PATCH 061/218] Add timing data --- src/Energy/Calc_PME.cpp | 17 +++++++++++++++-- src/Energy/Calc_PME.h | 2 ++ src/Energy/PME_Recip.h | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 503f80a9de..6979886f20 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -93,9 +93,10 @@ int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, // e_vdw6recip = 0.0; double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); //} - + t_direct_.Start(); Cpptraj::PairListTemplate(pairList_, Excluded_, NBengine_.EwaldParams().Cut2(), NBengine_); + t_direct_.Stop(); if (NBengine_.EwaldParams().Debug() > 0) { mprintf("DEBUG: Nonbond energy components:\n"); @@ -117,4 +118,16 @@ int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, return 0; } - +void Calc_PME::Timing(double total) const { + t_total_.WriteTiming(1, " PME Total:", total); + //t_self_.WriteTiming(2, "Self: ", t_total_.Total()); + Recip_.Timing().WriteTiming(2, "Recip: ", t_total_.Total()); +// if (t_trig_tables_.Total() > 0.0) +// t_trig_tables_.WriteTiming(3, "Calc trig tables:", t_recip_.Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); +//# ifndef _OPENMP +// t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); +// t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); +//# endif +// pairList_.Timing(total); +} diff --git a/src/Energy/Calc_PME.h b/src/Energy/Calc_PME.h index 7aa84adf7d..7cc1e7792f 100644 --- a/src/Energy/Calc_PME.h +++ b/src/Energy/Calc_PME.h @@ -20,6 +20,7 @@ class Calc_PME { int Setup(Topology const&, AtomMask const&); int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); + void Timing(double) const; private: PairListEngine_Ewald_LJLR NBengine_; PME_Recip Recip_; @@ -27,6 +28,7 @@ class Calc_PME { ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction Timer t_total_; + Timer t_direct_; }; } } diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 0c729ac02e..914e677670 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -16,6 +16,8 @@ class PME_Recip { PME_Recip(Type); void SetDebug(int); double Recip_ParticleMesh(Darray&, Box const&, Darray&, const int*, double, int); + + Timer const& Timing() const { return t_recip_; } private: static bool check_prime_factors(int); static int ComputeNFFT(double); From 9f2b07681b6537aaa77d86b394e46a5e81e63bd7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 14:48:08 -0400 Subject: [PATCH 062/218] Report pairlist timing data --- src/Energy/Calc_PME.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 6979886f20..8c341139cb 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -129,5 +129,5 @@ void Calc_PME::Timing(double total) const { // t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); // t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); //# endif -// pairList_.Timing(total); + pairList_.Timing(total); } From 1fded79132e89c8cf44c213ba41c68c25fb855de Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 14:48:23 -0400 Subject: [PATCH 063/218] New test action for comparing the old and new PME methods --- src/Action_PmeTest.cpp | 107 +++++++++++++++++++++++++++++++++++++++++ src/Action_PmeTest.h | 31 ++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/Action_PmeTest.cpp create mode 100644 src/Action_PmeTest.h diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp new file mode 100644 index 0000000000..483a87140d --- /dev/null +++ b/src/Action_PmeTest.cpp @@ -0,0 +1,107 @@ +#include "Action_PmeTest.h" +#include "CpptrajStdio.h" + +Action_PmeTest::Action_PmeTest() { + SetHidden(true); +} + +// Action_PmeTest::Help() +void Action_PmeTest::Help() const { + mprintf("\t[ %s\n", EwaldOptions::KeywordsPME()); + mprintf("\t %s\n", EwaldOptions::KeywordsCommon1()); + mprintf("\t %s ]\n", EwaldOptions::KeywordsCommon2()); + mprintf("\t{orginal|new} [out ] [] []\n"); +} + +// Action_PmeTest::Init() +Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int debugIn) +{ + debug_ = debugIn; + if (ewaldOpts_.GetOptions(EwaldOptions::PME, actionArgs, "pmetest")) { + mprinterr("Error: Could not get Ewald options.\n"); + return Action::ERR; + } + if (actionArgs.hasKey("original")) + method_ = 0; + else if (actionArgs.hasKey("new")) + method_ = 1; + else { + mprinterr("Error: Specify original or new.\n"); + return Action::ERR; + } + DataFile* outfile = init.DFL().AddDataFile( actionArgs.GetStringKey("out"), actionArgs ); + + if (Mask1_.SetMaskString( actionArgs.GetMaskNext() )) return Action::ERR; + std::string setname_ = actionArgs.GetStringNext(); + if (setname_.empty()) + setname_ = init.DSL().GenerateDefaultName("PME"); + ele_ = init.DSL().AddSet( DataSet::DOUBLE, MetaData(setname_, "ELE") ); + vdw_ = init.DSL().AddSet( DataSet::DOUBLE, MetaData(setname_, "VDW") ); + if (ele_ == 0 || vdw_ == 0) { + mprinterr("Error: Could not allocate data sets.\n"); + return Action::ERR; + } + if (outfile != 0) { + outfile->AddDataSet(ele_); + outfile->AddDataSet(vdw_); + } + + mprintf(" ENERGY: Calculating energy for atoms in mask '%s'\n", Mask1_.MaskString()); + if (method_ == 0) + mprintf("\tOriginal PME method.\n"); + else if (method_ == 1) + mprintf("\tNew PME method.\n"); + + ewaldOpts_.PrintOptions(); + + return Action::OK; +} + +// Action_PmeTest::Setup() +Action::RetType Action_PmeTest::Setup(ActionSetup& setup) +{ + // Set up mask + if (setup.Top().SetupIntegerMask(Mask1_)) return Action::ERR; + if (Mask1_.None()) { + mprintf("Warning: Mask '%s' selects no atoms.\n", Mask1_.MaskString()); + return Action::SKIP; + } + Mask1_.MaskInfo(); + + if (method_ == 0) { + if (PME0_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + return Action::ERR; + PME0_.Setup( setup.Top(), Mask1_ ); + } else if (method_ == 1) { + if (PME1_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + return Action::ERR; + if (PME1_.Setup( setup.Top(), Mask1_ )) + return Action::ERR; + } + return Action::OK; +} + +// Action_PmeTest::DoAction() +Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) +{ + t_nb_.Start(); + double ene, ene2; + int err = 1; + if (method_ == 0) { + err = PME0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + } else if (method_ == 1) { + err = PME1_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + } + if (err != 0) return Action::ERR; + ele_->Add(frameNum, &ene); + vdw_->Add(frameNum, &ene2); + t_nb_.Stop(); + return Action::OK; +} + +void Action_PmeTest::Print() { + if (method_ == 0) + PME0_.Timing(t_nb_.Total()); + else if (method_ == 1) + PME1_.Timing(t_nb_.Total()); +} diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h new file mode 100644 index 0000000000..66916973d0 --- /dev/null +++ b/src/Action_PmeTest.h @@ -0,0 +1,31 @@ +#ifndef INC_ACTION_PMETEST_H +#define INC_ACTION_PMETEST_H +#include "Action.h" +#include "Energy/Calc_PME.h" +#include "Ewald_ParticleMesh.h" +#include "EwaldOptions.h" +#include "Timer.h" +/// +class Action_PmeTest : public Action { + public: + Action_PmeTest(); + DispatchObject* Alloc() const { return (DispatchObject*)new Action_PmeTest(); } + void Help() const; + private: + Action::RetType Init(ArgList&, ActionInit&, int); + Action::RetType Setup(ActionSetup&); + Action::RetType DoAction(int, ActionFrame&); + void Print(); + + Ewald_ParticleMesh PME0_; + Cpptraj::Energy::Calc_PME PME1_; + EwaldOptions ewaldOpts_; + AtomMask Mask1_; + DataSet* ele_; + DataSet* vdw_; + Timer t_nb_; + + int method_; + int debug_; +}; +#endif From 7686d35c44db5e445db8e1dbc08f401d2d148d5b Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 14:48:57 -0400 Subject: [PATCH 064/218] Enable the new pmetest action (hidden) --- src/Command.cpp | 2 ++ src/cpptrajdepend | 9 ++++++++- src/cpptrajfiles | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Command.cpp b/src/Command.cpp index b4c6b91013..235c3f3d9e 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -165,6 +165,7 @@ #include "Action_MinMaxDist.h" #include "Action_AddAtom.h" #include "Action_EneDecomp.h" +#include "Action_PmeTest.h" // ----- ANALYSIS -------------------------------------------------------------- #include "Analysis_Hist.h" #include "Analysis_Corr.h" @@ -381,6 +382,7 @@ void Command::Init() { Command::AddCmd( new Action_Outtraj(), Cmd::ACT, 1, "outtraj" ); Command::AddCmd( new Action_PairDist(), Cmd::ACT, 1, "pairdist" ); Command::AddCmd( new Action_Pairwise(), Cmd::ACT, 1, "pairwise" ); + Command::AddCmd( new Action_PmeTest(), Cmd::ACT, 1, "pmetest" ); // hidden Command::AddCmd( new Action_Principal(), Cmd::ACT, 1, "principal" ); Command::AddCmd( new Action_Projection(), Cmd::ACT, 1, "projection" ); Command::AddCmd( new Action_Pucker(), Cmd::ACT, 1, "pucker" ); diff --git a/src/cpptrajdepend b/src/cpptrajdepend index a47ea37562..8d47bb9845 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,6 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -190,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -276,7 +277,13 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h +Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h +Energy/PME_Recip.o : Energy/PME_Recip.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Energy/PME_Recip.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index bdb04fd255..4c8c4b2635 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -67,6 +67,7 @@ COMMON_SOURCES= \ Action_Outtraj.cpp \ Action_PairDist.cpp \ Action_Pairwise.cpp \ + Action_PmeTest.cpp \ Action_Principal.cpp \ Action_Projection.cpp \ Action_Pucker.cpp \ From a8ca18841b74f6343390a06b88e349d0ace7ec56 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 15:04:21 -0400 Subject: [PATCH 065/218] Ensure previous coords are cleared --- src/Energy/EwaldParams_PME.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp index 5af5d6ade5..b35e256d31 100644 --- a/src/Energy/EwaldParams_PME.cpp +++ b/src/Energy/EwaldParams_PME.cpp @@ -76,6 +76,7 @@ int EwaldParams_PME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { /** Put selected coords in separate array for recip calc. */ void EwaldParams_PME::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) { + coordsD_.clear(); for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { const double* XYZ = frameIn.XYZ( *atm ); coordsD_.push_back( XYZ[0] ); From 8deddbe778349d3cea375b6ca129e88080300dd5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 20 Sep 2024 15:59:36 -0400 Subject: [PATCH 066/218] Add unit cell vector check to recip part --- src/Energy/PME_Recip.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 23c7c04853..bf54457732 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -130,6 +130,18 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); + // Check the unit cell vectors + PMEInstanceD::LatticeType lattice = PMEInstanceD::LatticeType::XAligned; + // TODO just pass in Ucell when helPME supports it + //boxIn.PrintDebug("pme"); + if (!boxIn.Is_X_Aligned()) { + if (boxIn.Is_Symmetric()) + lattice = PMEInstanceD::LatticeType::ShapeMatrix; + else { + mprinterr("Error: Unit cell is not X-aligned or symmetric; cannot set PME recip grid.\n"); + return 0; + } + } // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. // Args: 1 = the A lattice parameter in units consistent with the coordinates. // 2 = the B lattice parameter in units consistent with the coordinates. @@ -140,7 +152,7 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray // 7 = lattice type pme_object_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), - PMEInstanceD::LatticeType::XAligned); + lattice); double erecip = pme_object_.computeERec(0, chargesD, coordsD); t_recip_.Stop(); From 8a2e9765604623f217778798a507ab8002b50d3a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 13:28:47 -0400 Subject: [PATCH 067/218] Move LJ ewald coeff into a separate class --- src/Energy/CMakeLists.txt | 2 +- src/Energy/EwaldParams.cpp | 14 ++------------ src/Energy/EwaldParams.h | 7 ++----- src/Energy/EwaldParams_LJPME.cpp | 29 +++++++++++++++++++++++++++++ src/Energy/EwaldParams_LJPME.h | 21 +++++++++++++++++++++ src/Energy/EwaldParams_PME.cpp | 7 ++----- src/Energy/energydepend | 1 + src/Energy/energyfiles | 1 + src/cpptrajdepend | 1 + 9 files changed, 60 insertions(+), 23 deletions(-) create mode 100644 src/Energy/EwaldParams_LJPME.cpp create mode 100644 src/Energy/EwaldParams_LJPME.h diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 5b06b676c1..98477702fd 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,10 +1,10 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/Calc_PME.cpp - ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomp_Ewald.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index e1709fa235..00e3fade29 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -9,7 +9,6 @@ using namespace Cpptraj::Energy; /** CONSTRUCTOR */ EwaldParams::EwaldParams() : ew_coeff_(0.0), - lw_coeff_(0.0), switch_width_(0.0), cutoff_(0.0), cut2_(0.0), @@ -21,7 +20,6 @@ EwaldParams::EwaldParams() : sumq2_(0) {} -static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } /** Determine Ewald coefficient from cutoff and direct sum tolerance. * Original Code: SANDER: findewaldcof @@ -60,14 +58,12 @@ double EwaldParams::FindEwaldCoefficient(double cutoff, double dsum_tol) /** Check some common input. */ int EwaldParams::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, double dsumTolIn, - double ew_coeffIn, double lw_coeffIn, double switch_widthIn, - double erfcTableDxIn, double skinnbIn) + double ew_coeffIn, double switch_widthIn, double erfcTableDxIn, double skinnbIn) { debug_ = debugIn; cutoff_ = cutoffIn; dsumTol_ = dsumTolIn; ew_coeff_ = ew_coeffIn; - lw_coeff_ = lw_coeffIn; switch_width_ = switch_widthIn; double erfcTableDx = erfcTableDxIn; // Check input @@ -105,13 +101,7 @@ int EwaldParams::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, doub mprinterr("Error: Could not set up spline table for ERFC\n"); return 1; } - // TODO do for C6 as well - // TODO for C6 correction term - if (lw_coeff_ < 0.0) - lw_coeff_ = 0.0; - else if (DABS(lw_coeff_) < Constants::SMALL) - lw_coeff_ = ew_coeff_; - + // Calculate some common factors. cut2_ = cutoff_ * cutoff_; double cut0 = cutoff_ - switch_width_; diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 07c56c8410..98e78cfc03 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -54,8 +54,6 @@ class EwaldParams { double DirectSumTol() const { return dsumTol_; } /// \return Ewald coefficient double EwaldCoeff() const { return ew_coeff_; } - /// \return LJ Ewald coefficient - double LJ_EwaldCoeff() const { return lw_coeff_; } /// \return LJ switch width (in Ang.) double LJ_SwitchWidth() const { return switch_width_; } @@ -65,12 +63,12 @@ class EwaldParams { typedef std::vector Darray; typedef std::vector Iarray; + static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } /// \return Charge array Darray const& Charge() const { return Charge_; } /// Set Ewald parametsr, check them and set defaults if needed. int CheckInput(Box const&, int, double, double, - double, double, double, - double, double); + double, double, double, double); /// Calculate sum q, sum q^2. void CalculateCharges(Topology const&, AtomMask const&); private: @@ -78,7 +76,6 @@ class EwaldParams { double FindEwaldCoefficient(double, double); double ew_coeff_; ///< Ewald coefficient - double lw_coeff_; ///< LJ Ewald coefficient double switch_width_; ///< Switching window size for LJ switch if active double cutoff_; ///< Direct space cutoff double cut2_; ///< Direct space cutoff squared. diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp new file mode 100644 index 0000000000..e2e02ad6a4 --- /dev/null +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -0,0 +1,29 @@ +#include "EwaldParams_LJPME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR */ +EwaldParams_LJPME::EwaldParams_LJPME() : + lw_coeff_(0.0) +{} + +/** Set up LJPME parameters. */ +int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + if (EwaldParams_PME::InitEwald(boxIn, pmeOpts, debugIn)) return 1; + + lw_coeff_ = pmeOpts.LwCoeff(); + + // TODO do for C6 as well + // TODO for C6 correction term + if (lw_coeff_ < 0.0) + lw_coeff_ = 0.0; + else if (DABS(lw_coeff_) < Constants::SMALL) + lw_coeff_ = EwaldCoeff(); + + if (LJ_EwaldCoeff() > 0.0) + mprintf("\t LJ Ewald coeff.= %g\n", LJ_EwaldCoeff()); + return 0; +} diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h new file mode 100644 index 0000000000..0f6120645e --- /dev/null +++ b/src/Energy/EwaldParams_LJPME.h @@ -0,0 +1,21 @@ +#ifndef INC_ENERGY_EWALDPARAMS_LJPME_H +#define INC_ENERGY_EWALDPARAMS_LJPME_H +#include "EwaldParams_PME.h" +namespace Cpptraj { +namespace Energy { +class EwaldParams_LJPME : public EwaldParams_PME { + public: + EwaldParams_LJPME(); + + int InitEwald(Box const&, EwaldOptions const&, int); + int SetupEwald(Topology const&, AtomMask const&); + + /// \return LJ Ewald coefficient + double LJ_EwaldCoeff() const { return lw_coeff_; } + + private: + double lw_coeff_; ///< LJ Ewald coefficient +}; +} +} +#endif diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp index b35e256d31..fc5bd4d434 100644 --- a/src/Energy/EwaldParams_PME.cpp +++ b/src/Energy/EwaldParams_PME.cpp @@ -24,8 +24,7 @@ int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, in return 1; } if (CheckInput(boxIn, debugIn, pmeOpts.Cutoff(), pmeOpts.DsumTol(), pmeOpts.EwCoeff(), - pmeOpts.LwCoeff(), pmeOpts.LJ_SwWidth(), - pmeOpts.ErfcDx(), pmeOpts.SkinNB())) + pmeOpts.LJ_SwWidth(), pmeOpts.ErfcDx(), pmeOpts.SkinNB())) return 1; nfft_[0] = pmeOpts.Nfft1(); nfft_[1] = pmeOpts.Nfft2(); @@ -38,9 +37,7 @@ int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, in mprintf("\tParticle Mesh Ewald params:\n"); mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", Cutoff(), DirectSumTol(), EwaldCoeff(), pmeOpts.SkinNB()); - if (LJ_EwaldCoeff() > 0.0) - mprintf("\t LJ Ewald coeff.= %g\n", LJ_EwaldCoeff()); - if (LJ_SwitchWidth() > 0.0) + if (LJ_SwitchWidth() > 0.0) mprintf("\t LJ switch width= %g\n", LJ_SwitchWidth()); mprintf("\t Bspline order= %i\n", order_); //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); diff --git a/src/Energy/energydepend b/src/Energy/energydepend index a58f74e113..768adbb630 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -2,6 +2,7 @@ Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Cons EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h +EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Constants.h ../ParameterTypes.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h PME_Recip.o : PME_Recip.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 501a0a522f..8a39650cdc 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -4,6 +4,7 @@ ENERGY_SOURCES= \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ EwaldParams.cpp \ + EwaldParams_LJPME.cpp \ EwaldParams_PME.cpp \ PME_Recip.cpp \ VDW_LongRange_Correction.cpp diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 8d47bb9845..ae3691d699 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -281,6 +281,7 @@ Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Const Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Constants.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h ParameterTypes.h SplineFxnTable.h Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h Energy/PME_Recip.o : Energy/PME_Recip.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Energy/PME_Recip.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From d77bfd2d94656810a58fdbff05d7f34d170720ec Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 13:41:38 -0400 Subject: [PATCH 068/218] Add C6 param and LJ self energy calcs --- src/Energy/EwaldParams_LJPME.cpp | 45 +++++++++++++++++++++++++++++--- src/Energy/EwaldParams_LJPME.h | 6 ++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp index e2e02ad6a4..b688ad876b 100644 --- a/src/Energy/EwaldParams_LJPME.cpp +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -1,12 +1,15 @@ #include "EwaldParams_LJPME.h" +#include "../AtomMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Topology.h" using namespace Cpptraj::Energy; /** CONSTRUCTOR */ EwaldParams_LJPME::EwaldParams_LJPME() : - lw_coeff_(0.0) + lw_coeff_(0.0), + ljpme_self_(0.0) {} /** Set up LJPME parameters. */ @@ -18,12 +21,46 @@ int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, // TODO do for C6 as well // TODO for C6 correction term - if (lw_coeff_ < 0.0) - lw_coeff_ = 0.0; - else if (DABS(lw_coeff_) < Constants::SMALL) + if (lw_coeff_ < 0.0) { + mprinterr("Internal Error: LJ PME requested but LJ Ewald coefficient is < 0\n"); + return 1; + } + // lw_coeff_ = 0.0; + //else + if (DABS(lw_coeff_) < Constants::SMALL) lw_coeff_ = EwaldCoeff(); if (LJ_EwaldCoeff() > 0.0) mprintf("\t LJ Ewald coeff.= %g\n", LJ_EwaldCoeff()); return 0; } + +/** Setup LJPME calculation. */ +int EwaldParams_LJPME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { + if (EwaldParams_PME::SetupEwald(topIn, maskIn)) return 1; + + // Calcuate C6 parameters + if (lw_coeff_ > 0.0) { + for (AtomMask::const_iterator atom = maskIn.begin(); atom != maskIn.end(); ++atom) + { + double rmin = topIn.GetVDWradius( *atom ); + double eps = topIn.GetVDWdepth( *atom ); + Cparam_.push_back( 8.0 * (rmin*rmin*rmin) * sqrt(2 * eps) ); + if (Debug() > 0) + mprintf("DEBUG: C6 param atom %8i = %16.8f\n", *atom+1, Cparam_.back()); + } + } else { + mprinterr("Internal Error: LJ PME setup called with LJ Ewald coefficient <= 0\n"); + return 1; + } + // Lennard-Jones self energy. (used to be Ewald::Self6()) + double ew2 = lw_coeff_ * lw_coeff_; + double ew6 = ew2 * ew2 * ew2; + double c6sum = 0.0; + for (Darray::const_iterator it = Cparam_.begin(); it != Cparam_.end(); ++it) + c6sum += ew6 * (*it * *it); + ljpme_self_ = c6sum / 12.0; + + return 0; +} + diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index 0f6120645e..cffd9aac4a 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -13,8 +13,12 @@ class EwaldParams_LJPME : public EwaldParams_PME { /// \return LJ Ewald coefficient double LJ_EwaldCoeff() const { return lw_coeff_; } + /// \return LJPME self energy + double Self6() const; private: - double lw_coeff_; ///< LJ Ewald coefficient + Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME + double lw_coeff_; ///< LJ Ewald coefficient + double ljpme_self_; ///< LJ PME self energy calculated from C6 parameters and LJ Ewald coeff. }; } } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 768adbb630..2651e22e34 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -2,7 +2,7 @@ Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Cons EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h -EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Constants.h ../ParameterTypes.h ../SplineFxnTable.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h +EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h PME_Recip.o : PME_Recip.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index ae3691d699..9503af9d03 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -281,7 +281,7 @@ Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Const Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Constants.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h ParameterTypes.h SplineFxnTable.h +Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h Energy/PME_Recip.o : Energy/PME_Recip.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Energy/PME_Recip.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From eaa69288bc078fa5a4e31d062020293690b04bdd Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 13:54:01 -0400 Subject: [PATCH 069/218] Return the precalculated self energy --- src/Energy/EwaldParams_LJPME.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index cffd9aac4a..ef0296fc1f 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -14,7 +14,7 @@ class EwaldParams_LJPME : public EwaldParams_PME { double LJ_EwaldCoeff() const { return lw_coeff_; } /// \return LJPME self energy - double Self6() const; + double Self6() const { return ljpme_self_; } private: Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME double lw_coeff_; ///< LJ Ewald coefficient From 68f29021447f9ff83e88cd0e5d763447bf531509 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 13:54:12 -0400 Subject: [PATCH 070/218] First pass at the LJPME engine --- src/PairListEngine_Ewald_LJPME.h | 97 ++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/PairListEngine_Ewald_LJPME.h diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h new file mode 100644 index 0000000000..b6aab9c4f7 --- /dev/null +++ b/src/PairListEngine_Ewald_LJPME.h @@ -0,0 +1,97 @@ +#ifndef INC_PAIRLISTENGINE_EWALD_LJPME_H +#define INC_PAIRLISTENGINE_EWALD_LJPME_H +#include "Energy/EwaldParams_LJPME.h" +#include "Energy/Kernel_EwaldAdjust.h" +#include "PairList.h" +#include +namespace Cpptraj { +/// Direct space nonbond calculation using pairlist with Ewald and LJPME for VDW +template +class PairListEngine_Ewald_LJPME { + typedef std::vector Iarray; + public: + PairListEngine_Ewald_LJLR() {} + // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; + Eljpme_correction_ = 0; Eljpme_correction_excl_ = 0; } + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = EW_.Charge(atom0.Idx()); + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = EW_.Charge(atom1.Idx()); + } + /// Call when cutoff is satisfied + void CutoffSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt( rij2 ); + T qiqj = q0_ * q1_; + //double erfc = erfc_func(ew_coeff_ * rij); + T erfcval = EW_.ErfcEW( rij ); + T e_elec = qiqj * erfcval / rij; + Eelec_ += e_elec; + + int nbindex = EW_.NbIndex(atom0.Idx(), atom1.Idx()); + if (nbindex > -1) { + double vswitch = EW_.Switch_Fn(rij2); + NonbondType const& LJ = EW_.GetLJ( nbindex ); + T r2 = 1.0 / rij2; + T r6 = r2 * r2 * r2; + T r12 = r6 * r6; + T f12 = LJ.A() * r12; // A/r^12 + T f6 = LJ.B() * r6; // B/r^6 + T e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + Evdw_ += (e_vdw * vswitch); + //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); + // LJ PME direct space correction + T kr2 = lw_coeff_ * lw_coeff_ * rij2; + T kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + T expterm = exp(-kr2); + T Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; + } + } + /// Call when cutoff is not satisfied + void CutoffNotSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt(rij2); + T erfcval = EW_.ErfcEW( rij ); + Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + // LJ PME direct space exclusion correction + // NOTE: Assuming excluded pair is within cutoff + T kr2 = lw_coeff_ * lw_coeff_ * rij2; + T kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + T expterm = exp(-kr2); + T r4 = rij2 * rij2; + T r6 = rij2 * r4; + T Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; + } + // ------------------------------------------- + Cpptraj::Energy::EwaldParams_LJPME& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams_LJPME const& EwaldParams() const { return EW_; } + + T Evdw() const { return Evdw_; } + T Eelec() const { return Eelec_; } + T Eadjust() const { return Eadjust_; } + private: + T q0_; ///< Charge on atom 0 + T q1_; ///< Charge on atom 1 + T Evdw_; ///< VDW sum for current frame + T Eelec_; ///< Coulomb sum for current frame + T Eadjust_; ///< Adjust energy sum for current frame + T Eljpme_correction_; ///< LJ PME correction for VDW + T Eljpme_correction_excl_; ///< LJ PME correction for adjust + + Cpptraj::Energy::EwaldParams_LJPME EW_; ///< Hold Ewald parameters for LJPME +}; +} // END namespace Cpptraj +#endif From 7b4ad372126de0cd39e2bdf345511fad1de34558 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 13:59:30 -0400 Subject: [PATCH 071/218] Use Ewald parameters --- src/Energy/EwaldParams_LJPME.h | 2 ++ src/PairListEngine_Ewald_LJPME.h | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index ef0296fc1f..6d8d7b3c82 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -15,6 +15,8 @@ class EwaldParams_LJPME : public EwaldParams_PME { /// \return LJPME self energy double Self6() const { return ljpme_self_; } + /// \return C6 parameter pair for specified selected atoms + double CalcCij(int idx0, int idx1) const { return (Cparam_[idx0] * Cparam_[idx1]); } private: Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME double lw_coeff_; ///< LJ Ewald coefficient diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index b6aab9c4f7..4765094434 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -48,11 +48,11 @@ class PairListEngine_Ewald_LJPME { Evdw_ += (e_vdw * vswitch); //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); // LJ PME direct space correction - T kr2 = lw_coeff_ * lw_coeff_ * rij2; + T kr2 = EW_.LJ_EwaldCoeff() * EW_.LJ_EwaldCoeff() * rij2; T kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; T expterm = exp(-kr2); - T Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + T Cij = EW_.CalcCij(it0->Idx(), it1->Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; } } @@ -66,13 +66,13 @@ class PairListEngine_Ewald_LJPME { Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); // LJ PME direct space exclusion correction // NOTE: Assuming excluded pair is within cutoff - T kr2 = lw_coeff_ * lw_coeff_ * rij2; + T kr2 = EW_.LJ_EwaldCoeff() * EW_.LJ_EwaldCoeff() * rij2; T kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; T expterm = exp(-kr2); T r4 = rij2 * rij2; T r6 = rij2 * r4; - T Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + T Cij = EW_.CalcCij(it0->Idx(), it1->Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; } // ------------------------------------------- From 11750cee45ca3d062b88519294e4e429aa0a866d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:06:52 -0400 Subject: [PATCH 072/218] Remove unneeded typedef --- src/PairListEngine_Ewald_LJLR.h | 2 -- src/PairListEngine_Ewald_LJPME.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index ea22da83f4..e76024cf39 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -4,12 +4,10 @@ #include "Energy/EwaldParams_PME.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" -#include namespace Cpptraj { /// Direct space nonbond calculation using pairlist with Ewald and VDW LR correction template class PairListEngine_Ewald_LJLR { - typedef std::vector Iarray; public: PairListEngine_Ewald_LJLR() {} // ------------------------------------------- diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index 4765094434..2ebca3e793 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -3,12 +3,10 @@ #include "Energy/EwaldParams_LJPME.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" -#include namespace Cpptraj { /// Direct space nonbond calculation using pairlist with Ewald and LJPME for VDW template class PairListEngine_Ewald_LJPME { - typedef std::vector Iarray; public: PairListEngine_Ewald_LJLR() {} // ------------------------------------------- From eb0dbbfaf35d4ffc94bea5a40579d11b0ce5ab38 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:14:49 -0400 Subject: [PATCH 073/218] Start the LJPME calc class --- src/Energy/Calc_LJPME.cpp | 9 +++++++++ src/Energy/Calc_LJPME.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/Energy/Calc_LJPME.cpp create mode 100644 src/Energy/Calc_LJPME.h diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp new file mode 100644 index 0000000000..2f67007fd0 --- /dev/null +++ b/src/Energy/Calc_LJPME.cpp @@ -0,0 +1,9 @@ +#include "Calc_LJPME.h" + +using namespace Cpptraj::Energy; + +Calc_LJPME::Calc_LJPME() : + Recip_(PME_Recip::COULOMB), + LJrecip_(PME_Recip::LJ) +{} + diff --git a/src/Energy/Calc_LJPME.h b/src/Energy/Calc_LJPME.h new file mode 100644 index 0000000000..828ebafe5b --- /dev/null +++ b/src/Energy/Calc_LJPME.h @@ -0,0 +1,29 @@ +#ifndef INC_ENERGY_CALC_LJPME_H +#define INC_ENERGY_CALC_LJPME_H +#include "PME_Recip.h" +#include "../ExclusionArray.h" +#include "../PairList.h" +#include "../PairListEngine_Ewald_LJPME.h" +namespace Cpptraj { +namespace Energy { +class Calc_LJPME { + public: + Calc_LJPME(); + /// Init with Box, EwaldOptions and debug level + int Init(Box const&, EwaldOptions const&, int); + int Setup(Topology const&, AtomMask const&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); + + void Timing(double) const; + private: + PairListEngine_Ewald_LJPME NBengine_; + PME_Recip Recip_; + PME_Recip LJrecip_; + PairList pairList_; + ExclusionArray Excluded_; + Timer t_total_; + Timer t_direct_; +}; +} +} +#endif From 85eb8ee6061537cc0bb83a56a824e74270d296c6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:14:58 -0400 Subject: [PATCH 074/218] Use the right variables --- src/PairListEngine_Ewald_LJPME.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index 2ebca3e793..a6e4fff586 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -8,7 +8,7 @@ namespace Cpptraj { template class PairListEngine_Ewald_LJPME { public: - PairListEngine_Ewald_LJLR() {} + PairListEngine_Ewald_LJPME() {} // ------------------------------------------- /// Call at the beginning of the frame calculation void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; @@ -50,7 +50,7 @@ class PairListEngine_Ewald_LJPME { T kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; T expterm = exp(-kr2); - T Cij = EW_.CalcCij(it0->Idx(), it1->Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; } } @@ -70,7 +70,7 @@ class PairListEngine_Ewald_LJPME { T expterm = exp(-kr2); T r4 = rij2 * rij2; T r6 = rij2 * r4; - T Cij = EW_.CalcCij(it0->Idx(), it1->Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; } // ------------------------------------------- From 78adfe3450129ef29284ff68b2bb5dbd839386ec Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:15:19 -0400 Subject: [PATCH 075/218] Add Calc_LJPME to build --- src/Energy/CMakeLists.txt | 1 + src/Energy/energydepend | 1 + src/Energy/energyfiles | 1 + src/cpptrajdepend | 1 + 4 files changed, 4 insertions(+) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 98477702fd..3bf022a9c5 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,5 +1,6 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/Calc_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/Calc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 2651e22e34..3660828e99 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,3 +1,4 @@ +Calc_LJPME.o : Calc_LJPME.cpp ../Box.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 8a39650cdc..436088776b 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,5 +1,6 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ + Calc_LJPME.cpp \ Calc_PME.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 9503af9d03..79de1f9a6e 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,6 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Box.h Constants.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h ExclusionArray.h Matrix_3x3.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterTypes.h SplineFxnTable.h Timer.h Vec3.h helpme_standalone.h Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h From 2cd111f911b2627e85af09bd63a460952a33c0bf Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:16:54 -0400 Subject: [PATCH 076/218] Add Init routine --- src/Energy/Calc_LJPME.cpp | 19 +++++++++++++++++++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index 2f67007fd0..96a158dd24 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -1,4 +1,6 @@ #include "Calc_LJPME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" using namespace Cpptraj::Energy; @@ -7,3 +9,20 @@ Calc_LJPME::Calc_LJPME() : LJrecip_(PME_Recip::LJ) {} +/** Set up LJPME parameters. */ +int Calc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: LJPME calculation init failed.\n"); + return 1; + } + if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + Recip_.SetDebug( debugIn ); + LJrecip_.SetDebug( debugIn ); + + return 0; +} + diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 3660828e99..ab2f21416e 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Calc_LJPME.o : Calc_LJPME.cpp ../Box.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h +Calc_LJPME.o : Calc_LJPME.cpp ../Box.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 79de1f9a6e..b7e3b15cc9 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,7 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Box.h Constants.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h ExclusionArray.h Matrix_3x3.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterTypes.h SplineFxnTable.h Timer.h Vec3.h helpme_standalone.h +Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Box.h Constants.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Matrix_3x3.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterTypes.h SplineFxnTable.h Timer.h Vec3.h helpme_standalone.h Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h From 13b0754679c6ff6e0f41f333cc8e9c32a1a1e15c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:18:08 -0400 Subject: [PATCH 077/218] Add Setup routine --- src/Energy/Calc_LJPME.cpp | 21 +++++++++++++++++++++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index 96a158dd24..ef447ab824 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -1,6 +1,7 @@ #include "Calc_LJPME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Topology.h" using namespace Cpptraj::Energy; @@ -26,3 +27,23 @@ int Calc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) return 0; } +/** Setup LJPME calculation. */ +int Calc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { + if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { + mprinterr("Error: LJPME calculation setup failed.\n"); + return 1; + } + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for LJPME calculation.\n"); + return 1; + } + + return 0; +} + + diff --git a/src/Energy/energydepend b/src/Energy/energydepend index ab2f21416e..4f132d00b4 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Calc_LJPME.o : Calc_LJPME.cpp ../Box.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Matrix_3x3.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h +Calc_LJPME.o : Calc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index b7e3b15cc9..100ac50d02 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,7 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Box.h Constants.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Matrix_3x3.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterTypes.h SplineFxnTable.h Timer.h Vec3.h helpme_standalone.h +Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h From 2c43c569b8cd0d69a7f3647c04003beb657fdce6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:30:38 -0400 Subject: [PATCH 078/218] Add nonbonded calc routine --- src/Energy/Calc_LJPME.cpp | 68 ++++++++++++++++++++++++++++++++ src/Energy/energydepend | 2 +- src/PairListEngine_Ewald_LJPME.h | 2 +- src/cpptrajdepend | 2 +- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index ef447ab824..ed2f845d4a 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -1,6 +1,7 @@ #include "Calc_LJPME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../PairListTemplate.h" #include "../Topology.h" using namespace Cpptraj::Energy; @@ -46,4 +47,71 @@ int Calc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +/** Calculate full nonbonded energy with LJPME */ +int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + double& e_elec, double& e_vdw) +{ + t_total_.Start(); + double volume = frameIn.BoxCrd().CellVolume(); + double e_self = NBengine_.EwaldParams().SelfEnergy( volume ); + + int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn); + if (retVal != 0) { + mprinterr("Error: Pairlist creation failed for LJPME calc.\n"); + return 1; + } + + // TODO make more efficient + NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); + + // MapCoords(frameIn, ucell, recip, maskIn); + // FIXME helPME requires coords and charge arrays to be non-const + double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + double e_vdw6recip = LJrecip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().LJ_EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: e_vdw6self = %16.8f\n", NBengine_.EwaldParams().Self6()); + mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); + } + + t_direct_.Start(); + Cpptraj::PairListTemplate(pairList_, Excluded_, + NBengine_.EwaldParams().Cut2(), NBengine_); + t_direct_.Stop(); + + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: Nonbond energy components:\n"); + mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + + NBengine_.EwaldParams().Self6() + + e_vdw6recip); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + + NBengine_.Eelec() + + NBengine_.Eadjust()); + mprintf("\n"); + mprintf(" E electrostatic (self) = %24.12f\n", e_self); + mprintf(" (rec) = %24.12f\n", e_recip); + mprintf(" (dir) = %24.12f\n", NBengine_.Eelec()); + mprintf(" (adj) = %24.12f\n", NBengine_.Eadjust()); + mprintf(" E vanDerWaals (dir) = %24.12f\n", NBengine_.Evdw()); + mprintf(" (6slf) = %24.12f\n", NBengine_.EwaldParams().Self6()); + mprintf(" (6rcp) = %24.12f\n", e_vdw6recip); + } + e_vdw = NBengine_.Evdw() + NBengine_.EwaldParams().Self6() + e_vdw6recip; + e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); + t_total_.Stop(); + return 0; +} + diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 4f132d00b4..24a21b2f79 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Calc_LJPME.o : Calc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h +Calc_LJPME.o : Calc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index a6e4fff586..fd9d3e70a8 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -77,7 +77,7 @@ class PairListEngine_Ewald_LJPME { Cpptraj::Energy::EwaldParams_LJPME& ModifyEwaldParams() { return EW_; } Cpptraj::Energy::EwaldParams_LJPME const& EwaldParams() const { return EW_; } - T Evdw() const { return Evdw_; } + T Evdw() const { return Evdw_ + Eljpme_correction_ + Eljpme_correction_excl_; } T Eelec() const { return Eelec_; } T Eadjust() const { return Eadjust_; } private: diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 100ac50d02..f8f367cce6 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,7 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h From a0568b4110634ad8935b031c4dae32ff9aebedf1 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:31:32 -0400 Subject: [PATCH 079/218] Add timing routine --- src/Energy/Calc_LJPME.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index ed2f845d4a..ed1c01427f 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -114,4 +114,10 @@ int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, return 0; } +void Calc_LJPME::Timing(double total) const { + t_total_.WriteTiming(1, " LJPME Total:", total); + Recip_.Timing().WriteTiming(2, "Recip: ", t_total_.Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); + pairList_.Timing(total); +} From 8a3127db9ed53eeb6148ebaf7dd81d963f0b3f95 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:46:40 -0400 Subject: [PATCH 080/218] Need to pass C6 params to LJPME recip calc, not charges --- src/Energy/Calc_LJPME.cpp | 2 +- src/Energy/EwaldParams_LJPME.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index ed1c01427f..e78f356672 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -76,7 +76,7 @@ int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, ); double e_vdw6recip = LJrecip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), - NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.ModifyEwaldParams().SelectedC6params(), NBengine_.EwaldParams().NFFT(), NBengine_.EwaldParams().LJ_EwaldCoeff(), NBengine_.EwaldParams().Order() diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index 6d8d7b3c82..16bac93443 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -17,6 +17,9 @@ class EwaldParams_LJPME : public EwaldParams_PME { double Self6() const { return ljpme_self_; } /// \return C6 parameter pair for specified selected atoms double CalcCij(int idx0, int idx1) const { return (Cparam_[idx0] * Cparam_[idx1]); } + + // FIXME do not return const because helPME needs the array to be non-const. Should be fixed + std::vector& SelectedC6params() { return Cparam_; } private: Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME double lw_coeff_; ///< LJ Ewald coefficient From c6ff7965551e1914006d6b2143aa53127d4d25ad Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:46:58 -0400 Subject: [PATCH 081/218] Test new LJPME calc --- src/Action_PmeTest.cpp | 15 ++++++++++++++- src/Action_PmeTest.h | 2 ++ src/cpptrajdepend | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index 483a87140d..350e531d4f 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -25,8 +25,10 @@ Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int method_ = 0; else if (actionArgs.hasKey("new")) method_ = 1; + else if (actionArgs.hasKey("newljpme")) + method_ = 2; else { - mprinterr("Error: Specify original or new.\n"); + mprinterr("Error: Specify original, new, or newljpme.\n"); return Action::ERR; } DataFile* outfile = init.DFL().AddDataFile( actionArgs.GetStringKey("out"), actionArgs ); @@ -51,6 +53,8 @@ Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int mprintf("\tOriginal PME method.\n"); else if (method_ == 1) mprintf("\tNew PME method.\n"); + else if (method_ == 2) + mprintf("\tNew LJPME method.\n"); ewaldOpts_.PrintOptions(); @@ -77,6 +81,11 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) return Action::ERR; if (PME1_.Setup( setup.Top(), Mask1_ )) return Action::ERR; + } else if (method_ == 2) { + if (PME2_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + return Action::ERR; + if (PME2_.Setup( setup.Top(), Mask1_ )) + return Action::ERR; } return Action::OK; } @@ -91,6 +100,8 @@ Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) err = PME0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } else if (method_ == 1) { err = PME1_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + } else if (method_ == 2) { + err = PME2_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } if (err != 0) return Action::ERR; ele_->Add(frameNum, &ene); @@ -104,4 +115,6 @@ void Action_PmeTest::Print() { PME0_.Timing(t_nb_.Total()); else if (method_ == 1) PME1_.Timing(t_nb_.Total()); + else if (method_ == 2) + PME2_.Timing(t_nb_.Total()); } diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h index 66916973d0..b74186de88 100644 --- a/src/Action_PmeTest.h +++ b/src/Action_PmeTest.h @@ -2,6 +2,7 @@ #define INC_ACTION_PMETEST_H #include "Action.h" #include "Energy/Calc_PME.h" +#include "Energy/Calc_LJPME.h" #include "Ewald_ParticleMesh.h" #include "EwaldOptions.h" #include "Timer.h" @@ -19,6 +20,7 @@ class Action_PmeTest : public Action { Ewald_ParticleMesh PME0_; Cpptraj::Energy::Calc_PME PME1_; + Cpptraj::Energy::Calc_LJPME PME2_; EwaldOptions ewaldOpts_; AtomMask Mask1_; DataSet* ele_; diff --git a/src/cpptrajdepend b/src/cpptrajdepend index f8f367cce6..f065e57dde 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Calc_LJPME.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Calc_LJPME.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 740f35e6c23ec9981fceb170a96142e2863b0718 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 23 Sep 2024 14:52:06 -0400 Subject: [PATCH 082/218] Report LJ PME recip timing in addition to regular recip timing --- src/Energy/Calc_LJPME.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index e78f356672..a1e94b87b7 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -117,6 +117,7 @@ int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, void Calc_LJPME::Timing(double total) const { t_total_.WriteTiming(1, " LJPME Total:", total); Recip_.Timing().WriteTiming(2, "Recip: ", t_total_.Total()); + LJrecip_.Timing().WriteTiming(2,"LJRecip: ", t_total_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); pairList_.Timing(total); From a87b1d67465bf53920b87d18586834254c6cfe05 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 24 Sep 2024 13:09:21 -0400 Subject: [PATCH 083/218] Openmp parallelize the pairlist template loop --- src/PairListEngine_Ewald_LJLR.h | 11 +++++++++++ src/PairListEngine_Ewald_LJPME.h | 13 +++++++++++++ src/PairListTemplate.h | 9 ++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index e76024cf39..9b7fccb46a 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -57,6 +57,14 @@ class PairListEngine_Ewald_LJLR { T Evdw() const { return Evdw_; } T Eelec() const { return Eelec_; } T Eadjust() const { return Eadjust_; } +# ifdef _OPENMP + /// To allow reduction of the energy terms + void operator+=(PairListEngine_Ewald_LJLR const& rhs) { + Evdw_ += rhs.Evdw_; + Eelec_ += rhs.Eelec_; + Eadjust_ += rhs.Eadjust_; + } +# endif private: T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 @@ -66,5 +74,8 @@ class PairListEngine_Ewald_LJLR { Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME }; +#ifdef _OPENMP +#pragma omp declare reduction( + : PairListEngine_Ewald_LJLR : omp_out += omp_in ) initializer( omp_priv = omp_orig ) +#endif } // END namespace Cpptraj #endif diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index fd9d3e70a8..254892857b 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -80,6 +80,16 @@ class PairListEngine_Ewald_LJPME { T Evdw() const { return Evdw_ + Eljpme_correction_ + Eljpme_correction_excl_; } T Eelec() const { return Eelec_; } T Eadjust() const { return Eadjust_; } +# ifdef _OPENMP + /// To allow reduction of the energy terms + void operator+=(PairListEngine_Ewald_LJPME const& rhs) { + Evdw_ += rhs.Evdw_; + Eelec_ += rhs.Eelec_; + Eadjust_ += rhs.Eadjust_; + Eljpme_correction_ += rhs.Eljpme_correction_; + Eljpme_correction_excl_ += rhs.Eljpme_correction_excl_; + } +# endif private: T q0_; ///< Charge on atom 0 T q1_; ///< Charge on atom 1 @@ -91,5 +101,8 @@ class PairListEngine_Ewald_LJPME { Cpptraj::Energy::EwaldParams_LJPME EW_; ///< Hold Ewald parameters for LJPME }; +#ifdef _OPENMP +#pragma omp declare reduction( + : PairListEngine_Ewald_LJPME : omp_out += omp_in ) initializer( omp_priv = omp_orig ) +#endif } // END namespace Cpptraj #endif diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h index 31571ec423..972da49791 100644 --- a/src/PairListTemplate.h +++ b/src/PairListTemplate.h @@ -11,7 +11,11 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2 engine.FrameBeginCalc(); int cidx; - +# ifdef _OPENMP +# pragma omp parallel private(cidx) reduction(+: engine) + { +# pragma omp for +# endif for (cidx = 0; cidx < PL.NGridMax(); cidx++) { PairList::CellType const& thisCell = PL.Cell( cidx ); @@ -108,6 +112,9 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2 } // Loop over thisCell atoms } // END if thisCell is not empty } // Loop over cells +# ifdef _OPENMP + } // END pragma omp parallel +# endif } // END PairListTemplate } // END namespace Cpptraj #endif From 64f0c08d3346061c8514e776219429f1ea9c4702 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 24 Sep 2024 13:40:12 -0400 Subject: [PATCH 084/218] Add timer to check that the recip calc itself is what takes the majority of the time, not setup (and it does). Comment it out. --- src/Energy/Calc_LJPME.cpp | 6 ++++-- src/Energy/Calc_PME.cpp | 3 ++- src/Energy/PME_Recip.cpp | 3 ++- src/Energy/PME_Recip.h | 4 +++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/Calc_LJPME.cpp index a1e94b87b7..41cef39552 100644 --- a/src/Energy/Calc_LJPME.cpp +++ b/src/Energy/Calc_LJPME.cpp @@ -116,8 +116,10 @@ int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, void Calc_LJPME::Timing(double total) const { t_total_.WriteTiming(1, " LJPME Total:", total); - Recip_.Timing().WriteTiming(2, "Recip: ", t_total_.Total()); - LJrecip_.Timing().WriteTiming(2,"LJRecip: ", t_total_.Total()); + Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); + //Recip_.Timing_Calc().WriteTiming(3, "Recip. Calc :", Recip_.Timing_Total().Total()); + LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); + //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); pairList_.Timing(total); diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/Calc_PME.cpp index 8c341139cb..b03dcddfdc 100644 --- a/src/Energy/Calc_PME.cpp +++ b/src/Energy/Calc_PME.cpp @@ -121,7 +121,8 @@ int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, void Calc_PME::Timing(double total) const { t_total_.WriteTiming(1, " PME Total:", total); //t_self_.WriteTiming(2, "Self: ", t_total_.Total()); - Recip_.Timing().WriteTiming(2, "Recip: ", t_total_.Total()); + Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); + //Recip_.Timing_Calc().WriteTiming(3,"Recip. Calc:", Recip_.Timing_Total().Total()); // if (t_trig_tables_.Total() > 0.0) // t_trig_tables_.WriteTiming(3, "Calc trig tables:", t_recip_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index bf54457732..acdca19f04 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -153,8 +153,9 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray pme_object_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), lattice); + //t_calc_.Start(); double erecip = pme_object_.computeERec(0, chargesD, coordsD); - + //t_calc_.Stop(); t_recip_.Stop(); return erecip; } diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 914e677670..a4732b6bcc 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -17,7 +17,8 @@ class PME_Recip { void SetDebug(int); double Recip_ParticleMesh(Darray&, Box const&, Darray&, const int*, double, int); - Timer const& Timing() const { return t_recip_; } + Timer const& Timing_Total() const { return t_recip_; } + //Timer const& Timing_Calc() const { return t_calc_; } private: static bool check_prime_factors(int); static int ComputeNFFT(double); @@ -25,6 +26,7 @@ class PME_Recip { PMEInstanceD pme_object_; Timer t_recip_; ///< Recip calc timer + //Timer t_calc_; int debug_; int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof From 6e59fdb0c7d7c3d0bae887acbcb52bf992ea1ddb Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 24 Sep 2024 13:48:35 -0400 Subject: [PATCH 085/218] Rename --- src/PairListEngine_Ewald_LJLR.h | 2 +- src/PairListEngine_Ewald_LJPME.h | 2 +- src/PairListTemplate.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 9b7fccb46a..2eb623aa6e 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -42,7 +42,7 @@ class PairListEngine_Ewald_LJLR { } } /// Call when cutoff is not satisfied - void CutoffNotSatisfied(T const& rij2, + void AtomPairExcluded(T const& rij2, PairList::AtmType const& atom0, PairList::AtmType const& atom1) { diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index 254892857b..f077e95c80 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -55,7 +55,7 @@ class PairListEngine_Ewald_LJPME { } } /// Call when cutoff is not satisfied - void CutoffNotSatisfied(T const& rij2, + void AtomPairExcluded(T const& rij2, PairList::AtmType const& atom0, PairList::AtmType const& atom1) { diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h index 972da49791..8f522fcee5 100644 --- a/src/PairListTemplate.h +++ b/src/PairListTemplate.h @@ -60,7 +60,7 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2 engine.CutoffSatisfied(rij2, *it0, *it1); } } else { - engine.CutoffNotSatisfied(rij2, *it0, *it1); + engine.AtomPairExcluded(rij2, *it0, *it1); } } // END loop over other atoms in thisCell // Loop over all neighbor cells @@ -105,7 +105,7 @@ void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2 engine.CutoffSatisfied(rij2, *it0, *it1); } } else { - engine.CutoffNotSatisfied(rij2, *it0, *it1); + engine.AtomPairExcluded(rij2, *it0, *it1); } } // END loop over neighbor cell atoms } // END Loop over neighbor cells From 19c5e9f3abb374fbde8dd314b947ea2b176313e2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 24 Sep 2024 14:35:55 -0400 Subject: [PATCH 086/218] const correctness --- src/Energy/EwaldParams.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 98e78cfc03..87ebb71dd2 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -40,9 +40,9 @@ class EwaldParams { /// \return Direct space cutoff (in Ang squared) double Cut2() const { return cut2_; } /// \return Charge for given atom index - double Charge(int idx) { return Charge_[idx]; } + double Charge(int idx) const { return Charge_[idx]; } /// \return Nonbonded index for given atom indices - int NbIndex(int idx0, int idx1) { return NB_->GetLJindex(TypeIndices_[idx0], TypeIndices_[idx1]); } + int NbIndex(int idx0, int idx1) const { return NB_->GetLJindex(TypeIndices_[idx0], TypeIndices_[idx1]); } /// \return Nonbonded parameter at nonobonded parameter index NonbondType const& GetLJ(int nbindex) const { return NB_->NBarray()[ nbindex ]; } From a99fc0fed124442ee397c77386a0d6c883fbef42 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 08:54:46 -0400 Subject: [PATCH 087/218] Rename --- src/Energy/{Calc_LJPME.cpp => EwaldCalc_LJPME.cpp} | 0 src/Energy/{Calc_LJPME.h => EwaldCalc_LJPME.h} | 0 src/Energy/{Calc_PME.cpp => EwaldCalc_PME.cpp} | 0 src/Energy/{Calc_PME.h => EwaldCalc_PME.h} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/Energy/{Calc_LJPME.cpp => EwaldCalc_LJPME.cpp} (100%) rename src/Energy/{Calc_LJPME.h => EwaldCalc_LJPME.h} (100%) rename src/Energy/{Calc_PME.cpp => EwaldCalc_PME.cpp} (100%) rename src/Energy/{Calc_PME.h => EwaldCalc_PME.h} (100%) diff --git a/src/Energy/Calc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp similarity index 100% rename from src/Energy/Calc_LJPME.cpp rename to src/Energy/EwaldCalc_LJPME.cpp diff --git a/src/Energy/Calc_LJPME.h b/src/Energy/EwaldCalc_LJPME.h similarity index 100% rename from src/Energy/Calc_LJPME.h rename to src/Energy/EwaldCalc_LJPME.h diff --git a/src/Energy/Calc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp similarity index 100% rename from src/Energy/Calc_PME.cpp rename to src/Energy/EwaldCalc_PME.cpp diff --git a/src/Energy/Calc_PME.h b/src/Energy/EwaldCalc_PME.h similarity index 100% rename from src/Energy/Calc_PME.h rename to src/Energy/EwaldCalc_PME.h From 180f28413b7b8199d8541fdcf6fa8e77796d8b23 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 09:00:46 -0400 Subject: [PATCH 088/218] Finish renaming --- src/Action_PmeTest.h | 8 ++++---- src/Energy/CMakeLists.txt | 4 ++-- src/Energy/EwaldCalc_LJPME.cpp | 12 ++++++------ src/Energy/EwaldCalc_LJPME.h | 8 ++++---- src/Energy/EwaldCalc_PME.cpp | 12 ++++++------ src/Energy/EwaldCalc_PME.h | 8 ++++---- src/Energy/energydepend | 4 ++-- src/Energy/energyfiles | 4 ++-- src/cpptrajdepend | 8 ++++---- 9 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h index b74186de88..e5215e114d 100644 --- a/src/Action_PmeTest.h +++ b/src/Action_PmeTest.h @@ -1,8 +1,8 @@ #ifndef INC_ACTION_PMETEST_H #define INC_ACTION_PMETEST_H #include "Action.h" -#include "Energy/Calc_PME.h" -#include "Energy/Calc_LJPME.h" +#include "Energy/EwaldCalc_PME.h" +#include "Energy/EwaldCalc_LJPME.h" #include "Ewald_ParticleMesh.h" #include "EwaldOptions.h" #include "Timer.h" @@ -19,8 +19,8 @@ class Action_PmeTest : public Action { void Print(); Ewald_ParticleMesh PME0_; - Cpptraj::Energy::Calc_PME PME1_; - Cpptraj::Energy::Calc_LJPME PME2_; + Cpptraj::Energy::EwaldCalc_PME PME1_; + Cpptraj::Energy::EwaldCalc_LJPME PME2_; EwaldOptions ewaldOpts_; AtomMask Mask1_; DataSet* ele_; diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 3bf022a9c5..4b6c3e5a1d 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,9 +1,9 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/Calc_LJPME.cpp - ${CMAKE_CURRENT_LIST_DIR}/Calc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_LJPME.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index 41cef39552..c23294a237 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -1,4 +1,4 @@ -#include "Calc_LJPME.h" +#include "EwaldCalc_LJPME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../PairListTemplate.h" @@ -6,13 +6,13 @@ using namespace Cpptraj::Energy; -Calc_LJPME::Calc_LJPME() : +EwaldCalc_LJPME::EwaldCalc_LJPME() : Recip_(PME_Recip::COULOMB), LJrecip_(PME_Recip::LJ) {} /** Set up LJPME parameters. */ -int Calc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +int EwaldCalc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: LJPME calculation init failed.\n"); @@ -29,7 +29,7 @@ int Calc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) } /** Setup LJPME calculation. */ -int Calc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { +int EwaldCalc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { mprinterr("Error: LJPME calculation setup failed.\n"); return 1; @@ -48,7 +48,7 @@ int Calc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { } /** Calculate full nonbonded energy with LJPME */ -int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, +int EwaldCalc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, double& e_elec, double& e_vdw) { t_total_.Start(); @@ -114,7 +114,7 @@ int Calc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, return 0; } -void Calc_LJPME::Timing(double total) const { +void EwaldCalc_LJPME::Timing(double total) const { t_total_.WriteTiming(1, " LJPME Total:", total); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); //Recip_.Timing_Calc().WriteTiming(3, "Recip. Calc :", Recip_.Timing_Total().Total()); diff --git a/src/Energy/EwaldCalc_LJPME.h b/src/Energy/EwaldCalc_LJPME.h index 828ebafe5b..1bde62035d 100644 --- a/src/Energy/EwaldCalc_LJPME.h +++ b/src/Energy/EwaldCalc_LJPME.h @@ -1,14 +1,14 @@ -#ifndef INC_ENERGY_CALC_LJPME_H -#define INC_ENERGY_CALC_LJPME_H +#ifndef INC_ENERGY_EWALDCALC_LJPME_H +#define INC_ENERGY_EWALDCALC_LJPME_H #include "PME_Recip.h" #include "../ExclusionArray.h" #include "../PairList.h" #include "../PairListEngine_Ewald_LJPME.h" namespace Cpptraj { namespace Energy { -class Calc_LJPME { +class EwaldCalc_LJPME { public: - Calc_LJPME(); + EwaldCalc_LJPME(); /// Init with Box, EwaldOptions and debug level int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index b03dcddfdc..8dc70d7b8f 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -1,4 +1,4 @@ -#include "Calc_PME.h" +#include "EwaldCalc_PME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../PairListTemplate.h" @@ -6,12 +6,12 @@ using namespace Cpptraj::Energy; -Calc_PME::Calc_PME() : +EwaldCalc_PME::EwaldCalc_PME() : Recip_(PME_Recip::COULOMB) {} /** Set up PME parameters. */ -int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: PME calculation init failed.\n"); @@ -28,7 +28,7 @@ int Calc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) } /** Setup PME calculation. */ -int Calc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { +int EwaldCalc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { mprinterr("Error: PME calculation setup failed.\n"); return 1; @@ -51,7 +51,7 @@ int Calc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { } /** Calculate full nonbonded energy with PME */ -int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, +int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, double& e_elec, double& e_vdw) { t_total_.Start(); @@ -118,7 +118,7 @@ int Calc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, return 0; } -void Calc_PME::Timing(double total) const { +void EwaldCalc_PME::Timing(double total) const { t_total_.WriteTiming(1, " PME Total:", total); //t_self_.WriteTiming(2, "Self: ", t_total_.Total()); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); diff --git a/src/Energy/EwaldCalc_PME.h b/src/Energy/EwaldCalc_PME.h index 7cc1e7792f..4a9c523cbc 100644 --- a/src/Energy/EwaldCalc_PME.h +++ b/src/Energy/EwaldCalc_PME.h @@ -1,5 +1,5 @@ -#ifndef INC_ENERGY_CALC_PME_H -#define INC_ENERGY_CALC_PME_H +#ifndef INC_ENERGY_EWALDCALC_PME_H +#define INC_ENERGY_EWALDCALC_PME_H #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" #include "../ExclusionArray.h" @@ -12,9 +12,9 @@ class Frame; class Topology; namespace Cpptraj { namespace Energy { -class Calc_PME { +class EwaldCalc_PME { public: - Calc_PME(); + EwaldCalc_PME(); /// Init with Box, EwaldOptions and debug level int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 24a21b2f79..95a17c8bde 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,7 +1,7 @@ -Calc_LJPME.o : Calc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_LJPME.h PME_Recip.h -Calc_PME.o : Calc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Calc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 436088776b..29154c95cc 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,9 +1,9 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ - Calc_LJPME.cpp \ - Calc_PME.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ + EwaldCalc_LJPME.cpp \ + EwaldCalc_PME.cpp \ EwaldParams.cpp \ EwaldParams_LJPME.cpp \ EwaldParams_PME.cpp \ diff --git a/src/cpptrajdepend b/src/cpptrajdepend index f065e57dde..42cb18a53d 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Calc_LJPME.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Calc_LJPME.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -277,10 +277,10 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Calc_LJPME.o : Energy/Calc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_LJPME.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/Calc_PME.o : Energy/Calc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Calc_PME.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h From 002e05680701b75dae9e95bc1167a81846ec0d4c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:20:44 -0400 Subject: [PATCH 089/218] Start decomposable PME energy class --- src/Energy/EwaldCalc_Decomp_PME.cpp | 27 +++++++++++++++++++++++ src/Energy/EwaldCalc_Decomp_PME.h | 33 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/Energy/EwaldCalc_Decomp_PME.cpp create mode 100644 src/Energy/EwaldCalc_Decomp_PME.h diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp new file mode 100644 index 0000000000..f06494879d --- /dev/null +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -0,0 +1,27 @@ +#include "EwaldCalc_Decomp_PME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +EwaldCalc_Decomp_PME::EwaldCalc_Decomp_PME() : + Recip_(PME_Recip::COULOMB) +{} + +/** Set up PME parameters. */ +int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + //if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + // mprinterr("Error: PME calculation init failed.\n"); + // return 1; + //} + if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + VDW_LR_.SetDebug( debugIn ); + Recip_.SetDebug( debugIn ); + + return 0; +} + diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h new file mode 100644 index 0000000000..dfb5c717d2 --- /dev/null +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -0,0 +1,33 @@ +#ifndef INC_ENERGY_EWALDCALC_DECOMP_PME_H +#define INC_ENERGY_EWALDCALC_DECOMP_PME_H +#include "PME_Recip.h" +#include "VDW_LongRange_Correction.h" +#include "../ExclusionArray.h" +#include "../PairList.h" +class AtomMask; +class Box; +class EwaldOptions; +class Frame; +class Topology; +namespace Cpptraj { +namespace Energy { +class EwaldCalc_Decomp_PME { + public: + typedef std::vector Darray; + + EwaldCalc_Decomp_PME(); + int Init(Box const&, EwaldOptions const&, int); + int Setup(Topology const&, AtomMask const&); // TODO CharMask? + int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, + Darray&, Darray&); + private: + PME_Recip Recip_; + PairList pairList_; + ExclusionArray Excluded_; + VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction + Timer t_total_; + Timer t_direct_; +}; +} +} +#endif From 00318ac92954465240b5ef6c490a7768e0c6c89a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:23:27 -0400 Subject: [PATCH 090/218] Placeholder for decomp ewald engine --- src/PairListEngine_Ewald_Decomp_LJLR.h | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/PairListEngine_Ewald_Decomp_LJLR.h diff --git a/src/PairListEngine_Ewald_Decomp_LJLR.h b/src/PairListEngine_Ewald_Decomp_LJLR.h new file mode 100644 index 0000000000..8d11ce378c --- /dev/null +++ b/src/PairListEngine_Ewald_Decomp_LJLR.h @@ -0,0 +1,81 @@ +#ifndef INC_PAIRLISTENGINE_EWALD_DECOMP_LJLR_H +#define INC_PAIRLISTENGINE_EWALD_DECOMP_LJLR_H +#include "Energy/Ene_LJ_6_12.h" +#include "Energy/EwaldParams_PME.h" +#include "Energy/Kernel_EwaldAdjust.h" +#include "PairList.h" +namespace Cpptraj { +/// Direct space nonbond calculation using pairlist with decomposable Ewald and VDW LR correction +template +class PairListEngine_Ewald_Decomp_LJLR { + public: + PairListEngine_Ewald_Decomp_LJLR() {} + // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = EW_.Charge(atom0.Idx()); + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = EW_.Charge(atom1.Idx()); + } + /// Call when cutoff is satisfied + void CutoffSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt( rij2 ); + T qiqj = q0_ * q1_; + //double erfc = erfc_func(ew_coeff_ * rij); + T erfcval = EW_.ErfcEW( rij ); + T e_elec = qiqj * erfcval / rij; + Eelec_ += e_elec; + + int nbindex = EW_.NbIndex(atom0.Idx(), atom1.Idx()); + if (nbindex > -1) { + double vswitch = EW_.Switch_Fn(rij2); + NonbondType const& LJ = EW_.GetLJ( nbindex ); + T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); + Evdw_ += (e_vdw * vswitch); + } + } + /// Call when cutoff is not satisfied + void AtomPairExcluded(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt(rij2); + T erfcval = EW_.ErfcEW( rij ); + Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + } + // ------------------------------------------- + Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams_PME const& EwaldParams() const { return EW_; } + + T Evdw() const { return Evdw_; } + T Eelec() const { return Eelec_; } + T Eadjust() const { return Eadjust_; } +# ifdef _OPENMP + /// To allow reduction of the energy terms + void operator+=(PairListEngine_Ewald_Decomp_LJLR const& rhs) { + Evdw_ += rhs.Evdw_; + Eelec_ += rhs.Eelec_; + Eadjust_ += rhs.Eadjust_; + } +# endif + private: + T q0_; ///< Charge on atom 0 + T q1_; ///< Charge on atom 1 + T Evdw_; ///< VDW sum for current frame + T Eelec_; ///< Coulomb sum for current frame + T Eadjust_; ///< Adjust energy sum for current frame + + Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME +}; +#ifdef _OPENMP +#pragma omp declare reduction( + : PairListEngine_Ewald_Decomp_LJLR : omp_out += omp_in ) initializer( omp_priv = omp_orig ) +#endif +} // END namespace Cpptraj +#endif From 68d5a3cdeae84737afaf49810608790666ba6496 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:24:30 -0400 Subject: [PATCH 091/218] Add engine placeholder --- src/Energy/EwaldCalc_Decomp_PME.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index dfb5c717d2..b8de59db71 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -4,6 +4,7 @@ #include "VDW_LongRange_Correction.h" #include "../ExclusionArray.h" #include "../PairList.h" +#include "../PairListEngine_Ewald_Decomp_LJLR.h" class AtomMask; class Box; class EwaldOptions; @@ -21,6 +22,7 @@ class EwaldCalc_Decomp_PME { int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, Darray&, Darray&); private: + PairListEngine_Ewald_Decomp_LJLR NBengine_; PME_Recip Recip_; PairList pairList_; ExclusionArray Excluded_; From 503db3dcb5f897aa83693d4328513d796b8246ee Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:25:00 -0400 Subject: [PATCH 092/218] Do engine init --- src/Energy/EwaldCalc_Decomp_PME.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index f06494879d..e103aca655 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -11,10 +11,10 @@ EwaldCalc_Decomp_PME::EwaldCalc_Decomp_PME() : /** Set up PME parameters. */ int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { - //if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { - // mprinterr("Error: PME calculation init failed.\n"); - // return 1; - //} + if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: Decomposable PME calculation init failed.\n"); + return 1; + } if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) From 4cd4df6c8b05a6d64d9586d952cb7be547ce2b4a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:30:11 -0400 Subject: [PATCH 093/218] Add setup --- src/Energy/EwaldCalc_Decomp_PME.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index e103aca655..0189f72292 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -1,6 +1,7 @@ #include "EwaldCalc_Decomp_PME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Topology.h" using namespace Cpptraj::Energy; @@ -25,3 +26,26 @@ int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, in return 0; } +/** Setup PME calculation. */ +int EwaldCalc_Decomp_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { + if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { + mprinterr("Error: PME calculation setup failed.\n"); + return 1; + } + if (VDW_LR_.Setup_VDW_Correction( topIn, maskIn )) { + mprinterr("Error: PME calculation long range VDW correction setup failed.\n"); + return 1; + } + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for PME calculation.\n"); + return 1; + } + + return 0; +} + From 3d0617ce13a343d16f59f991deb13268d8399b04 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:41:29 -0400 Subject: [PATCH 094/218] Add decomposed self energy --- src/Energy/EwaldCalc_Decomp_PME.cpp | 34 +++++++++++++++++++++++++++++ src/Energy/EwaldParams.cpp | 25 +++++++++++++++++++-- src/Energy/EwaldParams.h | 3 +++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 0189f72292..8cbcf8b4b8 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -49,3 +49,37 @@ int EwaldCalc_Decomp_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +/** Calculate full nonbonded energy with PME */ +int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + double& e_elec, double& e_vdw, + Darray& atom_elec, Darray& atom_vdw) +{ + t_total_.Start(); + double volume = frameIn.BoxCrd().CellVolume(); + Darray atom_self; + double e_self = NBengine_.EwaldParams().DecomposedSelfEnergy( atom_self, volume ); + mprintf("DEBUG: Total self energy: %f\n", e_self); + + int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn); + if (retVal != 0) { + mprinterr("Error: Pairlist creation failed for PME calc.\n"); + return 1; + } + + // TODO make more efficient + NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); + + // MapCoords(frameIn, ucell, recip, maskIn); + // FIXME helPME requires coords and charge arrays to be non-const + double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + mprintf("DEBUG: Recip energy: %f\n", e_recip); + + return 0; +} diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index 00e3fade29..2830c6315c 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -6,6 +6,8 @@ using namespace Cpptraj::Energy; +const double EwaldParams::INVSQRTPI_ = 1.0 / sqrt(Constants::PI); + /** CONSTRUCTOR */ EwaldParams::EwaldParams() : ew_coeff_(0.0), @@ -131,9 +133,8 @@ void EwaldParams::CalculateCharges(Topology const& topIn, AtomMask const& maskIn /** Electrostatic self energy. This is the cancelling Gaussian plus the "neutralizing plasma". */ double EwaldParams::SelfEnergy(double volume) const { - static const double INVSQRTPI = 1.0 / sqrt(Constants::PI); // t_self_.Start(); - double d0 = -ew_coeff_ * INVSQRTPI; + double d0 = -ew_coeff_ * INVSQRTPI_; double ene = sumq2_ * d0; // mprintf("DEBUG: d0= %20.10f ene= %20.10f\n", d0, ene); double factor = Constants::PI / (ew_coeff_ * ew_coeff_ * volume); @@ -143,3 +144,23 @@ double EwaldParams::SelfEnergy(double volume) const { return ene; } +/** Electrostatic self energy on each atom. */ +double EwaldParams::DecomposedSelfEnergy(Darray& atom_self, double volume) const { + double d0 = -ew_coeff_ * INVSQRTPI_; + double ene = sumq2_ * d0; +// mprintf("DEBUG: d0= %20.10f ene= %20.10f\n", d0, ene); + double factor = Constants::PI / (ew_coeff_ * ew_coeff_ * volume); + double ee_plasma = -0.5 * factor * sumq_ * sumq_; + + atom_self.resize( Charge_.size() ); + + // Distribute the "neutrilizing plasma" to atoms equally + for (unsigned int i = 0; i < Charge_.size(); i++) + { + atom_self[i] = Charge_[i]*Charge_[i]*d0 + ee_plasma/Charge_.size(); + mprintf("DEBUG: Self energy atom %i = %f\n", i+1, atom_self[i]); + } + + ene += ee_plasma; + return ene; +} diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 87ebb71dd2..56eb4dfeab 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -36,6 +36,8 @@ class EwaldParams { } /// \return Self energy for the given volume double SelfEnergy(double) const; + /// \return Self energy for given volume. Set self energy for each atom. + double DecomposedSelfEnergy(std::vector&, double) const; /// \return Direct space cutoff (in Ang squared) double Cut2() const { return cut2_; } @@ -72,6 +74,7 @@ class EwaldParams { /// Calculate sum q, sum q^2. void CalculateCharges(Topology const&, AtomMask const&); private: + static const double INVSQRTPI_; double FindEwaldCoefficient(double, double); From fc2fd31c242b710f9252ca06bea146d901b918c5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:42:01 -0400 Subject: [PATCH 095/218] Add to build --- src/Energy/CMakeLists.txt | 1 + src/Energy/energydepend | 1 + src/Energy/energyfiles | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 4b6c3e5a1d..1982c84abf 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Decomp_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 95a17c8bde..10fe57487c 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,6 @@ EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h +EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 29154c95cc..d0c37f84c5 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -2,6 +2,7 @@ ENERGY_SOURCES= \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ + EwaldCalc_Decomp_PME.cpp \ EwaldCalc_LJPME.cpp \ EwaldCalc_PME.cpp \ EwaldParams.cpp \ From 06295cde6c3e56840a899ccaef000dbcd5749909 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 10:52:58 -0400 Subject: [PATCH 096/218] Start incorporating ene decomp --- src/Energy/EnergyDecomposer.cpp | 45 ++++++++++++++++++++++++--------- src/Energy/EnergyDecomposer.h | 10 ++++++-- src/Energy/energydepend | 2 +- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 0c27ff3479..ab61e1c3b8 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -33,6 +33,11 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFil debug_ = debugIn; // Process keywords outfile_ = DFLin.AddDataFile( argIn.GetStringKey("out"), argIn ); + use_pme_ = argIn.hasKey("pme"); + if (use_pme_) { + if (ewaldOpts_.GetOptions(EwaldOptions::PME, argIn, "enedecomp")) + return 1; + } // Get atom mask if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) return 1; @@ -65,6 +70,9 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); if (outfile_ != 0) mprintf("\tOutput file: %s\n", outfile_->DataFilename().full()); + if (use_pme_) + ewaldOpts_.PrintOptions(); + } // ----------------------------------------------------------------------------- @@ -128,7 +136,7 @@ int EnergyDecomposer::setupDihedrals(DihArrayType const& dihedralsIn) { /** Topology-based setup. * \return 0 if setup OK, 1 if error, -1 if nothing selected. */ -int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { +int EnergyDecomposer::SetupDecomposer(Topology const& topIn, Box const& boxIn) { // First set up the mask if (topIn.SetupCharMask( selectedAtoms_ )) { mprinterr("Error: Could not set up mask '%s'\n", selectedAtoms_.MaskString()); @@ -174,17 +182,30 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn) { if (setupDihedrals( topIn.Dihedrals() )) return 1; if (setupDihedrals( topIn.DihedralsH() )) return 1; std::sort( dihedrals_.begin(), dihedrals_.end() ); - // For nonbonds, set up all selected atoms in an integer atom mask. - //mask_ = AtomMask( selectedAtoms_.ConvertToIntMask(), selectedAtoms_.Natom() ); - // Need to set up ex - // TODO if using pairlist, needs to be EXCLUDE_SELF and FULL - //if (Excluded_.SetupExcludedForAtoms( topIn.Atoms(), mask_, 4 )) - if (Excluded_.SetupExcluded( topIn.Atoms(), 4, - ExclusionArray::NO_EXCLUDE_SELF, - ExclusionArray::ONLY_GREATER_IDX )) - { - mprinterr("Error: Could not set up atom exclusion list for energy decomposition.\n"); - return 1; + if (use_pme_) { + if (!boxIn.HasBox()) { + mprinterr("Error: PME requires unit cell information.\n"); + return 1; + } + // Set up for all atoms FIXME + AtomMask Imask(0, topIn.Natom()); + if (PME_.Init(boxIn, ewaldOpts_, debug_)) + return 1; + if (PME_.Setup( topIn, Imask )) + return 1; + } else { + // For nonbonds, set up all selected atoms in an integer atom mask. + //mask_ = AtomMask( selectedAtoms_.ConvertToIntMask(), selectedAtoms_.Natom() ); + // Need to set up ex + // TODO if using pairlist, needs to be EXCLUDE_SELF and FULL + //if (Excluded_.SetupExcludedForAtoms( topIn.Atoms(), mask_, 4 )) + if (Excluded_.SetupExcluded( topIn.Atoms(), 4, + ExclusionArray::NO_EXCLUDE_SELF, + ExclusionArray::ONLY_GREATER_IDX )) + { + mprinterr("Error: Could not set up atom exclusion list for energy decomposition.\n"); + return 1; + } } // DEBUG diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 6d82c77490..defc8b05d9 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -1,8 +1,10 @@ #ifndef INC_ENERGY_ENERGYDECOMPOSER_H #define INC_ENERGY_ENERGYDECOMPOSER_H #include +#include "EwaldCalc_Decomp_PME.h" #include "../AtomMask.h" #include "../CharMask.h" +#include "../EwaldOptions.h" #include "../ExclusionArray.h" #include "../OnlineVarT.h" class AngleType; @@ -26,8 +28,8 @@ class EnergyDecomposer { int InitDecomposer(ArgList&, DataSetList&, DataFileList&, int); /// Print options to stdout void PrintOpts() const; - /// Topology-based setup - int SetupDecomposer(Topology const&); + /// Topology-based setup. Box only needed for PME + int SetupDecomposer(Topology const&, Box const& boxIn); /// Calculate and decompose energies for given frame. int CalcEne(Frame const&); /// Finish the calculation by putting energies in output DataSet @@ -63,6 +65,8 @@ class EnergyDecomposer { DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. DataFile* outfile_; ///< Output file int debug_; ///< Debug level + bool use_pme_; ///< If true use PME for the nonbonds + EwaldOptions ewaldOpts_; ///< Hold Ewald options BndArrayType bonds_; ///< Hold all bonds to be calculated AngArrayType angles_; ///< Hold all angles to be calculated @@ -72,6 +76,8 @@ class EnergyDecomposer { EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. Topology const* currentTop_; ///< Current topology from Setup + EwaldCalc_Decomp_PME PME_; ///< For calculating pairwise decomposed PME energies + Darray currentEne_; ///< Hold the total energy of each atom for the current frame }; } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 10fe57487c..d0dcb520e4 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h From 52a5a44668286184a3de6e607b42b791f3343c30 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 11:05:52 -0400 Subject: [PATCH 097/218] Self energy decomp seems to work --- src/Action_EneDecomp.cpp | 2 +- src/Energy/EnergyDecomposer.cpp | 9 ++++++++- src/Energy/EwaldCalc_Decomp_PME.cpp | 8 ++++++++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 7 ++++--- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index 32e162a909..4d85c1cd42 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -20,7 +20,7 @@ Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, in // Action_EneDecomp::Setup() Action::RetType Action_EneDecomp::Setup(ActionSetup& setup) { - int ret = eneDecomp_.SetupDecomposer( setup.Top() ); + int ret = eneDecomp_.SetupDecomposer( setup.Top(), setup.CoordInfo().TrajBox() ); if (ret == -1) return Action::SKIP; else if (ret == 1) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index ab61e1c3b8..adbb98d8b6 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -358,7 +358,14 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { // Dihedrals calcDihedrals(frameIn); // Nonbonds - calcNB_simple(frameIn); + if (use_pme_) { // FIXME atommask? + double e_elec, e_vdw; + std::vector atom_elec, atom_vdw; + PME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), + e_elec, e_vdw, atom_elec, atom_vdw); + } else { + calcNB_simple(frameIn); + } // Accumulate the energies for (unsigned int idx = 0; idx != energies_.size(); idx++) { diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 8cbcf8b4b8..feb3e0a559 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -49,6 +49,13 @@ int EwaldCalc_Decomp_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +static inline double sumArray(std::vector const& arrayIn) { + double sum = 0; + for (std::vector::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) + sum += *it; + return sum; +} + /** Calculate full nonbonded energy with PME */ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, double& e_elec, double& e_vdw, @@ -59,6 +66,7 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom Darray atom_self; double e_self = NBengine_.EwaldParams().DecomposedSelfEnergy( atom_self, volume ); mprintf("DEBUG: Total self energy: %f\n", e_self); + mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); diff --git a/src/Energy/energydepend b/src/Energy/energydepend index d0dcb520e4..d082fa6dd9 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 42cb18a53d..17291ea83b 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,7 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/EnergyDecomposer.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -277,8 +277,9 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h +Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From d771f80e4bb57e9da54878fbbaf2b65f5b7e3de6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 11:28:16 -0400 Subject: [PATCH 098/218] Put lattice check in a separate routine --- src/Energy/PME_Recip.cpp | 29 ++++++++++++++++++----------- src/Energy/PME_Recip.h | 1 + 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index acdca19f04..04838cce67 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -96,6 +96,22 @@ int PME_Recip::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxI return 0; } +/** \return 1 if the box type is invalid for helPME */ +int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) { + lattice = PMEInstanceD::LatticeType::XAligned; + // TODO just pass in Ucell when helPME supports it + //boxIn.PrintDebug("pme"); + if (!boxIn.Is_X_Aligned()) { + if (boxIn.Is_Symmetric()) + lattice = PMEInstanceD::LatticeType::ShapeMatrix; + else { + mprinterr("Error: Unit cell is not X-aligned or symmetric; cannot set PME recip grid.\n"); + return 1; + } + } + return 0; +} + /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, @@ -131,17 +147,8 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray //auto pme_object = std::unique_ptr(new PMEInstanceD()); pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors - PMEInstanceD::LatticeType lattice = PMEInstanceD::LatticeType::XAligned; - // TODO just pass in Ucell when helPME supports it - //boxIn.PrintDebug("pme"); - if (!boxIn.Is_X_Aligned()) { - if (boxIn.Is_Symmetric()) - lattice = PMEInstanceD::LatticeType::ShapeMatrix; - else { - mprinterr("Error: Unit cell is not X-aligned or symmetric; cannot set PME recip grid.\n"); - return 0; - } - } + PMEInstanceD::LatticeType lattice; + if (set_lattice(lattice, boxIn)) return 0; // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. // Args: 1 = the A lattice parameter in units consistent with the coordinates. // 2 = the B lattice parameter in units consistent with the coordinates. diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index a4732b6bcc..bd17f396a3 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -23,6 +23,7 @@ class PME_Recip { static bool check_prime_factors(int); static int ComputeNFFT(double); int DetermineNfft(int&, int&, int&, Box const&) const; + static int set_lattice(PMEInstanceD::LatticeType&, Box const&); PMEInstanceD pme_object_; Timer t_recip_; ///< Recip calc timer From dc69b6a4c9888f58d8dcd05dae35ddc52ada5100 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 11:43:35 -0400 Subject: [PATCH 099/218] Decomposable recip energy --- src/Energy/EwaldCalc_Decomp_PME.cpp | 19 ++++++----- src/Energy/PME_Recip.cpp | 49 +++++++++++++++++++++++++++++ src/Energy/PME_Recip.h | 1 + 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index feb3e0a559..011eecbe7a 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -79,15 +79,18 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); // MapCoords(frameIn, ucell, recip, maskIn); + Darray atom_recip; // FIXME helPME requires coords and charge arrays to be non-const - double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), - frameIn.BoxCrd(), - NBengine_.ModifyEwaldParams().SelectedCharges(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().EwaldCoeff(), - NBengine_.EwaldParams().Order() - ); - mprintf("DEBUG: Recip energy: %f\n", e_recip); + double e_recip = Recip_.Recip_Decomp( atom_recip, + NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + mprintf("DEBUG: Recip energy : %f\n", e_recip); + mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); return 0; } diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 04838cce67..702ae3332d 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -167,3 +167,52 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray return erecip; } +/** \return Reciprocal space part of PME energy calc. */ +// TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that +double PME_Recip::Recip_Decomp(Darray& atom_recip, + Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, + const int* nfftIn, double ew_coeffIn, int orderIn) +{ + t_recip_.Start(); + atom_recip.resize( ChargeIn.size() ); + // This essentially makes coordsD and chargesD point to arrays. + Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); + Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); + int nfft1 = -1; + int nfft2 = -1; + int nfft3 = -1; + if (nfftIn != 0) { + nfft1 = nfftIn[0]; + nfft2 = nfftIn[1]; + nfft3 = nfftIn[2]; + } + if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + mprinterr("Error: Could not determine FFT grid spacing.\n"); + return 0.0; + } + // Instantiate double precision PME object + pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); + // Check the unit cell vectors + PMEInstanceD::LatticeType lattice; + if (set_lattice(lattice, boxIn)) return 0; + // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. + pme_object_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), + boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), + lattice); + //t_calc_.Start(); + // TODO precalc + Mat e_potentialD_(ChargeIn.size(), 4); + e_potentialD_.setConstant(0.0); + pme_object_.computePRec(0, chargesD, coordsD, coordsD, 1, e_potentialD_); + double erecip = 0; + for(unsigned int i = 0; i < ChargeIn.size(); i++) + { + atom_recip[i]=0.5 * ChargeIn[i] * e_potentialD_(i,0); + erecip += atom_recip[i]; + } + + //t_calc_.Stop(); + t_recip_.Stop(); + return erecip; +} + diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index bd17f396a3..21d3174613 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -16,6 +16,7 @@ class PME_Recip { PME_Recip(Type); void SetDebug(int); double Recip_ParticleMesh(Darray&, Box const&, Darray&, const int*, double, int); + double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, const int*, double, int); Timer const& Timing_Total() const { return t_recip_; } //Timer const& Timing_Calc() const { return t_calc_; } From 014dc2d98ca5edad04efb6f47f18f9f0a4ed0844 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 15:12:22 -0400 Subject: [PATCH 100/218] Decompose direct elec, vdw, and adjust energies --- src/Energy/EwaldCalc_Decomp_PME.cpp | 30 +++++++++++++++++++++ src/Energy/EwaldParams.h | 2 ++ src/Energy/energydepend | 2 +- src/PairListEngine_Ewald_Decomp_LJLR.h | 36 +++++++++++++++++++++++--- src/cpptrajdepend | 2 +- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 011eecbe7a..05d2d45e9f 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -1,6 +1,7 @@ #include "EwaldCalc_Decomp_PME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../PairListTemplate.h" #include "../Topology.h" using namespace Cpptraj::Energy; @@ -91,6 +92,35 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom ); mprintf("DEBUG: Recip energy : %f\n", e_recip); mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); + // TODO distribute + double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); + t_direct_.Start(); + Cpptraj::PairListTemplate(pairList_, Excluded_, + NBengine_.EwaldParams().Cut2(), NBengine_); + t_direct_.Stop(); + mprintf("DEBUG: Direct Elec. energy : %f\n", NBengine_.Eelec()); + mprintf("DEBUG: Sum of elec. energy : %f\n", sumArray(NBengine_.Eatom_Elec())); + mprintf("DEBUG: Direct VDW energy : %f\n", NBengine_.Evdw()); + mprintf("DEBUG: Sum of VDW energy : %f\n", sumArray(NBengine_.Eatom_EVDW())); + mprintf("DEBUG: Direct Adjust energy: %f\n", NBengine_.Eadjust()); + mprintf("DEBUG: Sum of Adjust energy: %f\n", sumArray(NBengine_.Eatom_EAdjust())); + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: Nonbond energy components:\n"); + mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + e_vdw_lr_correction ); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + + NBengine_.Eelec() + + NBengine_.Eadjust()); + mprintf("\n"); + mprintf(" E electrostatic (self) = %24.12f\n", e_self); + mprintf(" (rec) = %24.12f\n", e_recip); + mprintf(" (dir) = %24.12f\n", NBengine_.Eelec()); + mprintf(" (adj) = %24.12f\n", NBengine_.Eadjust()); + mprintf(" E vanDerWaals (dir) = %24.12f\n", NBengine_.Evdw()); + mprintf(" (LR) = %24.12f\n", e_vdw_lr_correction); + } + e_vdw = NBengine_.Evdw() + e_vdw_lr_correction; + e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); + t_total_.Stop(); return 0; } diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 56eb4dfeab..0f9994cb8f 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -47,6 +47,8 @@ class EwaldParams { int NbIndex(int idx0, int idx1) const { return NB_->GetLJindex(TypeIndices_[idx0], TypeIndices_[idx1]); } /// \return Nonbonded parameter at nonobonded parameter index NonbondType const& GetLJ(int nbindex) const { return NB_->NBarray()[ nbindex ]; } + /// \return Number of atoms (current size of charge array) + unsigned int Natom() const { return Charge_.size(); } /// \return Debug level int Debug() const { return debug_; } diff --git a/src/Energy/energydepend b/src/Energy/energydepend index d082fa6dd9..0e209f94ec 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,6 +1,6 @@ EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h -EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h diff --git a/src/PairListEngine_Ewald_Decomp_LJLR.h b/src/PairListEngine_Ewald_Decomp_LJLR.h index 8d11ce378c..4a6e85f07f 100644 --- a/src/PairListEngine_Ewald_Decomp_LJLR.h +++ b/src/PairListEngine_Ewald_Decomp_LJLR.h @@ -8,11 +8,16 @@ namespace Cpptraj { /// Direct space nonbond calculation using pairlist with decomposable Ewald and VDW LR correction template class PairListEngine_Ewald_Decomp_LJLR { + typedef std::vector Darray; public: PairListEngine_Ewald_Decomp_LJLR() {} // ------------------------------------------- /// Call at the beginning of the frame calculation - void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; } + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; + atom_elec_.assign(EW_.Natom(), 0); + atom_evdw_.assign(EW_.Natom(), 0); + atom_eadj_.assign(EW_.Natom(), 0); + } /// Call for atom 0 when looping over atoms of thisCell void SetupAtom0( PairList::AtmType const& atom0 ) { q0_ = EW_.Charge(atom0.Idx()); @@ -32,13 +37,20 @@ class PairListEngine_Ewald_Decomp_LJLR { T erfcval = EW_.ErfcEW( rij ); T e_elec = qiqj * erfcval / rij; Eelec_ += e_elec; + T e_half = e_elec * 0.5; + atom_elec_[atom0.Idx()] += e_half; + atom_elec_[atom1.Idx()] += e_half; int nbindex = EW_.NbIndex(atom0.Idx(), atom1.Idx()); if (nbindex > -1) { double vswitch = EW_.Switch_Fn(rij2); NonbondType const& LJ = EW_.GetLJ( nbindex ); T e_vdw = Cpptraj::Energy::Ene_LJ_6_12(rij2, LJ.A(), LJ.B()); - Evdw_ += (e_vdw * vswitch); + e_vdw *= vswitch; + Evdw_ += e_vdw; + e_half = e_vdw * 0.5; + atom_evdw_[atom0.Idx()] += e_half; + atom_evdw_[atom1.Idx()] += e_half; } } /// Call when cutoff is not satisfied @@ -48,7 +60,11 @@ class PairListEngine_Ewald_Decomp_LJLR { { T rij = sqrt(rij2); T erfcval = EW_.ErfcEW( rij ); - Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + T e_adj = Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + Eadjust_ += e_adj; + T e_half = e_adj * 0.5; + atom_eadj_[atom0.Idx()] += e_half; + atom_eadj_[atom1.Idx()] += e_half; } // ------------------------------------------- Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } @@ -57,12 +73,22 @@ class PairListEngine_Ewald_Decomp_LJLR { T Evdw() const { return Evdw_; } T Eelec() const { return Eelec_; } T Eadjust() const { return Eadjust_; } + Darray const& Eatom_Elec() const { return atom_elec_; } + Darray const& Eatom_EVDW() const { return atom_evdw_; } + Darray const& Eatom_EAdjust() const { return atom_eadj_; } # ifdef _OPENMP + static void sum_Darray(Darray& lhs, Darray const& rhs) { + for (unsigned int idx = 0; idx != rhs.size(); ++idx) + lhs[idx] += rhs[idx]; + } /// To allow reduction of the energy terms void operator+=(PairListEngine_Ewald_Decomp_LJLR const& rhs) { Evdw_ += rhs.Evdw_; Eelec_ += rhs.Eelec_; Eadjust_ += rhs.Eadjust_; + sum_Darray(atom_elec_, rhs.atom_elec_); + sum_Darray(atom_evdw_, rhs.atom_evdw_); + sum_Darray(atom_eadj_, rhs.atom_eadj_); } # endif private: @@ -72,6 +98,10 @@ class PairListEngine_Ewald_Decomp_LJLR { T Eelec_; ///< Coulomb sum for current frame T Eadjust_; ///< Adjust energy sum for current frame + Darray atom_elec_; ///< Sum of Coulomb E on each atom for current frame + Darray atom_evdw_; ///< Sum of VDW E on each atom for current frame + Darray atom_eadj_; ///< Sum of excluded atom adjust E on each atom for current frame + Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME }; #ifdef _OPENMP diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 17291ea83b..6b943ea6a6 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -279,7 +279,7 @@ DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3. Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h -Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 104fbabf87e0d2548809817d684db7ab8c502394 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 15:27:17 -0400 Subject: [PATCH 101/218] Restore arrays needed for atom decomp of LR vdw correction --- src/Energy/VDW_LongRange_Correction.cpp | 10 ++++++---- src/Energy/VDW_LongRange_Correction.h | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Energy/VDW_LongRange_Correction.cpp b/src/Energy/VDW_LongRange_Correction.cpp index deb5855f94..c5715286da 100644 --- a/src/Energy/VDW_LongRange_Correction.cpp +++ b/src/Energy/VDW_LongRange_Correction.cpp @@ -22,14 +22,16 @@ int VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, topIn.c_str()); return 1; } - Iarray N_vdw_type_; // Count the number of each unique nonbonded type. N_vdw_type_.assign( NB_->Ntypes(), 0 ); - //vdw_type_.clear(); + atype_vdw_recip_terms_.clear(); + atype_vdw_recip_terms_.reserve( N_vdw_type_.size() ); + vdw_type_.clear(); + vdw_type_.reserve( maskIn.Nselected() ); for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { N_vdw_type_[ topIn[*atm].TypeIndex() ]++; - //vdw_type_.push_back( topIn[*atm].TypeIndex() ); + vdw_type_.push_back( topIn[*atm].TypeIndex() ); } if (debug_ > 0) { mprintf("DEBUG: %zu VDW types.\n", N_vdw_type_.size()); @@ -51,7 +53,7 @@ int VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, Vdw_Recip_term_ += N_vdw_type_[itype] * N_vdw_type_[jtype] * NB_->NBarray()[ nbidx ].B(); } } - //atype_vdw_recip_terms_.push_back(atype_vdw_term); // the nonbond interaction for each atom type + atype_vdw_recip_terms_.push_back(atype_vdw_term); } return 0; } diff --git a/src/Energy/VDW_LongRange_Correction.h b/src/Energy/VDW_LongRange_Correction.h index 2cfe11048e..20cd980817 100644 --- a/src/Energy/VDW_LongRange_Correction.h +++ b/src/Energy/VDW_LongRange_Correction.h @@ -20,8 +20,13 @@ class VDW_LongRange_Correction { } private: typedef std::vector Iarray; + typedef std::vector Darray; double Vdw_Recip_term_; int debug_; + // Below variables are needed for per-atom decomp + Iarray vdw_type_; ///< VDW type for each seleccted atom (#atoms) + Iarray N_vdw_type_; ///< Count of atoms that have each VDW type index (#types) + Darray atype_vdw_recip_terms_; ///< the nonbond interaction for each atom type (#types) }; } } From 79c433fce8ce0e58fde48e6582483b4557046ac6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 25 Sep 2024 15:36:56 -0400 Subject: [PATCH 102/218] Decompose the long range correction --- src/Energy/EwaldCalc_Decomp_PME.cpp | 6 +++++- src/Energy/VDW_LongRange_Correction.cpp | 20 ++++++++++++++++++++ src/Energy/VDW_LongRange_Correction.h | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 05d2d45e9f..3e2aa6c9bb 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -93,7 +93,11 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom mprintf("DEBUG: Recip energy : %f\n", e_recip); mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); // TODO distribute - double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); + Darray atom_vdwlr; + double e_vdw_lr_correction = VDW_LR_.Vdw_Decomp_Correction( atom_vdwlr, + NBengine_.EwaldParams().Cutoff(), volume ); + mprintf("DEBUG: VDW correction : %f\n", e_vdw_lr_correction); + mprintf("DEBUG: Sum of VDW correction: %f\n", sumArray(atom_vdwlr)); t_direct_.Start(); Cpptraj::PairListTemplate(pairList_, Excluded_, NBengine_.EwaldParams().Cut2(), NBengine_); diff --git a/src/Energy/VDW_LongRange_Correction.cpp b/src/Energy/VDW_LongRange_Correction.cpp index c5715286da..1e69c7beb6 100644 --- a/src/Energy/VDW_LongRange_Correction.cpp +++ b/src/Energy/VDW_LongRange_Correction.cpp @@ -57,3 +57,23 @@ int VDW_LongRange_Correction::Setup_VDW_Correction(Topology const& topIn, } return 0; } + +/** Decomposed long range VDW correction */ +double VDW_LongRange_Correction::Vdw_Decomp_Correction(std::vector& atom_ecorr, + double cutoff_, double volume) +const +{ + atom_ecorr.resize( vdw_type_.size() ); + double prefac = Constants::TWOPI / (3.0*volume*cutoff_*cutoff_*cutoff_); + double e_vdwr = -prefac * Vdw_Recip_term_; + + for (unsigned int i = 0; i != vdw_type_.size(); i++) + { + int v_type = vdw_type_[i]; + + double term = atype_vdw_recip_terms_[v_type] / N_vdw_type_[v_type]; + + atom_ecorr[i] = -prefac * term; + } + return e_vdwr; +} diff --git a/src/Energy/VDW_LongRange_Correction.h b/src/Energy/VDW_LongRange_Correction.h index 20cd980817..6a0cf3b593 100644 --- a/src/Energy/VDW_LongRange_Correction.h +++ b/src/Energy/VDW_LongRange_Correction.h @@ -18,6 +18,8 @@ class VDW_LongRange_Correction { //if (debug_ > 0) mprintf("DEBUG: Vdw correction %20.10f\n", e_vdwr); return e_vdwr; } + /// VDW correction decomposed per atom + double Vdw_Decomp_Correction(std::vector&, double, double) const; private: typedef std::vector Iarray; typedef std::vector Darray; From 5d1e788748b520462ed8ad2dab9e7a3a88aadb98 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 10:01:13 -0400 Subject: [PATCH 103/218] Actually save the energies back to EnergyDecomposer --- src/Energy/EnergyDecomposer.cpp | 5 +++++ src/Energy/EwaldCalc_Decomp_PME.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index adbb98d8b6..c6ed64de24 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -363,6 +363,11 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { std::vector atom_elec, atom_vdw; PME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), e_elec, e_vdw, atom_elec, atom_vdw); + for (int at = 0; at < currentTop_->Natom(); at++) { + if (selectedAtoms_.AtomInCharMask(at)) { + saveEne( at, atom_elec[at] + atom_vdw[at] ); + } + } } else { calcNB_simple(frameIn); } diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 3e2aa6c9bb..31eeefdf4b 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -125,6 +125,14 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom } e_vdw = NBengine_.Evdw() + e_vdw_lr_correction; e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); + // TODO preallocate? + atom_elec.resize( NBengine_.Eatom_Elec().size() ); + atom_vdw.resize( NBengine_.Eatom_EVDW().size() ); + for (unsigned int idx = 0; idx != atom_elec.size(); idx++) + { + atom_elec[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; + atom_vdw[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwlr[idx]; + } t_total_.Stop(); return 0; } From d0dfb018b6ae0017c06fec13465d8dd9aa05bccf Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 10:32:33 -0400 Subject: [PATCH 104/218] Add timing data. Hide some debug info. --- src/Energy/EnergyDecomposer.cpp | 6 ++++++ src/Energy/EnergyDecomposer.h | 3 +++ src/Energy/EwaldCalc_Decomp_PME.cpp | 7 +++++++ src/Energy/EwaldCalc_Decomp_PME.h | 1 + src/Energy/EwaldParams.cpp | 2 +- 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index c6ed64de24..abdc22a6c3 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -346,6 +346,7 @@ void EnergyDecomposer::calcNB_simple(Frame const& frameIn) { /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { + t_total_.Start(); if (currentTop_ == 0) { mprinterr("Internal Error: EnergyDecomposer::CalcEne() called before setup.\n"); return 1; @@ -377,6 +378,7 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { if (selectedAtoms_.AtomInCharMask( idx )) energies_[idx].accumulate( currentEne_[idx] ); } + t_total_.Stop(); return 0; } @@ -397,5 +399,9 @@ int EnergyDecomposer::FinishCalc() { set.AddXY( idx+1, energies_[idx].mean() ); } } + t_total_.WriteTiming(0, " Decomp total:"); + if (use_pme_) { + PME_.Timing(t_total_.Total()); + } return 0; } diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index defc8b05d9..c9b48e7f7c 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -7,6 +7,7 @@ #include "../EwaldOptions.h" #include "../ExclusionArray.h" #include "../OnlineVarT.h" +#include "../Timer.h" class AngleType; class ArgList; class BondType; @@ -79,6 +80,8 @@ class EnergyDecomposer { EwaldCalc_Decomp_PME PME_; ///< For calculating pairwise decomposed PME energies Darray currentEne_; ///< Hold the total energy of each atom for the current frame + + Timer t_total_; ///< Total calc time }; } } diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 31eeefdf4b..71347124dc 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -136,3 +136,10 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom t_total_.Stop(); return 0; } + +void EwaldCalc_Decomp_PME::Timing(double total) const { + t_total_.WriteTiming(1, " PME decomp Total:", total); + Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); + pairList_.Timing(total); +} diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index b8de59db71..6cd57acee4 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -21,6 +21,7 @@ class EwaldCalc_Decomp_PME { int Setup(Topology const&, AtomMask const&); // TODO CharMask? int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, Darray&, Darray&); + void Timing(double) const; private: PairListEngine_Ewald_Decomp_LJLR NBengine_; PME_Recip Recip_; diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index 2830c6315c..f9e301b559 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -158,7 +158,7 @@ double EwaldParams::DecomposedSelfEnergy(Darray& atom_self, double volume) const for (unsigned int i = 0; i < Charge_.size(); i++) { atom_self[i] = Charge_[i]*Charge_[i]*d0 + ee_plasma/Charge_.size(); - mprintf("DEBUG: Self energy atom %i = %f\n", i+1, atom_self[i]); + //mprintf("DEBUG: Self energy atom %i = %f\n", i+1, atom_self[i]); } ene += ee_plasma; From 243371a3efc236341efbc4d1d5e730c3b93120b7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 11:04:29 -0400 Subject: [PATCH 105/218] Put LJ PME vdw calc into a template --- src/Energy/Ene_LJPME_6_12.h | 27 +++++++++++++++++++++++++++ src/Energy/energydepend | 2 +- src/PairListEngine_Ewald_LJPME.h | 11 ++++++++++- src/cpptrajdepend | 6 +++--- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/Energy/Ene_LJPME_6_12.h diff --git a/src/Energy/Ene_LJPME_6_12.h b/src/Energy/Ene_LJPME_6_12.h new file mode 100644 index 0000000000..14f80165b3 --- /dev/null +++ b/src/Energy/Ene_LJPME_6_12.h @@ -0,0 +1,27 @@ +#ifndef INC_ENERGY_ENE_LJPME_6_12_H +#define INC_ENERGY_ENE_LJPME_6_12_H +namespace Cpptraj { +namespace Energy { +/// \return LJ 6-12 energy +template +void Ene_LJPME_6_12(T& e_vdw, T& e_pmevdw, + T const& rij2, T const& LJA, T const& LJB, T const& lj_ewcoeff, T const& Cij) +{ + T r2 = 1.0 / rij2; + T r6 = r2 * r2 * r2; + T r12 = r6 * r6; + T f12 = LJA * r12; // A/r^12 + T f6 = LJB * r6; // B/r^6 + e_vdw = f12 - f6; // (A/r^12)-(B/r^6) + // LJ PME direct space correction + T kr2 = lj_ewcoeff * lj_ewcoeff * rij2; + T kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + T expterm = exp(-kr2); + //T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + //Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; + e_pmevdw = (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * Cij; +} +} +} +#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 0e209f94ec..ff7d626708 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,7 +1,7 @@ EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index f077e95c80..525c736780 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -1,6 +1,7 @@ #ifndef INC_PAIRLISTENGINE_EWALD_LJPME_H #define INC_PAIRLISTENGINE_EWALD_LJPME_H #include "Energy/EwaldParams_LJPME.h" +#include "Energy/Ene_LJPME_6_12.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" namespace Cpptraj { @@ -37,6 +38,14 @@ class PairListEngine_Ewald_LJPME { if (nbindex > -1) { double vswitch = EW_.Switch_Fn(rij2); NonbondType const& LJ = EW_.GetLJ( nbindex ); + T e_vdw, e_pmevdw; + Cpptraj::Energy:: + Ene_LJPME_6_12( e_vdw, e_pmevdw, + rij2, LJ.A(), LJ.B(), EW_.LJ_EwaldCoeff(), + EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); + Evdw_ += (e_vdw * vswitch); + Eljpme_correction_ += (e_pmevdw * vswitch); +/* T r2 = 1.0 / rij2; T r6 = r2 * r2 * r2; T r12 = r6 * r6; @@ -51,7 +60,7 @@ class PairListEngine_Ewald_LJPME { //double kr6 = kr2 * kr4; T expterm = exp(-kr2); T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; + Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij;*/ } } /// Call when cutoff is not satisfied diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 6b943ea6a6..f2bdf5ca2c 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -280,7 +280,7 @@ Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 53ec89fc53d6d61382afad0b73651ea2d674284b Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 11:12:30 -0400 Subject: [PATCH 106/218] Add LJPME exclude adjust kernel --- src/Energy/Kernel_LJPME_Adjust.h | 21 +++++++++++++++++++++ src/Energy/energydepend | 2 +- src/PairListEngine_Ewald_LJPME.h | 24 ++++++------------------ src/cpptrajdepend | 6 +++--- 4 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 src/Energy/Kernel_LJPME_Adjust.h diff --git a/src/Energy/Kernel_LJPME_Adjust.h b/src/Energy/Kernel_LJPME_Adjust.h new file mode 100644 index 0000000000..6569bdd0a6 --- /dev/null +++ b/src/Energy/Kernel_LJPME_Adjust.h @@ -0,0 +1,21 @@ +#ifndef INC_KERNEL_LJPME_ADJUST_H +#define INC_KERNEL_LJPME_ADJUST_H +namespace Cpptraj { +namespace Energy { +/// Used to adjust LJPME energy for excluded atoms +template T Kernel_LJPME_Adjust(T const& rij2, T const& lj_ewcoeff, T const& Cij) +{ + // LJ PME direct space exclusion correction + // NOTE: Assuming excluded pair is within cutoff + T kr2 = lj_ewcoeff * lj_ewcoeff * rij2; + T kr4 = kr2 * kr2; + //double kr6 = kr2 * kr4; + T expterm = exp(-kr2); + T r4 = rij2 * rij2; + T r6 = rij2 * r4; + //T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; + return (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; +} +} +} +#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index ff7d626708..850c7c6aad 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,7 +1,7 @@ EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index 525c736780..66a80dcefd 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -3,6 +3,7 @@ #include "Energy/EwaldParams_LJPME.h" #include "Energy/Ene_LJPME_6_12.h" #include "Energy/Kernel_EwaldAdjust.h" +#include "Energy/Kernel_LJPME_Adjust.h" #include "PairList.h" namespace Cpptraj { /// Direct space nonbond calculation using pairlist with Ewald and LJPME for VDW @@ -45,22 +46,6 @@ class PairListEngine_Ewald_LJPME { EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); Evdw_ += (e_vdw * vswitch); Eljpme_correction_ += (e_pmevdw * vswitch); -/* - T r2 = 1.0 / rij2; - T r6 = r2 * r2 * r2; - T r12 = r6 * r6; - T f12 = LJ.A() * r12; // A/r^12 - T f6 = LJ.B() * r6; // B/r^6 - T e_vdw = f12 - f6; // (A/r^12)-(B/r^6) - Evdw_ += (e_vdw * vswitch); - //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); - // LJ PME direct space correction - T kr2 = EW_.LJ_EwaldCoeff() * EW_.LJ_EwaldCoeff() * rij2; - T kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - T expterm = exp(-kr2); - T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij;*/ } } /// Call when cutoff is not satisfied @@ -72,7 +57,10 @@ class PairListEngine_Ewald_LJPME { T erfcval = EW_.ErfcEW( rij ); Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); // LJ PME direct space exclusion correction - // NOTE: Assuming excluded pair is within cutoff + Eljpme_correction_excl_ += Cpptraj::Energy:: + Kernel_LJPME_Adjust( rij2, EW_.LJ_EwaldCoeff(), + EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); +/* // NOTE: Assuming excluded pair is within cutoff T kr2 = EW_.LJ_EwaldCoeff() * EW_.LJ_EwaldCoeff() * rij2; T kr4 = kr2 * kr2; //double kr6 = kr2 * kr4; @@ -80,7 +68,7 @@ class PairListEngine_Ewald_LJPME { T r4 = rij2 * rij2; T r6 = rij2 * r4; T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; + Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij;*/ } // ------------------------------------------- Cpptraj::Energy::EwaldParams_LJPME& ModifyEwaldParams() { return EW_; } diff --git a/src/cpptrajdepend b/src/cpptrajdepend index f2bdf5ca2c..c3fdf639b3 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -280,7 +280,7 @@ Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 603ae5db2ef86d36dc5c551b43e103c89a2f7a6f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 11:14:16 -0400 Subject: [PATCH 107/218] Remove old code --- src/PairListEngine_Ewald_LJPME.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/PairListEngine_Ewald_LJPME.h b/src/PairListEngine_Ewald_LJPME.h index 66a80dcefd..6a6dba25df 100644 --- a/src/PairListEngine_Ewald_LJPME.h +++ b/src/PairListEngine_Ewald_LJPME.h @@ -60,15 +60,6 @@ class PairListEngine_Ewald_LJPME { Eljpme_correction_excl_ += Cpptraj::Energy:: Kernel_LJPME_Adjust( rij2, EW_.LJ_EwaldCoeff(), EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); -/* // NOTE: Assuming excluded pair is within cutoff - T kr2 = EW_.LJ_EwaldCoeff() * EW_.LJ_EwaldCoeff() * rij2; - T kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - T expterm = exp(-kr2); - T r4 = rij2 * rij2; - T r6 = rij2 * r4; - T Cij = EW_.CalcCij(atom0.Idx(), atom1.Idx()); //Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction_excl_ += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij;*/ } // ------------------------------------------- Cpptraj::Energy::EwaldParams_LJPME& ModifyEwaldParams() { return EW_; } From 5d2a29f3b100f344b5e4ccc3e18307fbcc5aeddc Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 26 Sep 2024 15:27:58 -0400 Subject: [PATCH 108/218] Add Ewald LJPME decomp --- src/PairListEngine_Ewald_Decomp_LJPME.h | 130 ++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/PairListEngine_Ewald_Decomp_LJPME.h diff --git a/src/PairListEngine_Ewald_Decomp_LJPME.h b/src/PairListEngine_Ewald_Decomp_LJPME.h new file mode 100644 index 0000000000..70662ecacc --- /dev/null +++ b/src/PairListEngine_Ewald_Decomp_LJPME.h @@ -0,0 +1,130 @@ +#ifndef INC_PAIRLISTENGINE_EWALD_DECOMP_LJPME_H +#define INC_PAIRLISTENGINE_EWALD_DECOMP_LJPME_H +#include "Energy/EwaldParams_LJPME.h" +#include "Energy/Ene_LJPME_6_12.h" +#include "Energy/Kernel_EwaldAdjust.h" +#include "Energy/Kernel_LJPME_Adjust.h" +#include "PairList.h" +namespace Cpptraj { +/// Direct space nonbond calculation using pairlist with decomposable Ewald and LJPME for VDW +template +class PairListEngine_Ewald_Decomp_LJPME { + typedef std::vector Darray; + public: + PairListEngine_Ewald_Decomp_LJPME() {} + // ------------------------------------------- + /// Call at the beginning of the frame calculation + void FrameBeginCalc() { Evdw_ = 0; Eelec_ = 0; Eadjust_ = 0; + Eljpme_correction_ = 0; Eljpme_correction_excl_ = 0; + atom_elec_.assign(EW_.Natom(), 0); + atom_evdw_.assign(EW_.Natom(), 0); + atom_eadj_.assign(EW_.Natom(), 0); + } + /// Call for atom 0 when looping over atoms of thisCell + void SetupAtom0( PairList::AtmType const& atom0 ) { + q0_ = EW_.Charge(atom0.Idx()); + } + /// Call for atom 1 when looping over interaction atoms of this/other cell + void SetupAtom1( PairList::AtmType const& atom1 ) { + q1_ = EW_.Charge(atom1.Idx()); + } + /// Call when cutoff is satisfied + void CutoffSatisfied(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt( rij2 ); + T qiqj = q0_ * q1_; + //double erfc = erfc_func(ew_coeff_ * rij); + T erfcval = EW_.ErfcEW( rij ); + T e_elec = qiqj * erfcval / rij; + Eelec_ += e_elec; + T e_half = e_elec * 0.5; + atom_elec_[atom0.Idx()] += e_half; + atom_elec_[atom1.Idx()] += e_half; + + int nbindex = EW_.NbIndex(atom0.Idx(), atom1.Idx()); + if (nbindex > -1) { + double vswitch = EW_.Switch_Fn(rij2); + NonbondType const& LJ = EW_.GetLJ( nbindex ); + T e_vdw, e_pmevdw; + Cpptraj::Energy:: + Ene_LJPME_6_12( e_vdw, e_pmevdw, + rij2, LJ.A(), LJ.B(), EW_.LJ_EwaldCoeff(), + EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); + e_vdw *= vswitch; + Evdw_ += e_vdw; + e_half = e_vdw * 0.5; + e_pmevdw *= vswitch; + Eljpme_correction_ += e_pmevdw; + e_half += (e_pmevdw * 0.5); + atom_evdw_[atom0.Idx()] += e_half; + atom_evdw_[atom1.Idx()] += e_half; + } + } + /// Call when cutoff is not satisfied + void AtomPairExcluded(T const& rij2, + PairList::AtmType const& atom0, + PairList::AtmType const& atom1) + { + T rij = sqrt(rij2); + T erfcval = EW_.ErfcEW( rij ); + T e_adj = Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); + Eadjust_ += e_adj; + e_half = e_adj * 0.5; + // LJ PME direct space exclusion correction + T e_ljpme_adj = Cpptraj::Energy:: + Kernel_LJPME_Adjust( rij2, EW_.LJ_EwaldCoeff(), + EW_.CalcCij(atom0.Idx(), atom1.Idx()) ); + Eljpme_correction_excl_ += e_ljpme_adj; + e_half += (e_ljpme_adj * 0.5); + atom_eadj_[atom0.Idx()] += e_half; + atom_eadj_[atom1.Idx()] += e_half; + } + // ------------------------------------------- + Cpptraj::Energy::EwaldParams_LJPME& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams_LJPME const& EwaldParams() const { return EW_; } + + T Evdw() const { return Evdw_ + Eljpme_correction_ + Eljpme_correction_excl_; } + T Eelec() const { return Eelec_; } + T Eadjust() const { return Eadjust_; } + Darray const& Eatom_Elec() const { return atom_elec_; } + Darray const& Eatom_EVDW() const { return atom_evdw_; } + Darray const& Eatom_EAdjust() const { return atom_eadj_; } +# ifdef _OPENMP + static void sum_Darray(Darray& lhs, Darray const& rhs) { + for (unsigned int idx = 0; idx != rhs.size(); ++idx) + lhs[idx] += rhs[idx]; + } + /// To allow reduction of the energy terms + void operator+=(PairListEngine_Ewald_LJPME const& rhs) { + Evdw_ += rhs.Evdw_; + Eelec_ += rhs.Eelec_; + Eadjust_ += rhs.Eadjust_; + Eljpme_correction_ += rhs.Eljpme_correction_; + Eljpme_correction_excl_ += rhs.Eljpme_correction_excl_; + sum_Darray(atom_elec_, rhs.atom_elec_); + sum_Darray(atom_evdw_, rhs.atom_evdw_); + sum_Darray(atom_eadj_, rhs.atom_eadj_); + } +# endif + private: + T q0_; ///< Charge on atom 0 + T q1_; ///< Charge on atom 1 + T Evdw_; ///< VDW sum for current frame + T Eelec_; ///< Coulomb sum for current frame + T Eadjust_; ///< Adjust energy sum for current frame + T Eljpme_correction_; ///< LJ PME correction for VDW + T Eljpme_correction_excl_; ///< LJ PME correction for adjust + + Darray atom_elec_; ///< Sum of Coulomb E on each atom for current frame + Darray atom_evdw_; ///< Sum of VDW E on each atom for current frame + Darray atom_eadj_; ///< Sum of excluded atom adjust E on each atom for current frame + + Cpptraj::Energy::EwaldParams_LJPME EW_; ///< Hold Ewald parameters for LJPME +}; +#ifdef _OPENMP +#pragma omp declare reduction( + : PairListEngine_Ewald_LJPME : omp_out += omp_in ) initializer( omp_priv = omp_orig ) +#endif +} // END namespace Cpptraj +#endif From 6281543b7686ec3fdc911eff819a31d3df43e72c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 27 Sep 2024 08:47:14 -0400 Subject: [PATCH 109/218] Create decomposed LJPME calc. Still need to do decomposed self6 energy. --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 163 ++++++++++++++++++++++++ src/Energy/EwaldCalc_Decomp_LJPME.h | 32 +++++ src/Energy/EwaldCalc_Decomp_PME.cpp | 1 + src/PairListEngine_Ewald_Decomp_LJPME.h | 2 +- 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/Energy/EwaldCalc_Decomp_LJPME.cpp create mode 100644 src/Energy/EwaldCalc_Decomp_LJPME.h diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp new file mode 100644 index 0000000000..d68eec036f --- /dev/null +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -0,0 +1,163 @@ +#include "EwaldCalc_Decomp_LJPME.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" +#include "../PairListTemplate.h" +#include "../Topology.h" + +using namespace Cpptraj::Energy; + +EwaldCalc_Decomp_LJPME::EwaldCalc_Decomp_LJPME() : + Recip_(PME_Recip::COULOMB), + LJrecip_(PME_Recip::LJ) +{} + +/** Set up LJPME parameters. */ +int EwaldCalc_Decomp_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: Decomposable LJPME calculation init failed.\n"); + return 1; + } + if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + Recip_.SetDebug( debugIn ); + LJrecip_.SetDebug( debugIn ); + + return 0; +} + +/** Setup LJPME calculation. */ +int EwaldCalc_Decomp_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { + if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { + mprinterr("Error: LJPME calculation setup failed.\n"); + return 1; + } + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for LJPME calculation.\n"); + return 1; + } + + return 0; +} + +// DEBUG +static inline double sumArray(std::vector const& arrayIn) { + double sum = 0; + for (std::vector::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) + sum += *it; + return sum; +} + +/** Calculate full nonbonded energy with LJPME */ +int EwaldCalc_Decomp_LJPME::CalcDecomposedNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + double& e_elec, double& e_vdw, + Darray& atom_elec, Darray& atom_vdw) +{ + t_total_.Start(); + double volume = frameIn.BoxCrd().CellVolume(); + Darray atom_self; + double e_self = NBengine_.EwaldParams().DecomposedSelfEnergy( atom_self, volume ); + mprintf("DEBUG: Total self energy: %f\n", e_self); + mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); + // FIXME do decomposed self6 + Darray atom_vdwself6; + + int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn); + if (retVal != 0) { + mprinterr("Error: Pairlist creation failed for LJPME calc.\n"); + return 1; + } + + // TODO make more efficient + NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); + + // MapCoords(frameIn, ucell, recip, maskIn); + Darray atom_recip; + // FIXME helPME requires coords and charge arrays to be non-const + double e_recip = Recip_.Recip_Decomp( atom_recip, + NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedCharges(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + mprintf("DEBUG: Recip energy : %f\n", e_recip); + mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); + Darray atom_vdw6recip; + double e_vdw6recip = LJrecip_.Recip_Decomp( atom_vdw6recip, + NBengine_.ModifyEwaldParams().SelectedCoords(), + frameIn.BoxCrd(), + NBengine_.ModifyEwaldParams().SelectedC6params(), + NBengine_.EwaldParams().NFFT(), + NBengine_.EwaldParams().LJ_EwaldCoeff(), + NBengine_.EwaldParams().Order() + ); + mprintf("DEBUG: VDW Recip energy : %f\n", e_vdw6recip); + mprintf("DEBUG: Sum of VDW recip array: %f\n", sumArray(atom_vdw6recip)); + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: e_vdw6self = %16.8f\n", NBengine_.EwaldParams().Self6()); + mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); + } + + t_direct_.Start(); + Cpptraj::PairListTemplate(pairList_, Excluded_, + NBengine_.EwaldParams().Cut2(), NBengine_); + t_direct_.Stop(); + mprintf("DEBUG: Direct Elec. energy : %f\n", NBengine_.Eelec()); + mprintf("DEBUG: Sum of elec. energy : %f\n", sumArray(NBengine_.Eatom_Elec())); + mprintf("DEBUG: Direct VDW energy : %f\n", NBengine_.Evdw()); + mprintf("DEBUG: Sum of VDW energy : %f\n", sumArray(NBengine_.Eatom_EVDW())); + mprintf("DEBUG: Direct Adjust energy: %f\n", NBengine_.Eadjust()); + mprintf("DEBUG: Sum of Adjust energy: %f\n", sumArray(NBengine_.Eatom_EAdjust())); + + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: Nonbond energy components:\n"); + mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + + NBengine_.EwaldParams().Self6() + + e_vdw6recip); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + + NBengine_.Eelec() + + NBengine_.Eadjust()); + mprintf("\n"); + mprintf(" E electrostatic (self) = %24.12f\n", e_self); + mprintf(" (rec) = %24.12f\n", e_recip); + mprintf(" (dir) = %24.12f\n", NBengine_.Eelec()); + mprintf(" (adj) = %24.12f\n", NBengine_.Eadjust()); + mprintf(" E vanDerWaals (dir) = %24.12f\n", NBengine_.Evdw()); + mprintf(" (6slf) = %24.12f\n", NBengine_.EwaldParams().Self6()); + mprintf(" (6rcp) = %24.12f\n", e_vdw6recip); + } + e_vdw = NBengine_.Evdw() + NBengine_.EwaldParams().Self6() + e_vdw6recip; + e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); + // TODO preallocate? + atom_elec.resize( NBengine_.Eatom_Elec().size() ); + atom_vdw.resize( NBengine_.Eatom_EVDW().size() ); + for (unsigned int idx = 0; idx != atom_elec.size(); idx++) + { + atom_elec[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; + atom_vdw[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwself6[idx] + atom_vdw6recip[idx]; + } + + t_total_.Stop(); + return 0; +} + +void EwaldCalc_Decomp_LJPME::Timing(double total) const { + t_total_.WriteTiming(1, " LJPME Total:", total); + Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); + //Recip_.Timing_Calc().WriteTiming(3, "Recip. Calc :", Recip_.Timing_Total().Total()); + LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); + //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); + + pairList_.Timing(total); +} diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.h b/src/Energy/EwaldCalc_Decomp_LJPME.h new file mode 100644 index 0000000000..73083fbad1 --- /dev/null +++ b/src/Energy/EwaldCalc_Decomp_LJPME.h @@ -0,0 +1,32 @@ +#ifndef INC_ENERGY_EWALDCALC_DECOMP_LJPME_H +#define INC_ENERGY_EWALDCALC_DECOMP_LJPME_H +#include "PME_Recip.h" +#include "../ExclusionArray.h" +#include "../PairList.h" +#include "../PairListEngine_Ewald_Decomp_LJPME.h" +namespace Cpptraj { +namespace Energy { +class EwaldCalc_Decomp_LJPME { + public: + typedef std::vector Darray; + + EwaldCalc_Decomp_LJPME(); + /// Init with Box, EwaldOptions and debug level + int Init(Box const&, EwaldOptions const&, int); + int Setup(Topology const&, AtomMask const&); + int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, + Darray&, Darray&); + + void Timing(double) const; + private: + PairListEngine_Ewald_Decomp_LJPME NBengine_; + PME_Recip Recip_; + PME_Recip LJrecip_; + PairList pairList_; + ExclusionArray Excluded_; + Timer t_total_; + Timer t_direct_; +}; +} +} +#endif diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 71347124dc..321b83f8db 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -50,6 +50,7 @@ int EwaldCalc_Decomp_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +// DEBUG static inline double sumArray(std::vector const& arrayIn) { double sum = 0; for (std::vector::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) diff --git a/src/PairListEngine_Ewald_Decomp_LJPME.h b/src/PairListEngine_Ewald_Decomp_LJPME.h index 70662ecacc..05fdf48d83 100644 --- a/src/PairListEngine_Ewald_Decomp_LJPME.h +++ b/src/PairListEngine_Ewald_Decomp_LJPME.h @@ -71,7 +71,7 @@ class PairListEngine_Ewald_Decomp_LJPME { T erfcval = EW_.ErfcEW( rij ); T e_adj = Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); Eadjust_ += e_adj; - e_half = e_adj * 0.5; + T e_half = e_adj * 0.5; // LJ PME direct space exclusion correction T e_ljpme_adj = Cpptraj::Energy:: Kernel_LJPME_Adjust( rij2, EW_.LJ_EwaldCoeff(), From 99c22d6f5b93deef83ad91234cf336ca64316916 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 27 Sep 2024 09:17:59 -0400 Subject: [PATCH 110/218] Add decomposed self6 calc --- src/Energy/EwaldParams_LJPME.cpp | 13 +++++++++++++ src/Energy/EwaldParams_LJPME.h | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp index b688ad876b..e4161a02d3 100644 --- a/src/Energy/EwaldParams_LJPME.cpp +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -64,3 +64,16 @@ int EwaldParams_LJPME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) return 0; } +/** Calculate decomposed self6 energies. */ +void EwaldParams_LJPME::CalcDecomposedSelf6Energy() { + atom_vdwself6_.clear(); + atom_vdwself6_.reserve( Cparam_.size() ); + double ew2 = lw_coeff_ * lw_coeff_; + double ew6 = ew2 * ew2 * ew2; + double c6sum = 0.0; + for (Darray::const_iterator it = Cparam_.begin(); it != Cparam_.end(); ++it) + { + c6sum += ew6 * (*it * *it); + atom_vdwself6_.push_back(ew6 * (*it * *it)/12.0); + } +} diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index 16bac93443..dd7a976f8f 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -17,6 +17,11 @@ class EwaldParams_LJPME : public EwaldParams_PME { double Self6() const { return ljpme_self_; } /// \return C6 parameter pair for specified selected atoms double CalcCij(int idx0, int idx1) const { return (Cparam_[idx0] * Cparam_[idx1]); } + /// Calculate decomposed LJPME self energy + void CalcDecomposedSelf6Energy(); + /// \return Array containing LJPME self energy decomposed by atom + std::vector const& Atom_Self6Energies() const { return atom_vdwself6_; } + // FIXME do not return const because helPME needs the array to be non-const. Should be fixed std::vector& SelectedC6params() { return Cparam_; } @@ -24,6 +29,7 @@ class EwaldParams_LJPME : public EwaldParams_PME { Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME double lw_coeff_; ///< LJ Ewald coefficient double ljpme_self_; ///< LJ PME self energy calculated from C6 parameters and LJ Ewald coeff. + Darray atom_vdwself6_; ///< LJ PME self energy decomposed by atom }; } } From 7d83077a254726093f82cd7dfd8fb3b7ea4af368 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 27 Sep 2024 09:18:23 -0400 Subject: [PATCH 111/218] Use decomposed self6 energies --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index d68eec036f..233b98fec3 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -34,6 +34,7 @@ int EwaldCalc_Decomp_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) mprinterr("Error: LJPME calculation setup failed.\n"); return 1; } + NBengine_.ModifyEwaldParams().CalcDecomposedSelf6Energy(); // Setup exclusion list // Use distance of 4 (up to dihedrals) if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, @@ -67,7 +68,9 @@ int EwaldCalc_Decomp_LJPME::CalcDecomposedNonbondEnergy(Frame const& frameIn, At mprintf("DEBUG: Total self energy: %f\n", e_self); mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); // FIXME do decomposed self6 - Darray atom_vdwself6; + Darray const& atom_vdwself6 = NBengine_.EwaldParams().Atom_Self6Energies(); + mprintf("DEBUG: Total self6 energy: %f\n", NBengine_.EwaldParams().Self6()); + mprintf("DEBUG: Sum of self6 array: %f\n", sumArray(atom_vdwself6)); int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); From 498b9ce8911c1cd4b784cf48e89d04da35b04b68 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 27 Sep 2024 09:18:43 -0400 Subject: [PATCH 112/218] Update depends --- src/Energy/CMakeLists.txt | 1 + src/Energy/energydepend | 1 + src/Energy/energyfiles | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 1982c84abf..2ec7f40eec 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Decomp_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Decomp_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_PME.cpp diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 850c7c6aad..f8c55b6eac 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,6 @@ EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h +EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_LJPME.h PME_Recip.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index d0c37f84c5..2ade756ee4 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -2,6 +2,7 @@ ENERGY_SOURCES= \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ + EwaldCalc_Decomp_LJPME.cpp \ EwaldCalc_Decomp_PME.cpp \ EwaldCalc_LJPME.cpp \ EwaldCalc_PME.cpp \ From 1519b88a850ed13e5db8d770e019b350ac9f41b8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 27 Sep 2024 09:34:46 -0400 Subject: [PATCH 113/218] Doesnt appear like the recip term for the LJPME is working yet. --- src/Energy/EnergyDecomposer.cpp | 40 +++++++++++++++++++++++---------- src/Energy/EnergyDecomposer.h | 6 ++++- src/Energy/energydepend | 2 +- src/cpptrajdepend | 7 +++--- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index abdc22a6c3..044055ea23 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -23,6 +23,7 @@ EnergyDecomposer::EnergyDecomposer() : eneOut_(0), outfile_(0), debug_(0), + nbcalctype_(SIMPLE), currentTop_(0) { } @@ -33,8 +34,12 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFil debug_ = debugIn; // Process keywords outfile_ = DFLin.AddDataFile( argIn.GetStringKey("out"), argIn ); - use_pme_ = argIn.hasKey("pme"); - if (use_pme_) { + nbcalctype_ = SIMPLE; + if (argIn.hasKey("pme")) + nbcalctype_ = PME; + else if (argIn.Contains("ljpme")) // FIXME using Contains() since EwaldOptions parses ljpme + nbcalctype_ = LJPME; + if (nbcalctype_ == PME || nbcalctype_ == LJPME) { if (ewaldOpts_.GetOptions(EwaldOptions::PME, argIn, "enedecomp")) return 1; } @@ -70,7 +75,7 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); if (outfile_ != 0) mprintf("\tOutput file: %s\n", outfile_->DataFilename().full()); - if (use_pme_) + if (nbcalctype_ != SIMPLE) ewaldOpts_.PrintOptions(); } @@ -182,17 +187,24 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn, Box const& boxIn) { if (setupDihedrals( topIn.Dihedrals() )) return 1; if (setupDihedrals( topIn.DihedralsH() )) return 1; std::sort( dihedrals_.begin(), dihedrals_.end() ); - if (use_pme_) { + if (nbcalctype_ != SIMPLE) { if (!boxIn.HasBox()) { mprinterr("Error: PME requires unit cell information.\n"); return 1; } // Set up for all atoms FIXME AtomMask Imask(0, topIn.Natom()); - if (PME_.Init(boxIn, ewaldOpts_, debug_)) - return 1; - if (PME_.Setup( topIn, Imask )) - return 1; + if (nbcalctype_ == PME) { + if (PME_.Init(boxIn, ewaldOpts_, debug_)) + return 1; + if (PME_.Setup( topIn, Imask )) + return 1; + } else if (nbcalctype_ == LJPME) { + if (LJPME_.Init(boxIn, ewaldOpts_, debug_)) + return 1; + if (LJPME_.Setup( topIn, Imask )) + return 1; + } } else { // For nonbonds, set up all selected atoms in an integer atom mask. //mask_ = AtomMask( selectedAtoms_.ConvertToIntMask(), selectedAtoms_.Natom() ); @@ -359,11 +371,15 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { // Dihedrals calcDihedrals(frameIn); // Nonbonds - if (use_pme_) { // FIXME atommask? + if (nbcalctype_ != SIMPLE) { // FIXME atommask? double e_elec, e_vdw; std::vector atom_elec, atom_vdw; - PME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), - e_elec, e_vdw, atom_elec, atom_vdw); + if (nbcalctype_ == PME) + PME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), + e_elec, e_vdw, atom_elec, atom_vdw); + else if (nbcalctype_ == LJPME) + LJPME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), + e_elec, e_vdw, atom_elec, atom_vdw); for (int at = 0; at < currentTop_->Natom(); at++) { if (selectedAtoms_.AtomInCharMask(at)) { saveEne( at, atom_elec[at] + atom_vdw[at] ); @@ -400,7 +416,7 @@ int EnergyDecomposer::FinishCalc() { } } t_total_.WriteTiming(0, " Decomp total:"); - if (use_pme_) { + if (nbcalctype_ != SIMPLE) { PME_.Timing(t_total_.Total()); } return 0; diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index c9b48e7f7c..cc9f991b56 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -2,6 +2,7 @@ #define INC_ENERGY_ENERGYDECOMPOSER_H #include #include "EwaldCalc_Decomp_PME.h" +#include "EwaldCalc_Decomp_LJPME.h" #include "../AtomMask.h" #include "../CharMask.h" #include "../EwaldOptions.h" @@ -36,6 +37,8 @@ class EnergyDecomposer { /// Finish the calculation by putting energies in output DataSet int FinishCalc(); private: + enum NonBondCalcType { SIMPLE = 0, PME, LJPME }; + static const double QFAC_; ///< Coulomb prefactor typedef std::vector Darray; @@ -66,7 +69,7 @@ class EnergyDecomposer { DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. DataFile* outfile_; ///< Output file int debug_; ///< Debug level - bool use_pme_; ///< If true use PME for the nonbonds + NonBondCalcType nbcalctype_; ///< What calc type to use for the nonbonds EwaldOptions ewaldOpts_; ///< Hold Ewald options BndArrayType bonds_; ///< Hold all bonds to be calculated @@ -78,6 +81,7 @@ class EnergyDecomposer { Topology const* currentTop_; ///< Current topology from Setup EwaldCalc_Decomp_PME PME_; ///< For calculating pairwise decomposed PME energies + EwaldCalc_Decomp_LJPME LJPME_; ///< For calculating pairwise decomposed LJPME energies Darray currentEne_; ///< Hold the total energy of each atom for the current frame diff --git a/src/Energy/energydepend b/src/Energy/energydepend index f8c55b6eac..88b5fe7dbe 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_LJPME.h PME_Recip.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index c3fdf639b3..fa07ce7972 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,7 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -277,8 +277,9 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h +Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h From fc8e5a206a9d358ac9ec968abcda403e35a629ce Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 1 Oct 2024 14:23:44 -0400 Subject: [PATCH 114/218] Use cutoff from EwaldOptions instead of the engine --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 2 +- src/Energy/EwaldCalc_Decomp_PME.cpp | 2 +- src/Energy/EwaldCalc_LJPME.cpp | 2 +- src/Energy/EwaldCalc_PME.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index 233b98fec3..fb51d38009 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -18,7 +18,7 @@ int EwaldCalc_Decomp_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, mprinterr("Error: Decomposable LJPME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) return 1; diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 321b83f8db..18410aecd1 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -17,7 +17,7 @@ int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, in mprinterr("Error: Decomposable PME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) return 1; diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index c23294a237..b812295046 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -18,7 +18,7 @@ int EwaldCalc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int deb mprinterr("Error: LJPME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) return 1; diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index 8dc70d7b8f..49a08fb37e 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -17,7 +17,7 @@ int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debug mprinterr("Error: PME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(NBengine_.EwaldParams().Cutoff(), pmeOpts.SkinNB(), debugIn)) + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) return 1; From 289f0d1b6e6b00b20c4e6758a3c16c88e434dce2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 2 Oct 2024 14:47:44 -0400 Subject: [PATCH 115/218] Start Ecalc_Nonbond --- src/Energy/Ecalc_Nonbond.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/Energy/Ecalc_Nonbond.h diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h new file mode 100644 index 0000000000..224d39791f --- /dev/null +++ b/src/Energy/Ecalc_Nonbond.h @@ -0,0 +1,25 @@ +#ifndef INC_ENERGY_ECALC_NONBOND_H +#define INC_ENERGY_ECALC_NONBOND_H +#include "../ExclusionArray.h" +#include "../PairList.h" +namespace Cpptraj { +namespace Energy { +/// Calculate nonbonded energy for atoms +class Ecalc_Nonbond { + public: + enum CalcType { SIMPLE = 0, PME, LJPME }; + /// CONSTRUCTOR + Ecalc_Nonbond(); + /// Init + InitNonbondCalc(CalcType, Box const&, EwaldOptions const&, int); + /// Setup + SetupNonbondCalc(Topology const&, AtomMask const&); + /// Calculate energy + int NonbondEnergy(Frame const&, AtomMask const&, double&, double&); + private: + PairList pairList_; + ExclusionArray Excluded_; +}; +} +} +#endif From 5dbc46ec51709d03412dc24372512eb6de47e56f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 2 Oct 2024 14:55:00 -0400 Subject: [PATCH 116/218] Start implementation --- src/Energy/Ecalc_Nonbond.cpp | 31 +++++++++++++++++++++++++++++++ src/Energy/Ecalc_Nonbond.h | 10 +++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/Energy/Ecalc_Nonbond.cpp diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp new file mode 100644 index 0000000000..0a1d79ab7a --- /dev/null +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -0,0 +1,31 @@ +#include "Ecalc_Nonbond.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR */ +Ecalc_Nonbond::Ecalc_Nonbond() : + type_(UNSPECIFIED), + needs_pairlist_(false) +{} + +/** Init */ +int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, + EwaldOptions const& pmeOpts, int debugIn) +{ + if (typeIn == UNSPECIFIED) { + mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); + return 1; + } + needs_pairlist_ = false; + + if (needs_pairlist_) { + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + } + + return 0; +} diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index 224d39791f..51d3d35e17 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -2,23 +2,27 @@ #define INC_ENERGY_ECALC_NONBOND_H #include "../ExclusionArray.h" #include "../PairList.h" +class EwaldOptions; +class Topology; namespace Cpptraj { namespace Energy { /// Calculate nonbonded energy for atoms class Ecalc_Nonbond { public: - enum CalcType { SIMPLE = 0, PME, LJPME }; + enum CalcType { SIMPLE = 0, PME, LJPME, UNSPECIFIED }; /// CONSTRUCTOR Ecalc_Nonbond(); /// Init - InitNonbondCalc(CalcType, Box const&, EwaldOptions const&, int); + int InitNonbondCalc(CalcType, Box const&, EwaldOptions const&, int); /// Setup - SetupNonbondCalc(Topology const&, AtomMask const&); + int SetupNonbondCalc(Topology const&, AtomMask const&); /// Calculate energy int NonbondEnergy(Frame const&, AtomMask const&, double&, double&); private: PairList pairList_; ExclusionArray Excluded_; + CalcType type_; + bool needs_pairlist_; }; } } From 21479a02311dac839e878d0d1d8524f58a9eb2eb Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 2 Oct 2024 14:56:34 -0400 Subject: [PATCH 117/218] Add pairlist setup --- src/Energy/Ecalc_Nonbond.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 0a1d79ab7a..5744103945 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,6 +1,7 @@ #include "Ecalc_Nonbond.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" +#include "../Topology.h" using namespace Cpptraj::Energy; @@ -29,3 +30,17 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, return 0; } + +/** Setup */ +int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskIn) { + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for nonbonded calculation.\n"); + return 1; + } + return 0; +} From 13243620f280734a517dcd0c595fb74e1e77d32c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 2 Oct 2024 15:39:37 -0400 Subject: [PATCH 118/218] Add pairlist setup to nonbond calc --- src/Energy/Ecalc_Nonbond.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 5744103945..afbd20981f 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -44,3 +44,19 @@ int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskI } return 0; } + +/** Calc */ +int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + double& e_elec, double& e_vdw) +{ + if (needs_pairlist_) { + if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn) != 0) + { + mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); + return 1; + } + } + + return 0; +} From 18506ed6842fe8c5556019e383449d40767c86fe Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 2 Oct 2024 15:39:49 -0400 Subject: [PATCH 119/218] Start refactoring so that pairlist and exclusion array are not part of the class --- src/Energy/EwaldCalc_LJPME.cpp | 25 ++----------------------- src/Energy/EwaldCalc_LJPME.h | 9 ++++----- src/Energy/EwaldCalc_PME.cpp | 24 ++---------------------- src/Energy/EwaldCalc_PME.h | 9 ++++----- 4 files changed, 12 insertions(+), 55 deletions(-) diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index b812295046..67c18a5163 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -18,10 +18,6 @@ int EwaldCalc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int deb mprinterr("Error: LJPME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) - return 1; - if (pairList_.SetupPairList( boxIn )) - return 1; Recip_.SetDebug( debugIn ); LJrecip_.SetDebug( debugIn ); @@ -34,34 +30,19 @@ int EwaldCalc_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) { mprinterr("Error: LJPME calculation setup failed.\n"); return 1; } - // Setup exclusion list - // Use distance of 4 (up to dihedrals) - if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, - ExclusionArray::EXCLUDE_SELF, - ExclusionArray::FULL)) - { - mprinterr("Error: Could not set up exclusion list for LJPME calculation.\n"); - return 1; - } return 0; } /** Calculate full nonbonded energy with LJPME */ int EwaldCalc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw) + PairList const& pairList_, ExclusionArray const& Excluded_, + double& e_elec, double& e_vdw) { t_total_.Start(); double volume = frameIn.BoxCrd().CellVolume(); double e_self = NBengine_.EwaldParams().SelfEnergy( volume ); - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Pairlist creation failed for LJPME calc.\n"); - return 1; - } - // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); @@ -121,6 +102,4 @@ void EwaldCalc_LJPME::Timing(double total) const { LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); - - pairList_.Timing(total); } diff --git a/src/Energy/EwaldCalc_LJPME.h b/src/Energy/EwaldCalc_LJPME.h index 1bde62035d..f78290a6bf 100644 --- a/src/Energy/EwaldCalc_LJPME.h +++ b/src/Energy/EwaldCalc_LJPME.h @@ -1,9 +1,8 @@ #ifndef INC_ENERGY_EWALDCALC_LJPME_H #define INC_ENERGY_EWALDCALC_LJPME_H #include "PME_Recip.h" -#include "../ExclusionArray.h" -#include "../PairList.h" #include "../PairListEngine_Ewald_LJPME.h" +class ExclusionArray; namespace Cpptraj { namespace Energy { class EwaldCalc_LJPME { @@ -12,15 +11,15 @@ class EwaldCalc_LJPME { /// Init with Box, EwaldOptions and debug level int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); - int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&); void Timing(double) const; private: PairListEngine_Ewald_LJPME NBengine_; PME_Recip Recip_; PME_Recip LJrecip_; - PairList pairList_; - ExclusionArray Excluded_; Timer t_total_; Timer t_direct_; }; diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index 49a08fb37e..de94c97b72 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -17,10 +17,6 @@ int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debug mprinterr("Error: PME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) - return 1; - if (pairList_.SetupPairList( boxIn )) - return 1; VDW_LR_.SetDebug( debugIn ); Recip_.SetDebug( debugIn ); @@ -37,34 +33,19 @@ int EwaldCalc_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { mprinterr("Error: PME calculation long range VDW correction setup failed.\n"); return 1; } - // Setup exclusion list - // Use distance of 4 (up to dihedrals) - if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, - ExclusionArray::EXCLUDE_SELF, - ExclusionArray::FULL)) - { - mprinterr("Error: Could not set up exclusion list for PME calculation.\n"); - return 1; - } return 0; } /** Calculate full nonbonded energy with PME */ int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw) + PairList const& pairList_, ExclusionArray const& Excluded_, + double& e_elec, double& e_vdw) { t_total_.Start(); double volume = frameIn.BoxCrd().CellVolume(); double e_self = NBengine_.EwaldParams().SelfEnergy( volume ); - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Pairlist creation failed for PME calc.\n"); - return 1; - } - // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); @@ -130,5 +111,4 @@ void EwaldCalc_PME::Timing(double total) const { // t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); // t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); //# endif - pairList_.Timing(total); } diff --git a/src/Energy/EwaldCalc_PME.h b/src/Energy/EwaldCalc_PME.h index 4a9c523cbc..3c0d1f2a72 100644 --- a/src/Energy/EwaldCalc_PME.h +++ b/src/Energy/EwaldCalc_PME.h @@ -2,12 +2,11 @@ #define INC_ENERGY_EWALDCALC_PME_H #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" -#include "../ExclusionArray.h" -#include "../PairList.h" #include "../PairListEngine_Ewald_LJLR.h" class AtomMask; class Box; class EwaldOptions; +class ExclusionArray; class Frame; class Topology; namespace Cpptraj { @@ -18,14 +17,14 @@ class EwaldCalc_PME { /// Init with Box, EwaldOptions and debug level int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); - int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&); void Timing(double) const; private: PairListEngine_Ewald_LJLR NBengine_; PME_Recip Recip_; - PairList pairList_; - ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction Timer t_total_; Timer t_direct_; From 34d547196db19fc95b1efe65778c8ecaa3e8c0b2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 09:13:10 -0400 Subject: [PATCH 120/218] Add .cpp.o rule so that subdir compile uses the correct flags --- devtools/CreateMake.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/devtools/CreateMake.sh b/devtools/CreateMake.sh index a476427901..ca0a683265 100755 --- a/devtools/CreateMake.sh +++ b/devtools/CreateMake.sh @@ -38,6 +38,11 @@ DEL_FILE = /bin/rm -f # Objects OBJECTS=\$($VARNAME:.cpp=.o) +# General rules +.cpp.o: + \$(VB)echo CXX $< + \$(VB)\$(CXX) \$(DIRECTIVES) \$(CPPTRAJ_INC) \$(CXXFLAGS) -c -o \$@ $< + # Default target: objects all: \$(OBJECTS) From debf31214d671efee09420f2dd442fcd2ae66007 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 09:26:11 -0400 Subject: [PATCH 121/218] Abstract base class for Ewald calcs --- src/Energy/EwaldCalc.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/Energy/EwaldCalc.h diff --git a/src/Energy/EwaldCalc.h b/src/Energy/EwaldCalc.h new file mode 100644 index 0000000000..b9e06855c6 --- /dev/null +++ b/src/Energy/EwaldCalc.h @@ -0,0 +1,32 @@ +#ifndef INC_ENERGY_EWALDCALC_H +#define INC_ENERGY_EWALDCALC_H +#include "../Timer.h" +class AtomMask; +class Box; +class EwaldOptions; +class ExclusionArray; +class Frame; +class PairList; +class Topology; +namespace Cpptraj { +namespace Energy { +/// Abstract base class for Ewald calcs +class EwaldCalc { + public: + EwaldCalc() {} + // virtual since inherited + virtual ~EwaldCalc() {} + + virtual int Init(Box const&, EwaldOptions const&, int) = 0; + virtual int Setup(Topology const&, AtomMask const&) = 0; + virtual int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&) = 0; + virtual void Timing(double) const = 0; + protected: + Timer t_total_; + Timer t_direct_; +}; +} +} +#endif From 75029a136e00025f5aefc688eb8d659c0f77b4d8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 09:26:44 -0400 Subject: [PATCH 122/218] Use abstract base class --- src/Energy/EwaldCalc_LJPME.h | 6 ++---- src/Energy/EwaldCalc_PME.h | 11 ++--------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Energy/EwaldCalc_LJPME.h b/src/Energy/EwaldCalc_LJPME.h index f78290a6bf..7f8a5068f3 100644 --- a/src/Energy/EwaldCalc_LJPME.h +++ b/src/Energy/EwaldCalc_LJPME.h @@ -1,11 +1,11 @@ #ifndef INC_ENERGY_EWALDCALC_LJPME_H #define INC_ENERGY_EWALDCALC_LJPME_H +#include "EwaldCalc.h" #include "PME_Recip.h" #include "../PairListEngine_Ewald_LJPME.h" -class ExclusionArray; namespace Cpptraj { namespace Energy { -class EwaldCalc_LJPME { +class EwaldCalc_LJPME : public EwaldCalc { public: EwaldCalc_LJPME(); /// Init with Box, EwaldOptions and debug level @@ -20,8 +20,6 @@ class EwaldCalc_LJPME { PairListEngine_Ewald_LJPME NBengine_; PME_Recip Recip_; PME_Recip LJrecip_; - Timer t_total_; - Timer t_direct_; }; } } diff --git a/src/Energy/EwaldCalc_PME.h b/src/Energy/EwaldCalc_PME.h index 3c0d1f2a72..04cb8dcaa2 100644 --- a/src/Energy/EwaldCalc_PME.h +++ b/src/Energy/EwaldCalc_PME.h @@ -1,17 +1,12 @@ #ifndef INC_ENERGY_EWALDCALC_PME_H #define INC_ENERGY_EWALDCALC_PME_H +#include "EwaldCalc.h" #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" #include "../PairListEngine_Ewald_LJLR.h" -class AtomMask; -class Box; -class EwaldOptions; -class ExclusionArray; -class Frame; -class Topology; namespace Cpptraj { namespace Energy { -class EwaldCalc_PME { +class EwaldCalc_PME : public EwaldCalc { public: EwaldCalc_PME(); /// Init with Box, EwaldOptions and debug level @@ -26,8 +21,6 @@ class EwaldCalc_PME { PairListEngine_Ewald_LJLR NBengine_; PME_Recip Recip_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction - Timer t_total_; - Timer t_direct_; }; } } From c214283953b15991e8bcc539ed8a362e4a534047 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 09:27:38 -0400 Subject: [PATCH 123/218] Use EwaldCalc ABC --- src/Energy/Ecalc_Nonbond.cpp | 41 +++++++++++++++++++++++++++++++----- src/Energy/Ecalc_Nonbond.h | 7 ++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index afbd20981f..779cfea262 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,4 +1,6 @@ #include "Ecalc_Nonbond.h" +#include "EwaldCalc_PME.h" +#include "EwaldCalc_LJPME.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Topology.h" @@ -11,16 +13,35 @@ Ecalc_Nonbond::Ecalc_Nonbond() : needs_pairlist_(false) {} +/** DESTRUCTOR */ +Ecalc_Nonbond::~Ecalc_Nonbond() { + if (calc_ != 0) + delete calc_; +} + /** Init */ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { - if (typeIn == UNSPECIFIED) { - mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); - return 1; - } + type_ = typeIn; needs_pairlist_ = false; + calc_ = 0; + switch (type_) { + case SIMPLE : break; + case PME : + needs_pairlist_ = true; + calc_ = new EwaldCalc_PME(); + break; + case LJPME : + needs_pairlist_ = true; + calc_ = new EwaldCalc_LJPME(); + break; + case UNSPECIFIED : + mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); + return 1; + } + if (needs_pairlist_) { if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; @@ -49,6 +70,7 @@ int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskI int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, double& e_elec, double& e_vdw) { + t_total_.Start(); if (needs_pairlist_) { if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn) != 0) @@ -58,5 +80,14 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, } } - return 0; + int err = calc_->CalcNonbondEnergy(frameIn, maskIn, pairList_, Excluded_, + e_elec, e_vdw); + t_total_.Stop(); + return err; +} + +/** Print timing */ +void Ecalc_Nonbond::PrintTiming(double total) const { + calc_->Timing( t_total_.Total() ); + t_total_.WriteTiming(0, "Nonbond total:"); } diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index 51d3d35e17..577ea21254 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -6,21 +6,28 @@ class EwaldOptions; class Topology; namespace Cpptraj { namespace Energy { +class EwaldCalc; /// Calculate nonbonded energy for atoms class Ecalc_Nonbond { public: enum CalcType { SIMPLE = 0, PME, LJPME, UNSPECIFIED }; /// CONSTRUCTOR Ecalc_Nonbond(); + /// DESTRUCTOR + ~Ecalc_Nonbond(); /// Init int InitNonbondCalc(CalcType, Box const&, EwaldOptions const&, int); /// Setup int SetupNonbondCalc(Topology const&, AtomMask const&); /// Calculate energy int NonbondEnergy(Frame const&, AtomMask const&, double&, double&); + /// Print timing to stdout + void PrintTiming(double) const; private: + EwaldCalc* calc_; PairList pairList_; ExclusionArray Excluded_; + Timer t_total_; CalcType type_; bool needs_pairlist_; }; From 8d06da0652f32dad5bd47cbdb20248fcd6551a38 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 09:28:03 -0400 Subject: [PATCH 124/218] Add to build --- src/Energy/CMakeLists.txt | 1 + src/Energy/Makefile | 5 +++++ src/Energy/energydepend | 5 +++-- src/Energy/energyfiles | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 2ec7f40eec..728e89892d 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -1,5 +1,6 @@ #CMake buildfile for CPPTRAJ Energy subdirectory. target_sources(cpptraj_common_obj PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/Ecalc_Nonbond.cpp ${CMAKE_CURRENT_LIST_DIR}/EnergyDecomposer.cpp ${CMAKE_CURRENT_LIST_DIR}/ErfcFxn.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Decomp_LJPME.cpp diff --git a/src/Energy/Makefile b/src/Energy/Makefile index c08a17fdc2..ff319845f7 100644 --- a/src/Energy/Makefile +++ b/src/Energy/Makefile @@ -8,6 +8,11 @@ DEL_FILE = /bin/rm -f # Objects OBJECTS=$(ENERGY_SOURCES:.cpp=.o) +# General rules +.cpp.o: + $(VB)echo CXX $< + $(VB)$(CXX) $(DIRECTIVES) $(CPPTRAJ_INC) $(CXXFLAGS) -c -o $@ $< + # Default target: objects all: $(OBJECTS) diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 88b5fe7dbe..9a4c32a4d0 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,9 +1,10 @@ +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h EwaldCalc.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_LJPME.h PME_Recip.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_LJPME.h PME_Recip.h -EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 2ade756ee4..47ab1a6fec 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -1,5 +1,6 @@ # Files for Energy subdirectory. ENERGY_SOURCES= \ + Ecalc_Nonbond.cpp \ EnergyDecomposer.cpp \ ErfcFxn.cpp \ EwaldCalc_Decomp_LJPME.cpp \ From 25d9d8526f20c709a235114641fdab4c5e6199f3 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 10:00:08 -0400 Subject: [PATCH 125/218] Add a nonbond kernel --- src/Energy/Ene_Nonbond.h | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/Energy/Ene_Nonbond.h diff --git a/src/Energy/Ene_Nonbond.h b/src/Energy/Ene_Nonbond.h new file mode 100644 index 0000000000..8785b47f41 --- /dev/null +++ b/src/Energy/Ene_Nonbond.h @@ -0,0 +1,66 @@ +#ifndef INC_ENERGY_ENE_NONBOND_H +#define INC_ENERGY_ENE_NONBOND_H +#include "Ene_LJ_6_12.h" +namespace Cpptraj { +namespace Energy { +/// Calculate simple nonbond energy with Coulomb and LJ 6-12 +template +void Ene_Nonbond(Frame const& fIn, Topology const& tIn, AtomMask const& mask, + ExclusionArray const& Excluded, T const& QFAC, T& Eelec, T& Evdw) +{ + Evdw = 0; + Eelec = 0; + int idx1; +# ifdef _OPENMP +# pragma omp parallel private(idx1) reduction(+ : Eelec, Evdw) + { +# pragma omp for +# endif + for (idx1 = 0; idx1 < mask.Nselected(); idx1++) + { + int atom1 = mask[idx1]; + // Set up coord for this atom + const double* crd1 = fIn.XYZ( atom1 ); + // Set up exclusion list for this atom + // TODO refactor inner loop to be more like StructureCheck, more efficient. + ExclusionArray::ExListType::const_iterator excluded_idx = Excluded[idx1].begin(); + for (int idx2 = idx1 + 1; idx2 < mask.Nselected(); idx2++) + { + int atom2 = mask[idx2]; + // Advance excluded list up to current selected atom + while (excluded_idx != Excluded[idx1].end() && *excluded_idx < idx2) ++excluded_idx; + // If atom is excluded, just increment to next excluded atom. + if (excluded_idx != Excluded[idx1].end() && idx2 == *excluded_idx) + ++excluded_idx; + else { + const double* crd2 = fIn.XYZ( atom2 ); + T dx = crd1[0] - crd2[0]; + T dy = crd1[1] - crd2[1]; + T dz = crd1[2] - crd2[2]; + T rij2 = (dx*dx) + (dy*dy) + (dz*dz); + // VDW + NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); + T e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + Evdw += e_vdw; + // Coulomb + T qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); + T rij = sqrt( rij2 ); + T e_elec = qiqj / rij; + Eelec += e_elec; +# ifdef DEBUG_ENERGY + mprintf("\tEVDW %4i -- %4i: A= %12.5e B= %12.5e r2= %12.5f E= %12.5e\n", + atom1+1, atom2+1, LJ.A(), LJ.B(), rij2, e_vdw); + mprintf("\tEELEC %4i -- %4i: q1= %12.5e q2= %12.5e r= %12.5f E= %12.5e\n", + atom1+1, atom2+1, tIn[atom1].Charge(), tIn[atom2].Charge(), + rij, e_elec); +# endif + } + } + } +# ifdef _OPENMP + } // END omp parallel +# endif +} +} // END namespace Energy +} // END namespace Cpptraj +#endif From f5753a5eeb890b6378299b488c79f43b227452bf Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 10:02:07 -0400 Subject: [PATCH 126/218] Add note about includes --- src/Energy/Ene_Nonbond.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Energy/Ene_Nonbond.h b/src/Energy/Ene_Nonbond.h index 8785b47f41..d443954b6c 100644 --- a/src/Energy/Ene_Nonbond.h +++ b/src/Energy/Ene_Nonbond.h @@ -4,6 +4,11 @@ namespace Cpptraj { namespace Energy { /// Calculate simple nonbond energy with Coulomb and LJ 6-12 +/** NOTE: To make this file more lightweight, there are no includes for + * Frame, AtomMask, etc. It is assumed that before this file is + * included there will be at least '#include "Topology.h" and + * 'include ' (for the sqrt). + */ template void Ene_Nonbond(Frame const& fIn, Topology const& tIn, AtomMask const& mask, ExclusionArray const& Excluded, T const& QFAC, T& Eelec, T& Evdw) From b6e4fa1ecdce0f89810b51a2fc3a0703124d9dd9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 10:07:05 -0400 Subject: [PATCH 127/218] Add calc init and setup, and simple nonbond calc --- src/Energy/Ecalc_Nonbond.cpp | 48 +++++++++++++++++++++++++++--------- src/Energy/Ecalc_Nonbond.h | 1 + src/Energy/energydepend | 2 +- src/cpptrajdepend | 9 ++++--- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 779cfea262..1bdb7c2ac1 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -4,11 +4,15 @@ #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Topology.h" +#include // sqrt for Ene_Nonbond +#include "Ene_Nonbond.h" using namespace Cpptraj::Energy; /** CONSTRUCTOR */ Ecalc_Nonbond::Ecalc_Nonbond() : + calc_(0), + currentTop_(0), type_(UNSPECIFIED), needs_pairlist_(false) {} @@ -23,12 +27,14 @@ Ecalc_Nonbond::~Ecalc_Nonbond() { int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + currentTop_ = 0; type_ = typeIn; - needs_pairlist_ = false; + needs_pairlist_ = false; calc_ = 0; switch (type_) { - case SIMPLE : break; + case SIMPLE : + break; case PME : needs_pairlist_ = true; calc_ = new EwaldCalc_PME(); @@ -48,12 +54,17 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, if (pairList_.SetupPairList( boxIn )) return 1; } + if (calc_ != 0) { + if (calc_->Init( boxIn, pmeOpts, debugIn )) + return 1; + } return 0; } /** Setup */ int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskIn) { + currentTop_ = &topIn; // Setup exclusion list // Use distance of 4 (up to dihedrals) if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, @@ -63,6 +74,10 @@ int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskI mprinterr("Error: Could not set up exclusion list for nonbonded calculation.\n"); return 1; } + if (calc_ != 0) { + if (calc_->Setup(topIn, maskIn)) + return 1; + } return 0; } @@ -71,23 +86,32 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, double& e_elec, double& e_vdw) { t_total_.Start(); - if (needs_pairlist_) { - if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn) != 0) - { - mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); - return 1; + + int err = 0; + if (type_ == SIMPLE) { + static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; + Ene_Nonbond(frameIn, *currentTop_, maskIn, Excluded_, QFAC, + e_elec, e_vdw); + } else { + + if (needs_pairlist_) { + if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn) != 0) + { + mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); + return 1; + } } - } - int err = calc_->CalcNonbondEnergy(frameIn, maskIn, pairList_, Excluded_, - e_elec, e_vdw); + err = calc_->CalcNonbondEnergy(frameIn, maskIn, pairList_, Excluded_, + e_elec, e_vdw); + } t_total_.Stop(); return err; } /** Print timing */ void Ecalc_Nonbond::PrintTiming(double total) const { - calc_->Timing( t_total_.Total() ); + if (calc_ != 0) calc_->Timing( t_total_.Total() ); t_total_.WriteTiming(0, "Nonbond total:"); } diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index 577ea21254..fef6aa53e2 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -25,6 +25,7 @@ class Ecalc_Nonbond { void PrintTiming(double) const; private: EwaldCalc* calc_; + Topology const* currentTop_; ///< Current Topology, set by SetupNonbondCalc() PairList pairList_; ExclusionArray Excluded_; Timer t_total_; diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 9a4c32a4d0..68f2bba825 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h EwaldCalc.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_LJPME.h PME_Recip.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index fa07ce7972..1628db083d 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -277,12 +277,13 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h From 8798a7b6ca2457b1fd4010d4f2ab421d5c7b947d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 10:12:45 -0400 Subject: [PATCH 128/218] Use new nonbond calc --- src/Action_PmeTest.cpp | 17 +++++++++-------- src/Action_PmeTest.h | 6 ++---- src/cpptrajdepend | 6 +++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index 350e531d4f..a1208b3368 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -64,6 +64,7 @@ Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int // Action_PmeTest::Setup() Action::RetType Action_PmeTest::Setup(ActionSetup& setup) { + using namespace Cpptraj::Energy; // Set up mask if (setup.Top().SetupIntegerMask(Mask1_)) return Action::ERR; if (Mask1_.None()) { @@ -77,14 +78,14 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) return Action::ERR; PME0_.Setup( setup.Top(), Mask1_ ); } else if (method_ == 1) { - if (PME1_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + if (NB_.InitNonbondCalc(Ecalc_Nonbond::PME, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; - if (PME1_.Setup( setup.Top(), Mask1_ )) + if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) return Action::ERR; } else if (method_ == 2) { - if (PME2_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + if (NB_.InitNonbondCalc(Ecalc_Nonbond::LJPME, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; - if (PME2_.Setup( setup.Top(), Mask1_ )) + if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) return Action::ERR; } return Action::OK; @@ -99,9 +100,9 @@ Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) if (method_ == 0) { err = PME0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } else if (method_ == 1) { - err = PME1_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + err = NB_.NonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } else if (method_ == 2) { - err = PME2_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + err = NB_.NonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } if (err != 0) return Action::ERR; ele_->Add(frameNum, &ene); @@ -114,7 +115,7 @@ void Action_PmeTest::Print() { if (method_ == 0) PME0_.Timing(t_nb_.Total()); else if (method_ == 1) - PME1_.Timing(t_nb_.Total()); + NB_.PrintTiming(t_nb_.Total()); else if (method_ == 2) - PME2_.Timing(t_nb_.Total()); + NB_.PrintTiming(t_nb_.Total()); } diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h index e5215e114d..fbb94a6029 100644 --- a/src/Action_PmeTest.h +++ b/src/Action_PmeTest.h @@ -1,8 +1,7 @@ #ifndef INC_ACTION_PMETEST_H #define INC_ACTION_PMETEST_H #include "Action.h" -#include "Energy/EwaldCalc_PME.h" -#include "Energy/EwaldCalc_LJPME.h" +#include "Energy/Ecalc_Nonbond.h" #include "Ewald_ParticleMesh.h" #include "EwaldOptions.h" #include "Timer.h" @@ -19,8 +18,7 @@ class Action_PmeTest : public Action { void Print(); Ewald_ParticleMesh PME0_; - Cpptraj::Energy::EwaldCalc_PME PME1_; - Cpptraj::Energy::EwaldCalc_LJPME PME2_; + Cpptraj::Energy::Ecalc_Nonbond NB_; EwaldOptions ewaldOpts_; AtomMask Mask1_; DataSet* ele_; diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 1628db083d..7724dca785 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -277,7 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h From 703bc6ad3714391b2abf164d9562ab186a9d33cb Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 10:34:54 -0400 Subject: [PATCH 129/218] Report pairlist timing --- src/Energy/Ecalc_Nonbond.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 1bdb7c2ac1..445b8c840b 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -113,5 +113,7 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, /** Print timing */ void Ecalc_Nonbond::PrintTiming(double total) const { if (calc_ != 0) calc_->Timing( t_total_.Total() ); + if (needs_pairlist_) + pairList_.Timing( t_total_.Total() ); t_total_.WriteTiming(0, "Nonbond total:"); } From c9e082fdfeefbcde617eb67ac6afb60246747c3f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 11:18:43 -0400 Subject: [PATCH 130/218] Try adding a simple nonbond decomposable energy kernel --- src/Energy/Ene_Decomp_Nonbond.h | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/Energy/Ene_Decomp_Nonbond.h diff --git a/src/Energy/Ene_Decomp_Nonbond.h b/src/Energy/Ene_Decomp_Nonbond.h new file mode 100644 index 0000000000..dfeeab0f39 --- /dev/null +++ b/src/Energy/Ene_Decomp_Nonbond.h @@ -0,0 +1,56 @@ +#ifndef INC_ENERGY_ENE_DECOMP_NONBOND_H +#define INC_ENERGY_ENE_DECOMP_NONBOND_H +#include "Ene_LJ_6_12.h" +namespace Cpptraj { +namespace Energy { +/// Calculate simple decomposed nonbond energy with Coulomb and LJ 6-12 +/** NOTE: To make this file more lightweight, there are no includes for + * Frame, CharMask, etc. It is assumed that before this file is + * included there will be at least '#include "Topology.h" and + * 'include ' (for the sqrt). + */ +template +void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& selectedAtoms, + ExclusionArray const& Excluded, T const& QFAC, + std::vector& atom_elec, + std::vector& atom_vdw) +{ + for (int atom1 = 0; atom1 < tIn.Natom(); atom1++) { + bool atom1_is_selected = selectedAtoms.AtomInCharMask( atom1 ); + const double* crd1 = fIn.XYZ( atom1 ); + ExclusionArray::ExListType const& excludedAtoms = Excluded[atom1]; + for (int atom2 = atom1 + 1; atom2 < tIn.Natom(); atom2++) { + bool atom2_is_selected = selectedAtoms.AtomInCharMask( atom2 ); + if (atom1_is_selected || atom2_is_selected) { + ExclusionArray::ExListType::const_iterator it = excludedAtoms.find( atom2 ); + if (it == excludedAtoms.end()) { + // Either atom1 or atom2 is selected and the interaction is not excluded. + // TODO image distances? + const double* crd2 = fIn.XYZ( atom2 ); + T dx = crd1[0] - crd2[0]; + T dy = crd1[1] - crd2[1]; + T dz = crd1[2] - crd2[2]; + T rij2 = (dx*dx) + (dy*dy) + (dz*dz); + // VDW + NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); + T e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); + mprintf("DEBUG: VDW %f\n", e_vdw); + T ene_half = e_vdw * 0.5; + if (atom1_is_selected) atom_vdw[atom1] += ene_half; + if (atom2_is_selected) atom_vdw[atom2] += ene_half; + // Coulomb energy + T rij = sqrt(rij2); + T qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); + T e_elec = qiqj / rij; + mprintf("DEBUG: ELE %f\n", e_elec); + ene_half = e_elec * 0.5; + if (atom1_is_selected) atom_elec[atom1] += ene_half; + if (atom2_is_selected) atom_elec[atom2] += ene_half; + } // END atom2 not excluded from atom1 + } // END atom1 or atom2 is selected + } // END inner loop over atoms + } // END outer loop over atoms +} +} // END namespace Energy +} // END namespace Cpptraj +#endif From 5cd33b8f5becc6c402c7f9c7d093d34cbb3f7a08 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 13:10:53 -0400 Subject: [PATCH 131/218] Start ewald decomp ABC --- src/Energy/EwaldCalc_Decomp.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/Energy/EwaldCalc_Decomp.h diff --git a/src/Energy/EwaldCalc_Decomp.h b/src/Energy/EwaldCalc_Decomp.h new file mode 100644 index 0000000000..9fb5bbfbad --- /dev/null +++ b/src/Energy/EwaldCalc_Decomp.h @@ -0,0 +1,30 @@ +#ifndef INC_ENERGY_EWALDCALC_DECOMP_H +#define INC_ENERGY_EWALDCALC_DECOMP_H +#include "EwaldCalc.h" +namespace Cpptraj { +namespace Energy { +/// Abstract base class for decomposable Ewald calcs. +class EwaldCalc_Decomp : public EwaldCalc { + public: + typedef std::vector Darray; + + EwaldCalc_Decomp() {} + // virtual since inherited + ~EwaldCalc_Decomp() {} + + virtual int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, + PairList const& pairList, ExclusionArray const& Excluded, + double&, double&, Darray&, Darray&) = 0; + + /// Just call the CalcDecomposedNonbondEnergy() routine with temp arrays. + int CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + PairList const& pairList, ExclusionArray const& Excluded, + double& e_elec, double& e_vdw) + { + Darray atom_elec, atom_vdw; + return CalcDecomposedNonbondEnergy(frameIn, maskIn, pairList, Excluded, e_elec, e_vdw, atom_elec, atom_vdw); + } +}; +} +} +#endif From 04ef64420b8f49219556ae25aa848f15f41fc3c7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 13:23:27 -0400 Subject: [PATCH 132/218] Fix includes --- src/Energy/EwaldCalc_LJPME.cpp | 3 +-- src/Energy/EwaldCalc_PME.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index 67c18a5163..45326758ec 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -1,8 +1,7 @@ #include "EwaldCalc_LJPME.h" #include "../CpptrajStdio.h" -#include "../EwaldOptions.h" +#include "../Frame.h" #include "../PairListTemplate.h" -#include "../Topology.h" using namespace Cpptraj::Energy; diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index de94c97b72..668fbf00aa 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -1,8 +1,7 @@ #include "EwaldCalc_PME.h" #include "../CpptrajStdio.h" -#include "../EwaldOptions.h" +#include "../Frame.h" #include "../PairListTemplate.h" -#include "../Topology.h" using namespace Cpptraj::Energy; From 399f54f92c29a1aa1f936db70c4c4791dd174830 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 13:24:12 -0400 Subject: [PATCH 133/218] Convert to EwaldCalc_Decomp class --- src/Energy/EwaldCalc_Decomp.h | 24 +++++++------- src/Energy/EwaldCalc_Decomp_PME.cpp | 51 +++++++---------------------- src/Energy/EwaldCalc_Decomp_PME.h | 19 +++-------- 3 files changed, 29 insertions(+), 65 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp.h b/src/Energy/EwaldCalc_Decomp.h index 9fb5bbfbad..f2a7841893 100644 --- a/src/Energy/EwaldCalc_Decomp.h +++ b/src/Energy/EwaldCalc_Decomp.h @@ -1,6 +1,7 @@ #ifndef INC_ENERGY_EWALDCALC_DECOMP_H #define INC_ENERGY_EWALDCALC_DECOMP_H #include "EwaldCalc.h" +#include namespace Cpptraj { namespace Energy { /// Abstract base class for decomposable Ewald calcs. @@ -12,18 +13,19 @@ class EwaldCalc_Decomp : public EwaldCalc { // virtual since inherited ~EwaldCalc_Decomp() {} - virtual int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, - PairList const& pairList, ExclusionArray const& Excluded, - double&, double&, Darray&, Darray&) = 0; - - /// Just call the CalcDecomposedNonbondEnergy() routine with temp arrays. - int CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - PairList const& pairList, ExclusionArray const& Excluded, - double& e_elec, double& e_vdw) - { - Darray atom_elec, atom_vdw; - return CalcDecomposedNonbondEnergy(frameIn, maskIn, pairList, Excluded, e_elec, e_vdw, atom_elec, atom_vdw); + Darray const& Atom_Elec() const { return atom_elec_; } + Darray const& Atom_VDW() const { return atom_vdw_; } + protected: + /// For DEBUG, \return sum of given array + static inline double sumArray(Darray const& arrayIn) { + double sum = 0; + for (Darray::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) + sum += *it; + return sum; } + + Darray atom_elec_; ///< Hold electrostatic contribution for each atom + Darray atom_vdw_; ///< Hold VDW contribution for each atom }; } } diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 18410aecd1..f39d2679f2 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -1,8 +1,7 @@ #include "EwaldCalc_Decomp_PME.h" #include "../CpptrajStdio.h" -#include "../EwaldOptions.h" +#include "../Frame.h" #include "../PairListTemplate.h" -#include "../Topology.h" using namespace Cpptraj::Energy; @@ -17,10 +16,6 @@ int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, in mprinterr("Error: Decomposable PME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) - return 1; - if (pairList_.SetupPairList( boxIn )) - return 1; VDW_LR_.SetDebug( debugIn ); Recip_.SetDebug( debugIn ); @@ -37,31 +32,15 @@ int EwaldCalc_Decomp_PME::Setup(Topology const& topIn, AtomMask const& maskIn) { mprinterr("Error: PME calculation long range VDW correction setup failed.\n"); return 1; } - // Setup exclusion list - // Use distance of 4 (up to dihedrals) - if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, - ExclusionArray::EXCLUDE_SELF, - ExclusionArray::FULL)) - { - mprinterr("Error: Could not set up exclusion list for PME calculation.\n"); - return 1; - } + // TODO reserve atom_elec and atom_vdw? return 0; } -// DEBUG -static inline double sumArray(std::vector const& arrayIn) { - double sum = 0; - for (std::vector::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) - sum += *it; - return sum; -} - -/** Calculate full nonbonded energy with PME */ -int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw, - Darray& atom_elec, Darray& atom_vdw) +/** Calculate full decompoesd nonbonded energy with PME */ +int EwaldCalc_Decomp_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + PairList const& pairList_, ExclusionArray const& Excluded_, + double& e_elec, double& e_vdw) { t_total_.Start(); double volume = frameIn.BoxCrd().CellVolume(); @@ -70,13 +49,6 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom mprintf("DEBUG: Total self energy: %f\n", e_self); mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Pairlist creation failed for PME calc.\n"); - return 1; - } - // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); @@ -127,12 +99,12 @@ int EwaldCalc_Decomp_PME::CalcDecomposedNonbondEnergy(Frame const& frameIn, Atom e_vdw = NBengine_.Evdw() + e_vdw_lr_correction; e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); // TODO preallocate? - atom_elec.resize( NBengine_.Eatom_Elec().size() ); - atom_vdw.resize( NBengine_.Eatom_EVDW().size() ); - for (unsigned int idx = 0; idx != atom_elec.size(); idx++) + atom_elec_.resize( NBengine_.Eatom_Elec().size() ); + atom_vdw_.resize( NBengine_.Eatom_EVDW().size() ); + for (unsigned int idx = 0; idx != atom_elec_.size(); idx++) { - atom_elec[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; - atom_vdw[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwlr[idx]; + atom_elec_[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; + atom_vdw_[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwlr[idx]; } t_total_.Stop(); return 0; @@ -142,5 +114,4 @@ void EwaldCalc_Decomp_PME::Timing(double total) const { t_total_.WriteTiming(1, " PME decomp Total:", total); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); - pairList_.Timing(total); } diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index 6cd57acee4..56e9f11029 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -1,35 +1,26 @@ #ifndef INC_ENERGY_EWALDCALC_DECOMP_PME_H #define INC_ENERGY_EWALDCALC_DECOMP_PME_H +#include "EwaldCalc_Decomp.h" #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" -#include "../ExclusionArray.h" -#include "../PairList.h" #include "../PairListEngine_Ewald_Decomp_LJLR.h" -class AtomMask; -class Box; -class EwaldOptions; -class Frame; -class Topology; namespace Cpptraj { namespace Energy { -class EwaldCalc_Decomp_PME { +class EwaldCalc_Decomp_PME : public EwaldCalc_Decomp { public: typedef std::vector Darray; EwaldCalc_Decomp_PME(); int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); // TODO CharMask? - int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, - Darray&, Darray&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&); void Timing(double) const; private: PairListEngine_Ewald_Decomp_LJLR NBengine_; PME_Recip Recip_; - PairList pairList_; - ExclusionArray Excluded_; VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction - Timer t_total_; - Timer t_direct_; }; } } From 9787d5c1f5bfde5d72140687d6fae681ed85b5f8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 13:30:16 -0400 Subject: [PATCH 134/218] Convert decomposd LJPME to Ewald_Decomp class. Update depends --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 53 ++++++--------------------- src/Energy/EwaldCalc_Decomp_LJPME.h | 16 +++----- src/Energy/EwaldCalc_Decomp_PME.h | 2 - src/Energy/energydepend | 10 ++--- src/cpptrajdepend | 14 +++---- 5 files changed, 29 insertions(+), 66 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index fb51d38009..e55286e509 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -1,8 +1,7 @@ #include "EwaldCalc_Decomp_LJPME.h" #include "../CpptrajStdio.h" -#include "../EwaldOptions.h" +#include "../Frame.h" #include "../PairListTemplate.h" -#include "../Topology.h" using namespace Cpptraj::Energy; @@ -18,10 +17,6 @@ int EwaldCalc_Decomp_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, mprinterr("Error: Decomposable LJPME calculation init failed.\n"); return 1; } - if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) - return 1; - if (pairList_.SetupPairList( boxIn )) - return 1; Recip_.SetDebug( debugIn ); LJrecip_.SetDebug( debugIn ); @@ -35,50 +30,28 @@ int EwaldCalc_Decomp_LJPME::Setup(Topology const& topIn, AtomMask const& maskIn) return 1; } NBengine_.ModifyEwaldParams().CalcDecomposedSelf6Energy(); - // Setup exclusion list - // Use distance of 4 (up to dihedrals) - if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, - ExclusionArray::EXCLUDE_SELF, - ExclusionArray::FULL)) - { - mprinterr("Error: Could not set up exclusion list for LJPME calculation.\n"); - return 1; - } + // TODO reserve atom_elec and atom_vdw? return 0; } -// DEBUG -static inline double sumArray(std::vector const& arrayIn) { - double sum = 0; - for (std::vector::const_iterator it = arrayIn.begin(); it != arrayIn.end(); ++it) - sum += *it; - return sum; -} - /** Calculate full nonbonded energy with LJPME */ -int EwaldCalc_Decomp_LJPME::CalcDecomposedNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw, - Darray& atom_elec, Darray& atom_vdw) +int EwaldCalc_Decomp_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + PairList const& pairList_, ExclusionArray const& Excluded_, + double& e_elec, double& e_vdw) { t_total_.Start(); double volume = frameIn.BoxCrd().CellVolume(); + // Do decomposed self Darray atom_self; double e_self = NBengine_.EwaldParams().DecomposedSelfEnergy( atom_self, volume ); mprintf("DEBUG: Total self energy: %f\n", e_self); mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); - // FIXME do decomposed self6 + // Do decomposed self6 Darray const& atom_vdwself6 = NBengine_.EwaldParams().Atom_Self6Energies(); mprintf("DEBUG: Total self6 energy: %f\n", NBengine_.EwaldParams().Self6()); mprintf("DEBUG: Sum of self6 array: %f\n", sumArray(atom_vdwself6)); - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Pairlist creation failed for LJPME calc.\n"); - return 1; - } - // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); @@ -142,12 +115,12 @@ int EwaldCalc_Decomp_LJPME::CalcDecomposedNonbondEnergy(Frame const& frameIn, At e_vdw = NBengine_.Evdw() + NBengine_.EwaldParams().Self6() + e_vdw6recip; e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); // TODO preallocate? - atom_elec.resize( NBengine_.Eatom_Elec().size() ); - atom_vdw.resize( NBengine_.Eatom_EVDW().size() ); - for (unsigned int idx = 0; idx != atom_elec.size(); idx++) + atom_elec_.resize( NBengine_.Eatom_Elec().size() ); + atom_vdw_.resize( NBengine_.Eatom_EVDW().size() ); + for (unsigned int idx = 0; idx != atom_elec_.size(); idx++) { - atom_elec[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; - atom_vdw[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwself6[idx] + atom_vdw6recip[idx]; + atom_elec_[idx] = atom_self[idx] + atom_recip[idx] + NBengine_.Eatom_Elec()[idx] + NBengine_.Eatom_EAdjust()[idx]; + atom_vdw_[idx] = NBengine_.Eatom_EVDW()[idx] + atom_vdwself6[idx] + atom_vdw6recip[idx]; } t_total_.Stop(); @@ -161,6 +134,4 @@ void EwaldCalc_Decomp_LJPME::Timing(double total) const { LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); - - pairList_.Timing(total); } diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.h b/src/Energy/EwaldCalc_Decomp_LJPME.h index 73083fbad1..e1ef3ecdef 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.h +++ b/src/Energy/EwaldCalc_Decomp_LJPME.h @@ -1,31 +1,25 @@ #ifndef INC_ENERGY_EWALDCALC_DECOMP_LJPME_H #define INC_ENERGY_EWALDCALC_DECOMP_LJPME_H +#include "EwaldCalc_Decomp.h" #include "PME_Recip.h" -#include "../ExclusionArray.h" -#include "../PairList.h" #include "../PairListEngine_Ewald_Decomp_LJPME.h" namespace Cpptraj { namespace Energy { -class EwaldCalc_Decomp_LJPME { +class EwaldCalc_Decomp_LJPME : public EwaldCalc_Decomp { public: - typedef std::vector Darray; - EwaldCalc_Decomp_LJPME(); /// Init with Box, EwaldOptions and debug level int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); - int CalcDecomposedNonbondEnergy(Frame const&, AtomMask const&, double&, double&, - Darray&, Darray&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&); void Timing(double) const; private: PairListEngine_Ewald_Decomp_LJPME NBengine_; PME_Recip Recip_; PME_Recip LJrecip_; - PairList pairList_; - ExclusionArray Excluded_; - Timer t_total_; - Timer t_direct_; }; } } diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index 56e9f11029..1be87c90a0 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -8,8 +8,6 @@ namespace Cpptraj { namespace Energy { class EwaldCalc_Decomp_PME : public EwaldCalc_Decomp { public: - typedef std::vector Darray; - EwaldCalc_Decomp_PME(); int Init(Box const&, EwaldOptions const&, int); int Setup(Topology const&, AtomMask const&); // TODO CharMask? diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 68f2bba825..6ee9106080 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,10 +1,10 @@ Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h -EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_LJPME.h PME_Recip.h -EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h -EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h +EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 7724dca785..0f5b75a4a7 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,7 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -278,12 +278,12 @@ DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h -Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h From 8bda700c9d450617afb70e87b3a446b873577714 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 13:55:31 -0400 Subject: [PATCH 135/218] Add energy decomp to Ecalc_Nonbond --- src/Energy/Ecalc_Nonbond.cpp | 69 ++++++++++++++++++++++++++++++--- src/Energy/Ecalc_Nonbond.h | 11 +++++- src/Energy/Ene_Decomp_Nonbond.h | 5 +++ src/Energy/energydepend | 2 +- src/cpptrajdepend | 2 +- 5 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 445b8c840b..3e6a92fbc4 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,11 +1,15 @@ #include "Ecalc_Nonbond.h" #include "EwaldCalc_PME.h" #include "EwaldCalc_LJPME.h" +#include "EwaldCalc_Decomp_PME.h" +#include "EwaldCalc_Decomp_LJPME.h" +#include "../CharMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Topology.h" -#include // sqrt for Ene_Nonbond +#include // sqrt for Ene_Nonbond, Ene_Decomp_Nonbond #include "Ene_Nonbond.h" +#include "Ene_Decomp_Nonbond.h" using namespace Cpptraj::Energy; @@ -14,7 +18,8 @@ Ecalc_Nonbond::Ecalc_Nonbond() : calc_(0), currentTop_(0), type_(UNSPECIFIED), - needs_pairlist_(false) + needs_pairlist_(false), + decompose_energy_(false) {} /** DESTRUCTOR */ @@ -24,11 +29,12 @@ Ecalc_Nonbond::~Ecalc_Nonbond() { } /** Init */ -int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, - EwaldOptions const& pmeOpts, int debugIn) +int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, + Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { currentTop_ = 0; type_ = typeIn; + decompose_energy_ = decompose_energyIn; needs_pairlist_ = false; calc_ = 0; @@ -37,11 +43,17 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, Box const& boxIn, break; case PME : needs_pairlist_ = true; - calc_ = new EwaldCalc_PME(); + if (decompose_energy_) + calc_ = new EwaldCalc_Decomp_PME(); + else + calc_ = new EwaldCalc_PME(); break; case LJPME : needs_pairlist_ = true; - calc_ = new EwaldCalc_LJPME(); + if (decompose_energy_) + calc_ = new EwaldCalc_Decomp_LJPME(); + else + calc_ = new EwaldCalc_LJPME(); break; case UNSPECIFIED : mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); @@ -110,6 +122,51 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, return err; } +/** Energy decomp calc */ +int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& cmaskIn, + double& e_elec, double& e_vdw, + Darray& atom_elec, Darray& atom_vdw) +{ + // sanity check + if (!decompose_energy_) { + mprinterr("Internal Error: Ecalc_Nonbond::DecomposedNonbondEnergy(): Not set up for energy decomp.\n"); + return 1; + } + t_total_.Start(); + + int err = 0; + if (type_ == SIMPLE) { + static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; + Ene_Decomp_Nonbond(frameIn, *currentTop_, cmaskIn, Excluded_, QFAC, + e_elec, e_vdw, atom_elec, atom_vdw); + } else { + // FIXME this is an unneeded atom mask. + AtomMask tmpMask(0, frameIn.Natom()); + + if (needs_pairlist_) { + if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), tmpMask) != 0) + { + mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); + return 1; + } + } + + err = calc_->CalcNonbondEnergy(frameIn, tmpMask, pairList_, Excluded_, + e_elec, e_vdw); + EwaldCalc_Decomp const* EW_ENE = static_cast( calc_ ); + for (int at = 0; at < frameIn.Natom(); at++) { + if (cmaskIn.AtomInCharMask(at)) { + atom_elec[at] += EW_ENE->Atom_Elec()[at]; + atom_vdw[at] += EW_ENE->Atom_VDW()[at]; + } + } + } + t_total_.Stop(); + return err; +} + + /** Print timing */ void Ecalc_Nonbond::PrintTiming(double total) const { if (calc_ != 0) calc_->Timing( t_total_.Total() ); diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index fef6aa53e2..31bf91cf5a 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -2,6 +2,7 @@ #define INC_ENERGY_ECALC_NONBOND_H #include "../ExclusionArray.h" #include "../PairList.h" +class CharMask; class EwaldOptions; class Topology; namespace Cpptraj { @@ -10,17 +11,22 @@ class EwaldCalc; /// Calculate nonbonded energy for atoms class Ecalc_Nonbond { public: + typedef std::vector Darray; + enum CalcType { SIMPLE = 0, PME, LJPME, UNSPECIFIED }; /// CONSTRUCTOR Ecalc_Nonbond(); /// DESTRUCTOR ~Ecalc_Nonbond(); - /// Init - int InitNonbondCalc(CalcType, Box const&, EwaldOptions const&, int); + /// Init - Calc type, decomp?, box, options, debug + int InitNonbondCalc(CalcType, bool, Box const&, EwaldOptions const&, int); /// Setup int SetupNonbondCalc(Topology const&, AtomMask const&); /// Calculate energy int NonbondEnergy(Frame const&, AtomMask const&, double&, double&); + /// Calculate decomposed energy + int DecomposedNonbondEnergy(Frame const&, CharMask const&, double&, double&, + Darray&, Darray&); /// Print timing to stdout void PrintTiming(double) const; private: @@ -31,6 +37,7 @@ class Ecalc_Nonbond { Timer t_total_; CalcType type_; bool needs_pairlist_; + bool decompose_energy_; }; } } diff --git a/src/Energy/Ene_Decomp_Nonbond.h b/src/Energy/Ene_Decomp_Nonbond.h index dfeeab0f39..c6d8d1092e 100644 --- a/src/Energy/Ene_Decomp_Nonbond.h +++ b/src/Energy/Ene_Decomp_Nonbond.h @@ -12,9 +12,12 @@ namespace Energy { template void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& selectedAtoms, ExclusionArray const& Excluded, T const& QFAC, + T& Eelec, T& Evdw, std::vector& atom_elec, std::vector& atom_vdw) { + Eelec = 0; + Evdw = 0; for (int atom1 = 0; atom1 < tIn.Natom(); atom1++) { bool atom1_is_selected = selectedAtoms.AtomInCharMask( atom1 ); const double* crd1 = fIn.XYZ( atom1 ); @@ -35,6 +38,7 @@ void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& s NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); T e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); mprintf("DEBUG: VDW %f\n", e_vdw); + Evdw += e_vdw; T ene_half = e_vdw * 0.5; if (atom1_is_selected) atom_vdw[atom1] += ene_half; if (atom2_is_selected) atom_vdw[atom2] += ene_half; @@ -43,6 +47,7 @@ void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& s T qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); T e_elec = qiqj / rij; mprintf("DEBUG: ELE %f\n", e_elec); + Eelec += e_elec; ene_half = e_elec * 0.5; if (atom1_is_selected) atom_elec[atom1] += ene_half; if (atom2_is_selected) atom_elec[atom2] += ene_half; diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 6ee9106080..2fabc7efa5 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 0f5b75a4a7..eb3ab14b43 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,7 +277,7 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h From 3915705598caa3471a69a1a2c196b7ab2b4362d0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 14:02:01 -0400 Subject: [PATCH 136/218] All ewald calcs need the pairlist --- src/Energy/Ecalc_Nonbond.cpp | 55 ++++++++++++++++++------------------ src/Energy/Ecalc_Nonbond.h | 1 - 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 3e6a92fbc4..8f782a0879 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -18,7 +18,6 @@ Ecalc_Nonbond::Ecalc_Nonbond() : calc_(0), currentTop_(0), type_(UNSPECIFIED), - needs_pairlist_(false), decompose_energy_(false) {} @@ -36,20 +35,17 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, type_ = typeIn; decompose_energy_ = decompose_energyIn; - needs_pairlist_ = false; calc_ = 0; switch (type_) { case SIMPLE : break; case PME : - needs_pairlist_ = true; if (decompose_energy_) calc_ = new EwaldCalc_Decomp_PME(); else calc_ = new EwaldCalc_PME(); break; case LJPME : - needs_pairlist_ = true; if (decompose_energy_) calc_ = new EwaldCalc_Decomp_LJPME(); else @@ -59,14 +55,17 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); return 1; } + if (type_ != SIMPLE && calc_ == 0) { + mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): Ewald calc alloc failed.\n"); + return 1; + } - if (needs_pairlist_) { + if (calc_ != 0) { + // Ewald calcs need pairlist if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; if (pairList_.SetupPairList( boxIn )) return 1; - } - if (calc_ != 0) { if (calc_->Init( boxIn, pmeOpts, debugIn )) return 1; } @@ -104,20 +103,19 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; Ene_Nonbond(frameIn, *currentTop_, maskIn, Excluded_, QFAC, e_elec, e_vdw); - } else { - - if (needs_pairlist_) { - if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), maskIn) != 0) - { - mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); - return 1; - } + } else if (calc_ != 0) { + if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), maskIn) != 0) + { + mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); + return 1; } err = calc_->CalcNonbondEnergy(frameIn, maskIn, pairList_, Excluded_, e_elec, e_vdw); - } + } else + return 1; // Sanity check + t_total_.Stop(); return err; } @@ -139,17 +137,15 @@ int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; Ene_Decomp_Nonbond(frameIn, *currentTop_, cmaskIn, Excluded_, QFAC, e_elec, e_vdw, atom_elec, atom_vdw); - } else { + } else if (calc_ != 0) { // FIXME this is an unneeded atom mask. AtomMask tmpMask(0, frameIn.Natom()); - if (needs_pairlist_) { - if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), - frameIn.BoxCrd().FracCell(), tmpMask) != 0) - { - mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); - return 1; - } + if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), + frameIn.BoxCrd().FracCell(), tmpMask) != 0) + { + mprinterr("Error: Pairlist creation failed for nonbond calc.\n"); + return 1; } err = calc_->CalcNonbondEnergy(frameIn, tmpMask, pairList_, Excluded_, @@ -161,7 +157,9 @@ int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& atom_vdw[at] += EW_ENE->Atom_VDW()[at]; } } - } + } else + return 1; // sanity check + t_total_.Stop(); return err; } @@ -169,8 +167,9 @@ int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& /** Print timing */ void Ecalc_Nonbond::PrintTiming(double total) const { - if (calc_ != 0) calc_->Timing( t_total_.Total() ); - if (needs_pairlist_) + if (calc_ != 0) { + calc_->Timing( t_total_.Total() ); pairList_.Timing( t_total_.Total() ); + } t_total_.WriteTiming(0, "Nonbond total:"); } diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index 31bf91cf5a..a98ae2a465 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -36,7 +36,6 @@ class Ecalc_Nonbond { ExclusionArray Excluded_; Timer t_total_; CalcType type_; - bool needs_pairlist_; bool decompose_energy_; }; } From c21cdf5163f64d4656f1af14df0126bb337e4915 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 3 Oct 2024 14:24:42 -0400 Subject: [PATCH 137/218] Use Ecalc_Nonbond to do the decomp --- src/Action_PmeTest.cpp | 4 +- src/Energy/Ecalc_Nonbond.cpp | 5 +++ src/Energy/EnergyDecomposer.cpp | 70 +++++++++++++-------------------- src/Energy/EnergyDecomposer.h | 15 ++----- src/Energy/energydepend | 2 +- src/cpptrajdepend | 6 +-- 6 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index a1208b3368..62634cd684 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -78,12 +78,12 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) return Action::ERR; PME0_.Setup( setup.Top(), Mask1_ ); } else if (method_ == 1) { - if (NB_.InitNonbondCalc(Ecalc_Nonbond::PME, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + if (NB_.InitNonbondCalc(Ecalc_Nonbond::PME, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) return Action::ERR; } else if (method_ == 2) { - if (NB_.InitNonbondCalc(Ecalc_Nonbond::LJPME, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + if (NB_.InitNonbondCalc(Ecalc_Nonbond::LJPME, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) return Action::ERR; diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 8f782a0879..80197e5fce 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -60,6 +60,11 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, return 1; } + if (type_ != SIMPLE && !boxIn.HasBox()) { + mprinterr("Error: Ewald requires unit cell information.\n"); + return 1; + } + if (calc_ != 0) { // Ewald calcs need pairlist if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 044055ea23..3cdda2947d 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -23,7 +23,6 @@ EnergyDecomposer::EnergyDecomposer() : eneOut_(0), outfile_(0), debug_(0), - nbcalctype_(SIMPLE), currentTop_(0) { } @@ -34,12 +33,12 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFil debug_ = debugIn; // Process keywords outfile_ = DFLin.AddDataFile( argIn.GetStringKey("out"), argIn ); - nbcalctype_ = SIMPLE; + nbcalctype_ = Ecalc_Nonbond::SIMPLE; if (argIn.hasKey("pme")) - nbcalctype_ = PME; + nbcalctype_ = Ecalc_Nonbond::PME; else if (argIn.Contains("ljpme")) // FIXME using Contains() since EwaldOptions parses ljpme - nbcalctype_ = LJPME; - if (nbcalctype_ == PME || nbcalctype_ == LJPME) { + nbcalctype_ = Ecalc_Nonbond::LJPME; + if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) { if (ewaldOpts_.GetOptions(EwaldOptions::PME, argIn, "enedecomp")) return 1; } @@ -75,7 +74,7 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); if (outfile_ != 0) mprintf("\tOutput file: %s\n", outfile_->DataFilename().full()); - if (nbcalctype_ != SIMPLE) + if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) ewaldOpts_.PrintOptions(); } @@ -187,37 +186,16 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn, Box const& boxIn) { if (setupDihedrals( topIn.Dihedrals() )) return 1; if (setupDihedrals( topIn.DihedralsH() )) return 1; std::sort( dihedrals_.begin(), dihedrals_.end() ); - if (nbcalctype_ != SIMPLE) { - if (!boxIn.HasBox()) { - mprinterr("Error: PME requires unit cell information.\n"); - return 1; - } - // Set up for all atoms FIXME - AtomMask Imask(0, topIn.Natom()); - if (nbcalctype_ == PME) { - if (PME_.Init(boxIn, ewaldOpts_, debug_)) - return 1; - if (PME_.Setup( topIn, Imask )) - return 1; - } else if (nbcalctype_ == LJPME) { - if (LJPME_.Init(boxIn, ewaldOpts_, debug_)) - return 1; - if (LJPME_.Setup( topIn, Imask )) - return 1; - } - } else { - // For nonbonds, set up all selected atoms in an integer atom mask. - //mask_ = AtomMask( selectedAtoms_.ConvertToIntMask(), selectedAtoms_.Natom() ); - // Need to set up ex - // TODO if using pairlist, needs to be EXCLUDE_SELF and FULL - //if (Excluded_.SetupExcludedForAtoms( topIn.Atoms(), mask_, 4 )) - if (Excluded_.SetupExcluded( topIn.Atoms(), 4, - ExclusionArray::NO_EXCLUDE_SELF, - ExclusionArray::ONLY_GREATER_IDX )) - { - mprinterr("Error: Could not set up atom exclusion list for energy decomposition.\n"); - return 1; - } + // Set up nonbonds + // Set up for all atoms FIXME + AtomMask Imask(0, topIn.Natom()); + if (NB_.InitNonbondCalc(nbcalctype_, true, boxIn, ewaldOpts_, debug_)) { + mprinterr("Error: Nonbond decomp init failed.\n"); + return 1; + } + if (NB_.SetupNonbondCalc(topIn, Imask)) { + mprinterr("Error: Nonbond decomp setup failed.\n"); + return 1; } // DEBUG @@ -324,6 +302,7 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { } /** Simple nonbonded energy calculation with no cutoff. */ +/* void EnergyDecomposer::calcNB_simple(Frame const& frameIn) { for (int atom1 = 0; atom1 < currentTop_->Natom(); atom1++) { bool atom1_is_selected = selectedAtoms_.AtomInCharMask( atom1 ); @@ -354,7 +333,7 @@ void EnergyDecomposer::calcNB_simple(Frame const& frameIn) { } // END atom1 or atom2 is selected } // END inner loop over atoms } // END outer loop over atoms -} +}*/ /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { @@ -371,7 +350,14 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { // Dihedrals calcDihedrals(frameIn); // Nonbonds - if (nbcalctype_ != SIMPLE) { // FIXME atommask? + double e_elec, e_vdw; + if (NB_.DecomposedNonbondEnergy(frameIn, selectedAtoms_, e_elec, e_vdw, + currentEne_, currentEne_)) + { + mprinterr("Error: Decompose nonbond energy calc failed.\n"); + return 1; + } +/* if (nbcalctype_ != SIMPLE) { // FIXME atommask? double e_elec, e_vdw; std::vector atom_elec, atom_vdw; if (nbcalctype_ == PME) @@ -387,7 +373,7 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { } } else { calcNB_simple(frameIn); - } + }*/ // Accumulate the energies for (unsigned int idx = 0; idx != energies_.size(); idx++) { @@ -416,8 +402,6 @@ int EnergyDecomposer::FinishCalc() { } } t_total_.WriteTiming(0, " Decomp total:"); - if (nbcalctype_ != SIMPLE) { - PME_.Timing(t_total_.Total()); - } + NB_.PrintTiming(t_total_.Total()); return 0; } diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index cc9f991b56..e7d1e92ce0 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -1,12 +1,9 @@ #ifndef INC_ENERGY_ENERGYDECOMPOSER_H #define INC_ENERGY_ENERGYDECOMPOSER_H #include -#include "EwaldCalc_Decomp_PME.h" -#include "EwaldCalc_Decomp_LJPME.h" -#include "../AtomMask.h" +#include "Ecalc_Nonbond.h" #include "../CharMask.h" #include "../EwaldOptions.h" -#include "../ExclusionArray.h" #include "../OnlineVarT.h" #include "../Timer.h" class AngleType; @@ -37,8 +34,6 @@ class EnergyDecomposer { /// Finish the calculation by putting energies in output DataSet int FinishCalc(); private: - enum NonBondCalcType { SIMPLE = 0, PME, LJPME }; - static const double QFAC_; ///< Coulomb prefactor typedef std::vector Darray; @@ -63,25 +58,23 @@ class EnergyDecomposer { /// Calculate dihedral energies void calcDihedrals(Frame const&); /// Calculate simple nonbonded energies, no cutoff - void calcNB_simple(Frame const&); + //void calcNB_simple(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. DataFile* outfile_; ///< Output file int debug_; ///< Debug level - NonBondCalcType nbcalctype_; ///< What calc type to use for the nonbonds EwaldOptions ewaldOpts_; ///< Hold Ewald options + Cpptraj::Energy::Ecalc_Nonbond::CalcType nbcalctype_; BndArrayType bonds_; ///< Hold all bonds to be calculated AngArrayType angles_; ///< Hold all angles to be calculated DihArrayType dihedrals_; ///< Hold all dihedrals to be calculated //AtomMask mask_; ///< Atom mask for nonbonded calculations - ExclusionArray Excluded_; ///< Hold excluded atoms lists for each selected atom EneArrayType energies_; ///< Used to accumulate the average energy of each selected entity. Topology const* currentTop_; ///< Current topology from Setup - EwaldCalc_Decomp_PME PME_; ///< For calculating pairwise decomposed PME energies - EwaldCalc_Decomp_LJPME LJPME_; ///< For calculating pairwise decomposed LJPME energies + Ecalc_Nonbond NB_; ///< For calculating pairwise decomposed nonbond energies Darray currentEne_; ///< Hold the total energy of each atom for the current frame diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 2fabc7efa5..47b5757e41 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,5 +1,5 @@ Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h -EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h Kernel_Fourier.h Kernel_Harmonic.h PME_Recip.h VDW_LongRange_Correction.h +EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ecalc_Nonbond.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index eb3ab14b43..9122a93005 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -31,7 +31,7 @@ Action_DihedralRMS.o : Action_DihedralRMS.cpp Action.h ActionState.h Action_Dihe Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -278,7 +278,7 @@ DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h From 7e335b74eeb8278808b048af544a1348d9aeea8d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 4 Oct 2024 13:19:33 -0400 Subject: [PATCH 138/218] Start moving nfft and order to inside PME_Recip --- src/Energy/PME_Recip.cpp | 61 ++++++++++++++++++++++++---------------- src/Energy/PME_Recip.h | 16 +++++++---- src/Energy/energydepend | 2 +- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 702ae3332d..53d756e39d 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -1,8 +1,7 @@ #include "PME_Recip.h" -#include "../AtomMask.h" #include "../Box.h" #include "../CpptrajStdio.h" -#include "../Frame.h" +#include "../EwaldOptions.h" typedef helpme::Matrix Mat; @@ -23,7 +22,29 @@ PME_Recip::PME_Recip(Type typeIn) : } } -void PME_Recip::SetDebug(int d) { debug_ = d; } +/** Init */ +int PME_Recip::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { + debug_ = debugIn; + nfft_[0] = pmeOpts.Nfft1(); + nfft_[1] = pmeOpts.Nfft2(); + nfft_[2] = pmeOpts.Nfft3(); + order_ = pmeOpts.SplineOrder(); + // Set defaults if necessary + if (order_ < 1) order_ = 6; + return 0; +} + +/** Print options to stdout. */ +void PME_Recip::PrintRecipOpts() const { + mprintf("\t Bspline order= %i\n", order_); + mprintf("\t "); + for (int i = 0; i != 3; i++) + if (nfft_[i] == -1) + mprintf(" NFFT%i=auto", i+1); + else + mprintf(" NFFT%i=%i", i+1, nfft_[i]); + mprintf("\n"); +} /** \return true if given number is a product of powers of 2, 3, or 5. */ bool PME_Recip::check_prime_factors(int nIn) { @@ -114,21 +135,16 @@ int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that -double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, - const int* nfftIn, double ew_coeffIn, int orderIn) +double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) { t_recip_.Start(); // This essentially makes coordsD and chargesD point to arrays. Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); - int nfft1 = -1; - int nfft2 = -1; - int nfft3 = -1; - if (nfftIn != 0) { - nfft1 = nfftIn[0]; - nfft2 = nfftIn[1]; - nfft3 = nfftIn[2]; - } + int nfft1 = nfft_[0]; + int nfft2 = nfft_[1]; + int nfft3 = nfft_[2]; + if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; @@ -145,7 +161,7 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, order_, nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; @@ -170,28 +186,23 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that double PME_Recip::Recip_Decomp(Darray& atom_recip, - Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, - const int* nfftIn, double ew_coeffIn, int orderIn) + Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) { t_recip_.Start(); atom_recip.resize( ChargeIn.size() ); // This essentially makes coordsD and chargesD point to arrays. Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); - int nfft1 = -1; - int nfft2 = -1; - int nfft3 = -1; - if (nfftIn != 0) { - nfft1 = nfftIn[0]; - nfft2 = nfftIn[1]; - nfft3 = nfftIn[2]; - } + int nfft1 = nfft_[0]; + int nfft2 = nfft_[1]; + int nfft3 = nfft_[2]; + if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; } // Instantiate double precision PME object - pme_object_.setup(distKernelExponent_, ew_coeffIn, orderIn, nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, order_, nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 21d3174613..67d0a7f7e0 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -2,9 +2,8 @@ #define INC_ENERGY_PME_RECIP_H #include "../helpme_standalone.h" #include "../Timer.h" -class AtomMask; class Box; -class Frame; +class EwaldOptions; namespace Cpptraj { namespace Energy { /// Do the reciprocal part of a PME calculation @@ -14,9 +13,14 @@ class PME_Recip { enum Type { COULOMB = 0, LJ }; PME_Recip(Type); - void SetDebug(int); - double Recip_ParticleMesh(Darray&, Box const&, Darray&, const int*, double, int); - double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, const int*, double, int); + /// Initialize + int InitRecip(EwaldOptions const& pmeOpts, int); + + /// Print options to stdout + void PrintRecipOpts() const; + + double Recip_ParticleMesh(Darray&, Box const&, Darray&, double); + double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, double); Timer const& Timing_Total() const { return t_recip_; } //Timer const& Timing_Calc() const { return t_calc_; } @@ -29,6 +33,8 @@ class PME_Recip { PMEInstanceD pme_object_; Timer t_recip_; ///< Recip calc timer //Timer t_calc_; + int nfft_[3]; ///< Number of grid points for FFT in X, Y, Z + int order_; ///< B-Spline order int debug_; int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 47b5757e41..95608c9ab8 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -8,5 +8,5 @@ EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constant EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h -PME_Recip.o : PME_Recip.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h PME_Recip.h +PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h From 10a322dba691b9821fe49828a03bf082ea181e4e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 13:39:34 -0400 Subject: [PATCH 139/218] New class to hold recip coords --- src/Energy/RecipCoords.cpp | 26 ++++++++++++++++++++++++++ src/Energy/RecipCoords.h | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/Energy/RecipCoords.cpp create mode 100644 src/Energy/RecipCoords.h diff --git a/src/Energy/RecipCoords.cpp b/src/Energy/RecipCoords.cpp new file mode 100644 index 0000000000..30a209c65c --- /dev/null +++ b/src/Energy/RecipCoords.cpp @@ -0,0 +1,26 @@ +#include "RecipCoords.h" +#include "../AtomMask.h" +#include "../Frame.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR */ +RecipCoords::RecipCoords() {} + +/** Reserve space for selected atoms */ +int RecipCoords::ReserveForSelected(AtomMask const& maskIn) { + coordsD_.reserve( maskIn.Nselected()*3 ); + return 0; +} + +/** Fill recip coords with XYZ coords of selected atoms. */ +void RecipCoords::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) +{ + coordsD_.clear(); + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { + const double* XYZ = frameIn.XYZ( *atm ); + coordsD_.push_back( XYZ[0] ); + coordsD_.push_back( XYZ[1] ); + coordsD_.push_back( XYZ[2] ); + } +} diff --git a/src/Energy/RecipCoords.h b/src/Energy/RecipCoords.h new file mode 100644 index 0000000000..355f4ceadc --- /dev/null +++ b/src/Energy/RecipCoords.h @@ -0,0 +1,23 @@ +#ifndef INC_ENERGY_RECIPCOORDS_H +#define INC_ENERGY_RECIPCOORDS_H +#include +class AtomMask; +class Frame; +namespace Cpptraj { +namespace Energy { +/// Hold selected XYZ coords for PME recip calcs with helPME +class RecipCoords { + public: + typedef std::vector Darray; + + RecipCoords(); + + int ReserveForSelected(AtomMask const&); + void FillRecipCoords(Frame const&, AtomMask const&); + + private: + Darray coordsD_; +}; +} +} +#endif From 9ff25b7051781ec1515946d54d0d7a56fb325e46 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 13:45:59 -0400 Subject: [PATCH 140/218] Add routine to access coords array, update depends --- src/Energy/CMakeLists.txt | 1 + src/Energy/RecipCoords.h | 2 ++ src/Energy/energydepend | 7 ++++--- src/Energy/energyfiles | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index 728e89892d..e7f5e41db8 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -11,5 +11,6 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp + ${CMAKE_CURRENT_LIST_DIR}/RecipCoords.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/RecipCoords.h b/src/Energy/RecipCoords.h index 355f4ceadc..b72a3bdff0 100644 --- a/src/Energy/RecipCoords.h +++ b/src/Energy/RecipCoords.h @@ -15,6 +15,8 @@ class RecipCoords { int ReserveForSelected(AtomMask const&); void FillRecipCoords(Frame const&, AtomMask const&); + // FIXME: helPME requires this array be non-const right now + Darray& CoordsD() { return coordsD_; } private: Darray coordsD_; }; diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 95608c9ab8..7e9c318a1c 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,12 +1,13 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h RecipCoords.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ecalc_Nonbond.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h -EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h RecipCoords.h VDW_LongRange_Correction.h +EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h +RecipCoords.o : RecipCoords.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h ../Vec3.h RecipCoords.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 47ab1a6fec..bf928bf493 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -11,4 +11,5 @@ ENERGY_SOURCES= \ EwaldParams_LJPME.cpp \ EwaldParams_PME.cpp \ PME_Recip.cpp \ + RecipCoords.cpp \ VDW_LongRange_Correction.cpp From c495811002a393ca9868f8633d2469e225f80fe5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:09:04 -0400 Subject: [PATCH 141/218] Remove files --- src/Energy/EwaldParams_PME.cpp | 83 ---------------------------------- src/Energy/EwaldParams_PME.h | 28 ------------ src/Energy/RecipCoords.cpp | 26 ----------- src/Energy/RecipCoords.h | 25 ---------- 4 files changed, 162 deletions(-) delete mode 100644 src/Energy/EwaldParams_PME.cpp delete mode 100644 src/Energy/EwaldParams_PME.h delete mode 100644 src/Energy/RecipCoords.cpp delete mode 100644 src/Energy/RecipCoords.h diff --git a/src/Energy/EwaldParams_PME.cpp b/src/Energy/EwaldParams_PME.cpp deleted file mode 100644 index fc5bd4d434..0000000000 --- a/src/Energy/EwaldParams_PME.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "EwaldParams_PME.h" -#include "../AtomMask.h" -#include "../CpptrajStdio.h" -#include "../EwaldOptions.h" -#include "../Frame.h" - -using namespace Cpptraj::Energy; - -/** CONSTRUCTOR */ -EwaldParams_PME::EwaldParams_PME() : - order_(6) -{ - nfft_[0] = -1; - nfft_[1] = -1; - nfft_[2] = -1; -} - -/** Set up PME parameters. */ -int EwaldParams_PME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) -{ - // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); - return 1; - } - if (CheckInput(boxIn, debugIn, pmeOpts.Cutoff(), pmeOpts.DsumTol(), pmeOpts.EwCoeff(), - pmeOpts.LJ_SwWidth(), pmeOpts.ErfcDx(), pmeOpts.SkinNB())) - return 1; - nfft_[0] = pmeOpts.Nfft1(); - nfft_[1] = pmeOpts.Nfft2(); - nfft_[2] = pmeOpts.Nfft3(); - order_ = pmeOpts.SplineOrder(); - - // Set defaults if necessary - if (order_ < 1) order_ = 6; - - mprintf("\tParticle Mesh Ewald params:\n"); - mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", - Cutoff(), DirectSumTol(), EwaldCoeff(), pmeOpts.SkinNB()); - if (LJ_SwitchWidth() > 0.0) - mprintf("\t LJ switch width= %g\n", LJ_SwitchWidth()); - mprintf("\t Bspline order= %i\n", order_); - //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); - mprintf("\t "); - for (int i = 0; i != 3; i++) - if (nfft_[i] == -1) - mprintf(" NFFT%i=auto", i+1); - else - mprintf(" NFFT%i=%i", i+1, nfft_[i]); - mprintf("\n"); - - // Set up pair list - //if (Setup_Pairlist(boxIn, pmeOpts.SkinNB())) return 1; - - return 0; -} - -/** Setup PME calculation. */ -int EwaldParams_PME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { - CalculateCharges(topIn, maskIn); - // Sanity check - if (Charge().size() != (unsigned int)maskIn.Nselected()) { - mprinterr("Internal Error: EwaldParams_PME::SetupEwald(): Charge/coords size mismatch (%zu vs %i\n", - Charge().size(), maskIn.Nselected()); - return 1; - } - - coordsD_.clear(); - coordsD_.reserve( maskIn.Nselected()*3 ); - return 0; -} - -/** Put selected coords in separate array for recip calc. */ -void EwaldParams_PME::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) -{ - coordsD_.clear(); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { - const double* XYZ = frameIn.XYZ( *atm ); - coordsD_.push_back( XYZ[0] ); - coordsD_.push_back( XYZ[1] ); - coordsD_.push_back( XYZ[2] ); - } -} diff --git a/src/Energy/EwaldParams_PME.h b/src/Energy/EwaldParams_PME.h deleted file mode 100644 index 5f58b40fe1..0000000000 --- a/src/Energy/EwaldParams_PME.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef INC_ENERGY_EWALDPARAMS_PME_H -#define INC_ENERGY_EWALDPARAMS_PME_H -#include "EwaldParams.h" -class Frame; -namespace Cpptraj { -namespace Energy { -class EwaldParams_PME : public EwaldParams { - public: - EwaldParams_PME(); - int InitEwald(Box const&, EwaldOptions const&, int); - int SetupEwald(Topology const&, AtomMask const&); - - void FillRecipCoords(Frame const&, AtomMask const&); - - // FIXME do not return const because helPME needs the array to be non-const. Should be fixed - Darray& SelectedCoords() { return coordsD_; } - /// \return NFFT array pointer - const int* NFFT() const { return nfft_; } - /// \return B-spline order - int Order() const { return order_; } - private: - Darray coordsD_; ///< Hold coords for selected atoms (for recip. calc) - int nfft_[3]; ///< Number of FFT grid points in each direction - int order_; ///< PME B spline order -}; -} -} -#endif diff --git a/src/Energy/RecipCoords.cpp b/src/Energy/RecipCoords.cpp deleted file mode 100644 index 30a209c65c..0000000000 --- a/src/Energy/RecipCoords.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "RecipCoords.h" -#include "../AtomMask.h" -#include "../Frame.h" - -using namespace Cpptraj::Energy; - -/** CONSTRUCTOR */ -RecipCoords::RecipCoords() {} - -/** Reserve space for selected atoms */ -int RecipCoords::ReserveForSelected(AtomMask const& maskIn) { - coordsD_.reserve( maskIn.Nselected()*3 ); - return 0; -} - -/** Fill recip coords with XYZ coords of selected atoms. */ -void RecipCoords::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) -{ - coordsD_.clear(); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { - const double* XYZ = frameIn.XYZ( *atm ); - coordsD_.push_back( XYZ[0] ); - coordsD_.push_back( XYZ[1] ); - coordsD_.push_back( XYZ[2] ); - } -} diff --git a/src/Energy/RecipCoords.h b/src/Energy/RecipCoords.h deleted file mode 100644 index b72a3bdff0..0000000000 --- a/src/Energy/RecipCoords.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef INC_ENERGY_RECIPCOORDS_H -#define INC_ENERGY_RECIPCOORDS_H -#include -class AtomMask; -class Frame; -namespace Cpptraj { -namespace Energy { -/// Hold selected XYZ coords for PME recip calcs with helPME -class RecipCoords { - public: - typedef std::vector Darray; - - RecipCoords(); - - int ReserveForSelected(AtomMask const&); - void FillRecipCoords(Frame const&, AtomMask const&); - - // FIXME: helPME requires this array be non-const right now - Darray& CoordsD() { return coordsD_; } - private: - Darray coordsD_; -}; -} -} -#endif From 9ed3b29520a69d219aa719f7f6956acd03783d3d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:11:27 -0400 Subject: [PATCH 142/218] Move EwaldParams_PME Init, Setup, and coordsD routines to EwaldParams --- src/Energy/EwaldParams.cpp | 43 ++++++++++++++++++++++++++++++++++++-- src/Energy/EwaldParams.h | 14 +++++++++---- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index f9e301b559..6f82ca3668 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -2,6 +2,7 @@ #include "../Box.h" #include "../Constants.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Topology.h" using namespace Cpptraj::Energy; @@ -111,14 +112,50 @@ int EwaldParams::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, doub return 0; } -/** Convert charges to Amber units. Calculate sum of charges and squared charges. */ -void EwaldParams::CalculateCharges(Topology const& topIn, AtomMask const& maskIn) { + +/** Initialize */ +int EwaldParams::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + if (CheckInput(boxIn, debugIn, pmeOpts.Cutoff(), pmeOpts.DsumTol(), pmeOpts.EwCoeff(), + pmeOpts.LJ_SwWidth(), pmeOpts.ErfcDx(), pmeOpts.SkinNB())) + return 1; + mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", + Cutoff(), DirectSumTol(), EwaldCoeff(), pmeOpts.SkinNB()); + if (LJ_SwitchWidth() > 0.0) + mprintf("\t LJ switch width= %g\n", LJ_SwitchWidth()); + //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); + return 0; +} + +/** Reserve space for selected atoms */ +void EwaldParams::reserveRecipCoords(AtomMask const& maskIn) { + coordsD_.reserve( maskIn.Nselected()*3 ); +} + +/** Fill recip coords with XYZ coords of selected atoms. */ +void EwaldParams::FillRecipCoords(Frame const& frameIn, AtomMask const& maskIn) +{ + coordsD_.clear(); + for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) { + const double* XYZ = frameIn.XYZ( *atm ); + coordsD_.push_back( XYZ[0] ); + coordsD_.push_back( XYZ[1] ); + coordsD_.push_back( XYZ[2] ); + } +} + +/** Convert charges to Amber units. Calculate sum of charges and squared charges. + * Store LJ type indices for selected atoms. + */ +int EwaldParams::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { NB_ = static_cast( &(topIn.Nonbond()) ); sumq_ = 0.0; sumq2_ = 0.0; Charge_.clear(); + Charge_.reserve( maskIn.Nselected() ); TypeIndices_.clear(); + TypeIndices_.reserve( maskIn.Nselected() ); for (AtomMask::const_iterator atom = maskIn.begin(); atom != maskIn.end(); ++atom) { double qi = topIn[*atom].Charge() * Constants::ELECTOAMBER; Charge_.push_back(qi); @@ -129,6 +166,8 @@ void EwaldParams::CalculateCharges(Topology const& topIn, AtomMask const& maskIn } //mprintf("DEBUG: sumq= %20.10f sumq2= %20.10f\n", sumq_, sumq2_); //Setup_VDW_Correction( topIn, maskIn ); + reserveRecipCoords(maskIn); + return 0; } /** Electrostatic self energy. This is the cancelling Gaussian plus the "neutralizing plasma". */ diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 0f9994cb8f..4dd1b91b28 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -5,6 +5,7 @@ class AtomMask; class Box; class EwaldOptions; +class Frame; class Topology; namespace Cpptraj { namespace Energy { @@ -15,10 +16,12 @@ class EwaldParams { // Virtual since inherited virtual ~EwaldParams() {} // ------------------------------------------- - virtual int InitEwald(Box const&, EwaldOptions const&, int) = 0; - virtual int SetupEwald(Topology const&, AtomMask const&) = 0; + virtual int InitEwald(Box const&, EwaldOptions const&, int); + virtual int SetupEwald(Topology const&, AtomMask const&); // ------------------------------------------- + /// Fill recip coords with XYZ coords of selected atoms. + void FillRecipCoords(Frame const&, AtomMask const&); /// \return ERFC value of given distance times the Ewald coefficient double ErfcEW(double rIn) const { return erfc_.ErfcInterpolated( ew_coeff_*rIn ); } /// \return LJ switch fn value @@ -63,6 +66,8 @@ class EwaldParams { // FIXME do not return const because helPME needs the array to be non-const. Should be fixed std::vector& SelectedCharges() { return Charge_; } + // FIXME do not return const because helPME needs the array to be non-const. Should be fixed + std::vector& SelectedCoords() { return coordsD_; } protected: typedef std::vector Darray; typedef std::vector Iarray; @@ -73,12 +78,12 @@ class EwaldParams { /// Set Ewald parametsr, check them and set defaults if needed. int CheckInput(Box const&, int, double, double, double, double, double, double); - /// Calculate sum q, sum q^2. - void CalculateCharges(Topology const&, AtomMask const&); private: static const double INVSQRTPI_; double FindEwaldCoefficient(double, double); + /// Reserve space for selected coordinates for recip calcs + void reserveRecipCoords(AtomMask const&); double ew_coeff_; ///< Ewald coefficient double switch_width_; ///< Switching window size for LJ switch if active @@ -90,6 +95,7 @@ class EwaldParams { ErfcFxn erfc_; ///< Hold spline interpolation for erfc + Darray coordsD_; ///< Hold selected coords for recip calcs Darray Charge_; ///< Hold charges for selected atoms Iarray TypeIndices_; ///< Hold atom type indices for selected atoms NonbondParmType const* NB_; ///< Pointer to nonbonded parameters From 5584d11e25319e1ece4125e6bfc886dc74246dad Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:13:19 -0400 Subject: [PATCH 143/218] Use new EwaldParams --- src/Energy/EwaldCalc_PME.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index 668fbf00aa..b74bd0c47b 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -1,5 +1,6 @@ #include "EwaldCalc_PME.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Frame.h" #include "../PairListTemplate.h" @@ -12,12 +13,22 @@ EwaldCalc_PME::EwaldCalc_PME() : /** Set up PME parameters. */ int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + mprintf("\tParticle Mesh Ewald params:\n"); if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: PME calculation init failed.\n"); return 1; } VDW_LR_.SetDebug( debugIn ); - Recip_.SetDebug( debugIn ); + if (Recip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: PME recip init failed.\n"); + return 1; + } + Recip_.PrintRecipOpts(); return 0; } @@ -53,9 +64,7 @@ int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskI double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedCharges(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().EwaldCoeff() ); // TODO branch From adc88a7ca818ff908740425b8b87e7345ed9d2d1 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:13:56 -0400 Subject: [PATCH 144/218] Use EwaldParams --- src/Energy/EwaldParams_LJPME.cpp | 4 ++-- src/Energy/EwaldParams_LJPME.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp index e4161a02d3..9014387a93 100644 --- a/src/Energy/EwaldParams_LJPME.cpp +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -15,7 +15,7 @@ EwaldParams_LJPME::EwaldParams_LJPME() : /** Set up LJPME parameters. */ int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { - if (EwaldParams_PME::InitEwald(boxIn, pmeOpts, debugIn)) return 1; + if (EwaldParams::InitEwald(boxIn, pmeOpts, debugIn)) return 1; lw_coeff_ = pmeOpts.LwCoeff(); @@ -37,7 +37,7 @@ int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, /** Setup LJPME calculation. */ int EwaldParams_LJPME::SetupEwald(Topology const& topIn, AtomMask const& maskIn) { - if (EwaldParams_PME::SetupEwald(topIn, maskIn)) return 1; + if (EwaldParams::SetupEwald(topIn, maskIn)) return 1; // Calcuate C6 parameters if (lw_coeff_ > 0.0) { diff --git a/src/Energy/EwaldParams_LJPME.h b/src/Energy/EwaldParams_LJPME.h index dd7a976f8f..a0eea59e5f 100644 --- a/src/Energy/EwaldParams_LJPME.h +++ b/src/Energy/EwaldParams_LJPME.h @@ -1,9 +1,9 @@ #ifndef INC_ENERGY_EWALDPARAMS_LJPME_H #define INC_ENERGY_EWALDPARAMS_LJPME_H -#include "EwaldParams_PME.h" +#include "EwaldParams.h" namespace Cpptraj { namespace Energy { -class EwaldParams_LJPME : public EwaldParams_PME { +class EwaldParams_LJPME : public EwaldParams { public: EwaldParams_LJPME(); From f1b0bede6cf319690238bf2da01c684b2cca8056 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:16:47 -0400 Subject: [PATCH 145/218] Have recip print opts right after init --- src/Energy/EwaldCalc_PME.cpp | 1 - src/Energy/PME_Recip.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index b74bd0c47b..8ce28e794d 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -28,7 +28,6 @@ int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debug mprinterr("Error: PME recip init failed.\n"); return 1; } - Recip_.PrintRecipOpts(); return 0; } diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 53d756e39d..1a841a0147 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -31,11 +31,13 @@ int PME_Recip::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { order_ = pmeOpts.SplineOrder(); // Set defaults if necessary if (order_ < 1) order_ = 6; + PrintRecipOpts(); return 0; } /** Print options to stdout. */ void PME_Recip::PrintRecipOpts() const { + mprintf("\tRecip opts (distance kernel exponent= %i\n", distKernelExponent_); mprintf("\t Bspline order= %i\n", order_); mprintf("\t "); for (int i = 0; i != 3; i++) From 2f827048fb7abaf73d180525ad1c8b61d8f7ea32 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 14:21:25 -0400 Subject: [PATCH 146/218] Use new EwaldParams --- src/Energy/EwaldCalc_Decomp_PME.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index f39d2679f2..fc4989aac1 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -1,5 +1,6 @@ #include "EwaldCalc_Decomp_PME.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Frame.h" #include "../PairListTemplate.h" @@ -12,12 +13,21 @@ EwaldCalc_Decomp_PME::EwaldCalc_Decomp_PME() : /** Set up PME parameters. */ int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + mprintf("\tDecomposed Particle Mesh Ewald params:\n"); if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: Decomposable PME calculation init failed.\n"); return 1; } VDW_LR_.SetDebug( debugIn ); - Recip_.SetDebug( debugIn ); + if (Recip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: PME recip init failed.\n"); + return 1; + } return 0; } @@ -59,9 +69,7 @@ int EwaldCalc_Decomp_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedCharges(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().EwaldCoeff() ); mprintf("DEBUG: Recip energy : %f\n", e_recip); mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); From 93509157ada2b0578298535180e04b936d97a812 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 15:28:39 -0400 Subject: [PATCH 147/218] Update for new EwaldParams and PME_Recip --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 25 +++++++++++++++++-------- src/Energy/EwaldCalc_LJPME.cpp | 25 +++++++++++++++++-------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index e55286e509..01a4d5d8a3 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -1,5 +1,6 @@ #include "EwaldCalc_Decomp_LJPME.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Frame.h" #include "../PairListTemplate.h" @@ -13,12 +14,24 @@ EwaldCalc_Decomp_LJPME::EwaldCalc_Decomp_LJPME() : /** Set up LJPME parameters. */ int EwaldCalc_Decomp_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + mprintf("\tDecomposable Particle Mesh Ewald (LJPME) params:\n"); if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: Decomposable LJPME calculation init failed.\n"); return 1; } - Recip_.SetDebug( debugIn ); - LJrecip_.SetDebug( debugIn ); + if (Recip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: Decomposable LJPME recip init failed.\n"); + return 1; + } + if (LJrecip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: Decomposable LJPME LJ recip init failed.\n"); + return 1; + } return 0; } @@ -62,9 +75,7 @@ int EwaldCalc_Decomp_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask con NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedCharges(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().EwaldCoeff() ); mprintf("DEBUG: Recip energy : %f\n", e_recip); mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); @@ -73,9 +84,7 @@ int EwaldCalc_Decomp_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask con NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedC6params(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().LJ_EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().LJ_EwaldCoeff() ); mprintf("DEBUG: VDW Recip energy : %f\n", e_vdw6recip); mprintf("DEBUG: Sum of VDW recip array: %f\n", sumArray(atom_vdw6recip)); diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index 45326758ec..58b7b2d4fb 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -1,5 +1,6 @@ #include "EwaldCalc_LJPME.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Frame.h" #include "../PairListTemplate.h" @@ -13,12 +14,24 @@ EwaldCalc_LJPME::EwaldCalc_LJPME() : /** Set up LJPME parameters. */ int EwaldCalc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + mprintf("\tParticle Mesh Ewald (LJPME) params:\n"); if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { mprinterr("Error: LJPME calculation init failed.\n"); return 1; } - Recip_.SetDebug( debugIn ); - LJrecip_.SetDebug( debugIn ); + if (Recip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: LJPME recip init failed.\n"); + return 1; + } + if (LJrecip_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: LJPME LJ recip init failed.\n"); + return 1; + } return 0; } @@ -50,16 +63,12 @@ int EwaldCalc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& mas double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedCharges(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().EwaldCoeff() ); double e_vdw6recip = LJrecip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), NBengine_.ModifyEwaldParams().SelectedC6params(), - NBengine_.EwaldParams().NFFT(), - NBengine_.EwaldParams().LJ_EwaldCoeff(), - NBengine_.EwaldParams().Order() + NBengine_.EwaldParams().LJ_EwaldCoeff() ); if (NBengine_.EwaldParams().Debug() > 0) { mprintf("DEBUG: e_vdw6self = %16.8f\n", NBengine_.EwaldParams().Self6()); From eb0aab32a06b1ac042bec29ccb566d168d886b50 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 15:29:21 -0400 Subject: [PATCH 148/218] Update depends --- src/Energy/CMakeLists.txt | 2 -- src/Energy/energydepend | 14 ++++++-------- src/Energy/energyfiles | 2 -- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index e7f5e41db8..f244070108 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -9,8 +9,6 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp - ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp - ${CMAKE_CURRENT_LIST_DIR}/RecipCoords.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 7e9c318a1c..68dbc935cb 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,13 +1,11 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h RecipCoords.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ecalc_Nonbond.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h -EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h -EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/EwaldParams_PME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h -EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h RecipCoords.h VDW_LongRange_Correction.h +EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h +EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h -EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h EwaldParams_PME.h -EwaldParams_PME.o : EwaldParams_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterTypes.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_PME.h +EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h -RecipCoords.o : RecipCoords.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Unit.h ../Vec3.h RecipCoords.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index bf928bf493..4bd342ffb6 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -9,7 +9,5 @@ ENERGY_SOURCES= \ EwaldCalc_PME.cpp \ EwaldParams.cpp \ EwaldParams_LJPME.cpp \ - EwaldParams_PME.cpp \ PME_Recip.cpp \ - RecipCoords.cpp \ VDW_LongRange_Correction.cpp From 7af5105b4ec6255e70dac37f7e10e14886b28f02 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 7 Oct 2024 15:33:56 -0400 Subject: [PATCH 149/218] Use EwaldParams intead of EwaldParams_PME. Update depends --- src/PairListEngine_Ewald_Decomp_LJLR.h | 8 ++++---- src/PairListEngine_Ewald_LJLR.h | 8 ++++---- src/cpptrajdepend | 17 ++++++++--------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/PairListEngine_Ewald_Decomp_LJLR.h b/src/PairListEngine_Ewald_Decomp_LJLR.h index 4a6e85f07f..61e4c7ecd4 100644 --- a/src/PairListEngine_Ewald_Decomp_LJLR.h +++ b/src/PairListEngine_Ewald_Decomp_LJLR.h @@ -1,7 +1,7 @@ #ifndef INC_PAIRLISTENGINE_EWALD_DECOMP_LJLR_H #define INC_PAIRLISTENGINE_EWALD_DECOMP_LJLR_H #include "Energy/Ene_LJ_6_12.h" -#include "Energy/EwaldParams_PME.h" +#include "Energy/EwaldParams.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" namespace Cpptraj { @@ -67,8 +67,8 @@ class PairListEngine_Ewald_Decomp_LJLR { atom_eadj_[atom1.Idx()] += e_half; } // ------------------------------------------- - Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } - Cpptraj::Energy::EwaldParams_PME const& EwaldParams() const { return EW_; } + Cpptraj::Energy::EwaldParams& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams const& EwaldParams() const { return EW_; } T Evdw() const { return Evdw_; } T Eelec() const { return Eelec_; } @@ -102,7 +102,7 @@ class PairListEngine_Ewald_Decomp_LJLR { Darray atom_evdw_; ///< Sum of VDW E on each atom for current frame Darray atom_eadj_; ///< Sum of excluded atom adjust E on each atom for current frame - Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME + Cpptraj::Energy::EwaldParams EW_; ///< Hold Ewald parameters for PME }; #ifdef _OPENMP #pragma omp declare reduction( + : PairListEngine_Ewald_Decomp_LJLR : omp_out += omp_in ) initializer( omp_priv = omp_orig ) diff --git a/src/PairListEngine_Ewald_LJLR.h b/src/PairListEngine_Ewald_LJLR.h index 2eb623aa6e..d9cc8a0336 100644 --- a/src/PairListEngine_Ewald_LJLR.h +++ b/src/PairListEngine_Ewald_LJLR.h @@ -1,7 +1,7 @@ #ifndef INC_PAIRLISTENGINE_EWALD_LJLR_H #define INC_PAIRLISTENGINE_EWALD_LJLR_H #include "Energy/Ene_LJ_6_12.h" -#include "Energy/EwaldParams_PME.h" +#include "Energy/EwaldParams.h" #include "Energy/Kernel_EwaldAdjust.h" #include "PairList.h" namespace Cpptraj { @@ -51,8 +51,8 @@ class PairListEngine_Ewald_LJLR { Eadjust_ += Cpptraj::Energy::Kernel_EwaldAdjust( q0_, q1_, rij, erfcval ); } // ------------------------------------------- - Cpptraj::Energy::EwaldParams_PME& ModifyEwaldParams() { return EW_; } - Cpptraj::Energy::EwaldParams_PME const& EwaldParams() const { return EW_; } + Cpptraj::Energy::EwaldParams& ModifyEwaldParams() { return EW_; } + Cpptraj::Energy::EwaldParams const& EwaldParams() const { return EW_; } T Evdw() const { return Evdw_; } T Eelec() const { return Eelec_; } @@ -72,7 +72,7 @@ class PairListEngine_Ewald_LJLR { T Eelec_; ///< Coulomb sum for current frame T Eadjust_; ///< Adjust energy sum for current frame - Cpptraj::Energy::EwaldParams_PME EW_; ///< Hold Ewald parameters for PME + Cpptraj::Energy::EwaldParams EW_; ///< Hold Ewald parameters for PME }; #ifdef _OPENMP #pragma omp declare reduction( + : PairListEngine_Ewald_LJLR : omp_out += omp_in ) initializer( omp_priv = omp_orig ) diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 9122a93005..a18780f272 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,17 +277,16 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h -Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_PME.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/EwaldParams_PME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Energy/EwaldParams_PME.o : Energy/EwaldParams_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_PME.h EwaldOptions.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Unit.h Vec3.h -Energy/PME_Recip.o : Energy/PME_Recip.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Energy/PME_Recip.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/PME_Recip.o : Energy/PME_Recip.cpp Box.h CpptrajStdio.h Energy/PME_Recip.h EwaldOptions.h Matrix_3x3.h Parallel.h Timer.h Vec3.h helpme_standalone.h Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 71be5c6b855f37282b6f618f6abf9120297c1da8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 09:54:07 -0400 Subject: [PATCH 150/218] Start Ewald_Recip class --- src/Energy/Ewald_Recip.cpp | 102 +++++++++++++++++++++++++++++++++++++ src/Energy/Ewald_Recip.h | 46 +++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 src/Energy/Ewald_Recip.cpp create mode 100644 src/Energy/Ewald_Recip.h diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp new file mode 100644 index 0000000000..cc0ef38dab --- /dev/null +++ b/src/Energy/Ewald_Recip.cpp @@ -0,0 +1,102 @@ +#include "Ewald_Recip.h" +#include "ErfcFxn.h" // erfc_func +#include "EwaldParams.h" +#include "../Constants.h" +#include "../CpptrajStdio.h" +#include "../Matrix_3x3.h" +#include "../Vec3.h" +#include // sqrt +#include // std::max + +using namespace Cpptraj::Energy; + +// Absolute value functions +static inline int IABS( int xIn) { if (xIn < 0 ) return -xIn; else return xIn; } +static inline double DABS(double xIn) { if (xIn < 0 ) return -xIn; else return xIn; } + +/** CONSTRUCTOR */ +Ewald_Recip::Ewald_Recip() : +# ifdef _OPENMP + multCut_(0), +# endif + maxexp_(0.0), + rsumTol_(0.0), + maxmlim_(0) +{ + mlimit_[0] = 0; + mlimit_[1] = 0; + mlimit_[2] = 0; +} + +/** \return maxexp value based on mlimits */ +double Ewald_Recip::FindMaxexpFromMlim(const int* mlimit, Matrix_3x3 const& recip) { + double maxexp = DABS( (double)mlimit[0] * recip[0] ); + double z2 = DABS( (double)mlimit[1] * recip[4] ); + maxexp = std::max(maxexp, z2); + double z3 = DABS( (double)mlimit[2] * recip[8] ); + maxexp = std::max(maxexp, z3); + return maxexp; +} + +/** \return maxexp value based on Ewald coefficient and reciprocal sum tolerance. */ +double Ewald_Recip::FindMaxexpFromTol(double ewCoeff, double rsumTol) { + double xval = 0.5; + int nloop = 0; + double term = 0.0; + do { + xval = 2.0 * xval; + nloop++; + double yval = Constants::PI * xval / ewCoeff; + term = 2.0 * ewCoeff * ErfcFxn::erfc_func(yval) * EwaldParams::INVSQRTPI(); + } while (term >= rsumTol); + + // Binary search tolerance is 2^-60 + int ntimes = nloop + 60; + double xlo = 0.0; + double xhi = xval; + for (int i = 0; i != ntimes; i++) { + xval = (xlo + xhi) / 2.0; + double yval = Constants::PI * xval / ewCoeff; + double term = 2.0 * ewCoeff * ErfcFxn::erfc_func(yval) * EwaldParams::INVSQRTPI(); + if (term > rsumTol) + xlo = xval; + else + xhi = xval; + } + mprintf("\tMaxExp for Ewald coefficient %g, direct sum tol %g is %g\n", + ewCoeff, rsumTol, xval); + return xval; +} + + +/** Get mlimits. */ +void Ewald_Recip::GetMlimits(int* mlimit, double maxexp, double eigmin, + Vec3 const& reclng, Matrix_3x3 const& recip) +{ + //mprintf("DEBUG: Recip lengths %12.4f%12.4f%12.4f\n", reclng[0], reclng[1], reclng[2]); + + int mtop1 = (int)(reclng[0] * maxexp / sqrt(eigmin)); + int mtop2 = (int)(reclng[1] * maxexp / sqrt(eigmin)); + int mtop3 = (int)(reclng[2] * maxexp / sqrt(eigmin)); + + int nrecvecs = 0; + mlimit[0] = 0; + mlimit[1] = 0; + mlimit[2] = 0; + double maxexp2 = maxexp * maxexp; + for (int m1 = -mtop1; m1 <= mtop1; m1++) { + for (int m2 = -mtop2; m2 <= mtop2; m2++) { + for (int m3 = -mtop3; m3 <= mtop3; m3++) { + Vec3 Zvec = recip.TransposeMult( Vec3(m1,m2,m3) ); + if ( Zvec.Magnitude2() <= maxexp2 ) { + nrecvecs++; + mlimit[0] = std::max( mlimit[0], IABS(m1) ); + mlimit[1] = std::max( mlimit[1], IABS(m2) ); + mlimit[2] = std::max( mlimit[2], IABS(m3) ); + } + } + } + } + mprintf("\tNumber of reciprocal vectors: %i\n", nrecvecs); +} + diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h new file mode 100644 index 0000000000..6893602b0e --- /dev/null +++ b/src/Energy/Ewald_Recip.h @@ -0,0 +1,46 @@ +#ifndef INC_ENERGY_EWALD_RECIP_H +#define INC_ENERGY_EWALD_RECIP_H +#include +class Matrix_3x3; +class Vec3; +namespace Cpptraj { +namespace Energy { +/// For calculating reciprocal space energy using the "regular" Ewald summation +class Ewald_Recip { + public: + Ewald_Recip(); + private: + typedef std::vector Darray; + + /// Determine max length for reciprocal calcs based on reciprocal limits + static double FindMaxexpFromMlim(const int*, Matrix_3x3 const&); + /// Determine max length for reciprocal calcs based on Ewald coefficient and recip tol. + static double FindMaxexpFromTol(double, double); + /// Determine reciprocal limits based on unit cell reciprocal vectors + static void GetMlimits(int*, double, double, Vec3 const&, Matrix_3x3 const&); + + // Hold trig tables + Darray cosf1_; + Darray cosf2_; + Darray cosf3_; + Darray sinf1_; + Darray sinf2_; + Darray sinf3_; + Darray c12_; + Darray s12_; + Darray c3_; + Darray s3_; +# ifdef _OPENMP + typedef Ewald::Iarray Iarray; + Iarray mlim1_; ///< Hold m1 reciprocal indices + Iarray mlim2_; ///< Hold m2 reciprocal indices + int multCut_; ///< Hold index after which multiplier should be 2.0. +# endif + double maxexp_; ///< Determines how far out recip vectors go? TODO check! + double rsumTol_; ///< Reciprocal space sum tolerance. + int mlimit_[3]; ///< Number of units in each direction to calc recip. sum. + int maxmlim_; ///< The max of the three mlimit_ values. +}; +} +} +#endif From a36fbc3ce25e6fa94ab3fc0a086a2b822d622580 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 09:54:17 -0400 Subject: [PATCH 151/218] Make 1 / sqrt(PI) constant available --- src/Energy/EwaldParams.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index 4dd1b91b28..d3d41a8044 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -11,6 +11,7 @@ namespace Cpptraj { namespace Energy { /// Parameters common to all Ewald methods class EwaldParams { + static const double INVSQRTPI_; public: EwaldParams(); // Virtual since inherited @@ -63,6 +64,8 @@ class EwaldParams { double EwaldCoeff() const { return ew_coeff_; } /// \return LJ switch width (in Ang.) double LJ_SwitchWidth() const { return switch_width_; } + /// \return 1 / sqrt(PI) + static const double INVSQRTPI() { return INVSQRTPI_; } // FIXME do not return const because helPME needs the array to be non-const. Should be fixed std::vector& SelectedCharges() { return Charge_; } @@ -79,8 +82,6 @@ class EwaldParams { int CheckInput(Box const&, int, double, double, double, double, double, double); private: - static const double INVSQRTPI_; - double FindEwaldCoefficient(double, double); /// Reserve space for selected coordinates for recip calcs void reserveRecipCoords(AtomMask const&); From e14f404731aa41c17c2da4e9471caa53b76dcbf7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:03:52 -0400 Subject: [PATCH 152/218] Add init and print routines --- src/Energy/Ewald_Recip.cpp | 54 ++++++++++++++++++++++++++++++++++++++ src/Energy/Ewald_Recip.h | 8 ++++++ 2 files changed, 62 insertions(+) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index cc0ef38dab..927ae38002 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -1,8 +1,10 @@ #include "Ewald_Recip.h" #include "ErfcFxn.h" // erfc_func #include "EwaldParams.h" +#include "../Box.h" #include "../Constants.h" #include "../CpptrajStdio.h" +#include "../EwaldOptions.h" #include "../Matrix_3x3.h" #include "../Vec3.h" #include // sqrt @@ -100,3 +102,55 @@ void Ewald_Recip::GetMlimits(int* mlimit, double maxexp, double eigmin, mprintf("\tNumber of reciprocal vectors: %i\n", nrecvecs); } +/** Init */ +int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, EwaldParams const& ewParams, + Box const& boxIn, int debugIn) +{ + debug_ = debugIn; + rsumTol_ = ewOpts.RsumTol(); + maxexp_ = ewOpts.MaxExp(); + mlimit_[0] = ewOpts.Mlimits1(); + mlimit_[1] = ewOpts.Mlimits2(); + mlimit_[2] = ewOpts.Mlimits3(); + + // Check input + if (mlimit_[0] < 0 || mlimit_[1] < 0 || mlimit_[2] < 0) { + mprinterr("Error: Cannot specify negative mlimit values.\n"); + return 1; + } + maxmlim_ = mlimit_[0]; + maxmlim_ = std::max(maxmlim_, mlimit_[1]); + maxmlim_ = std::max(maxmlim_, mlimit_[2]); + if (maxexp_ < 0.0) { + mprinterr("Error: maxexp is less than 0.0\n"); + return 1; + } + + // Set defaults if necessary + if (rsumTol_ < Constants::SMALL) + rsumTol_ = 5E-5; + if (maxmlim_ > 0) + maxexp_ = FindMaxexpFromMlim(mlimit_, boxIn.FracCell()); + else { + if ( maxexp_ < Constants::SMALL ) + maxexp_ = FindMaxexpFromTol(ewParams.EwaldCoeff(), rsumTol_); + // eigmin typically bigger than this unless cell is badly distorted. + double eigmin = 0.5; + // Calculate lengths of reciprocal vectors + GetMlimits(mlimit_, maxexp_, eigmin, boxIn.RecipLengths(), boxIn.FracCell()); + maxmlim_ = mlimit_[0]; + maxmlim_ = std::max(maxmlim_, mlimit_[1]); + maxmlim_ = std::max(maxmlim_, mlimit_[2]); + } + + PrintRecipOpts(); + return 0; +} + +/** Print options to stdout */ +void Ewald_Recip::PrintRecipOpts() const { + mprintf("\tRecip opts (regular Ewald):\n"); + mprintf("\t MaxExp= %g Recip. Sum Tol= %g\n", maxexp_, rsumTol_); + //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); + mprintf("\t mlimits= {%i,%i,%i} Max=%i\n", mlimit_[0], mlimit_[1], mlimit_[2], maxmlim_); +} diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index 6893602b0e..3b632032e2 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -1,14 +1,21 @@ #ifndef INC_ENERGY_EWALD_RECIP_H #define INC_ENERGY_EWALD_RECIP_H #include +class Box; +class EwaldOptions; class Matrix_3x3; class Vec3; namespace Cpptraj { namespace Energy { +class EwaldParams; /// For calculating reciprocal space energy using the "regular" Ewald summation class Ewald_Recip { public: Ewald_Recip(); + + + int InitRecip(EwaldOptions const&, EwaldParams const&, Box const&, int); + void PrintRecipOpts() const; private: typedef std::vector Darray; @@ -40,6 +47,7 @@ class Ewald_Recip { double rsumTol_; ///< Reciprocal space sum tolerance. int mlimit_[3]; ///< Number of units in each direction to calc recip. sum. int maxmlim_; ///< The max of the three mlimit_ values. + int debug_; }; } } From 348b5ef11080645cf7ca526a797ecd56fe9bc057 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:06:33 -0400 Subject: [PATCH 153/218] Add setup --- src/Energy/Ewald_Recip.cpp | 29 +++++++++++++++++++++++++++++ src/Energy/Ewald_Recip.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 927ae38002..c3e447da9e 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -6,6 +6,7 @@ #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Matrix_3x3.h" +#include "../StringRoutines.h" // ByteString #include "../Vec3.h" #include // sqrt #include // std::max @@ -154,3 +155,31 @@ void Ewald_Recip::PrintRecipOpts() const { //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); mprintf("\t mlimits= {%i,%i,%i} Max=%i\n", mlimit_[0], mlimit_[1], mlimit_[2], maxmlim_); } + +/** Setup trig tables for given number of selected atoms. */ +int Ewald_Recip::SetupRecip(int nselected) { + // Build exponential factors for use in structure factors. + // These arrays are laid out in 1D; value for each atom at each m, i.e. + // A0M0 A1M0 A2M0 ... ANM0 A0M1 ... ANMX + // Number of M values is the max + 1. + int mmax = maxmlim_ + 1; + unsigned int tsize = nselected * mmax; + cosf1_.assign( tsize, 1.0 ); + cosf2_.assign( tsize, 1.0 ); + cosf3_.assign( tsize, 1.0 ); + sinf1_.assign( tsize, 0.0 ); + sinf2_.assign( tsize, 0.0 ); + sinf3_.assign( tsize, 0.0 ); + mprintf("\tMemory used by trig tables: %s\n", + ByteString(6*tsize*sizeof(double), BYTE_DECIMAL).c_str()); + // M0 +// for (int i = 0; i != maskIn.Nselected(); i++) { +// cosf1_.push_back( 1.0 ); +// cosf2_.push_back( 1.0 ); +// cosf3_.push_back( 1.0 ); +// sinf1_.push_back( 0.0 ); +// sinf2_.push_back( 0.0 ); +// sinf3_.push_back( 0.0 ); +// } + return 0; +} diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index 3b632032e2..cd4d7dbf3e 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -16,6 +16,8 @@ class Ewald_Recip { int InitRecip(EwaldOptions const&, EwaldParams const&, Box const&, int); void PrintRecipOpts() const; + /// Set up trig tables for the given number of selected atoms + int SetupRecip(int); private: typedef std::vector Darray; From d6fcccfa888c5205749636ad99513a29607d0117 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:08:06 -0400 Subject: [PATCH 154/218] Finish setup --- src/Energy/Ewald_Recip.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index c3e447da9e..3e26ec9d96 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -181,5 +181,41 @@ int Ewald_Recip::SetupRecip(int nselected) { // sinf2_.push_back( 0.0 ); // sinf3_.push_back( 0.0 ); // } +# ifdef _OPENMP + // Pre-calculate m1 and m2 indices + mlim1_.clear(); + mlim2_.clear(); + multCut_ = 0; + for (int m1 = 0; m1 <= mlimit_[0]; m1++) { + for (int m2 = -mlimit_[1]; m2 <= mlimit_[1]; m2++) { + mlim1_.push_back( m1 ); + mlim2_.push_back( m2 ); + } + // After this index (end of m1 == 0) multiplier must be 2.0 + if (m1 == 0) + multCut_ = (int)mlim1_.size(); + } + // Each thread will need its own space for trig math + int numthreads; +# pragma omp parallel + { +# pragma omp master + { + numthreads = omp_get_num_threads(); + mprintf("\tParallelizing calculation with %i threads\n", numthreads); + } + } + unsigned int asize = (unsigned int)nselected * (unsigned int)numthreads; + c12_.resize( asize ); + s12_.resize( asize ); + c3_.resize( asize ); + s3_.resize( asize ); +#else /* _OPENMP */ + c12_.resize( nselected ); + s12_.resize( nselected ); + c3_.resize( nselected ); + s3_.resize( nselected ); +# endif /* _OPENMP */ + return 0; } From 231bb28392a3dd4afce221f4ad956a71c4835e2a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:17:45 -0400 Subject: [PATCH 155/218] Finish regular recip calc --- src/Energy/Ewald_Recip.cpp | 163 ++++++++++++++++++++++++++++++++++++- src/Energy/Ewald_Recip.h | 18 ++-- 2 files changed, 173 insertions(+), 8 deletions(-) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 3e26ec9d96..73d978144f 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -1,6 +1,6 @@ #include "Ewald_Recip.h" #include "ErfcFxn.h" // erfc_func -#include "EwaldParams.h" +#include "EwaldParams.h" // INVSQRTPI #include "../Box.h" #include "../Constants.h" #include "../CpptrajStdio.h" @@ -22,6 +22,7 @@ Ewald_Recip::Ewald_Recip() : # ifdef _OPENMP multCut_(0), # endif + ew_coeff_(0.0), maxexp_(0.0), rsumTol_(0.0), maxmlim_(0) @@ -104,12 +105,13 @@ void Ewald_Recip::GetMlimits(int* mlimit, double maxexp, double eigmin, } /** Init */ -int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, EwaldParams const& ewParams, +int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, double ew_coeffIn, Box const& boxIn, int debugIn) { debug_ = debugIn; rsumTol_ = ewOpts.RsumTol(); maxexp_ = ewOpts.MaxExp(); + ew_coeff_ = ew_coeffIn; mlimit_[0] = ewOpts.Mlimits1(); mlimit_[1] = ewOpts.Mlimits2(); mlimit_[2] = ewOpts.Mlimits3(); @@ -128,13 +130,14 @@ int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, EwaldParams const& ewPara } // Set defaults if necessary + ew_coeff_ = ew_coeffIn; if (rsumTol_ < Constants::SMALL) rsumTol_ = 5E-5; if (maxmlim_ > 0) maxexp_ = FindMaxexpFromMlim(mlimit_, boxIn.FracCell()); else { if ( maxexp_ < Constants::SMALL ) - maxexp_ = FindMaxexpFromTol(ewParams.EwaldCoeff(), rsumTol_); + maxexp_ = FindMaxexpFromTol(ew_coeff_, rsumTol_); // eigmin typically bigger than this unless cell is badly distorted. double eigmin = 0.5; // Calculate lengths of reciprocal vectors @@ -219,3 +222,157 @@ int Ewald_Recip::SetupRecip(int nselected) { return 0; } + +/** Reciprocal space energy counteracting the neutralizing charge distribution. */ +double Ewald_Recip::Recip_Regular(Matrix_3x3 const& recip, double volume, + Varray const& Frac, Darray const& Charge) +{ + t_recip_.Start(); + double fac = (Constants::PI*Constants::PI) / (ew_coeff_ * ew_coeff_); + double maxexp2 = maxexp_ * maxexp_; + double ene = 0.0; + // Number of M values is the max + 1. + int mmax = maxmlim_ + 1; + // Build exponential factors for use in structure factors. + // These arrays are laid out in 1D; value for each atom at each m, i.e. + // A0M0 A1M0 A2M0 ... ANM0 A0M1 ... ANMX + // M0 is done in EwaldSetup() + t_trig_tables_.Start(); + unsigned int mnidx = Frac.size(); + // M1 + for (unsigned int i = 0; i != Frac.size(); i++, mnidx++) { + //mprintf("FRAC: %6i%20.10f%20.10f%20.10f\n", i+1, Frac[i][0], Frac[i][1], Frac[i][2]); + cosf1_[mnidx] = cos(Constants::TWOPI * Frac[i][0]); + cosf2_[mnidx] = cos(Constants::TWOPI * Frac[i][1]); + cosf3_[mnidx] = cos(Constants::TWOPI * Frac[i][2]); + sinf1_[mnidx] = sin(Constants::TWOPI * Frac[i][0]); + sinf2_[mnidx] = sin(Constants::TWOPI * Frac[i][1]); + sinf3_[mnidx] = sin(Constants::TWOPI * Frac[i][2]); + } + // M2-MX + // Get the higher factors by recursion using trig addition rules. + // Negative values of M by complex conjugation, or even cosf, odd sinf. + // idx will always point to M-1 values + unsigned int idx = Frac.size(); + for (int m = 2; m < mmax; m++) { + // Set m1idx to beginning of M1 values. + unsigned int m1idx = Frac.size(); + for (unsigned int i = 0; i != Frac.size(); i++, idx++, m1idx++, mnidx++) { + cosf1_[mnidx] = cosf1_[idx]*cosf1_[m1idx] - sinf1_[idx]*sinf1_[m1idx]; + cosf2_[mnidx] = cosf2_[idx]*cosf2_[m1idx] - sinf2_[idx]*sinf2_[m1idx]; + cosf3_[mnidx] = cosf3_[idx]*cosf3_[m1idx] - sinf3_[idx]*sinf3_[m1idx]; + sinf1_[mnidx] = sinf1_[idx]*cosf1_[m1idx] + cosf1_[idx]*sinf1_[m1idx]; + sinf2_[mnidx] = sinf2_[idx]*cosf2_[m1idx] + cosf2_[idx]*sinf2_[m1idx]; + sinf3_[mnidx] = sinf3_[idx]*cosf3_[m1idx] + cosf3_[idx]*sinf3_[m1idx]; + } + } + // DEBUG +/* unsigned int midx = 0; + for (int m = 0; m != mmax; m++) { + for (unsigned int i = 0; i != Frac.size(); i++, midx++) + mprintf("TRIG: %6i%6u%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f\n", m,i+1, + cosf1_[midx], cosf2_[midx], cosf3_[midx], + sinf1_[midx], sinf2_[midx], sinf3_[midx]); + }*/ + t_trig_tables_.Stop(); +# ifdef _OPENMP + double mult; + unsigned int offset; + int mlim_idx; + int mlim_end = (int)mlim1_.size(); + double *c12, *s12, *c3, *s3; +# pragma omp parallel private(mult,mlim_idx,c12,s12,c3,s3,offset) reduction(+:ene) + { + offset = (unsigned int)omp_get_thread_num() * Frac.size(); + c12 = &c12_[0] + offset; + s12 = &s12_[0] + offset; + c3 = &c3_[0] + offset; + s3 = &s3_[0] + offset; +# pragma omp for + for (mlim_idx = 0; mlim_idx < mlim_end; mlim_idx++) + { + if (mlim_idx < multCut_) + mult = 1.0; + else + mult = 2.0; + int m1 = mlim1_[mlim_idx]; + int m2 = mlim2_[mlim_idx]; +# else + Darray& c12 = c12_; + Darray& s12 = s12_; + Darray& c3 = c3_; + Darray& s3 = s3_; + double mult = 1.0; + for (int m1 = 0; m1 <= mlimit_[0]; m1++) + { + for (int m2 = -mlimit_[1]; m2 <= mlimit_[1]; m2++) + { +# endif + int m1idx = Frac.size() * m1; + int m2idx = Frac.size() * IABS(m2); + + if (m2 < 0) { + for (unsigned int i = 0; i != Frac.size(); i++, m1idx++, m2idx++) { + c12[i] = cosf1_[m1idx]*cosf2_[m2idx] + sinf1_[m1idx]*sinf2_[m2idx]; + s12[i] = sinf1_[m1idx]*cosf2_[m2idx] - cosf1_[m1idx]*sinf2_[m2idx]; + } + } else { + for (unsigned int i = 0; i != Frac.size(); i++, m1idx++, m2idx++) { + c12[i] = cosf1_[m1idx]*cosf2_[m2idx] - sinf1_[m1idx]*sinf2_[m2idx]; + s12[i] = sinf1_[m1idx]*cosf2_[m2idx] + cosf1_[m1idx]*sinf2_[m2idx]; + } + } + for (int m3 = -mlimit_[2]; m3 <= mlimit_[2]; m3++) + { + // Columns of recip are reciprocal unit cell vecs, so + // mhat contains Cartesian components of recip vector M. + Vec3 mhat = recip.TransposeMult( Vec3(m1, m2, m3) ); + double msq = mhat.Magnitude2(); + double denom = Constants::PI * volume * msq; + double eterm = 0.0; +// double vterm = 0.0; + if ( m1*m1 + m2*m2 + m3*m3 > 0 ) { + eterm = exp(-fac*msq) / denom; +// vterm = 2.0 * (fac*msq + 1.0) / msq; + } + // mult takes care to double count for symmetry. Can take care of + // with eterm. + eterm *= mult; + if (msq < maxexp2) { + int m3idx = Frac.size() * IABS(m3); + // Get the product of complex exponentials. + if (m3 < 0) { + for (unsigned int i = 0; i != Frac.size(); i++, m3idx++) { + c3[i] = c12[i]*cosf3_[m3idx] + s12[i]*sinf3_[m3idx]; + s3[i] = s12[i]*cosf3_[m3idx] - c12[i]*sinf3_[m3idx]; + } + } else { + for (unsigned int i = 0; i != Frac.size(); i++, m3idx++) { + c3[i] = c12[i]*cosf3_[m3idx] - s12[i]*sinf3_[m3idx]; + s3[i] = s12[i]*cosf3_[m3idx] + c12[i]*sinf3_[m3idx]; + } + } + // Get the structure factor + double cstruct = 0.0; + double sstruct = 0.0; + for (unsigned int i = 0; i != Frac.size(); i++) { + cstruct += Charge[i] * c3[i]; + sstruct += Charge[i] * s3[i]; + } + double struc2 = cstruct*cstruct + sstruct*sstruct; + ene += eterm * struc2; + //mprintf("LOOP: %3i%3i%3i ENE= %20.10f\n", m1, m2, m3, ene); + } // END IF msq < maxexp2 + } // END loop over m3 +# ifdef _OPENMP + } // END loop over mlim_idx + } // END pragma omp parallel +# else + } // END loop over m2 + mult = 2.0; + } // END loop over m1 +# endif + t_recip_.Stop(); + return ene * 0.5; +} + diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index cd4d7dbf3e..51fe663dee 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -1,26 +1,30 @@ #ifndef INC_ENERGY_EWALD_RECIP_H #define INC_ENERGY_EWALD_RECIP_H #include +#include "../Timer.h" class Box; class EwaldOptions; class Matrix_3x3; class Vec3; namespace Cpptraj { namespace Energy { -class EwaldParams; /// For calculating reciprocal space energy using the "regular" Ewald summation class Ewald_Recip { public: - Ewald_Recip(); + typedef std::vector Darray; + typedef std::vector Varray; + Ewald_Recip(); - int InitRecip(EwaldOptions const&, EwaldParams const&, Box const&, int); + /// Init with options, Ewald coeff, box, debug + int InitRecip(EwaldOptions const&, double, Box const&, int); + /// print options to stdout void PrintRecipOpts() const; /// Set up trig tables for the given number of selected atoms int SetupRecip(int); + /// Regular Ewald recip energy (unit cell vecs, volume, frac coords, charges) + double Recip_Regular(Matrix_3x3 const&, double, Varray const&, Darray const&); private: - typedef std::vector Darray; - /// Determine max length for reciprocal calcs based on reciprocal limits static double FindMaxexpFromMlim(const int*, Matrix_3x3 const&); /// Determine max length for reciprocal calcs based on Ewald coefficient and recip tol. @@ -45,11 +49,15 @@ class Ewald_Recip { Iarray mlim2_; ///< Hold m2 reciprocal indices int multCut_; ///< Hold index after which multiplier should be 2.0. # endif + double ew_coeff_; ///< Ewald coefficient double maxexp_; ///< Determines how far out recip vectors go? TODO check! double rsumTol_; ///< Reciprocal space sum tolerance. int mlimit_[3]; ///< Number of units in each direction to calc recip. sum. int maxmlim_; ///< The max of the three mlimit_ values. int debug_; + + Timer t_recip_; ///< Recip calc timer + Timer t_trig_tables_; ///< Trig tables calc timer }; } } From 890d2e64043e1a5b99c117455cb8e4799277f5b9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:19:46 -0400 Subject: [PATCH 156/218] Add timing --- src/Energy/Ewald_Recip.cpp | 5 +++++ src/Energy/Ewald_Recip.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 73d978144f..4b13bb054d 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -376,3 +376,8 @@ double Ewald_Recip::Recip_Regular(Matrix_3x3 const& recip, double volume, return ene * 0.5; } +void Ewald_Recip::PrintTiming(double total) const { + t_recip_.WriteTiming(2, "Recip: ", total); + if (t_trig_tables_.Total() > 0.0) + t_trig_tables_.WriteTiming(3, "Calc trig tables:", t_recip_.Total()); +} diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index 51fe663dee..ce5db1e474 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -24,6 +24,8 @@ class Ewald_Recip { int SetupRecip(int); /// Regular Ewald recip energy (unit cell vecs, volume, frac coords, charges) double Recip_Regular(Matrix_3x3 const&, double, Varray const&, Darray const&); + /// Print timing + void PrintTiming(double) const; private: /// Determine max length for reciprocal calcs based on reciprocal limits static double FindMaxexpFromMlim(const int*, Matrix_3x3 const&); From 1799e401940d750903109004c317811cd0c26a13 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:20:30 -0400 Subject: [PATCH 157/218] Update docs --- src/Energy/Ewald_Recip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 4b13bb054d..509f79303f 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -8,7 +8,7 @@ #include "../Matrix_3x3.h" #include "../StringRoutines.h" // ByteString #include "../Vec3.h" -#include // sqrt +#include // sqrt, cos, sin #include // std::max using namespace Cpptraj::Energy; From 5298f0d8716dbb5db79d339f43b99ae8d77b903e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 10:26:01 -0400 Subject: [PATCH 158/218] No need to save ewald coeff, just calculate the factor in Init --- src/Energy/Ewald_Recip.cpp | 10 ++++------ src/Energy/Ewald_Recip.h | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 509f79303f..09f8b9c8f9 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -22,7 +22,7 @@ Ewald_Recip::Ewald_Recip() : # ifdef _OPENMP multCut_(0), # endif - ew_coeff_(0.0), + fac_(0.0), maxexp_(0.0), rsumTol_(0.0), maxmlim_(0) @@ -111,7 +111,7 @@ int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, double ew_coeffIn, debug_ = debugIn; rsumTol_ = ewOpts.RsumTol(); maxexp_ = ewOpts.MaxExp(); - ew_coeff_ = ew_coeffIn; + fac_ = (Constants::PI*Constants::PI) / (ew_coeffIn * ew_coeffIn); mlimit_[0] = ewOpts.Mlimits1(); mlimit_[1] = ewOpts.Mlimits2(); mlimit_[2] = ewOpts.Mlimits3(); @@ -130,14 +130,13 @@ int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, double ew_coeffIn, } // Set defaults if necessary - ew_coeff_ = ew_coeffIn; if (rsumTol_ < Constants::SMALL) rsumTol_ = 5E-5; if (maxmlim_ > 0) maxexp_ = FindMaxexpFromMlim(mlimit_, boxIn.FracCell()); else { if ( maxexp_ < Constants::SMALL ) - maxexp_ = FindMaxexpFromTol(ew_coeff_, rsumTol_); + maxexp_ = FindMaxexpFromTol(ew_coeffIn, rsumTol_); // eigmin typically bigger than this unless cell is badly distorted. double eigmin = 0.5; // Calculate lengths of reciprocal vectors @@ -228,7 +227,6 @@ double Ewald_Recip::Recip_Regular(Matrix_3x3 const& recip, double volume, Varray const& Frac, Darray const& Charge) { t_recip_.Start(); - double fac = (Constants::PI*Constants::PI) / (ew_coeff_ * ew_coeff_); double maxexp2 = maxexp_ * maxexp_; double ene = 0.0; // Number of M values is the max + 1. @@ -332,7 +330,7 @@ double Ewald_Recip::Recip_Regular(Matrix_3x3 const& recip, double volume, double eterm = 0.0; // double vterm = 0.0; if ( m1*m1 + m2*m2 + m3*m3 > 0 ) { - eterm = exp(-fac*msq) / denom; + eterm = exp(-fac_*msq) / denom; // vterm = 2.0 * (fac*msq + 1.0) / msq; } // mult takes care to double count for symmetry. Can take care of diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index ce5db1e474..f4b97a7d9f 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -51,7 +51,7 @@ class Ewald_Recip { Iarray mlim2_; ///< Hold m2 reciprocal indices int multCut_; ///< Hold index after which multiplier should be 2.0. # endif - double ew_coeff_; ///< Ewald coefficient + double fac_; ///< Hold (PI^2) / (Ewald coefficient)^2 double maxexp_; ///< Determines how far out recip vectors go? TODO check! double rsumTol_; ///< Reciprocal space sum tolerance. int mlimit_[3]; ///< Number of units in each direction to calc recip. sum. From 8a7f2e059377088560219dd7dd4875a731fc3f4a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 11:35:42 -0400 Subject: [PATCH 159/218] Start regular Ewald calc class --- src/Energy/EwaldCalc_Regular.cpp | 33 ++++++++++++++++++++++++++++++++ src/Energy/EwaldCalc_Regular.h | 28 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/Energy/EwaldCalc_Regular.cpp create mode 100644 src/Energy/EwaldCalc_Regular.h diff --git a/src/Energy/EwaldCalc_Regular.cpp b/src/Energy/EwaldCalc_Regular.cpp new file mode 100644 index 0000000000..d18880bcb9 --- /dev/null +++ b/src/Energy/EwaldCalc_Regular.cpp @@ -0,0 +1,33 @@ +#include "EwaldCalc_Regular.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" +#include "../Frame.h" +#include "../PairListTemplate.h" + +using namespace Cpptraj::Energy; + +EwaldCalc_Regular::EwaldCalc_Regular() +{} + +/** Set up regular Ewald parameters. */ +int EwaldCalc_Regular::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + // Sanity check + if (pmeOpts.Type() == EwaldOptions::PME) { + mprinterr("Internal Error: Options were set up for PME only.\n"); + return 1; + } + mprintf("\tRegular Ewald params:\n"); + if (NBengine_.ModifyEwaldParams().InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: Ewald calculation init failed.\n"); + return 1; + } + VDW_LR_.SetDebug( debugIn ); + if (Recip_.InitRecip(pmeOpts, NBengine_.EwaldParams().EwaldCoeff(), boxIn, debugIn)) { + mprinterr("Error: Ewald recip init failed.\n"); + return 1; + } + + return 0; +} + diff --git a/src/Energy/EwaldCalc_Regular.h b/src/Energy/EwaldCalc_Regular.h new file mode 100644 index 0000000000..d7bde906d0 --- /dev/null +++ b/src/Energy/EwaldCalc_Regular.h @@ -0,0 +1,28 @@ +#ifndef INC_ENERGY_EWALDCALC_REGULAR_H +#define INC_ENERGY_EWALDCALC_REGULAR_H +#include "EwaldCalc.h" +#include "Ewald_Recip.h" +#include "VDW_LongRange_Correction.h" +#include "../PairListEngine_Ewald_LJLR.h" +namespace Cpptraj { +namespace Energy { +class EwaldCalc_Regular : public EwaldCalc { + public: + EwaldCalc_Regular(); + /// Init with Box, EwaldOptions and debug level + int Init(Box const&, EwaldOptions const&, int); + int Setup(Topology const&, AtomMask const&); + int CalcNonbondEnergy(Frame const&, AtomMask const&, + PairList const&, ExclusionArray const&, + double&, double&); + + void Timing(double) const; + private: + PairListEngine_Ewald_LJLR NBengine_; + Ewald_Recip Recip_; + VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction +}; +} +} + +#endif From 0a48302ad9f9b9b5847da3a5867fe1671ee7d042 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 12:35:09 -0400 Subject: [PATCH 160/218] Add setup --- src/Energy/EwaldCalc_Regular.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Energy/EwaldCalc_Regular.cpp b/src/Energy/EwaldCalc_Regular.cpp index d18880bcb9..aedbdeea15 100644 --- a/src/Energy/EwaldCalc_Regular.cpp +++ b/src/Energy/EwaldCalc_Regular.cpp @@ -31,3 +31,21 @@ int EwaldCalc_Regular::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int d return 0; } +/** Setup PME calculation. */ +int EwaldCalc_Regular::Setup(Topology const& topIn, AtomMask const& maskIn) { + if (NBengine_.ModifyEwaldParams().SetupEwald(topIn, maskIn)) { + mprinterr("Error: Ewald calculation setup failed.\n"); + return 1; + } + if (VDW_LR_.Setup_VDW_Correction( topIn, maskIn )) { + mprinterr("Error: Ewald calculation long range VDW correction setup failed.\n"); + return 1; + } + if (Recip_.SetupRecip( maskIn.Nselected() )) { + mprinterr("Error: Ewald calculation recip setup failed.\n"); + return 1; + } + + return 0; +} + From c9f7fe9167741bc53d963ed223153eb507a0e817 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 12:42:35 -0400 Subject: [PATCH 161/218] Finish regular ewald --- src/Energy/EwaldCalc_Regular.cpp | 49 ++++++++++++++++++++++++++++++++ src/Energy/EwaldParams.h | 4 +-- src/Energy/Ewald_Recip.h | 2 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Energy/EwaldCalc_Regular.cpp b/src/Energy/EwaldCalc_Regular.cpp index aedbdeea15..f92377acfb 100644 --- a/src/Energy/EwaldCalc_Regular.cpp +++ b/src/Energy/EwaldCalc_Regular.cpp @@ -49,3 +49,52 @@ int EwaldCalc_Regular::Setup(Topology const& topIn, AtomMask const& maskIn) { return 0; } +/** Calculate full nonbonded energy with regular Ewald */ +int EwaldCalc_Regular::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, + PairList const& pairList_, ExclusionArray const& Excluded_, + double& e_elec, double& e_vdw) +{ + t_total_.Start(); + double volume = frameIn.BoxCrd().CellVolume(); + double e_self = NBengine_.EwaldParams().SelfEnergy( volume ); + + // TODO make more efficient + //NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); + + double e_recip = Recip_.Recip_Regular( frameIn.BoxCrd().FracCell(), + volume, + pairList_.FracCoords(), + NBengine_.EwaldParams().Charge() ); + + double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); + + t_direct_.Start(); + Cpptraj::PairListTemplate(pairList_, Excluded_, + NBengine_.EwaldParams().Cut2(), NBengine_); + t_direct_.Stop(); + + if (NBengine_.EwaldParams().Debug() > 0) { + mprintf("DEBUG: Nonbond energy components:\n"); + mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + e_vdw_lr_correction ); + mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + + NBengine_.Eelec() + + NBengine_.Eadjust()); + mprintf("\n"); + mprintf(" E electrostatic (self) = %24.12f\n", e_self); + mprintf(" (rec) = %24.12f\n", e_recip); + mprintf(" (dir) = %24.12f\n", NBengine_.Eelec()); + mprintf(" (adj) = %24.12f\n", NBengine_.Eadjust()); + mprintf(" E vanDerWaals (dir) = %24.12f\n", NBengine_.Evdw()); + mprintf(" (LR) = %24.12f\n", e_vdw_lr_correction); + } + e_vdw = NBengine_.Evdw() + e_vdw_lr_correction; + e_elec = e_self + e_recip + NBengine_.Eelec() + NBengine_.Eadjust(); + t_total_.Stop(); + return 0; +} + +void EwaldCalc_Regular::Timing(double total) const { + t_total_.WriteTiming(1, " PME Total:", total); + Recip_.PrintTiming(t_total_.Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); +} diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index d3d41a8044..d92dedeeaf 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -66,6 +66,8 @@ class EwaldParams { double LJ_SwitchWidth() const { return switch_width_; } /// \return 1 / sqrt(PI) static const double INVSQRTPI() { return INVSQRTPI_; } + /// \return Charge array + std::vector const& Charge() const { return Charge_; } // FIXME do not return const because helPME needs the array to be non-const. Should be fixed std::vector& SelectedCharges() { return Charge_; } @@ -76,8 +78,6 @@ class EwaldParams { typedef std::vector Iarray; static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } - /// \return Charge array - Darray const& Charge() const { return Charge_; } /// Set Ewald parametsr, check them and set defaults if needed. int CheckInput(Box const&, int, double, double, double, double, double, double); diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index f4b97a7d9f..dcfca82024 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -22,7 +22,7 @@ class Ewald_Recip { void PrintRecipOpts() const; /// Set up trig tables for the given number of selected atoms int SetupRecip(int); - /// Regular Ewald recip energy (unit cell vecs, volume, frac coords, charges) + /// Regular Ewald recip energy (fractional cell vecs, volume, frac coords, charges) double Recip_Regular(Matrix_3x3 const&, double, Varray const&, Darray const&); /// Print timing void PrintTiming(double) const; From 22d7eafdcc9e92d6ae8dee71eb704e6a87376c87 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 12:43:04 -0400 Subject: [PATCH 162/218] Add EwaldCalc_Regular and Ewald_Recip to build --- src/Energy/CMakeLists.txt | 2 ++ src/Energy/energydepend | 2 ++ src/Energy/energyfiles | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index f244070108..d41cbefd44 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -7,8 +7,10 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Decomp_PME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_PME.cpp + ${CMAKE_CURRENT_LIST_DIR}/EwaldCalc_Regular.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams.cpp ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp + ${CMAKE_CURRENT_LIST_DIR}/Ewald_Recip.cpp ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 68dbc935cb..956b122b90 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -5,7 +5,9 @@ EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h .. EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_Regular.o : EwaldCalc_Regular.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h EwaldCalc.h EwaldCalc_Regular.h Ewald_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h +Ewald_Recip.o : Ewald_Recip.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../StringRoutines.h ../Timer.h ../Vec3.h ErfcFxn.h EwaldParams.h Ewald_Recip.h PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index 4bd342ffb6..acc799bc74 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -7,7 +7,9 @@ ENERGY_SOURCES= \ EwaldCalc_Decomp_PME.cpp \ EwaldCalc_LJPME.cpp \ EwaldCalc_PME.cpp \ + EwaldCalc_Regular.cpp \ EwaldParams.cpp \ EwaldParams_LJPME.cpp \ + Ewald_Recip.cpp \ PME_Recip.cpp \ VDW_LongRange_Correction.cpp From 966e02d0936f74d821ea90083d148c7697b0d449 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 12:46:33 -0400 Subject: [PATCH 163/218] Add regular ewald to Ecalc_Nonbond --- src/Energy/Ecalc_Nonbond.cpp | 12 ++++++++++-- src/Energy/Ecalc_Nonbond.h | 2 +- src/Energy/energydepend | 2 +- src/cpptrajdepend | 4 +++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 80197e5fce..a051b97316 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,8 +1,9 @@ #include "Ecalc_Nonbond.h" -#include "EwaldCalc_PME.h" #include "EwaldCalc_LJPME.h" -#include "EwaldCalc_Decomp_PME.h" +#include "EwaldCalc_PME.h" +#include "EwaldCalc_Regular.h" #include "EwaldCalc_Decomp_LJPME.h" +#include "EwaldCalc_Decomp_PME.h" #include "../CharMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" @@ -51,6 +52,13 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, else calc_ = new EwaldCalc_LJPME(); break; + case REGULAR_EWALD : + if (decompose_energy_) { + mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): Cannot decompose regular Ewald calc.\n"); + return 1; + } else + calc_ = new EwaldCalc_Regular(); + break; case UNSPECIFIED : mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): No nonbonded calc type specified.\n"); return 1; diff --git a/src/Energy/Ecalc_Nonbond.h b/src/Energy/Ecalc_Nonbond.h index a98ae2a465..aa1c792cb8 100644 --- a/src/Energy/Ecalc_Nonbond.h +++ b/src/Energy/Ecalc_Nonbond.h @@ -13,7 +13,7 @@ class Ecalc_Nonbond { public: typedef std::vector Darray; - enum CalcType { SIMPLE = 0, PME, LJPME, UNSPECIFIED }; + enum CalcType { SIMPLE = 0, PME, LJPME, REGULAR_EWALD, UNSPECIFIED }; /// CONSTRUCTOR Ecalc_Nonbond(); /// DESTRUCTOR diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 956b122b90..77f95f9b6a 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,4 +1,4 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h EwaldCalc_Regular.h Ewald_Recip.h PME_Recip.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ecalc_Nonbond.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h diff --git a/src/cpptrajdepend b/src/cpptrajdepend index a18780f272..ac39ffe3fa 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,15 +277,17 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Regular.o : Energy/EwaldCalc_Regular.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Energy/Ewald_Recip.o : Energy/Ewald_Recip.cpp Box.h Constants.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/Ewald_Recip.h EwaldOptions.h Matrix_3x3.h Parallel.h ParameterTypes.h SplineFxnTable.h StringRoutines.h Timer.h Vec3.h Energy/PME_Recip.o : Energy/PME_Recip.cpp Box.h CpptrajStdio.h Energy/PME_Recip.h EwaldOptions.h Matrix_3x3.h Parallel.h Timer.h Vec3.h helpme_standalone.h Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h From 0092a1ba8e77f5a3660e14a97c5d4f171bdb7772 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 14:17:38 -0400 Subject: [PATCH 164/218] Add ability to test Ewald regular --- src/Action_PmeTest.cpp | 74 ++++++++++++++++++++++++++++-------------- src/Action_PmeTest.h | 2 ++ src/cpptrajdepend | 4 +-- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index 62634cd684..14d2b656c8 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -10,27 +10,42 @@ void Action_PmeTest::Help() const { mprintf("\t[ %s\n", EwaldOptions::KeywordsPME()); mprintf("\t %s\n", EwaldOptions::KeywordsCommon1()); mprintf("\t %s ]\n", EwaldOptions::KeywordsCommon2()); - mprintf("\t{orginal|new} [out ] [] []\n"); + mprintf("\t{{orginal|new|newljpme} | ewald {original|new}} [out ] [] []\n"); } // Action_PmeTest::Init() Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { debug_ = debugIn; - if (ewaldOpts_.GetOptions(EwaldOptions::PME, actionArgs, "pmetest")) { + EwaldOptions::OptType opt = EwaldOptions::PME; + if (actionArgs.hasKey("ewald")) + opt = EwaldOptions::REG_EWALD; + if (ewaldOpts_.GetOptions(opt, actionArgs, "pmetest")) { mprinterr("Error: Could not get Ewald options.\n"); return Action::ERR; } - if (actionArgs.hasKey("original")) - method_ = 0; - else if (actionArgs.hasKey("new")) - method_ = 1; - else if (actionArgs.hasKey("newljpme")) - method_ = 2; - else { - mprinterr("Error: Specify original, new, or newljpme.\n"); - return Action::ERR; + if (opt == EwaldOptions::PME) { + if (actionArgs.hasKey("original")) + method_ = 0; + else if (actionArgs.hasKey("new")) + method_ = 1; + else if (actionArgs.hasKey("newljpme")) + method_ = 2; + else { + mprinterr("Error: Specify original, new, or newljpme.\n"); + return Action::ERR; + } + } else { + if (actionArgs.hasKey("original")) + method_ = 3; + else if (actionArgs.hasKey("new")) + method_ = 4; + else { + mprinterr("Error: Specify original or new.\n"); + return Action::ERR; + } } + DataFile* outfile = init.DFL().AddDataFile( actionArgs.GetStringKey("out"), actionArgs ); if (Mask1_.SetMaskString( actionArgs.GetMaskNext() )) return Action::ERR; @@ -55,6 +70,10 @@ Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int mprintf("\tNew PME method.\n"); else if (method_ == 2) mprintf("\tNew LJPME method.\n"); + else if (method_ == 3) + mprintf("\tOriginal Ewald method.\n"); + else if (method_ == 4) + mprintf("\tNew Ewald method.\n"); ewaldOpts_.PrintOptions(); @@ -77,17 +96,22 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) if (PME0_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; PME0_.Setup( setup.Top(), Mask1_ ); - } else if (method_ == 1) { - if (NB_.InitNonbondCalc(Ecalc_Nonbond::PME, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) - return Action::ERR; - if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) - return Action::ERR; - } else if (method_ == 2) { - if (NB_.InitNonbondCalc(Ecalc_Nonbond::LJPME, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + } else if (method_ == 3) { + EWALD0_.Setup( setup.Top(), Mask1_ ); + } else { + Ecalc_Nonbond::CalcType opt = Ecalc_Nonbond::UNSPECIFIED; + if (method_ == 1) + opt = Ecalc_Nonbond::PME; + else if (method_ == 2) + opt = Ecalc_Nonbond::LJPME; + else if (method_ == 3) + opt = Ecalc_Nonbond::REGULAR_EWALD; + + if (NB_.InitNonbondCalc(opt, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) return Action::ERR; if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) return Action::ERR; - } + } return Action::OK; } @@ -99,9 +123,9 @@ Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) int err = 1; if (method_ == 0) { err = PME0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); - } else if (method_ == 1) { - err = NB_.NonbondEnergy(frm.Frm(), Mask1_, ene, ene2); - } else if (method_ == 2) { + } else if (method_ == 3) { + err = EWALD0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); + } else { err = NB_.NonbondEnergy(frm.Frm(), Mask1_, ene, ene2); } if (err != 0) return Action::ERR; @@ -114,8 +138,8 @@ Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) void Action_PmeTest::Print() { if (method_ == 0) PME0_.Timing(t_nb_.Total()); - else if (method_ == 1) - NB_.PrintTiming(t_nb_.Total()); - else if (method_ == 2) + else if (method_ == 3) + EWALD0_.Timing(t_nb_.Total()); + else NB_.PrintTiming(t_nb_.Total()); } diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h index fbb94a6029..820409b17f 100644 --- a/src/Action_PmeTest.h +++ b/src/Action_PmeTest.h @@ -3,6 +3,7 @@ #include "Action.h" #include "Energy/Ecalc_Nonbond.h" #include "Ewald_ParticleMesh.h" +#include "Ewald_Regular.h" #include "EwaldOptions.h" #include "Timer.h" /// @@ -18,6 +19,7 @@ class Action_PmeTest : public Action { void Print(); Ewald_ParticleMesh PME0_; + Ewald_Regular EWALD0_; Cpptraj::Energy::Ecalc_Nonbond NB_; EwaldOptions ewaldOpts_; AtomMask Mask1_; diff --git a/src/cpptrajdepend b/src/cpptrajdepend index ac39ffe3fa..2adf75267d 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -64,7 +64,7 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +191,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 91661095a5074e4ddcb7e3b80fc1fa5ffc1c1a9a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 14:37:50 -0400 Subject: [PATCH 165/218] Add missing init --- src/Action_PmeTest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index 14d2b656c8..e9c15b1fc5 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -97,6 +97,8 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) return Action::ERR; PME0_.Setup( setup.Top(), Mask1_ ); } else if (method_ == 3) { + if (EWALD0_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + return Action::ERR; EWALD0_.Setup( setup.Top(), Mask1_ ); } else { Ecalc_Nonbond::CalcType opt = Ecalc_Nonbond::UNSPECIFIED; From 064e6f293cfc26a51377271b98b08fcc651090c2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 8 Oct 2024 15:34:25 -0400 Subject: [PATCH 166/218] Need to look for method == 4. Improve error message. Fix timing message. --- src/Action_PmeTest.cpp | 2 +- src/Energy/Ecalc_Nonbond.cpp | 4 +++- src/Energy/EwaldCalc_Regular.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp index e9c15b1fc5..cd88d4b5d4 100644 --- a/src/Action_PmeTest.cpp +++ b/src/Action_PmeTest.cpp @@ -106,7 +106,7 @@ Action::RetType Action_PmeTest::Setup(ActionSetup& setup) opt = Ecalc_Nonbond::PME; else if (method_ == 2) opt = Ecalc_Nonbond::LJPME; - else if (method_ == 3) + else if (method_ == 4) opt = Ecalc_Nonbond::REGULAR_EWALD; if (NB_.InitNonbondCalc(opt, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index a051b97316..24878a6a05 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -99,8 +99,10 @@ int Ecalc_Nonbond::SetupNonbondCalc(Topology const& topIn, AtomMask const& maskI return 1; } if (calc_ != 0) { - if (calc_->Setup(topIn, maskIn)) + if (calc_->Setup(topIn, maskIn)) { + mprinterr("Error: Nonbonded calculation setup failed.\n"); return 1; + } } return 0; } diff --git a/src/Energy/EwaldCalc_Regular.cpp b/src/Energy/EwaldCalc_Regular.cpp index f92377acfb..f92f9449eb 100644 --- a/src/Energy/EwaldCalc_Regular.cpp +++ b/src/Energy/EwaldCalc_Regular.cpp @@ -94,7 +94,7 @@ int EwaldCalc_Regular::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& m } void EwaldCalc_Regular::Timing(double total) const { - t_total_.WriteTiming(1, " PME Total:", total); + t_total_.WriteTiming(1, " Ewald Total:", total); Recip_.PrintTiming(t_total_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } From 1e02fbf4c286c0c03e8cbaeb2684b5708181394b Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 9 Oct 2024 08:57:16 -0400 Subject: [PATCH 167/218] Fix reduction pragma --- src/PairListEngine_Ewald_Decomp_LJPME.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PairListEngine_Ewald_Decomp_LJPME.h b/src/PairListEngine_Ewald_Decomp_LJPME.h index 05fdf48d83..0a1fb53137 100644 --- a/src/PairListEngine_Ewald_Decomp_LJPME.h +++ b/src/PairListEngine_Ewald_Decomp_LJPME.h @@ -97,7 +97,7 @@ class PairListEngine_Ewald_Decomp_LJPME { lhs[idx] += rhs[idx]; } /// To allow reduction of the energy terms - void operator+=(PairListEngine_Ewald_LJPME const& rhs) { + void operator+=(PairListEngine_Ewald_Decomp_LJPME const& rhs) { Evdw_ += rhs.Evdw_; Eelec_ += rhs.Eelec_; Eadjust_ += rhs.Eadjust_; @@ -124,7 +124,7 @@ class PairListEngine_Ewald_Decomp_LJPME { Cpptraj::Energy::EwaldParams_LJPME EW_; ///< Hold Ewald parameters for LJPME }; #ifdef _OPENMP -#pragma omp declare reduction( + : PairListEngine_Ewald_LJPME : omp_out += omp_in ) initializer( omp_priv = omp_orig ) +#pragma omp declare reduction( + : PairListEngine_Ewald_Decomp_LJPME : omp_out += omp_in ) initializer( omp_priv = omp_orig ) #endif } // END namespace Cpptraj #endif From 521fdbb947b39a2f469d8b93446a98f217a5e209 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 9 Oct 2024 08:59:18 -0400 Subject: [PATCH 168/218] Fix OpenMP compile --- src/Energy/Ewald_Recip.cpp | 5 ++++- src/Energy/Ewald_Recip.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 09f8b9c8f9..1f7fdbdff7 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -9,7 +9,10 @@ #include "../StringRoutines.h" // ByteString #include "../Vec3.h" #include // sqrt, cos, sin -#include // std::max +#include // std::max +#ifdef _OPENMP +# include +#endif using namespace Cpptraj::Energy; diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index dcfca82024..8b40091c04 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -46,7 +46,7 @@ class Ewald_Recip { Darray c3_; Darray s3_; # ifdef _OPENMP - typedef Ewald::Iarray Iarray; + typedef std::vector Iarray; Iarray mlim1_; ///< Hold m1 reciprocal indices Iarray mlim2_; ///< Hold m2 reciprocal indices int multCut_; ///< Hold index after which multiplier should be 2.0. From 8a5e4f4f4590c4c643513614aa91797f56b3e2a3 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 9 Oct 2024 12:32:54 -0400 Subject: [PATCH 169/218] Introduce new constant COULOMBFACTOR to replace all separate instances of QFAC --- src/Action_GIST.cpp | 3 +-- src/Action_GIST.h | 1 - src/Action_Pairwise.cpp | 4 +--- src/Action_Pairwise.h | 1 - src/Constants.h | 2 ++ src/Energy.cpp | 10 ++++------ src/Energy.h | 1 - src/Energy/Ecalc_Nonbond.cpp | 6 ++---- src/Energy/EnergyDecomposer.cpp | 4 +--- src/Energy/EnergyDecomposer.h | 2 -- src/MdOpts.cpp | 4 ++-- src/PotentialTerm_Dihedral.cpp | 4 +--- 12 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/Action_GIST.cpp b/src/Action_GIST.cpp index 58929ea3be..37a2273dad 100644 --- a/src/Action_GIST.cpp +++ b/src/Action_GIST.cpp @@ -965,7 +965,6 @@ void Action_GIST::setSoluteSolvent(const Topology& top) const Vec3 Action_GIST::x_lab_ = Vec3(1.0, 0.0, 0.0); const Vec3 Action_GIST::y_lab_ = Vec3(0.0, 1.0, 0.0); const Vec3 Action_GIST::z_lab_ = Vec3(0.0, 0.0, 1.0); -const double Action_GIST::QFAC_ = Constants::ELECTOAMBER * Constants::ELECTOAMBER; const int Action_GIST::OFF_GRID_ = -1; const int Action_GIST::UNKNOWN_MOLECULE_ = -1; @@ -1023,7 +1022,7 @@ void Action_GIST::Ecalc(double rij2, double q1, double q2, NonbondType const& LJ double f6 = LJ.B() * r6; // B/r^6 Evdw = f12 - f6; // (A/r^12)-(B/r^6) // Coulomb - double qiqj = QFAC_ * q1 * q2; + double qiqj = Constants::COULOMBFACTOR * q1 * q2; Eelec = qiqj / rij; } diff --git a/src/Action_GIST.h b/src/Action_GIST.h index f8de4fa71a..5f01dcc867 100644 --- a/src/Action_GIST.h +++ b/src/Action_GIST.h @@ -184,7 +184,6 @@ class Action_GIST : public Action { static const Vec3 y_lab_; static const Vec3 z_lab_; static const double maxD_; - static const double QFAC_; static const int OFF_GRID_; ///< Value in atom_voxel_ that indicates atom is off the grid static const int UNKNOWN_MOLECULE_; diff --git a/src/Action_Pairwise.cpp b/src/Action_Pairwise.cpp index 92e0a6a0ef..5d809c41b5 100644 --- a/src/Action_Pairwise.cpp +++ b/src/Action_Pairwise.cpp @@ -43,8 +43,6 @@ void Action_Pairwise::Help() const { " and : Print both energies if both cutoffs are satisfied.\n"); } -const double Action_Pairwise::QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - // Action_Pairwise::Init() Action::RetType Action_Pairwise::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { @@ -369,7 +367,7 @@ void Action_Pairwise::NonbondEnergy(Frame const& frameIn, Topology const& parmIn //force=((12*f12)-(6*f6))*r2; // (12A/r^13)-(6B/r^7) //scalarmult(f,JI,F); // Coulomb energy - double qiqj = QFAC * parmIn[maskatom1].Charge() * parmIn[maskatom2].Charge(); + double qiqj = Constants::COULOMBFACTOR * parmIn[maskatom1].Charge() * parmIn[maskatom2].Charge(); double e_elec = qiqj / rij; Eelec_ += e_elec; // Coulomb Force diff --git a/src/Action_Pairwise.h b/src/Action_Pairwise.h index 6b27eb90da..3e6382a8bc 100644 --- a/src/Action_Pairwise.h +++ b/src/Action_Pairwise.h @@ -70,7 +70,6 @@ class Action_Pairwise: public Action { CpptrajFile* avgout_; ///< File for printing average energies PDBfile PdbOut_; ///< PDB with atoms colored by evdw/eelec CpptrajFile* Eout_; ///< Output file for atom energies. - static const double QFAC; ///< Convert charges to kcal/mol units bool scalePdbE_; ///< If true scale PDB energy each frame between 0 and 100 ExclusionArray Excluded0_; ///< Hold exclusion arrays for atoms selected by Mask0_ ExclusionArray ExcludedR_; ///< Hold exclusion arrays for atoms selected by RefMask_ diff --git a/src/Constants.h b/src/Constants.h index 2fc72e1f0e..f835a2aca2 100644 --- a/src/Constants.h +++ b/src/Constants.h @@ -58,6 +58,8 @@ namespace Constants { const double ELECTOAMBER = 18.2223; /// Convert Amber charge to electron charge const double AMBERTOELEC = 1.0 / ELECTOAMBER; + /// Calculate energy in kcal/mol from charge^2/Ang + const double COULOMBFACTOR = ELECTOAMBER * ELECTOAMBER; /// Convert from Amber internal units of time (1/20.455 ps) to ps. /** Amber operates in kcal/mol units for energy, amu for masses, * and Angstoms for distances. For convenience when calculating KE from diff --git a/src/Energy.cpp b/src/Energy.cpp index 44f6386bb0..72255af143 100644 --- a/src/Energy.cpp +++ b/src/Energy.cpp @@ -11,8 +11,6 @@ #include "Energy/Ene_Bond.h" #include "Energy/Ene_LJ_6_12.h" -const double Energy_Amber::QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - // CONSTRUCTOR Energy_Amber::Energy_Amber() : debug_(0) {} @@ -187,7 +185,7 @@ double Energy_Amber::Calc_14_Energy(Frame const& fIn, DihedralArray const& Dihed e_vdw /= dp.SCNB(); Evdw14 += e_vdw; // Coulomb - double qiqj = QFAC * tIn[d->A1()].Charge() * tIn[d->A4()].Charge(); + double qiqj = Constants::COULOMBFACTOR * tIn[d->A1()].Charge() * tIn[d->A4()].Charge(); double e_elec = qiqj / rij; e_elec /= dp.SCEE(); Eq14 += e_elec; @@ -246,7 +244,7 @@ double Energy_Amber::E_Nonbond(Frame const& fIn, Topology const& tIn, AtomMask c double e_vdw = f12 - f6; // (A/r^12)-(B/r^6)*/ Evdw += e_vdw; // Coulomb - double qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); + double qiqj = Constants::COULOMBFACTOR * tIn[atom1].Charge() * tIn[atom2].Charge(); double e_elec = qiqj / rij; Eelec += e_elec; # ifdef DEBUG_ENERGY @@ -349,7 +347,7 @@ double Energy_Amber::E_Elec(Frame const& fIn, Topology const& tIn, AtomMask cons double rij2 = DIST2_NoImage( crd1, fIn.XYZ( atom2 ) ); double rij = sqrt( rij2 ); // Coulomb - double qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); + double qiqj = Constants::COULOMBFACTOR * tIn[atom1].Charge() * tIn[atom2].Charge(); double e_elec = qiqj / rij; Eelec += e_elec; # ifdef DEBUG_ENERGY @@ -392,7 +390,7 @@ double Energy_Amber::E_DirectSum(Frame const& fIn, Topology const& tIn, AtomMask for (AtomMask::const_iterator atom2 = mask.begin(); atom2 != mask.end(); ++atom2) { Vec3 frac2 = fIn.BoxCrd().FracCell() * Vec3(fIn.XYZ( *atom2 )); // atom j in fractional coords - double qiqj = QFAC * tIn[*atom1].Charge() * tIn[*atom2].Charge(); + double qiqj = Constants::COULOMBFACTOR * tIn[*atom1].Charge() * tIn[*atom2].Charge(); // Loop over images of atom j for (std::vector::const_iterator ixyz = Cells.begin(); ixyz != Cells.end(); ++ixyz) { diff --git a/src/Energy.h b/src/Energy.h index 08d5e4c674..61a8b24eff 100644 --- a/src/Energy.h +++ b/src/Energy.h @@ -37,7 +37,6 @@ class Energy_Amber { double Calc_14_Energy(Frame const&, DihedralArray const&, DihedralParmArray const&, Topology const&, CharMask const&, double&); - static const double QFAC; int debug_; }; #endif diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 24878a6a05..73c12f56a2 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -115,8 +115,7 @@ int Ecalc_Nonbond::NonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, int err = 0; if (type_ == SIMPLE) { - static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - Ene_Nonbond(frameIn, *currentTop_, maskIn, Excluded_, QFAC, + Ene_Nonbond(frameIn, *currentTop_, maskIn, Excluded_, Constants::COULOMBFACTOR, e_elec, e_vdw); } else if (calc_ != 0) { if (pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), @@ -149,8 +148,7 @@ int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& int err = 0; if (type_ == SIMPLE) { - static const double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - Ene_Decomp_Nonbond(frameIn, *currentTop_, cmaskIn, Excluded_, QFAC, + Ene_Decomp_Nonbond(frameIn, *currentTop_, cmaskIn, Excluded_, Constants::COULOMBFACTOR, e_elec, e_vdw, atom_elec, atom_vdw); } else if (calc_ != 0) { // FIXME this is an unneeded atom mask. diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 3cdda2947d..27aa4c7880 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -16,8 +16,6 @@ using namespace Cpptraj::Energy; -const double EnergyDecomposer::QFAC_ = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - /** CONSTRUCTOR */ EnergyDecomposer::EnergyDecomposer() : eneOut_(0), @@ -290,7 +288,7 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { saveEne( dih->A4(), ene_half ); // 1-4 coulomb energy double rij = sqrt(rij2); - double qiqj = QFAC_ * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); + double qiqj = Constants::COULOMBFACTOR * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); double e_elec = qiqj / rij; e_elec /= DP.SCEE(); mprintf("DEBUG: E14 %f\n", e_elec); diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index e7d1e92ce0..45161dc8c7 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -34,8 +34,6 @@ class EnergyDecomposer { /// Finish the calculation by putting energies in output DataSet int FinishCalc(); private: - static const double QFAC_; ///< Coulomb prefactor - typedef std::vector Darray; typedef std::vector< Stats > EneArrayType; typedef std::vector BndArrayType; diff --git a/src/MdOpts.cpp b/src/MdOpts.cpp index 8f9eb4e559..1efe37e12b 100644 --- a/src/MdOpts.cpp +++ b/src/MdOpts.cpp @@ -9,7 +9,7 @@ MdOpts::MdOpts() : scaleNB_(1.0/2.0), // Amber default cutEE_(8.0), // in Ang., Amber default cutNB_(8.0), // in Ang., Amber default - qfac_(Constants::ELECTOAMBER * Constants::ELECTOAMBER), // Assume charges in elec. units, Amber default + qfac_(Constants::COULOMBFACTOR), // Assume charges in elec. units, Amber default nExclude_(4) // Exclude dihedral, angle, bond {} @@ -53,7 +53,7 @@ int MdOpts::GetOptsFromArgs(ArgList& argIn) } } nExclude_ = argIn.getKeyInt("nexclude", 4); - qfac_ = argIn.getKeyDouble("qfac", Constants::ELECTOAMBER * Constants::ELECTOAMBER); + qfac_ = argIn.getKeyDouble("qfac", Constants::COULOMBFACTOR); return 0; } diff --git a/src/PotentialTerm_Dihedral.cpp b/src/PotentialTerm_Dihedral.cpp index 5c92117498..5a8c578d01 100644 --- a/src/PotentialTerm_Dihedral.cpp +++ b/src/PotentialTerm_Dihedral.cpp @@ -65,8 +65,6 @@ void PotentialTerm_Dihedral::CalcForce(Frame& frameIn, CharMask const& maskIn) c double dr[13]; double dtx[7][13]; - double QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; - EnergyKernel_NonBond_Simple NB14; //mprintf("FCALC\n"); for (DihedralArray::const_iterator dih = activeDihs_.begin(); dih != activeDihs_.end(); ++dih) @@ -80,7 +78,7 @@ void PotentialTerm_Dihedral::CalcForce(Frame& frameIn, CharMask const& maskIn) c int nbindex = nonbond_->GetLJindex( A1.TypeIndex(), A4.TypeIndex() ); NonbondType const& LJ = nonbond_->NBarray( nbindex ); NB14.Calc_F_E( frameIn, dih->A1(), dih->A4(), LJ.A(), LJ.B(), - QFAC, A1.Charge(), A4.Charge(), + Constants::COULOMBFACTOR, A1.Charge(), A4.Charge(), 1.0/DP.SCNB(), 1.0/DP.SCEE(), maskIn, *Enb14_, *Eq14_); } From 190f17f6f48fa11f3e3f5f9f712e5ccdcbbbbf34 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 9 Oct 2024 13:21:48 -0400 Subject: [PATCH 170/218] Start adding ifdefs --- src/Energy/Ecalc_Nonbond.cpp | 9 ++++++++- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 2 ++ src/Energy/EwaldCalc_Decomp_LJPME.h | 2 ++ src/Energy/EwaldCalc_Decomp_PME.cpp | 2 ++ src/Energy/EwaldCalc_Decomp_PME.h | 2 ++ src/Energy/EwaldCalc_LJPME.cpp | 2 ++ src/Energy/EwaldCalc_LJPME.h | 2 ++ src/Energy/EwaldCalc_PME.cpp | 2 ++ src/Energy/EwaldCalc_PME.h | 2 ++ 9 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index 73c12f56a2..d1d26eb7a7 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,9 +1,11 @@ #include "Ecalc_Nonbond.h" +#include "EwaldCalc_Regular.h" +#ifdef LIBPME #include "EwaldCalc_LJPME.h" #include "EwaldCalc_PME.h" -#include "EwaldCalc_Regular.h" #include "EwaldCalc_Decomp_LJPME.h" #include "EwaldCalc_Decomp_PME.h" +#endif #include "../CharMask.h" #include "../CpptrajStdio.h" #include "../EwaldOptions.h" @@ -40,6 +42,7 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, switch (type_) { case SIMPLE : break; +# ifdef LIBPME case PME : if (decompose_energy_) calc_ = new EwaldCalc_Decomp_PME(); @@ -52,6 +55,10 @@ int Ecalc_Nonbond::InitNonbondCalc(CalcType typeIn, bool decompose_energyIn, else calc_ = new EwaldCalc_LJPME(); break; +# else + case PME : mprinterr("Error: PME requires compiling with LIBPME (FFTW3 and C++11 support).\n"); return 1; + case LJPME : mprinterr("Error: LJPME requires compiling with LIBPME (FFTW3 and C++11 support).\n"); return 1; +# endif case REGULAR_EWALD : if (decompose_energy_) { mprinterr("Internal Error: Ecalc_Nonbond::InitNonbondCalc(): Cannot decompose regular Ewald calc.\n"); diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index 01a4d5d8a3..13bb3f9bb2 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -1,4 +1,5 @@ #include "EwaldCalc_Decomp_LJPME.h" +#ifdef LIBPME #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Frame.h" @@ -144,3 +145,4 @@ void EwaldCalc_Decomp_LJPME::Timing(double total) const { //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } +#endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.h b/src/Energy/EwaldCalc_Decomp_LJPME.h index e1ef3ecdef..fa5fd8feb4 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.h +++ b/src/Energy/EwaldCalc_Decomp_LJPME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_EWALDCALC_DECOMP_LJPME_H #define INC_ENERGY_EWALDCALC_DECOMP_LJPME_H +#ifdef LIBPME #include "EwaldCalc_Decomp.h" #include "PME_Recip.h" #include "../PairListEngine_Ewald_Decomp_LJPME.h" @@ -24,3 +25,4 @@ class EwaldCalc_Decomp_LJPME : public EwaldCalc_Decomp { } } #endif +#endif diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index fc4989aac1..54a9e1c1cd 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -1,4 +1,5 @@ #include "EwaldCalc_Decomp_PME.h" +#ifdef LIBPME #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Frame.h" @@ -123,3 +124,4 @@ void EwaldCalc_Decomp_PME::Timing(double total) const { Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } +#endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index 1be87c90a0..83344b85be 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_EWALDCALC_DECOMP_PME_H #define INC_ENERGY_EWALDCALC_DECOMP_PME_H +#ifdef LIBPME #include "EwaldCalc_Decomp.h" #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" @@ -22,4 +23,5 @@ class EwaldCalc_Decomp_PME : public EwaldCalc_Decomp { }; } } +#endif /* LIBPME */ #endif diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index 58b7b2d4fb..8b34f7a2ba 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -1,4 +1,5 @@ #include "EwaldCalc_LJPME.h" +#ifdef LIBPME #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Frame.h" @@ -111,3 +112,4 @@ void EwaldCalc_LJPME::Timing(double total) const { //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } +#endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_LJPME.h b/src/Energy/EwaldCalc_LJPME.h index 7f8a5068f3..9a5cf8a272 100644 --- a/src/Energy/EwaldCalc_LJPME.h +++ b/src/Energy/EwaldCalc_LJPME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_EWALDCALC_LJPME_H #define INC_ENERGY_EWALDCALC_LJPME_H +#ifdef LIBPME #include "EwaldCalc.h" #include "PME_Recip.h" #include "../PairListEngine_Ewald_LJPME.h" @@ -24,3 +25,4 @@ class EwaldCalc_LJPME : public EwaldCalc { } } #endif +#endif diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index 8ce28e794d..b8f9f61b7c 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -1,4 +1,5 @@ #include "EwaldCalc_PME.h" +#ifdef LIBPME #include "../CpptrajStdio.h" #include "../EwaldOptions.h" #include "../Frame.h" @@ -119,3 +120,4 @@ void EwaldCalc_PME::Timing(double total) const { // t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); //# endif } +#endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_PME.h b/src/Energy/EwaldCalc_PME.h index 04cb8dcaa2..367a1b2d1b 100644 --- a/src/Energy/EwaldCalc_PME.h +++ b/src/Energy/EwaldCalc_PME.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_EWALDCALC_PME_H #define INC_ENERGY_EWALDCALC_PME_H +#ifdef LIBPME #include "EwaldCalc.h" #include "PME_Recip.h" #include "VDW_LongRange_Correction.h" @@ -25,3 +26,4 @@ class EwaldCalc_PME : public EwaldCalc { } } #endif +#endif From 60770df08eac95e0efb2e78fde43e6cbdc4b2680 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 9 Oct 2024 13:52:13 -0400 Subject: [PATCH 171/218] Start splitting off the direct sum routines --- src/Energy/Ene_Elec.h | 57 +++++++++++++++++++++++++++++++++++++ src/Energy/Ene_Elec_Image.h | 49 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/Energy/Ene_Elec.h create mode 100644 src/Energy/Ene_Elec_Image.h diff --git a/src/Energy/Ene_Elec.h b/src/Energy/Ene_Elec.h new file mode 100644 index 0000000000..04048936e8 --- /dev/null +++ b/src/Energy/Ene_Elec.h @@ -0,0 +1,57 @@ +#ifndef INC_ENERGY_ENE_ELEC_H +#define INC_ENERGY_ENE_ELEC_H +namespace Cpptraj { +namespace Energy { +template +T Ene_Elec(Frame const& fIn, Topology const& tIn, AtomMask const& mask, ExclusionArray const& Excluded) +{ + T Eelec = 0.0; + int idx1; +# ifdef _OPENMP +# pragma omp parallel private(idx1) reduction(+ : Eelec) + { +# pragma omp for +# endif + for (idx1 = 0; idx1 < mask.Nselected(); idx1++) + { + int atom1 = mask[idx1]; + // Set up coord for this atom + const double* xyz1 = fIn.XYZ( atom1 ); + // Set up exclusion list for this atom + // TODO refactor inner loop to be like StructureCheck + ExclusionArray::ExListType::const_iterator excluded_idx = Excluded[idx1].begin(); + for (int idx2 = idx1 + 1; idx2 < mask.Nselected(); idx2++) + { + int atom2 = mask[idx2]; + // Advance excluded list up to current selected atom + while (excluded_idx != Excluded[idx1].end() && *excluded_idx < idx2) ++excluded_idx; + // If atom is excluded, just increment to next excluded atom. + if (excluded_idx != Excluded[idx1].end() && idx2 == *excluded_idx) + ++excluded_idx; + else { + const double* xyz2 = fIn.XYZ( atom2 ); + T x = xyz1[0] - xyz2[0]; + T y = xyz1[1] - xyz2[1]; + T z = xyz1[2] - xyz2[2]; + T rij2 = (x*x + y*y + z*z); + T rij = sqrt(rij2); + // Coulomb + T qiqj = Constants::COULOMBFACTOR * tIn[atom1].Charge() * tIn[atom2].Charge(); + T e_elec = qiqj / rij; + Eelec += e_elec; +# ifdef DEBUG_ENERGY + mprintf("\tEELEC %4i -- %4i: q1= %12.5e q2= %12.5e r= %12.5f E= %12.5e\n", + atom1+1, atom2+1, tIn[atom1].Charge(), tIn[atom2].Charge(), + rij, e_elec); +# endif + } + } + } +# ifdef _OPENMP + } // END omp parallel +# endif + return Eelec; +} +} +} +#endif diff --git a/src/Energy/Ene_Elec_Image.h b/src/Energy/Ene_Elec_Image.h new file mode 100644 index 0000000000..22b600bb76 --- /dev/null +++ b/src/Energy/Ene_Elec_Image.h @@ -0,0 +1,49 @@ +#ifndef INC_ENERGY_ENE_ELEC_IMAGE_H +#define INC_ENERGY_ENE_ELEC_IMAGE_H +namespace Cpptraj { +namespace Energy { +template +T Ene_Elec_Image(Frame const& fIn, Topology const& tIn, AtomMask const& mask, + ExclusionArray const& Excluded, + int n_points) +{ + // Sum over images. + T Eimage = 0.0; + // Cache npoints values, excluding this cell (0,0,0) + std::vector Cells; + int Ncells = (2*n_points)+1; + Cells.reserve( (Ncells*Ncells*Ncells) - 1 ); + for (int ix = -n_points; ix <= n_points; ix++) + for (int iy = -n_points; iy <= n_points; iy++) + for (int iz = -n_points; iz <= n_points; iz++) + if (ix != 0 || iy != 0 || iz != 0) + Cells.push_back( Vec3(ix, iy, iz) ); + // Outer loop over atoms (i) + for (AtomMask::const_iterator atom1 = mask.begin(); atom1 != mask.end(); ++atom1) + { +// mprintf("\nDEBUG: Atom %i\n", *atom1+1); + Vec3 T1( fIn.XYZ(*atom1) ); + // Inner loop over atoms (j) + for (AtomMask::const_iterator atom2 = mask.begin(); atom2 != mask.end(); ++atom2) + { + Vec3 frac2 = fIn.BoxCrd().FracCell() * Vec3(fIn.XYZ( *atom2 )); // atom j in fractional coords + T qiqj = Constants::COULOMBFACTOR * tIn[*atom1].Charge() * tIn[*atom2].Charge(); + // Loop over images of atom j + for (std::vector::const_iterator ixyz = Cells.begin(); ixyz != Cells.end(); ++ixyz) + { +// mprintf("DEBUG: Atom %4i to %4i Image %3i %3i %3i", *atom1+1, *atom2+1, ix, iy, iz); + // atom j image back in Cartesian space minus atom i in Cartesian space. + Vec3 dxyz = fIn.BoxCrd().UnitCell().TransposeMult(frac2 + *ixyz) - T1; + T rij2 = dxyz.Magnitude2(); + T rij = sqrt(rij2); +// mprintf(" Distance= %g\n", rij); + T e_elec = qiqj / rij; + Eimage += e_elec; + } + } // atom j + } // atom i + return (Eimage/2.0); +} +} +} +#endif From 2b102cddeba9c539c04aa4149943a4914dfbcb30 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 10 Oct 2024 06:53:38 -0400 Subject: [PATCH 172/218] Start removing old Ewald --- src/Action_PmeTest.cpp | 147 ---------- src/Action_PmeTest.h | 33 --- src/Command.cpp | 2 - src/Ewald.cpp | 574 ------------------------------------- src/Ewald.h | 142 --------- src/Ewald_ParticleMesh.cpp | 344 ---------------------- src/Ewald_ParticleMesh.h | 48 ---- src/Ewald_Regular.cpp | 412 -------------------------- src/Ewald_Regular.h | 48 ---- src/cpptrajdepend | 12 +- src/cpptrajfiles | 4 - 11 files changed, 4 insertions(+), 1762 deletions(-) delete mode 100644 src/Action_PmeTest.cpp delete mode 100644 src/Action_PmeTest.h delete mode 100644 src/Ewald.cpp delete mode 100644 src/Ewald.h delete mode 100644 src/Ewald_ParticleMesh.cpp delete mode 100644 src/Ewald_ParticleMesh.h delete mode 100644 src/Ewald_Regular.cpp delete mode 100644 src/Ewald_Regular.h diff --git a/src/Action_PmeTest.cpp b/src/Action_PmeTest.cpp deleted file mode 100644 index cd88d4b5d4..0000000000 --- a/src/Action_PmeTest.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "Action_PmeTest.h" -#include "CpptrajStdio.h" - -Action_PmeTest::Action_PmeTest() { - SetHidden(true); -} - -// Action_PmeTest::Help() -void Action_PmeTest::Help() const { - mprintf("\t[ %s\n", EwaldOptions::KeywordsPME()); - mprintf("\t %s\n", EwaldOptions::KeywordsCommon1()); - mprintf("\t %s ]\n", EwaldOptions::KeywordsCommon2()); - mprintf("\t{{orginal|new|newljpme} | ewald {original|new}} [out ] [] []\n"); -} - -// Action_PmeTest::Init() -Action::RetType Action_PmeTest::Init(ArgList& actionArgs, ActionInit& init, int debugIn) -{ - debug_ = debugIn; - EwaldOptions::OptType opt = EwaldOptions::PME; - if (actionArgs.hasKey("ewald")) - opt = EwaldOptions::REG_EWALD; - if (ewaldOpts_.GetOptions(opt, actionArgs, "pmetest")) { - mprinterr("Error: Could not get Ewald options.\n"); - return Action::ERR; - } - if (opt == EwaldOptions::PME) { - if (actionArgs.hasKey("original")) - method_ = 0; - else if (actionArgs.hasKey("new")) - method_ = 1; - else if (actionArgs.hasKey("newljpme")) - method_ = 2; - else { - mprinterr("Error: Specify original, new, or newljpme.\n"); - return Action::ERR; - } - } else { - if (actionArgs.hasKey("original")) - method_ = 3; - else if (actionArgs.hasKey("new")) - method_ = 4; - else { - mprinterr("Error: Specify original or new.\n"); - return Action::ERR; - } - } - - DataFile* outfile = init.DFL().AddDataFile( actionArgs.GetStringKey("out"), actionArgs ); - - if (Mask1_.SetMaskString( actionArgs.GetMaskNext() )) return Action::ERR; - std::string setname_ = actionArgs.GetStringNext(); - if (setname_.empty()) - setname_ = init.DSL().GenerateDefaultName("PME"); - ele_ = init.DSL().AddSet( DataSet::DOUBLE, MetaData(setname_, "ELE") ); - vdw_ = init.DSL().AddSet( DataSet::DOUBLE, MetaData(setname_, "VDW") ); - if (ele_ == 0 || vdw_ == 0) { - mprinterr("Error: Could not allocate data sets.\n"); - return Action::ERR; - } - if (outfile != 0) { - outfile->AddDataSet(ele_); - outfile->AddDataSet(vdw_); - } - - mprintf(" ENERGY: Calculating energy for atoms in mask '%s'\n", Mask1_.MaskString()); - if (method_ == 0) - mprintf("\tOriginal PME method.\n"); - else if (method_ == 1) - mprintf("\tNew PME method.\n"); - else if (method_ == 2) - mprintf("\tNew LJPME method.\n"); - else if (method_ == 3) - mprintf("\tOriginal Ewald method.\n"); - else if (method_ == 4) - mprintf("\tNew Ewald method.\n"); - - ewaldOpts_.PrintOptions(); - - return Action::OK; -} - -// Action_PmeTest::Setup() -Action::RetType Action_PmeTest::Setup(ActionSetup& setup) -{ - using namespace Cpptraj::Energy; - // Set up mask - if (setup.Top().SetupIntegerMask(Mask1_)) return Action::ERR; - if (Mask1_.None()) { - mprintf("Warning: Mask '%s' selects no atoms.\n", Mask1_.MaskString()); - return Action::SKIP; - } - Mask1_.MaskInfo(); - - if (method_ == 0) { - if (PME0_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) - return Action::ERR; - PME0_.Setup( setup.Top(), Mask1_ ); - } else if (method_ == 3) { - if (EWALD0_.Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) - return Action::ERR; - EWALD0_.Setup( setup.Top(), Mask1_ ); - } else { - Ecalc_Nonbond::CalcType opt = Ecalc_Nonbond::UNSPECIFIED; - if (method_ == 1) - opt = Ecalc_Nonbond::PME; - else if (method_ == 2) - opt = Ecalc_Nonbond::LJPME; - else if (method_ == 4) - opt = Ecalc_Nonbond::REGULAR_EWALD; - - if (NB_.InitNonbondCalc(opt, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) - return Action::ERR; - if (NB_.SetupNonbondCalc( setup.Top(), Mask1_ )) - return Action::ERR; - } - return Action::OK; -} - -// Action_PmeTest::DoAction() -Action::RetType Action_PmeTest::DoAction(int frameNum, ActionFrame& frm) -{ - t_nb_.Start(); - double ene, ene2; - int err = 1; - if (method_ == 0) { - err = PME0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); - } else if (method_ == 3) { - err = EWALD0_.CalcNonbondEnergy(frm.Frm(), Mask1_, ene, ene2); - } else { - err = NB_.NonbondEnergy(frm.Frm(), Mask1_, ene, ene2); - } - if (err != 0) return Action::ERR; - ele_->Add(frameNum, &ene); - vdw_->Add(frameNum, &ene2); - t_nb_.Stop(); - return Action::OK; -} - -void Action_PmeTest::Print() { - if (method_ == 0) - PME0_.Timing(t_nb_.Total()); - else if (method_ == 3) - EWALD0_.Timing(t_nb_.Total()); - else - NB_.PrintTiming(t_nb_.Total()); -} diff --git a/src/Action_PmeTest.h b/src/Action_PmeTest.h deleted file mode 100644 index 820409b17f..0000000000 --- a/src/Action_PmeTest.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef INC_ACTION_PMETEST_H -#define INC_ACTION_PMETEST_H -#include "Action.h" -#include "Energy/Ecalc_Nonbond.h" -#include "Ewald_ParticleMesh.h" -#include "Ewald_Regular.h" -#include "EwaldOptions.h" -#include "Timer.h" -/// -class Action_PmeTest : public Action { - public: - Action_PmeTest(); - DispatchObject* Alloc() const { return (DispatchObject*)new Action_PmeTest(); } - void Help() const; - private: - Action::RetType Init(ArgList&, ActionInit&, int); - Action::RetType Setup(ActionSetup&); - Action::RetType DoAction(int, ActionFrame&); - void Print(); - - Ewald_ParticleMesh PME0_; - Ewald_Regular EWALD0_; - Cpptraj::Energy::Ecalc_Nonbond NB_; - EwaldOptions ewaldOpts_; - AtomMask Mask1_; - DataSet* ele_; - DataSet* vdw_; - Timer t_nb_; - - int method_; - int debug_; -}; -#endif diff --git a/src/Command.cpp b/src/Command.cpp index 235c3f3d9e..b4c6b91013 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -165,7 +165,6 @@ #include "Action_MinMaxDist.h" #include "Action_AddAtom.h" #include "Action_EneDecomp.h" -#include "Action_PmeTest.h" // ----- ANALYSIS -------------------------------------------------------------- #include "Analysis_Hist.h" #include "Analysis_Corr.h" @@ -382,7 +381,6 @@ void Command::Init() { Command::AddCmd( new Action_Outtraj(), Cmd::ACT, 1, "outtraj" ); Command::AddCmd( new Action_PairDist(), Cmd::ACT, 1, "pairdist" ); Command::AddCmd( new Action_Pairwise(), Cmd::ACT, 1, "pairwise" ); - Command::AddCmd( new Action_PmeTest(), Cmd::ACT, 1, "pmetest" ); // hidden Command::AddCmd( new Action_Principal(), Cmd::ACT, 1, "principal" ); Command::AddCmd( new Action_Projection(), Cmd::ACT, 1, "projection" ); Command::AddCmd( new Action_Pucker(), Cmd::ACT, 1, "pucker" ); diff --git a/src/Ewald.cpp b/src/Ewald.cpp deleted file mode 100644 index c1e0e068b8..0000000000 --- a/src/Ewald.cpp +++ /dev/null @@ -1,574 +0,0 @@ -#include //sqrt -#include "Ewald.h" -#include "CpptrajStdio.h" -#include "Constants.h" -#include "StringRoutines.h" // ByteString -#include "Spline.h" -#include "Topology.h" -#include "CharMask.h" -#include "ParameterTypes.h" -#ifdef DEBUG_PAIRLIST -#incl ude "PDBfile.h" -#endif - -/// CONSTRUCTOR -Ewald::Ewald() : - ew_coeff_(0.0), - lw_coeff_(0.0), - switch_width_(0.0), - cutoff_(0.0), - cut2_(0.0), - cut2_0_(0.0), - dsumTol_(0.0), - debug_(0), - sumq_(0.0), - sumq2_(0.0), - Vdw_Recip_term_(0) -{ -# ifdef DEBUG_EWALD - // Save fractional translations for 1 cell in each direction (and primary cell). - // This is only for the non-pairlist version of direct. - Cells_.reserve( 27 ); - for (int ix = -1; ix < 2; ix++) - for (int iy = -1; iy < 2; iy++) - for (int iz = -1; iz < 2; iz++) - Cells_.push_back( Vec3(ix, iy, iz) ); -# endif -} - -const double Ewald::INVSQRTPI_ = 1.0 / sqrt(Constants::PI); - -/** Complimentary error function: 2/sqrt(PI) * SUM[exp(-t^2)*dt] - * Original code: SANDER: erfcfun.F90 - */ -double Ewald::erfc_func(double xIn) { - double erfc; - double absx = DABS( xIn ); - - if (xIn > 26.0) - erfc = 0.0; - else if (xIn < -5.5) - erfc = 2.0; - else if (absx <= 0.5) { - double cval = xIn * xIn; - double pval = ((-0.356098437018154E-1*cval+0.699638348861914E1)*cval + 0.219792616182942E2) * - cval + 0.242667955230532E3; - double qval = ((cval+0.150827976304078E2)*cval+0.911649054045149E2)*cval + 0.215058875869861E3; - double erf = xIn * pval/qval; - erfc = 1.0 - erf; - } else if (absx < 4.0) { - double cval = absx; - double pval=((((((-0.136864857382717E-6*cval+0.564195517478974)*cval+ - 0.721175825088309E1)*cval+0.431622272220567E2)*cval+ - 0.152989285046940E3)*cval+0.339320816734344E3)*cval+ - 0.451918953711873E3)*cval+0.300459261020162E3; - double qval=((((((cval+0.127827273196294E2)*cval+0.770001529352295E2)*cval+ - 0.277585444743988E3)*cval+0.638980264465631E3)*cval+ - 0.931354094850610E3)*cval+0.790950925327898E3)*cval+ - 0.300459260956983E3; - double nonexperfc; - if ( xIn > 0.0 ) - nonexperfc = pval/qval; - else - nonexperfc = 2.0*exp(xIn*xIn) - pval/qval; - erfc = exp(-absx*absx)*nonexperfc; - } else { - double cval = 1.0/(xIn*xIn); - double pval = (((0.223192459734185E-1*cval+0.278661308609648)*cval+ - 0.226956593539687)*cval+0.494730910623251E-1)*cval+ - 0.299610707703542E-2; - double qval = (((cval+0.198733201817135E1)*cval+0.105167510706793E1)*cval+ - 0.191308926107830)*cval+0.106209230528468E-1; - cval = (-cval*pval/qval + 0.564189583547756)/absx; - double nonexperfc; - if ( xIn > 0.0 ) - nonexperfc = cval; - else - nonexperfc = 2.0*exp(xIn*xIn) - cval; - erfc = exp(-absx*absx)*nonexperfc; - } - return erfc; -} - -// Ewald::ERFC() -double Ewald::ERFC(double xIn) const { - return table_.Yval( xIn); -} - -/** Non-inlined version of ERFC */ -double Ewald::ErfcFxn(double xIn) const { - return table_.Yval( xIn ); -} - -/** Determine Ewald coefficient from cutoff and direct sum tolerance. - * Original Code: SANDER: findewaldcof - */ -double Ewald::FindEwaldCoefficient(double cutoff, double dsum_tol) -{ - // First get direct sum tolerance. How big must the Ewald coefficient be to - // get terms outside the cutoff below tolerance? - double xval = 0.5; - int nloop = 0; - double term = 0.0; - do { - xval = 2.0 * xval; - nloop++; - double yval = xval * cutoff; - term = erfc_func(yval) / cutoff; - } while (term >= dsum_tol); - - // Binary search tolerance is 2^-50 - int ntimes = nloop + 50; - double xlo = 0.0; - double xhi = xval; - for (int i = 0; i != ntimes; i++) { - xval = (xlo + xhi) / 2.0; - double yval = xval * cutoff; - double term = erfc_func(yval) / cutoff; - if (term >= dsum_tol) - xlo = xval; - else - xhi = xval; - } - mprintf("\tEwald coefficient for cut=%g, direct sum tol=%g is %g\n", - cutoff, dsum_tol, xval); - return xval; -} - -/** Convert charges to Amber units. Calculate sum of charges and squared charges. */ -void Ewald::CalculateCharges(Topology const& topIn, AtomMask const& maskIn) { - sumq_ = 0.0; - sumq2_ = 0.0; - Charge_.clear(); - TypeIndices_.clear(); - for (AtomMask::const_iterator atom = maskIn.begin(); atom != maskIn.end(); ++atom) { - double qi = topIn[*atom].Charge() * Constants::ELECTOAMBER; - Charge_.push_back(qi); - sumq_ += qi; - sumq2_ += (qi * qi); - // Store atom type indices for selected atoms. - TypeIndices_.push_back( topIn[*atom].TypeIndex() ); - } - //mprintf("DEBUG: sumq= %20.10f sumq2= %20.10f\n", sumq_, sumq2_); - Setup_VDW_Correction( topIn, maskIn ); -} - -void Ewald::CalculateC6params(Topology const& topIn, AtomMask const& maskIn) { - Cparam_.clear(); - if (lw_coeff_ > 0.0) { - for (AtomMask::const_iterator atom = maskIn.begin(); atom != maskIn.end(); ++atom) - { - double rmin = topIn.GetVDWradius( *atom ); - double eps = topIn.GetVDWdepth( *atom ); - Cparam_.push_back( 8.0 * (rmin*rmin*rmin) * sqrt(2 * eps) ); - if (debug_ > 0) - mprintf("DEBUG: C6 param atom %8i = %16.8f\n", *atom+1, Cparam_.back()); - } - } else - Cparam_.assign(maskIn.Nselected(), 0.0); -} - -/** Set up exclusion lists for selected atoms. */ -void Ewald::SetupExclusionList(Topology const& topIn, AtomMask const& maskIn) -{ - // Use distance of 4 (up to dihedrals) - if (Excluded_.SetupExcluded(topIn.Atoms(), maskIn, 4, - ExclusionArray::EXCLUDE_SELF, - ExclusionArray::FULL)) - { - mprinterr("Error: Ewald: Could not set up exclusion list.\n"); - return; - } -} - -/** Check some common input. */ -int Ewald::CheckInput(Box const& boxIn, int debugIn, double cutoffIn, double dsumTolIn, - double ew_coeffIn, double lw_coeffIn, double switch_widthIn, - double erfcTableDxIn, double skinnbIn) -{ - debug_ = debugIn; - cutoff_ = cutoffIn; - dsumTol_ = dsumTolIn; - ew_coeff_ = ew_coeffIn; - lw_coeff_ = lw_coeffIn; - switch_width_ = switch_widthIn; - double erfcTableDx = erfcTableDxIn; - // Check input - if (cutoff_ < Constants::SMALL) { - mprinterr("Error: Direct space cutoff (%g) is too small.\n", cutoff_); - return 1; - } - char dir[3] = {'X', 'Y', 'Z'}; - // NOTE: First 3 box parameters are X Y Z - for (int i = 0; i < 3; i++) { - if (cutoff_ > boxIn.Param((Box::ParamType)i)/2.0) { - mprinterr("Error: Cutoff must be less than half the box length (%g > %g, %c)\n", - cutoff_, boxIn.Param((Box::ParamType)i)/2.0, dir[i]); - return 1; - } - } - if (skinnbIn < 0.0) { - mprinterr("Error: skinnb is less than 0.0\n"); - return 1; - } - if (switch_width_ < 0.0) switch_width_ = 0.0; - if (switch_width_ > cutoff_) { - mprinterr("Error: Switch width must be less than the cutoff.\n"); - return 1; - } - - // Set defaults if necessary - if (dsumTol_ < Constants::SMALL) - dsumTol_ = 1E-5; - if (DABS(ew_coeff_) < Constants::SMALL) - ew_coeff_ = FindEwaldCoefficient( cutoff_, dsumTol_ ); - if (erfcTableDx <= 0.0) erfcTableDx = 1.0 / 5000; - // TODO make this optional - if (table_.FillTable( erfc_func, erfcTableDx, 0.0, cutoff_*ew_coeff_*1.5 )) { - mprinterr("Error: Could not set up spline table for ERFC\n"); - return 1; - } - table_.PrintMemUsage("\t"); - table_.PrintTableInfo("\t"); - // TODO do for C6 as well - // TODO for C6 correction term - if (lw_coeff_ < 0.0) - lw_coeff_ = 0.0; - else if (DABS(lw_coeff_) < Constants::SMALL) - lw_coeff_ = ew_coeff_; - - // Calculate some common factors. - cut2_ = cutoff_ * cutoff_; - double cut0 = cutoff_ - switch_width_; - cut2_0_ = cut0 * cut0; - - return 0; -} - -/** Initialize and set up pairlist. */ -int Ewald::Setup_Pairlist(Box const& boxIn, double skinnbIn) { - if (pairList_.InitPairList(cutoff_, skinnbIn, debug_)) return 1; - if (pairList_.SetupPairList( boxIn )) return 1; -# ifdef DEBUG_PAIRLIST - // Write grid PDB - PDBfile gridpdb; - gridpdb.OpenWrite("gridpoints.pdb"); - for (int iz = 0; iz != pairList_.NZ(); iz++) - for (int iy = 0; iy != pairList_.NY(); iy++) - for (int ix = 0; ix != pairList_.NX(); ix++) { - double fx = (double)ix / (double)pairList_.NX(); - double fy = (double)iy / (double)pairList_.NY(); - double fz = (double)iz / (double)pairList_.NZ(); - Vec3 cart = boxIn.UnitCell().TransposeMult( Vec3(fx,fy,fz) ); - gridpdb.WriteHET(1, cart[0], cart[1], cart[2]); - } - gridpdb.CloseFile(); -# endif - return 0; -} - -/** Electrostatic self energy. This is the cancelling Gaussian plus the "neutralizing plasma". */ -double Ewald::Self(double volume) { - t_self_.Start(); - double d0 = -ew_coeff_ * INVSQRTPI_; - double ene = sumq2_ * d0; -// mprintf("DEBUG: d0= %20.10f ene= %20.10f\n", d0, ene); - double factor = Constants::PI / (ew_coeff_ * ew_coeff_ * volume); - double ee_plasma = -0.5 * factor * sumq_ * sumq_; - ene += ee_plasma; - t_self_.Stop(); - return ene; -} - -/** Lennard-Jones self energy. */ -double Ewald::Self6() { - t_self_.Start(); // TODO precalc - double ew2 = lw_coeff_ * lw_coeff_; - double ew6 = ew2 * ew2 * ew2; - double c6sum = 0.0; - for (Darray::const_iterator it = Cparam_.begin(); it != Cparam_.end(); ++it) - c6sum += ew6 * (*it * *it); - t_self_.Stop(); - return c6sum / 12.0; -} - -// Ewald::Adjust() -# ifdef _OPENMP -double Ewald::Adjust(double q0, double q1, double rij) const { - double erfc = ERFC(ew_coeff_ * rij); - double d0 = (erfc - 1.0) / rij; - return (q0 * q1 * d0); -} -# else -double Ewald::Adjust(double q0, double q1, double rij) { - t_adjust_.Start(); - t_erfc_.Start(); - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(ew_coeff_ * rij); - t_erfc_.Stop(); - double d0 = (erfc - 1.0) / rij; - t_adjust_.Stop(); - return (q0 * q1 * d0); -} -# endif - -/** Ewald adjustment, for inheriting classes. */ -#ifdef _OPENMP -double Ewald::AdjustFxn(double q0, double q1, double rij) const { - return Adjust(q0, q1, rij); -} -#else -double Ewald::AdjustFxn(double q0, double q1, double rij) { - return Adjust(q0, q1, rij); -} -#endif - -/** Switching function for Lennard-Jones. */ -static inline double switch_fn(double rij2, double cut2_0, double cut2_1) -{ - if (rij2 <= cut2_0) - return 1.0; - else if (rij2 > cut2_1) - return 0.0; - else { - double xoff_m_x = cut2_1 - rij2; - double fac = 1.0 / (cut2_1 - cut2_0); - return (xoff_m_x*xoff_m_x) * (cut2_1 + 2.0*rij2 - 3.0*cut2_0) * (fac*fac*fac); - } -} - -/** Switching function for Lennard-Jones, for inheriting classes. */ -double Ewald::SwitchFxn(double rij2, double cut2_0, double cut2_1) { - return switch_fn(rij2, cut2_0, cut2_1); -} - -/** Nonbond direct-space calculation for Coulomb electrostatics and Lennard-Jones, - * intended for use with long-range LJ correction. - */ -double Ewald::Direct_VDW_LongRangeCorrection(PairList const& PL, double& evdw_out, double& eadjust_out) -{ - t_direct_.Start(); - double Eelec = 0.0; - double e_adjust = 0.0; - double Evdw = 0.0; - int cidx; -# ifdef _OPENMP -# pragma omp parallel private(cidx) reduction(+: Eelec, Evdw, e_adjust) - { -# pragma omp for -# endif -# include "PairListLoop.h" -# ifdef _OPENMP - } // END pragma omp parallel -# endif - t_direct_.Stop(); -# ifdef DEBUG_PAIRLIST - mprintf("DEBUG: Elec = %16.8f\n", Eelec); - mprintf("DEBUG: Eadjust = %16.8f\n", e_adjust); - mprintf("DEBUG: LJ vdw = %16.8f\n", Evdw); -# endif - evdw_out = Evdw; - eadjust_out = e_adjust; - return Eelec; -} - -/** Nonbond direct-space calculation for Coulomb electrostatics and Lennard-Jones - * calculated via PME. - */ -double Ewald::Direct_VDW_LJPME(PairList const& PL, double& evdw_out, double& eadjust_out) -{ - t_direct_.Start(); - double Eelec = 0.0; - double e_adjust = 0.0; - double Evdw = 0.0; - double Eljpme_correction = 0.0; - double Eljpme_correction_excl = 0.0; - int cidx; -# define CPPTRAJ_EKERNEL_LJPME -# ifdef _OPENMP -# pragma omp parallel private(cidx) reduction(+: Eelec, Evdw, e_adjust, Eljpme_correction,Eljpme_correction_excl) - { -# pragma omp for -# endif -# include "PairListLoop.h" -# ifdef _OPENMP - } // END pragma omp parallel -# endif -# undef CPPTRAJ_EKERNEL_LJPME - t_direct_.Stop(); -# ifdef DEBUG_PAIRLIST - mprintf("DEBUG: Elec = %16.8f\n", Eelec); - mprintf("DEBUG: Eadjust = %16.8f\n", e_adjust); - mprintf("DEBUG: LJ vdw = %16.8f\n", Evdw); - mprintf("DEBUG: LJ vdw PME correction = %16.8f\n", Eljpme_correction); - mprintf("DEBUG: LJ vdw PME correction (excluded) = %16.8f\n", Eljpme_correction_excl); -# endif - evdw_out = Evdw + Eljpme_correction + Eljpme_correction_excl; - eadjust_out = e_adjust; - return Eelec; -} - - -// Ewald::Direct() -/** Calculate direct space energy. This is the faster version that uses - * a pair list. Also calculate the energy adjustment for excluded - * atoms. - * \param PL The pairlist used to calculate energy. - * \param e_adjust_out The electrostatic adjust energy for excluded atoms. - * \param evdw_out The direct space van der Waals term (corrected for exclusion if LJ PME). - * \return The electrostatics term. - */ -double Ewald::Direct(PairList const& PL, double& evdw_out, double& e_adjust_out) -{ - if (lw_coeff_ > 0.0) - return Direct_VDW_LJPME(PL, evdw_out, e_adjust_out); - else - return Direct_VDW_LongRangeCorrection(PL, evdw_out, e_adjust_out); -} - -/** Determine VDW long range correction prefactor. */ -void Ewald::Setup_VDW_Correction(Topology const& topIn, AtomMask const& maskIn) { - Vdw_Recip_term_ = 0.0; - NB_ = static_cast( &(topIn.Nonbond()) ); - if (!NB_->HasNonbond()) { - mprintf("Warning: '%s' has no nonbonded parameters. Cannot calculate VDW correction.\n", - topIn.c_str()); - return; - } - // Count the number of each unique nonbonded type. - N_vdw_type_.assign( NB_->Ntypes(), 0 ); - vdw_type_.clear(); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm) - { - N_vdw_type_[ topIn[*atm].TypeIndex() ]++; - vdw_type_.push_back( topIn[*atm].TypeIndex() ); - } - if (debug_ > 0) { - mprintf("DEBUG: %zu VDW types.\n", N_vdw_type_.size()); - for (Iarray::const_iterator it = N_vdw_type_.begin(); it != N_vdw_type_.end(); ++it) - mprintf("\tType %li = %i\n", it-N_vdw_type_.begin(), *it); - } - // Determine correction term from types and LJ B parameters - for (unsigned int itype = 0; itype != N_vdw_type_.size(); itype++) - { - double atype_vdw_term = 0.0; // term for each nonbond atom type - unsigned int offset = N_vdw_type_.size() * itype; - for (unsigned int jtype = 0; jtype != N_vdw_type_.size(); jtype++) - { - unsigned int idx = offset + jtype; - int nbidx = NB_->NBindex()[ idx ]; - if (nbidx > -1) { - atype_vdw_term += N_vdw_type_[itype] * N_vdw_type_[jtype] * NB_->NBarray()[ nbidx ].B(); - - Vdw_Recip_term_ += N_vdw_type_[itype] * N_vdw_type_[jtype] * NB_->NBarray()[ nbidx ].B(); - } - } - atype_vdw_recip_terms_.push_back(atype_vdw_term); // the nonbond interaction for each atom type - } -} - -/** Calculate full VDW long range correction from volume. */ -double Ewald::Vdw_Correction(double volume) { - double prefac = Constants::TWOPI / (3.0*volume*cutoff_*cutoff_*cutoff_); - double e_vdwr = -prefac * Vdw_Recip_term_; - if (debug_ > 0) mprintf("DEBUG: Vdw correction %20.10f\n", e_vdwr); - return e_vdwr; -} - -#ifdef DEBUG_EWALD -/** Calculate direct space energy. This is the slow version that doesn't - * use a pair list; for debug purposes only. - */ -double Ewald::Direct(Matrix_3x3 const& ucell, Topology const& tIn, AtomMask const& mask) -{ - t_direct_.Start(); - double cut2 = cutoff_ * cutoff_; - double Eelec = 0.0; - Varray const& Image = pairList_.ImageCoords(); - Varray const& Frac = pairList_.FracCoords(); - unsigned int maxidx = Image.size(); - for (unsigned int idx1 = 0; idx1 != maxidx; idx1++) - { - // Set up coord for this atom - Vec3 const& crd1 = Image[idx1]; - // Set up exclusion list for this atom - int atom1 = mask[idx1]; - Atom::excluded_iterator excluded_atom = tIn[atom1].excludedbegin(); - for (unsigned int idx2 = idx1 + 1; idx2 != maxidx; idx2++) - { - int atom2 = mask[idx2]; - // If atom is excluded, just increment to next excluded atom. - if (excluded_atom != tIn[atom1].excludedend() && atom2 == *excluded_atom) { - ++excluded_atom; - //mprintf("ATOM: Atom %4i to %4i excluded.\n", atom1+1, atom2+1); - } else { - // Only need to check nearest neighbors. - Vec3 const& frac2 = Frac[idx2]; - for (Varray::const_iterator ixyz = Cells_.begin(); ixyz != Cells_.end(); ++ixyz) - { - Vec3 dxyz = ucell.TransposeMult(frac2 + *ixyz) - crd1; - double rij2 = dxyz.Magnitude2(); - if ( rij2 < cut2 ) { - double rij = sqrt( rij2 ); - // Coulomb - double qiqj = Charge_[idx1] * Charge_[idx2]; - t_erfc_.Start(); - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(ew_coeff_ * rij); - t_erfc_.Stop(); - double e_elec = qiqj * erfc / rij; - Eelec += e_elec; - //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", -// mprintf("EELEC %6i%6i%12.5f%12.5f%12.5f\n", atom1, atom2, rij, erfc, e_elec); - // TODO can we break here? - } //else - //mprintf("ATOM: Atom %4i to %4i outside cut, %6.2f > %6.2f %3.0f%3.0f%3.0f\n", - //mprintf("ATOM: Atom %4i to %4i outside cut, %6.2f > %6.2f\n", - // atom1, atom2,sqrt(rij2),cutoff_); - } - } - } - } - t_direct_.Stop(); - return Eelec; -} - -/** Calculate Ewald energy. - * Slow version that does not use pair list. Note that pair list is still - * called since we require the fractional and imaged coords. - * FIXME No Eadjust calc. - */ -double Ewald::CalcEnergy_NoPairList(Frame const& frameIn, Topology const& topIn, - AtomMask const& maskIn) -{ - t_total_.Start(); - double volume = frameIn.BoxCrd().CellVolume(); - double e_self = Self( volume ); - // Place atoms in pairlist. This calcs frac/imaged coords. - pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); - - double e_recip = Recip_Regular( recip, volume ); - - double e_direct = Direct( ucell, topIn, maskIn ); - - //mprintf("DEBUG: Eself= %20.10f Erecip= %20.10f Edirect= %20.10f\n", - // e_self, e_recip, e_direct); - t_total_.Stop(); - return e_self + e_recip + e_direct; -} -#endif /* DEBUG_EWALD */ - -// Ewald::Timing() -void Ewald::Timing(double total) const { - t_total_.WriteTiming(1, " EwaldTotal:", total); - t_self_.WriteTiming(2, "Self: ", t_total_.Total()); - t_recip_.WriteTiming(2, "Recip: ", t_total_.Total()); - if (t_trig_tables_.Total() > 0.0) - t_trig_tables_.WriteTiming(3, "Calc trig tables:", t_recip_.Total()); - t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); -# ifndef _OPENMP - t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); - t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); -# endif - pairList_.Timing(total); -} diff --git a/src/Ewald.h b/src/Ewald.h deleted file mode 100644 index 5996e5a77d..0000000000 --- a/src/Ewald.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef INC_EWALD_H -#define INC_EWALD_H -class Topology; -class AtomMask; -class Frame; -class NonbondParmType; -class EwaldOptions; -#include "Timer.h" -#include "PairList.h" -#include "ExclusionArray.h" -#include "SplineFxnTable.h" -/// Base class for calculating non-bonded energy using Ewald methods. -class Ewald { - public: - Ewald(); - // ----- Virtual functions ------------------- - virtual ~Ewald() {} - virtual int Init(Box const&, EwaldOptions const&, int) = 0; - virtual int Setup(Topology const&, AtomMask const&) = 0; - /// Calculate electrostatic and van der Waals energy - virtual int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&) = 0; - // ------------------------------------------- - /// Report timings. - void Timing(double) const; -# ifdef DEBUG_EWALD - /// Slow non-pairlist version of energy calc. For debug only. - double CalcEnergy_NoPairList(Frame const&, Topology const&, AtomMask const&); -# endif - protected: - typedef std::vector Darray; - typedef std::vector Iarray; - typedef std::vector Varray; - - static inline double DABS(double xIn) { if (xIn < 0.0) return -xIn; else return xIn; } - /// Complimentary error function, erfc. - static double erfc_func(double); - - /// Ewald "self" energy - double Self(double); - /// Ewald "self" energy for C6 term - double Self6(); - /// Get analytical estimate of energy due to dispersion interactions > cutoff - double Vdw_Correction(double); - /// Box, debug, cutoff, dsum tol, ew coeff, lj coeff, switch window, erfc dx, nb skin - int CheckInput(Box const&, int, double, double, double, double, double, double, double); - /// Set up pair list for given box and NB "skin" size - int Setup_Pairlist(Box const&, double); - /// Calculate sum q, sum q^2. Calls setup for vdw correction - void CalculateCharges(Topology const&, AtomMask const&); - /// Calculate VDW C6 parameters for LJ PME - void CalculateC6params(Topology const&, AtomMask const&); - /// Setup main excluded atom list - void SetupExclusionList(Topology const&, AtomMask const&); - -# ifdef DEBUG_EWALD - /// Slow version of direct space energy, no pairlist. - double Direct(Matrix_3x3 const&, Topology const&, AtomMask const&); -# endif - /// Fast version of direct space energy using a pairlist - double Direct(PairList const&, double&, double&); - /// \return adjusted energy for excluded atom pair -# ifdef _OPENMP - inline double Adjust(double,double,double) const; -# else - inline double Adjust(double,double,double); // Cannot be const bc timers -# endif - - /// \return sum of charges squared - double SumQ2() const { return sumq2_; } - /// \return sum of charges - double SumQ() const { return sumq_; } - /// \return VDW recip correction term from # types and B parameters - double Vdw_Recip_Term() const { return Vdw_Recip_term_; } - /// \return Atom exclusion array - ExclusionArray const& Excluded() const { return Excluded_; } - /// \return Value of Erfc at given value - double ErfcFxn(double) const; - /// \return Nonbond parameters - NonbondParmType const& NB() const { return *NB_; } - /// \return Type index for given atom - int TypeIdx(unsigned int idx) const { return TypeIndices_[idx]; } - /// \return Value of LJ switching function - static double SwitchFxn(double, double, double); - /// \return Value of Ewald adjustment -# ifdef _OPENMP - double AdjustFxn(double,double,double) const; -# else - double AdjustFxn(double,double,double); -# endif - - // TODO make variables private - Darray Charge_; ///< Hold selected atomic charges converted to Amber units. - Darray Cparam_; ///< Hold selected atomic C6 coefficients for LJ PME - PairList pairList_; ///< Atom pair list for direct sum. - - Iarray vdw_type_; ///< Store nonbond vdw type for each atom - Iarray N_vdw_type_; ///< Total number of atoms for each vdw type - Darray atype_vdw_recip_terms_; ///< Nonbond PME interaction correction for each vdw type - - static const double INVSQRTPI_; - double ew_coeff_; ///< Ewald coefficient for electrostatics - double lw_coeff_; ///< Ewald coefficient for LJ - double switch_width_; ///< Switching window size for LJ switch if active - double cutoff_; ///< Direct space cutoff - double cut2_; ///< Direct space cutoff squared. - double cut2_0_; ///< Direct space cutoff minus switch width, squared. - double dsumTol_; ///< Direct space sum tolerance. - int debug_; - Timer t_total_; // TODO make timing external - Timer t_self_; - Timer t_recip_; - Timer t_trig_tables_; - Timer t_direct_; - Timer t_erfc_; - Timer t_adjust_; - private: - /// \return erfc value from erfc lookup table. - inline double ERFC(double) const; - /// Determine Ewald coefficient from cutoff and direct sum tolerance. - static double FindEwaldCoefficient(double,double); - - /// Setup VDW correction for selected atom types - void Setup_VDW_Correction(Topology const&, AtomMask const&); - /// Direct-space energy with VDW long range corrected energy - double Direct_VDW_LongRangeCorrection(PairList const&, double&, double&); - /// Direct-space energy with VDW handled via PME - double Direct_VDW_LJPME(PairList const&, double&, double&); - - SplineFxnTable table_; ///< Hold spline interpolation for erfc -# ifdef DEBUG_EWALD - Varray Cells_; ///< Hold fractional translations to neighbor cells (non-pairlist only) -# endif - double sumq_; ///< Sum of charges - double sumq2_; ///< Sum of charges squared - double Vdw_Recip_term_; ///< VDW recip correction term from # types and B parameters - // TODO should Exlcusions be passed in? - ExclusionArray Excluded_; ///< Full exclusion list for each selected atom. - Iarray TypeIndices_; ///< Hold atom type indices for selected atoms - NonbondParmType const* NB_; ///< Pointer to nonbonded parameters - -}; -#endif diff --git a/src/Ewald_ParticleMesh.cpp b/src/Ewald_ParticleMesh.cpp deleted file mode 100644 index 9336c00c78..0000000000 --- a/src/Ewald_ParticleMesh.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#ifdef LIBPME -#include // copy/fill -//#incl ude // unique_ptr -#include "Ewald_ParticleMesh.h" -#include "CpptrajStdio.h" -#include "AtomMask.h" -#include "Frame.h" -#include "EwaldOptions.h" - -typedef helpme::Matrix Mat; - -/// CONSTRUCTOR -Ewald_ParticleMesh::Ewald_ParticleMesh() : order_(6) -{ - nfft_[0] = -1; - nfft_[1] = -1; - nfft_[2] = -1; -} - -/** \return true if given number is a product of powers of 2, 3, or 5. */ -static inline bool check_prime_factors(int nIn) { - if (nIn == 1) return true; - int NL = nIn; - int NQ; - // First divide down by 2 - while (NL > 0) { - NQ = NL / 2; - if (NQ * 2 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - // Next try 3 - while (NL > 0) { - NQ = NL / 3; - if (NQ * 3 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - // Last try 5 - while (NL > 0) { - NQ = NL / 5; - if (NQ * 5 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - return false; -} - -/** Compute the ceiling of len that is also a product of powers of 2, 3, 5. - * Use check_prime_factors to get the smallest integer greater or equal - * than len which is decomposable into powers of 2, 3, 5. - */ -int Ewald_ParticleMesh::ComputeNFFT(double len) { - int mval = (int)len - 1; - for (int i = 0; i < 100; i++) { - mval += 1; - // Sanity check - if (mval < 1) { - mprinterr("Error: Bad box length %g, cannot get NFFT value.\n", len); - return 0; - } - if (check_prime_factors(mval)) - return mval; - } - mprinterr("Error: Failed to get good FFT array size for length %g Ang.\n", len); - return 0; -} - -/** Given a box, determine number of FFT grid points in each dimension. */ -int Ewald_ParticleMesh::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxIn) const -{ - if (nfft1 < 1) { - // Need even dimension for X direction - nfft1 = ComputeNFFT( (boxIn.Param(Box::X) + 1.0) * 0.5 ); - nfft1 *= 2; - } - if (nfft2 < 1) - nfft2 = ComputeNFFT( boxIn.Param(Box::Y) ); - if (nfft3 < 1) - nfft3 = ComputeNFFT( boxIn.Param(Box::Z) ); - - if (nfft1 < 1 || nfft2 < 1 || nfft3 < 1) { - mprinterr("Error: Bad NFFT values: %i %i %i\n", nfft1, nfft2, nfft3); - return 1; - } - if (debug_ > 0) mprintf("DEBUG: NFFTs: %i %i %i\n", nfft1, nfft2, nfft3); - - return 0; -} - -/** Set up PME parameters. */ -int Ewald_ParticleMesh::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) -{ - // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); - return 1; - } - if (CheckInput(boxIn, debugIn, pmeOpts.Cutoff(), pmeOpts.DsumTol(), pmeOpts.EwCoeff(), - pmeOpts.LwCoeff(), pmeOpts.LJ_SwWidth(), - pmeOpts.ErfcDx(), pmeOpts.SkinNB())) - return 1; - nfft_[0] = pmeOpts.Nfft1(); - nfft_[1] = pmeOpts.Nfft2(); - nfft_[2] = pmeOpts.Nfft3(); - order_ = pmeOpts.SplineOrder(); - - // Set defaults if necessary - if (order_ < 1) order_ = 6; - - mprintf("\tParticle Mesh Ewald params:\n"); - mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", - cutoff_, dsumTol_, ew_coeff_, pmeOpts.SkinNB()); - if (lw_coeff_ > 0.0) - mprintf("\t LJ Ewald coeff.= %g\n", lw_coeff_); - if (switch_width_ > 0.0) - mprintf("\t LJ switch width= %g\n", switch_width_); - mprintf("\t Bspline order= %i\n", order_); - //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); - mprintf("\t "); - for (int i = 0; i != 3; i++) - if (nfft_[i] == -1) - mprintf(" NFFT%i=auto", i+1); - else - mprintf(" NFFT%i=%i", i+1, nfft_[i]); - mprintf("\n"); - - // Set up pair list - if (Setup_Pairlist(boxIn, pmeOpts.SkinNB())) return 1; - - return 0; -} - -/** Set up PME parameters. */ -/* -int Ewald_ParticleMesh::Init(Box const& boxIn, double cutoffIn, double dsumTolIn, - double ew_coeffIn, double lw_coeffIn, double switch_widthIn, - double skinnbIn, double erfcTableDxIn, - int orderIn, int debugIn, const int* nfftIn) -{ - if (CheckInput(boxIn, debugIn, cutoffIn, dsumTolIn, ew_coeffIn, lw_coeffIn, switch_widthIn, - erfcTableDxIn, skinnbIn)) - return 1; - if (nfftIn != 0) - std::copy(nfftIn, nfftIn+3, nfft_); - else - std::fill(nfft_, nfft_+3, -1); - order_ = orderIn; - - // Set defaults if necessary - if (order_ < 1) order_ = 6; - - mprintf("\tParticle Mesh Ewald params:\n"); - mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g NB skin= %g\n", - cutoff_, dsumTol_, ew_coeff_, skinnbIn); - if (lw_coeff_ > 0.0) - mprintf("\t LJ Ewald coeff.= %g\n", lw_coeff_); - if (switch_width_ > 0.0) - mprintf("\t LJ switch width= %g\n", switch_width_); - mprintf("\t Bspline order= %i\n", order_); - //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); - mprintf("\t "); - for (int i = 0; i != 3; i++) - if (nfft_[i] == -1) - mprintf(" NFFT%i=auto", i+1); - else - mprintf(" NFFT%i=%i", i+1, nfft_[i]); - mprintf("\n"); - - // Set up pair list - if (Setup_Pairlist(boxIn, skinnbIn)) return 1; - - return 0; -}*/ - -/** Setup PME calculation. */ -int Ewald_ParticleMesh::Setup(Topology const& topIn, AtomMask const& maskIn) { - CalculateCharges(topIn, maskIn); - // NOTE: These dont need to actually be calculated if the lj ewald coeff - // is 0.0, but do it here anyway to avoid segfaults. - CalculateC6params( topIn, maskIn ); - coordsD_.clear(); - coordsD_.reserve( maskIn.Nselected() * 3); - SetupExclusionList(topIn, maskIn); - return 0; -} - -/* -static inline void PrintM(const char* Title, Mat const& M_) -{ - mprintf(" %s\n",Title); - mprintf(" %16.10f %16.10f %16.10f\n", M_(0,0), M_(0,1), M_(0,2)); - mprintf(" %16.10f %16.10f %16.10f\n", M_(1,0), M_(1,1), M_(1,2)); - mprintf(" %16.10f %16.10f %16.10f\n", M_(2,0), M_(2,1), M_(2,2)); -}*/ - -// Ewald::Recip_ParticleMesh() -double Ewald_ParticleMesh::Recip_ParticleMesh(Box const& boxIn) -{ - t_recip_.Start(); - // This essentially makes coordsD and chargesD point to arrays. - Mat coordsD(&coordsD_[0], Charge_.size(), 3); - Mat chargesD(&Charge_[0], Charge_.size(), 1); - int nfft1 = nfft_[0]; - int nfft2 = nfft_[1]; - int nfft3 = nfft_[2]; - if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { - mprinterr("Error: Could not determine grid spacing.\n"); - return 0.0; - } - // Instantiate double precision PME object - // Args: 1 = Exponent of the distance kernel: 1 for Coulomb - // 2 = Kappa - // 3 = Spline order - // 4 = nfft1 - // 5 = nfft2 - // 6 = nfft3 - // 7 = scale factor to be applied to all computed energies and derivatives thereof - // 8 = max # threads to use for each MPI instance; 0 = all available threads used. - // NOTE: Scale factor for Charmm is 332.0716 - // NOTE: The electrostatic constant has been baked into the Charge_ array already. - //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(1, ew_coeff_, order_, nfft1, nfft2, nfft3, 1.0, 0); - // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. - // Args: 1 = the A lattice parameter in units consistent with the coordinates. - // 2 = the B lattice parameter in units consistent with the coordinates. - // 3 = the C lattice parameter in units consistent with the coordinates. - // 4 = the alpha lattice parameter in degrees. - // 5 = the beta lattice parameter in degrees. - // 6 = the gamma lattice parameter in degrees. - // 7 = lattice type - pme_object_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), - boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), - PMEInstanceD::LatticeType::XAligned); - double erecip = pme_object_.computeERec(0, chargesD, coordsD); - - t_recip_.Stop(); - return erecip; -} - -/** The LJ PME reciprocal term. */ -double Ewald_ParticleMesh::LJ_Recip_ParticleMesh(Box const& boxIn) -{ - t_recip_.Start(); - int nfft1 = nfft_[0]; - int nfft2 = nfft_[1]; - int nfft3 = nfft_[2]; - if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { - mprinterr("Error: Could not determine grid spacing.\n"); - return 0.0; - } - - Mat coordsD(&coordsD_[0], Charge_.size(), 3); - Mat cparamD(&Cparam_[0], Cparam_.size(), 1); - - //auto pme_vdw = std::unique_ptr(new PMEInstanceD()); - pme_vdw_.setup(6, lw_coeff_, order_, nfft1, nfft2, nfft3, -1.0, 0); - PMEInstanceD::LatticeType lattice = PMEInstanceD::LatticeType::XAligned; - // TODO just pass in Ucell when helPME supports it - //boxIn.PrintDebug("pme"); - if (!boxIn.Is_X_Aligned()) { - if (boxIn.Is_Symmetric()) - lattice = PMEInstanceD::LatticeType::ShapeMatrix; - else { - mprinterr("Error: Unit cell is not X-aligned or symmetric; cannot set PME recip grid.\n"); - return 0; - } - } - pme_vdw_.setLatticeVectors(boxIn.Param(Box::X), boxIn.Param(Box::Y), boxIn.Param(Box::Z), - boxIn.Param(Box::ALPHA), boxIn.Param(Box::BETA), boxIn.Param(Box::GAMMA), - lattice); - double evdwrecip = pme_vdw_.computeERec(0, cparamD, coordsD); - t_recip_.Stop(); - return evdwrecip; -} - -/** Calculate full nonbonded energy with PME */ -int Ewald_ParticleMesh::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw) -{ - t_total_.Start(); - double volume = frameIn.BoxCrd().CellVolume(); - double e_self = Self( volume ); - double e_vdw_lr_correction; - - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Grid setup failed.\n"); - return 1; - } - - // TODO make more efficient - int idx = 0; - coordsD_.clear(); - for (AtomMask::const_iterator atm = maskIn.begin(); atm != maskIn.end(); ++atm, ++idx) { - const double* XYZ = frameIn.XYZ( *atm ); - coordsD_.push_back( XYZ[0] ); - coordsD_.push_back( XYZ[1] ); - coordsD_.push_back( XYZ[2] ); - } - -// MapCoords(frameIn, ucell, recip, maskIn); - double e_recip = Recip_ParticleMesh( frameIn.BoxCrd() ); - - // TODO branch - double e_vdw6self, e_vdw6recip; - if (lw_coeff_ > 0.0) { - e_vdw6self = Self6(); - e_vdw6recip = LJ_Recip_ParticleMesh( frameIn.BoxCrd() ); - if (debug_ > 0) { - mprintf("DEBUG: e_vdw6self = %16.8f\n", e_vdw6self); - mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); - } - e_vdw_lr_correction = 0.0; - } else { - e_vdw6self = 0.0; - e_vdw6recip = 0.0; - e_vdw_lr_correction = Vdw_Correction( volume ); - } - - e_vdw = 0.0; - double e_adjust = 0.0; - double e_direct = Direct( pairList_, e_vdw, e_adjust ); - if (debug_ > 0) { - mprintf("DEBUG: Nonbond energy components:\n"); - mprintf(" Evdw = %24.12f\n", e_vdw + e_vdw_lr_correction + e_vdw6self + e_vdw6recip); - mprintf(" Ecoulomb = %24.12f\n", e_self + e_recip + e_direct + e_adjust); - mprintf("\n"); - mprintf(" E electrostatic (self) = %24.12f\n", e_self); - mprintf(" (rec) = %24.12f\n", e_recip); - mprintf(" (dir) = %24.12f\n", e_direct); - mprintf(" (adj) = %24.12f\n", e_adjust); - mprintf(" E vanDerWaals (dir) = %24.12f\n", e_vdw); - mprintf(" (LR) = %24.12f\n", e_vdw_lr_correction); - mprintf(" (6slf) = %24.12f\n", e_vdw6self); - mprintf(" (6rcp) = %24.12f\n", e_vdw6recip); - } - e_vdw += (e_vdw_lr_correction + e_vdw6self + e_vdw6recip); - t_total_.Stop(); - e_elec = e_self + e_recip + e_direct + e_adjust; - return 0; -} - -#endif /* LIBPME */ diff --git a/src/Ewald_ParticleMesh.h b/src/Ewald_ParticleMesh.h deleted file mode 100644 index 60cd76c5ac..0000000000 --- a/src/Ewald_ParticleMesh.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef INC_EWALD_PARTICLEMESH_H -#define INC_EWALD_PARTICLEMESH_H -#ifdef LIBPME -#include "Ewald.h" -#include "helpme_standalone.h" -/// Class for calculating electrostatics with particle mesh Ewald. -class Ewald_ParticleMesh : public Ewald { - public: - Ewald_ParticleMesh(); - /// Virtual destructor since this can be inherited - virtual ~Ewald_ParticleMesh() {} - /// Box, cut, dsum tol, ew coeff, lj ew coeff, switch width, NB skin, erfc dx, order, dbg, nfft - //int Init(Box const&, double, double, double, double, double, double, double, - // int, int, const int*); - // ----- Inherited --------------------------- - /// Init with Box, EwaldOptions and debug level - int Init(Box const&, EwaldOptions const&, int); - int Setup(Topology const&, AtomMask const&); - int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); - - protected: - /// Determine grid points for FFT in each dimension - int DetermineNfft(int&, int&, int&, Box const&) const; - /// \return Number of FFT grid points in specified direction - int Nfft(unsigned int idx) const { return nfft_[idx]; } - /// \return PME B-spline order - int Order() const { return order_; } - - Darray coordsD_; ///< Hold coordinates for selected atoms - PMEInstanceD pme_object_; - PMEInstanceD pme_vdw_; - - private: - typedef Ewald::Darray Darray; - /// Based on given length return number of grid points that is power of 2, 3, or 5 - static int ComputeNFFT(double); - /// Particle mesh Ewald reciprocal energy - double Recip_ParticleMesh(Box const&); - /// Particle mesh Ewald LJ recip energy - double LJ_Recip_ParticleMesh(Box const&); - - - int nfft_[3]; ///< Number of FFT grid points in each direction - int order_; ///< PME B spline order - - }; -#endif /* LIBPME */ -#endif diff --git a/src/Ewald_Regular.cpp b/src/Ewald_Regular.cpp deleted file mode 100644 index b03b263dcd..0000000000 --- a/src/Ewald_Regular.cpp +++ /dev/null @@ -1,412 +0,0 @@ -#include // copy/fill/min/max -#include -#include "Ewald_Regular.h" -#include "CpptrajStdio.h" -#include "Constants.h" -#include "StringRoutines.h" // ByteString -#include "AtomMask.h" -#include "Frame.h" -#include "EwaldOptions.h" -#ifdef _OPENMP -# include -#endif - -/// CONSTRUCTOR -Ewald_Regular::Ewald_Regular() : -# ifdef _OPENMP - multCut_(0), -# endif - maxexp_(0.0), - rsumTol_(0.0), - maxmlim_(0) -{ - mlimit_[0] = 0; - mlimit_[1] = 0; - mlimit_[2] = 0; -} - -/** \return maxexp value based on mlimits */ -double Ewald_Regular::FindMaxexpFromMlim(const int* mlimit, Matrix_3x3 const& recip) { - double maxexp = DABS( (double)mlimit[0] * recip[0] ); - double z2 = DABS( (double)mlimit[1] * recip[4] ); - maxexp = std::max(maxexp, z2); - double z3 = DABS( (double)mlimit[2] * recip[8] ); - maxexp = std::max(maxexp, z3); - return maxexp; -} - -/** \return maxexp value based on Ewald coefficient and reciprocal sum tolerance. */ -double Ewald_Regular::FindMaxexpFromTol(double ewCoeff, double rsumTol) { - double xval = 0.5; - int nloop = 0; - double term = 0.0; - do { - xval = 2.0 * xval; - nloop++; - double yval = Constants::PI * xval / ewCoeff; - term = 2.0 * ewCoeff * erfc_func(yval) * INVSQRTPI_; - } while (term >= rsumTol); - - // Binary search tolerance is 2^-60 - int ntimes = nloop + 60; - double xlo = 0.0; - double xhi = xval; - for (int i = 0; i != ntimes; i++) { - xval = (xlo + xhi) / 2.0; - double yval = Constants::PI * xval / ewCoeff; - double term = 2.0 * ewCoeff * erfc_func(yval) * INVSQRTPI_; - if (term > rsumTol) - xlo = xval; - else - xhi = xval; - } - mprintf("\tMaxExp for Ewald coefficient %g, direct sum tol %g is %g\n", - ewCoeff, rsumTol, xval); - return xval; -} - -static inline int IABS(int xIn) { if (xIn < 0 ) return -xIn; else return xIn; } - -/** Get mlimits. */ -void Ewald_Regular::GetMlimits(int* mlimit, double maxexp, double eigmin, - Vec3 const& reclng, Matrix_3x3 const& recip) -{ - //mprintf("DEBUG: Recip lengths %12.4f%12.4f%12.4f\n", reclng[0], reclng[1], reclng[2]); - - int mtop1 = (int)(reclng[0] * maxexp / sqrt(eigmin)); - int mtop2 = (int)(reclng[1] * maxexp / sqrt(eigmin)); - int mtop3 = (int)(reclng[2] * maxexp / sqrt(eigmin)); - - int nrecvecs = 0; - mlimit[0] = 0; - mlimit[1] = 0; - mlimit[2] = 0; - double maxexp2 = maxexp * maxexp; - for (int m1 = -mtop1; m1 <= mtop1; m1++) { - for (int m2 = -mtop2; m2 <= mtop2; m2++) { - for (int m3 = -mtop3; m3 <= mtop3; m3++) { - Vec3 Zvec = recip.TransposeMult( Vec3(m1,m2,m3) ); - if ( Zvec.Magnitude2() <= maxexp2 ) { - nrecvecs++; - mlimit[0] = std::max( mlimit[0], IABS(m1) ); - mlimit[1] = std::max( mlimit[1], IABS(m2) ); - mlimit[2] = std::max( mlimit[2], IABS(m3) ); - } - } - } - } - mprintf("\tNumber of reciprocal vectors: %i\n", nrecvecs); -} - -/** Init regular Ewald calculation. */ -int Ewald_Regular::Init(Box const& boxIn, EwaldOptions const& ewOpts, int debugIn) -//double cutoffIn, double dsumTolIn, double rsumTolIn, -// double ew_coeffIn, double maxexpIn, double skinnbIn, -// double erfcTableDxIn, int debugIn, const int* mlimitsIn) -{ - if (ewOpts.Type() == EwaldOptions::PME) { - mprinterr("Internal Error: Ewald options set up for PME\n"); - return 1; - } - if (CheckInput(boxIn, debugIn, ewOpts.Cutoff(), ewOpts.DsumTol(), ewOpts.EwCoeff(), - -1.0, ewOpts.LJ_SwWidth(), - ewOpts.ErfcDx(), ewOpts.SkinNB())) - return 1; - rsumTol_ = ewOpts.RsumTol(); - maxexp_ = ewOpts.MaxExp(); - mlimit_[0] = ewOpts.Mlimits1(); - mlimit_[1] = ewOpts.Mlimits2(); - mlimit_[2] = ewOpts.Mlimits3(); - - // Check input - if (mlimit_[0] < 0 || mlimit_[1] < 0 || mlimit_[2] < 0) { - mprinterr("Error: Cannot specify negative mlimit values.\n"); - return 1; - } - maxmlim_ = mlimit_[0]; - maxmlim_ = std::max(maxmlim_, mlimit_[1]); - maxmlim_ = std::max(maxmlim_, mlimit_[2]); - if (maxexp_ < 0.0) { - mprinterr("Error: maxexp is less than 0.0\n"); - return 1; - } - - // Set defaults if necessary - if (rsumTol_ < Constants::SMALL) - rsumTol_ = 5E-5; - if (maxmlim_ > 0) - maxexp_ = FindMaxexpFromMlim(mlimit_, boxIn.FracCell()); - else { - if ( maxexp_ < Constants::SMALL ) - maxexp_ = FindMaxexpFromTol(ew_coeff_, rsumTol_); - // eigmin typically bigger than this unless cell is badly distorted. - double eigmin = 0.5; - // Calculate lengths of reciprocal vectors - GetMlimits(mlimit_, maxexp_, eigmin, boxIn.RecipLengths(), boxIn.FracCell()); - maxmlim_ = mlimit_[0]; - maxmlim_ = std::max(maxmlim_, mlimit_[1]); - maxmlim_ = std::max(maxmlim_, mlimit_[2]); - } - - mprintf("\tEwald params:\n"); - mprintf("\t Cutoff= %g Direct Sum Tol= %g Ewald coeff.= %g\n", - cutoff_, dsumTol_, ew_coeff_); - mprintf("\t MaxExp= %g Recip. Sum Tol= %g NB skin= %g\n", - maxexp_, rsumTol_, ewOpts.SkinNB()); - //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); - mprintf("\t mlimits= {%i,%i,%i} Max=%i\n", mlimit_[0], mlimit_[1], mlimit_[2], maxmlim_); - // Set up pair list - if (Setup_Pairlist(boxIn, ewOpts.SkinNB())) return 1; - - return 0; -} - -/** Setup regular Ewald calculation. */ -int Ewald_Regular::Setup(Topology const& topIn, AtomMask const& maskIn) { - CalculateCharges(topIn, maskIn); - // Blank C6 Arrays. TODO actually blank them - CalculateC6params( topIn, maskIn ); - - // Build exponential factors for use in structure factors. - // These arrays are laid out in 1D; value for each atom at each m, i.e. - // A0M0 A1M0 A2M0 ... ANM0 A0M1 ... ANMX - // Number of M values is the max + 1. - int mmax = maxmlim_ + 1; - unsigned int tsize = maskIn.Nselected() * mmax; - cosf1_.assign( tsize, 1.0 ); - cosf2_.assign( tsize, 1.0 ); - cosf3_.assign( tsize, 1.0 ); - sinf1_.assign( tsize, 0.0 ); - sinf2_.assign( tsize, 0.0 ); - sinf3_.assign( tsize, 0.0 ); - mprintf("\tMemory used by trig tables: %s\n", - ByteString(6*tsize*sizeof(double), BYTE_DECIMAL).c_str()); - // M0 -// for (int i = 0; i != maskIn.Nselected(); i++) { -// cosf1_.push_back( 1.0 ); -// cosf2_.push_back( 1.0 ); -// cosf3_.push_back( 1.0 ); -// sinf1_.push_back( 0.0 ); -// sinf2_.push_back( 0.0 ); -// sinf3_.push_back( 0.0 ); -// } - - SetupExclusionList(topIn, maskIn); - -# ifdef _OPENMP - // Pre-calculate m1 and m2 indices - mlim1_.clear(); - mlim2_.clear(); - multCut_ = 0; - for (int m1 = 0; m1 <= mlimit_[0]; m1++) { - for (int m2 = -mlimit_[1]; m2 <= mlimit_[1]; m2++) { - mlim1_.push_back( m1 ); - mlim2_.push_back( m2 ); - } - // After this index (end of m1 == 0) multiplier must be 2.0 - if (m1 == 0) - multCut_ = (int)mlim1_.size(); - } - // Each thread will need its own space for trig math - int numthreads; -# pragma omp parallel - { -# pragma omp master - { - numthreads = omp_get_num_threads(); - mprintf("\tParallelizing calculation with %i threads\n", numthreads); - } - } - unsigned int asize = (unsigned int)maskIn.Nselected() * (unsigned int)numthreads; - c12_.resize( asize ); - s12_.resize( asize ); - c3_.resize( asize ); - s3_.resize( asize ); -#else - c12_.resize( maskIn.Nselected() ); - s12_.resize( maskIn.Nselected() ); - c3_.resize( maskIn.Nselected() ); - s3_.resize( maskIn.Nselected() ); -# endif - return 0; -} - -/** Reciprocal space energy counteracting the neutralizing charge distribution. */ -double Ewald_Regular::Recip_Regular(Matrix_3x3 const& recip, double volume) { - t_recip_.Start(); - double fac = (Constants::PI*Constants::PI) / (ew_coeff_ * ew_coeff_); - double maxexp2 = maxexp_ * maxexp_; - double ene = 0.0; - Varray const& Frac = pairList_.FracCoords(); - // Number of M values is the max + 1. - int mmax = maxmlim_ + 1; - // Build exponential factors for use in structure factors. - // These arrays are laid out in 1D; value for each atom at each m, i.e. - // A0M0 A1M0 A2M0 ... ANM0 A0M1 ... ANMX - // M0 is done in EwaldSetup() - t_trig_tables_.Start(); - unsigned int mnidx = Frac.size(); - // M1 - for (unsigned int i = 0; i != Frac.size(); i++, mnidx++) { - //mprintf("FRAC: %6i%20.10f%20.10f%20.10f\n", i+1, Frac[i][0], Frac[i][1], Frac[i][2]); - cosf1_[mnidx] = cos(Constants::TWOPI * Frac[i][0]); - cosf2_[mnidx] = cos(Constants::TWOPI * Frac[i][1]); - cosf3_[mnidx] = cos(Constants::TWOPI * Frac[i][2]); - sinf1_[mnidx] = sin(Constants::TWOPI * Frac[i][0]); - sinf2_[mnidx] = sin(Constants::TWOPI * Frac[i][1]); - sinf3_[mnidx] = sin(Constants::TWOPI * Frac[i][2]); - } - // M2-MX - // Get the higher factors by recursion using trig addition rules. - // Negative values of M by complex conjugation, or even cosf, odd sinf. - // idx will always point to M-1 values - unsigned int idx = Frac.size(); - for (int m = 2; m < mmax; m++) { - // Set m1idx to beginning of M1 values. - unsigned int m1idx = Frac.size(); - for (unsigned int i = 0; i != Frac.size(); i++, idx++, m1idx++, mnidx++) { - cosf1_[mnidx] = cosf1_[idx]*cosf1_[m1idx] - sinf1_[idx]*sinf1_[m1idx]; - cosf2_[mnidx] = cosf2_[idx]*cosf2_[m1idx] - sinf2_[idx]*sinf2_[m1idx]; - cosf3_[mnidx] = cosf3_[idx]*cosf3_[m1idx] - sinf3_[idx]*sinf3_[m1idx]; - sinf1_[mnidx] = sinf1_[idx]*cosf1_[m1idx] + cosf1_[idx]*sinf1_[m1idx]; - sinf2_[mnidx] = sinf2_[idx]*cosf2_[m1idx] + cosf2_[idx]*sinf2_[m1idx]; - sinf3_[mnidx] = sinf3_[idx]*cosf3_[m1idx] + cosf3_[idx]*sinf3_[m1idx]; - } - } - // DEBUG -/* unsigned int midx = 0; - for (int m = 0; m != mmax; m++) { - for (unsigned int i = 0; i != Frac.size(); i++, midx++) - mprintf("TRIG: %6i%6u%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f\n", m,i+1, - cosf1_[midx], cosf2_[midx], cosf3_[midx], - sinf1_[midx], sinf2_[midx], sinf3_[midx]); - }*/ - t_trig_tables_.Stop(); -# ifdef _OPENMP - double mult; - unsigned int offset; - int mlim_idx; - int mlim_end = (int)mlim1_.size(); - double *c12, *s12, *c3, *s3; -# pragma omp parallel private(mult,mlim_idx,c12,s12,c3,s3,offset) reduction(+:ene) - { - offset = (unsigned int)omp_get_thread_num() * Frac.size(); - c12 = &c12_[0] + offset; - s12 = &s12_[0] + offset; - c3 = &c3_[0] + offset; - s3 = &s3_[0] + offset; -# pragma omp for - for (mlim_idx = 0; mlim_idx < mlim_end; mlim_idx++) - { - if (mlim_idx < multCut_) - mult = 1.0; - else - mult = 2.0; - int m1 = mlim1_[mlim_idx]; - int m2 = mlim2_[mlim_idx]; -# else - Darray& c12 = c12_; - Darray& s12 = s12_; - Darray& c3 = c3_; - Darray& s3 = s3_; - double mult = 1.0; - for (int m1 = 0; m1 <= mlimit_[0]; m1++) - { - for (int m2 = -mlimit_[1]; m2 <= mlimit_[1]; m2++) - { -# endif - int m1idx = Frac.size() * m1; - int m2idx = Frac.size() * IABS(m2); - - if (m2 < 0) { - for (unsigned int i = 0; i != Frac.size(); i++, m1idx++, m2idx++) { - c12[i] = cosf1_[m1idx]*cosf2_[m2idx] + sinf1_[m1idx]*sinf2_[m2idx]; - s12[i] = sinf1_[m1idx]*cosf2_[m2idx] - cosf1_[m1idx]*sinf2_[m2idx]; - } - } else { - for (unsigned int i = 0; i != Frac.size(); i++, m1idx++, m2idx++) { - c12[i] = cosf1_[m1idx]*cosf2_[m2idx] - sinf1_[m1idx]*sinf2_[m2idx]; - s12[i] = sinf1_[m1idx]*cosf2_[m2idx] + cosf1_[m1idx]*sinf2_[m2idx]; - } - } - for (int m3 = -mlimit_[2]; m3 <= mlimit_[2]; m3++) - { - // Columns of recip are reciprocal unit cell vecs, so - // mhat contains Cartesian components of recip vector M. - Vec3 mhat = recip.TransposeMult( Vec3(m1, m2, m3) ); - double msq = mhat.Magnitude2(); - double denom = Constants::PI * volume * msq; - double eterm = 0.0; -// double vterm = 0.0; - if ( m1*m1 + m2*m2 + m3*m3 > 0 ) { - eterm = exp(-fac*msq) / denom; -// vterm = 2.0 * (fac*msq + 1.0) / msq; - } - // mult takes care to double count for symmetry. Can take care of - // with eterm. - eterm *= mult; - if (msq < maxexp2) { - int m3idx = Frac.size() * IABS(m3); - // Get the product of complex exponentials. - if (m3 < 0) { - for (unsigned int i = 0; i != Frac.size(); i++, m3idx++) { - c3[i] = c12[i]*cosf3_[m3idx] + s12[i]*sinf3_[m3idx]; - s3[i] = s12[i]*cosf3_[m3idx] - c12[i]*sinf3_[m3idx]; - } - } else { - for (unsigned int i = 0; i != Frac.size(); i++, m3idx++) { - c3[i] = c12[i]*cosf3_[m3idx] - s12[i]*sinf3_[m3idx]; - s3[i] = s12[i]*cosf3_[m3idx] + c12[i]*sinf3_[m3idx]; - } - } - // Get the structure factor - double cstruct = 0.0; - double sstruct = 0.0; - for (unsigned int i = 0; i != Frac.size(); i++) { - cstruct += Charge_[i] * c3[i]; - sstruct += Charge_[i] * s3[i]; - } - double struc2 = cstruct*cstruct + sstruct*sstruct; - ene += eterm * struc2; - //mprintf("LOOP: %3i%3i%3i ENE= %20.10f\n", m1, m2, m3, ene); - } // END IF msq < maxexp2 - } // END loop over m3 -# ifdef _OPENMP - } // END loop over mlim_idx - } // END pragma omp parallel -# else - } // END loop over m2 - mult = 2.0; - } // END loop over m1 -# endif - t_recip_.Stop(); - return ene * 0.5; -} - -/** Calculate Ewald energy. Faster version that uses pair list. */ -int Ewald_Regular::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskIn, - double& e_elec, double& e_vdw) -{ - t_total_.Start(); - double volume = frameIn.BoxCrd().CellVolume(); - double e_self = Self( volume ); - double e_vdwr = Vdw_Correction( volume ); - - int retVal = pairList_.CreatePairList(frameIn, frameIn.BoxCrd().UnitCell(), frameIn.BoxCrd().FracCell(), maskIn); - if (retVal != 0) { - mprinterr("Error: Grid setup failed.\n"); - return 1; - } - -// MapCoords(frameIn, ucell, recip, maskIn); - double e_recip = Recip_Regular( frameIn.BoxCrd().FracCell(), volume ); - e_vdw = 0.0; - double e_adjust = 0.0; - double e_direct = Direct( pairList_, e_vdw, e_adjust ); - if (debug_ > 0) - mprintf("DEBUG: Eself= %20.10f Erecip= %20.10f Edirect= %20.10f Eadjust= %20.10f Evdw= %20.10f\n", e_self, e_recip, e_direct, e_adjust, e_vdw); - e_vdw += e_vdwr; - t_total_.Stop(); - e_elec = e_self + e_recip + e_direct + e_adjust; - return 0; -} diff --git a/src/Ewald_Regular.h b/src/Ewald_Regular.h deleted file mode 100644 index bd38662dda..0000000000 --- a/src/Ewald_Regular.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef INC_EWALD_REGULAR_H -#define INC_EWALD_REGULAR_H -#include "Ewald.h" -/// Calculate regular Ewald energy -class Ewald_Regular : public Ewald { - public: - Ewald_Regular(); - /// Box, cutoff, dsum tol, rsum tol, ew coeff, maxexp, nb skin, erfc dx, debug, mlimits - /*int Init(Box const&, double, double, double, double, double, double, - double, int, const int*);*/ - // ----- Inherited --------------------------- - int Init(Box const&, EwaldOptions const&, int); - int Setup(Topology const&, AtomMask const&); - int CalcNonbondEnergy(Frame const&, AtomMask const&, double&, double&); - private: - /// Determine max length for reciprocal calcs based on reciprocal limits - static double FindMaxexpFromMlim(const int*, Matrix_3x3 const&); - /// Determine max length for reciprocal calcs based on Ewald coefficient and recip tol. - static double FindMaxexpFromTol(double, double); - /// Determine reciprocal limits based on unit cell reciprocal vectors - static void GetMlimits(int*, double, double, Vec3 const&, Matrix_3x3 const&); - /// Ewald reciprocal energy - double Recip_Regular(Matrix_3x3 const&, double); - - typedef Ewald::Darray Darray; - // Hold trig tables - Darray cosf1_; - Darray cosf2_; - Darray cosf3_; - Darray sinf1_; - Darray sinf2_; - Darray sinf3_; - Darray c12_; - Darray s12_; - Darray c3_; - Darray s3_; -# ifdef _OPENMP - typedef Ewald::Iarray Iarray; - Iarray mlim1_; ///< Hold m1 reciprocal indices - Iarray mlim2_; ///< Hold m2 reciprocal indices - int multCut_; ///< Hold index after which multiplier should be 2.0. -# endif - double maxexp_; ///< Determines how far out recip vectors go? TODO check! - double rsumTol_; ///< Reciprocal space sum tolerance. - int mlimit_[3]; ///< Number of units in each direction to calc recip. sum. / nfft - int maxmlim_; ///< The max of the three mlimit_ values. / pme spline order -}; -#endif diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 2adf75267d..3dcfb1cc54 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -32,12 +32,12 @@ Action_Dipole.o : Action_Dipole.cpp Action.h ActionState.h Action_Dipole.h ArgLi Action_DistRmsd.o : Action_DistRmsd.cpp Action.h ActionState.h Action_DistRmsd.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceAction.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Distance.o : Action_Distance.cpp Action.h ActionState.h Action_Distance.h ArgList.h AssociatedData.h AssociatedData_NOE.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_EneDecomp.o : Action_EneDecomp.cpp Action.h ActionState.h Action_EneDecomp.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h EnergyArray.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Action_Energy.o : Action_Energy.cpp Action.h ActionState.h Action_Energy.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h EnergyArray.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy_Sander.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FixAtomOrder.o : Action_FixAtomOrder.cpp Action.h ActionState.h ActionTopWriter.h Action_FixAtomOrder.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomTopType.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FixImagedBonds.o : Action_FixImagedBonds.cpp Action.h ActionState.h Action_FixImagedBonds.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_GIST.o : Action_GIST.cpp Action.h ActionState.h Action_GIST.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_MatrixFlt.h Dimension.h DispatchObject.h DistRoutines.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h GIST_PME.h GistEntropyUtils.h Grid.h GridBin.h GridMover.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h +Action_GIST.o : Action_GIST.cpp Action.h ActionState.h Action_GIST.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_MatrixFlt.h Dimension.h DispatchObject.h DistRoutines.h EwaldOptions.h FileIO.h FileName.h FileTypes.h Frame.h GIST_PME.h GistEntropyUtils.h Grid.h GridBin.h GridMover.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh Action_Grid.o : Action_Grid.cpp Action.h ActionState.h Action_Grid.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskArray.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_GridFreeEnergy.o : Action_GridFreeEnergy.cpp Action.h ActionState.h Action_GridFreeEnergy.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_HydrogenBond.o : Action_HydrogenBond.cpp Action.h ActionState.h Action_HydrogenBond.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h DataSet_integer.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -64,7 +64,6 @@ Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Actio Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PmeTest.o : Action_PmeTest.cpp Action.h ActionState.h Action_PmeTest.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h Energy/Ecalc_Nonbond.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pucker.o : Action_Pucker.cpp Action.h ActionState.h Action_Pucker.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -191,7 +190,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_PmeTest.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h Ewald_Regular.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h EwaldOptions.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -300,10 +299,7 @@ EnsembleOut.o : EnsembleOut.cpp ActionFrameCounter.h BaseIOtype.h Box.h Coordina EnsembleOutList.o : EnsembleOutList.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOutList.h EnsembleOut_Multi.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Multi.o : EnsembleOut_Multi.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Multi.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h EnsembleOut_Single.o : EnsembleOut_Single.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnsembleOut.h EnsembleOut_Single.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h -Ewald.o : Ewald.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h Ewald.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListLoop.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h Spline.h SplineFxnTable.h StringRoutines.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h EwaldOptions.o : EwaldOptions.cpp ArgList.h CpptrajStdio.h EwaldOptions.h -Ewald_ParticleMesh.o : Ewald_ParticleMesh.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Ewald_Regular.o : Ewald_Regular.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Ewald.h EwaldOptions.h Ewald_Regular.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h StringRoutines.h SymbolExporting.h Timer.h Unit.h Vec3.h ExclusionArray.o : ExclusionArray.cpp Atom.h AtomMask.h CharMask.h CpptrajStdio.h ExclusionArray.h MaskToken.h Molecule.h NameType.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Unit.h Exec_AddMissingRes.o : Exec_AddMissingRes.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h CharMask.h CompactFrameArray.h Constants.h Constraints.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnergyArray.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_AddMissingRes.h Exec_AddMissingRes_Pres.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MdOpts.h MetaData.h Minimize_SteepestDescent.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h PotentialFunction.h PotentialTerm.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h Trajin_Single.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Exec_Analyze.o : Exec_Analyze.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Cmd.h CmdList.h Command.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Analyze.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h @@ -380,7 +376,7 @@ ForLoop_list.o : ForLoop_list.cpp Action.h ActionList.h ActionState.h Analysis.h ForLoop_mask.o : ForLoop_mask.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_mask.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h ForLoop_overSets.o : ForLoop_overSets.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_overSets.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Frame.o : Frame.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Unit.h Vec3.h -GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h Ewald.h Ewald_ParticleMesh.h ExclusionArray.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h GistEntropyUtils.o : GistEntropyUtils.cpp CpptrajFile.h FileIO.h FileName.h GistEntropyUtils.h Parallel.h Vec3.h Gpu.o : Gpu.cpp Gpu.h GridAction.o : GridAction.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index 4c8c4b2635..b82dd96794 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -67,7 +67,6 @@ COMMON_SOURCES= \ Action_Outtraj.cpp \ Action_PairDist.cpp \ Action_Pairwise.cpp \ - Action_PmeTest.cpp \ Action_Principal.cpp \ Action_Projection.cpp \ Action_Pucker.cpp \ @@ -257,9 +256,6 @@ COMMON_SOURCES= \ EnsembleOut_Multi.cpp \ EnsembleOut_Single.cpp \ EnsembleOutList.cpp \ - Ewald.cpp \ - Ewald_ParticleMesh.cpp \ - Ewald_Regular.cpp \ EwaldOptions.cpp \ ExclusionArray.cpp \ Exec_AddMissingRes.cpp \ From 527d74f5a6658241791de5e7c2b66f7691a3c280 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 10 Oct 2024 06:54:12 -0400 Subject: [PATCH 173/218] These dont need to be separate yet --- src/Energy/Ene_Elec.h | 57 ------------------------------------- src/Energy/Ene_Elec_Image.h | 49 ------------------------------- 2 files changed, 106 deletions(-) delete mode 100644 src/Energy/Ene_Elec.h delete mode 100644 src/Energy/Ene_Elec_Image.h diff --git a/src/Energy/Ene_Elec.h b/src/Energy/Ene_Elec.h deleted file mode 100644 index 04048936e8..0000000000 --- a/src/Energy/Ene_Elec.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef INC_ENERGY_ENE_ELEC_H -#define INC_ENERGY_ENE_ELEC_H -namespace Cpptraj { -namespace Energy { -template -T Ene_Elec(Frame const& fIn, Topology const& tIn, AtomMask const& mask, ExclusionArray const& Excluded) -{ - T Eelec = 0.0; - int idx1; -# ifdef _OPENMP -# pragma omp parallel private(idx1) reduction(+ : Eelec) - { -# pragma omp for -# endif - for (idx1 = 0; idx1 < mask.Nselected(); idx1++) - { - int atom1 = mask[idx1]; - // Set up coord for this atom - const double* xyz1 = fIn.XYZ( atom1 ); - // Set up exclusion list for this atom - // TODO refactor inner loop to be like StructureCheck - ExclusionArray::ExListType::const_iterator excluded_idx = Excluded[idx1].begin(); - for (int idx2 = idx1 + 1; idx2 < mask.Nselected(); idx2++) - { - int atom2 = mask[idx2]; - // Advance excluded list up to current selected atom - while (excluded_idx != Excluded[idx1].end() && *excluded_idx < idx2) ++excluded_idx; - // If atom is excluded, just increment to next excluded atom. - if (excluded_idx != Excluded[idx1].end() && idx2 == *excluded_idx) - ++excluded_idx; - else { - const double* xyz2 = fIn.XYZ( atom2 ); - T x = xyz1[0] - xyz2[0]; - T y = xyz1[1] - xyz2[1]; - T z = xyz1[2] - xyz2[2]; - T rij2 = (x*x + y*y + z*z); - T rij = sqrt(rij2); - // Coulomb - T qiqj = Constants::COULOMBFACTOR * tIn[atom1].Charge() * tIn[atom2].Charge(); - T e_elec = qiqj / rij; - Eelec += e_elec; -# ifdef DEBUG_ENERGY - mprintf("\tEELEC %4i -- %4i: q1= %12.5e q2= %12.5e r= %12.5f E= %12.5e\n", - atom1+1, atom2+1, tIn[atom1].Charge(), tIn[atom2].Charge(), - rij, e_elec); -# endif - } - } - } -# ifdef _OPENMP - } // END omp parallel -# endif - return Eelec; -} -} -} -#endif diff --git a/src/Energy/Ene_Elec_Image.h b/src/Energy/Ene_Elec_Image.h deleted file mode 100644 index 22b600bb76..0000000000 --- a/src/Energy/Ene_Elec_Image.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef INC_ENERGY_ENE_ELEC_IMAGE_H -#define INC_ENERGY_ENE_ELEC_IMAGE_H -namespace Cpptraj { -namespace Energy { -template -T Ene_Elec_Image(Frame const& fIn, Topology const& tIn, AtomMask const& mask, - ExclusionArray const& Excluded, - int n_points) -{ - // Sum over images. - T Eimage = 0.0; - // Cache npoints values, excluding this cell (0,0,0) - std::vector Cells; - int Ncells = (2*n_points)+1; - Cells.reserve( (Ncells*Ncells*Ncells) - 1 ); - for (int ix = -n_points; ix <= n_points; ix++) - for (int iy = -n_points; iy <= n_points; iy++) - for (int iz = -n_points; iz <= n_points; iz++) - if (ix != 0 || iy != 0 || iz != 0) - Cells.push_back( Vec3(ix, iy, iz) ); - // Outer loop over atoms (i) - for (AtomMask::const_iterator atom1 = mask.begin(); atom1 != mask.end(); ++atom1) - { -// mprintf("\nDEBUG: Atom %i\n", *atom1+1); - Vec3 T1( fIn.XYZ(*atom1) ); - // Inner loop over atoms (j) - for (AtomMask::const_iterator atom2 = mask.begin(); atom2 != mask.end(); ++atom2) - { - Vec3 frac2 = fIn.BoxCrd().FracCell() * Vec3(fIn.XYZ( *atom2 )); // atom j in fractional coords - T qiqj = Constants::COULOMBFACTOR * tIn[*atom1].Charge() * tIn[*atom2].Charge(); - // Loop over images of atom j - for (std::vector::const_iterator ixyz = Cells.begin(); ixyz != Cells.end(); ++ixyz) - { -// mprintf("DEBUG: Atom %4i to %4i Image %3i %3i %3i", *atom1+1, *atom2+1, ix, iy, iz); - // atom j image back in Cartesian space minus atom i in Cartesian space. - Vec3 dxyz = fIn.BoxCrd().UnitCell().TransposeMult(frac2 + *ixyz) - T1; - T rij2 = dxyz.Magnitude2(); - T rij = sqrt(rij2); -// mprintf(" Distance= %g\n", rij); - T e_elec = qiqj / rij; - Eimage += e_elec; - } - } // atom j - } // atom i - return (Eimage/2.0); -} -} -} -#endif From ead268e591a3018ecf4d1f28b7fbe51a5eb03259 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 10 Oct 2024 06:54:30 -0400 Subject: [PATCH 174/218] Make vars available for GIST PME --- src/Energy/EwaldParams.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Energy/EwaldParams.h b/src/Energy/EwaldParams.h index d92dedeeaf..efdd4fb451 100644 --- a/src/Energy/EwaldParams.h +++ b/src/Energy/EwaldParams.h @@ -73,6 +73,10 @@ class EwaldParams { std::vector& SelectedCharges() { return Charge_; } // FIXME do not return const because helPME needs the array to be non-const. Should be fixed std::vector& SelectedCoords() { return coordsD_; } + + // FIXME these can probably go away after GIST_PME is converted + double SumQ() const { return sumq_; } + double SumQ2() const { return sumq2_; } protected: typedef std::vector Darray; typedef std::vector Iarray; From acb9a21024c1d6ef264a679a9b200bebf86a440c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 10 Oct 2024 06:54:58 -0400 Subject: [PATCH 175/218] Use Ecalc_Nonbond --- src/Action_Energy.cpp | 27 ++++++++++++++------------- src/Action_Energy.h | 5 +++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Action_Energy.cpp b/src/Action_Energy.cpp index 1f8f6c299d..29eef54adc 100644 --- a/src/Action_Energy.cpp +++ b/src/Action_Energy.cpp @@ -1,10 +1,10 @@ #include "Action_Energy.h" #include "CpptrajStdio.h" -#include "Ewald_Regular.h" -#include "Ewald_ParticleMesh.h" #include "PotentialFunction.h" #include "MdOpts.h" +using namespace Cpptraj::Energy; + /// CONSTRUCTOR Action_Energy::Action_Energy() : elecType_(NO_ELE), @@ -12,7 +12,7 @@ Action_Energy::Action_Energy() : currentParm_(0), npoints_(0), debug_(0), - EW_(0), + nbCalcType_(Ecalc_Nonbond::UNSPECIFIED), potential_(0), use_openmm_(false), dt_(0), @@ -23,7 +23,6 @@ Action_Energy::Action_Energy() : /// DESTRUCTOR Action_Energy::~Action_Energy() { - if (EW_ != 0) delete EW_; if (potential_ != 0) delete potential_; } @@ -160,7 +159,6 @@ Action::RetType Action_Energy::Init(ArgList& actionArgs, ActionInit& init, int d // Electrostatics type. std::string etypearg = actionArgs.GetStringKey("etype"); elecType_ = NO_ELE; - EW_ = 0; if (!etypearg.empty()) { termEnabled[ELEC] = true; if (etypearg == "directsum") { @@ -170,16 +168,18 @@ Action::RetType Action_Energy::Init(ArgList& actionArgs, ActionInit& init, int d } else if (etypearg == "ewald") { // Ewald method elecType_ = EWALD; + nbCalcType_ = Ecalc_Nonbond::REGULAR_EWALD; if (ewaldOpts_.GetOptions(EwaldOptions::REG_EWALD, actionArgs, "energy")) return Action::ERR; - EW_ = (Ewald*)new Ewald_Regular(); } else if (etypearg == "pme") { // particle mesh Ewald method # ifdef LIBPME elecType_ = PME; + nbCalcType_ = Ecalc_Nonbond::PME; + if (actionArgs.Contains("ljpme")) + nbCalcType_ = Ecalc_Nonbond::LJPME; if (ewaldOpts_.GetOptions(EwaldOptions::PME, actionArgs, "energy")) return Action::ERR; - EW_ = (Ewald*)new Ewald_ParticleMesh(); # else mprinterr("Error: 'pme' requires compiling with LIBPME (FFTW3 and C++11 support).\n"); return Action::ERR; @@ -361,10 +361,11 @@ Action::RetType Action_Energy::Setup(ActionSetup& setup) { } } // Set up Ewald if necessary. - if (elecType_ == EWALD || elecType_ == PME) { - if (EW_->Init(setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + if (nbCalcType_ != Ecalc_Nonbond::UNSPECIFIED) { + if (NB_.InitNonbondCalc(nbCalcType_, false, setup.CoordInfo().TrajBox(), ewaldOpts_, debug_)) + return Action::ERR; + if (NB_.SetupNonbondCalc( setup.Top(), Imask_ )) return Action::ERR; - EW_->Setup( setup.Top(), Imask_ ); } // For KE, check for velocities/forces if (KEtype_ != KE_NONE) { @@ -480,7 +481,7 @@ Action::RetType Action_Energy::DoAction(int frameNum, ActionFrame& frm) { case C_EWALD: case C_PME: // Elec must be enabled, vdw may not be time_NB_.Start(); - err = EW_->CalcNonbondEnergy(frm.Frm(), Imask_, ene, ene2); + err = NB_.NonbondEnergy(frm.Frm(), Imask_, ene, ene2); time_NB_.Stop(); if (err != 0) return Action::ERR; Energy_[ELEC]->Add(frameNum, &ene); @@ -534,8 +535,8 @@ void Action_Energy::Print() { time_14_.WriteTiming(1, "1-4_NONBOND :", time_total_.Total()); if (time_NB_.Total() > 0.0) { time_NB_.WriteTiming(1, "NONBOND :", time_total_.Total()); - if (elecType_ == EWALD || elecType_ == PME) - EW_->Timing(time_NB_.Total()); + if (nbCalcType_ != Ecalc_Nonbond::UNSPECIFIED) + NB_.PrintTiming(time_NB_.Total()); } if (time_ke_.Total() > 0.0) time_ke_.WriteTiming(1, "KE :", time_total_.Total()); diff --git a/src/Action_Energy.h b/src/Action_Energy.h index 19dec5a387..7d47a6a07b 100644 --- a/src/Action_Energy.h +++ b/src/Action_Energy.h @@ -6,7 +6,7 @@ #include "Timer.h" #include "ExclusionArray.h" #include "EwaldOptions.h" -class Ewald; +#include "Energy/Ecalc_Nonbond.h" class PotentialFunction; /// Calculate energy class Action_Energy: public Action { @@ -50,7 +50,8 @@ class Action_Energy: public Action { std::string setname_; ///< Output DataSet name int npoints_; ///< # cells in each direction (DIRECT) int debug_; - Ewald* EW_; ///< Ewald energy class. + Cpptraj::Energy::Ecalc_Nonbond NB_; ///< Nonbond energy calc class. + Cpptraj::Energy::Ecalc_Nonbond::CalcType nbCalcType_; ///< Nonbond calculation type EwaldOptions ewaldOpts_; ///< Ewald options PotentialFunction* potential_; ///< TODO currently just for openmm, use for everything From be9e8a3a39558e7fb2de56f319188f8dce16d6b9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 10 Oct 2024 06:55:18 -0400 Subject: [PATCH 176/218] Start converting to use EwaldParams --- src/GIST_PME.cpp | 110 +++++++++++++++++++++++++++++------------------ src/GIST_PME.h | 28 ++++++++---- 2 files changed, 86 insertions(+), 52 deletions(-) diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index 5e336c81ec..18c701694b 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -6,6 +6,7 @@ #include "Constants.h" #include "ParameterTypes.h" #include "Topology.h" +#include "EwaldOptions.h" /** CONSTRUCTOR */ GIST_PME::GIST_PME() : @@ -22,6 +23,29 @@ const char* GIST_PME::InteractionTypeStr_[] = { "Both_Ongrid" }; +/** Init GIST PME calculation */ +int GIST_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) +{ + // Sanity check + if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { + mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + return 1; + } + mprintf("\tGIST Particle Mesh Ewald params:\n"); + if (InitEwald(boxIn, pmeOpts, debugIn)) { + mprinterr("Error: PME calculation init failed.\n"); + return 1; + } + // Ewald calcs need pairlist + if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) + return 1; + if (pairList_.SetupPairList( boxIn )) + return 1; + + return 0; +} + + /** Setup up GIST PME calculation. Currently must be run on all atoms. */ int GIST_PME::Setup_PME_GIST(Topology const& topIn, unsigned int nthreads, double NeighborCut2_in) { @@ -29,7 +53,7 @@ int GIST_PME::Setup_PME_GIST(Topology const& topIn, unsigned int nthreads, doubl // Select everything allAtoms_ = AtomMask(0, topIn.Natom()); // Set up PME - if (Setup( topIn, allAtoms_ )) { + if (SetupEwald( topIn, allAtoms_ )) { mprinterr("Error: GIST PME setup failed.\n"); return 1; } @@ -112,7 +136,7 @@ int GIST_PME::CalcNonbondEnergy_GIST(Frame const& frameIn, coordsD_.push_back( XYZ[2] ); } - unsigned int natoms = E_elec_self_.size(); + //unsigned int natoms = E_elec_self_.size(); // Recip Potential for each atom e_potentialD_.setConstant(0.0); @@ -126,7 +150,7 @@ int GIST_PME::CalcNonbondEnergy_GIST(Frame const& frameIn, // TODO branch // e_vdw_lr_correction was previously set but unused. // double e_vdw_lr_correction; - double e_vdw6self, e_vdw6recip; + /*double e_vdw6self, e_vdw6recip; if (lw_coeff_ > 0.0) { std::fill(E_vdw_self_.begin(), E_vdw_self_.end(), 0); e_vdw6self = Self6_GIST(E_vdw_self_); @@ -151,12 +175,12 @@ int GIST_PME::CalcNonbondEnergy_GIST(Frame const& frameIn, // e_vdw_lr_correction = 0.0; } else { e_vdw6self = 0.0; - e_vdw6recip = 0.0; + e_vdw6recip = 0.0;*/ std::fill(E_vdw_lr_cor_.begin(), E_vdw_lr_cor_.end(), 0); // e_vdw_lr_correction = Vdw_Correction_GIST( volume, atomIsSolute, E_UV_in[0], E_VV_in[0] ); Vdw_Correction_GIST( volume, atomIsSolute, E_UV_in[0], E_VV_in[0] ); //mprintf("e_vdw_lr_correction: %f \n", e_vdw_lr_correction); - } + /*}*/ double e_vdw = 0.0; double e_direct = Direct_GIST( pairList_, e_vdw, atom_voxel, atomIsSolute, atomIsSolventO, @@ -166,7 +190,7 @@ int GIST_PME::CalcNonbondEnergy_GIST(Frame const& frameIn, //mprintf("e_elec_self: %f , e_elec_direct: %f, e_vdw6direct: %f \n", e_self, e_direct, e_vdw); - if (debug_ > 0) + if (Debug() > 0) mprintf("DEBUG: gistpme Eself= %20.10f Erecip= %20.10f Edirect= %20.10f Evdw= %20.10f\n", e_self, e_recip, e_direct, e_vdw); @@ -197,7 +221,7 @@ int GIST_PME::CalcNonbondEnergy_GIST(Frame const& frameIn, # endif // DEBUG - if (debug_ > 0) { + if (Debug() > 0) { // Calculate the sum of each terms double E_elec_direct_sum = SumDarray( E_elec_direct_[0] ); double E_vdw_direct_sum = SumDarray( E_vdw_direct_[0] ); @@ -225,12 +249,13 @@ double GIST_PME::Self_GIST(double volume, Darray& atom_self, Darray& e_vv_elec) { t_self_.Start(); - double d0 = -ew_coeff_ * INVSQRTPI_; + double d0 = -EwaldCoeff() * INVSQRTPI(); double ene = SumQ2() * d0; // mprintf("DEBUG: d0= %20.10f ene= %20.10f\n", d0, ene); - double factor = Constants::PI / (ew_coeff_ * ew_coeff_ * volume); + double factor = Constants::PI / (EwaldCoeff() * EwaldCoeff() * volume); double ee_plasma = -0.5 * factor * SumQ() * SumQ(); + Darray const& Charge_ = Charge(); for( unsigned int i=0; i< Charge_.size();i++) { // distribute the "neutrilizing plasma" to atoms equally @@ -253,7 +278,7 @@ double GIST_PME::Self_GIST(double volume, Darray& atom_self, } /** Lennard-Jones self energy. for GIST */ -double GIST_PME::Self6_GIST(Darray& atom_vdw_self) { +/*double GIST_PME::Self6_GIST(Darray& atom_vdw_self) { t_self_.Start(); // TODO precalc double ew2 = lw_coeff_ * lw_coeff_; double ew6 = ew2 * ew2 * ew2; @@ -267,7 +292,7 @@ double GIST_PME::Self6_GIST(Darray& atom_vdw_self) { } t_self_.Stop(); return c6sum / 12.0; -} +}*/ /** PME recip calc for GIST to store decomposed recipical energy for every atom. */ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, @@ -277,8 +302,8 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, { t_recip_.Start(); // This essentially makes coordsD and chargesD point to arrays. - MatType coordsD(&coordsD_[0], Charge_.size(), 3); - MatType chargesD(&Charge_[0], Charge_.size(), 1); + MatType coordsD(&coordsD_[0], Charge().size(), 3); + MatType chargesD(&SelectedCharges()[0], Charge().size(), 1); int nfft1 = Nfft(0); int nfft2 = Nfft(1); int nfft3 = Nfft(2); @@ -298,7 +323,7 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(1, ew_coeff_, Order(), nfft1, nfft2, nfft3, 1.0, 0); + pme_object_.setup(1, EwaldCoeff(), Order(), nfft1, nfft2, nfft3, 1.0, 0); // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. // Args: 1 = the A lattice parameter in units consistent with the coordinates. // 2 = the B lattice parameter in units consistent with the coordinates. @@ -313,9 +338,9 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, //double erecip = pme_object_.computeERec(0, chargesD, coordsD); double erecip = 0; pme_object_.computePRec(0,chargesD,coordsD,coordsD,1,e_potentialD_); - for(unsigned int i =0; i < Charge_.size(); i++) + for(unsigned int i =0; i < Charge().size(); i++) { - E_elec_recip_[i]=0.5 * Charge_[i] * e_potentialD_(i,0); + E_elec_recip_[i]=0.5 * Charge()[i] * e_potentialD_(i,0); } // For UV interaction, we need solute charges + positions and on-grid solvent positions. @@ -326,18 +351,18 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, Darray Vcoords, Vcharges; unsigned int xidx = 0; // Index into coordsD_ unsigned int n_on_grid = 0; // Number of solvent atoms on grid - for (unsigned int atidx = 0; atidx != Charge_.size(); atidx++, xidx += 3) + for (unsigned int atidx = 0; atidx != Charge().size(); atidx++, xidx += 3) { if (atomIsSolute[atidx]) { Ucoords.push_back( coordsD_[xidx ] ); Ucoords.push_back( coordsD_[xidx+1] ); Ucoords.push_back( coordsD_[xidx+2] ); - Ucharges.push_back( Charge_[atidx] ); + Ucharges.push_back( Charge()[atidx] ); } else { Vcoords.push_back( coordsD_[xidx ] ); Vcoords.push_back( coordsD_[xidx+1] ); Vcoords.push_back( coordsD_[xidx+2] ); - Vcharges.push_back( Charge_[atidx] ); + Vcharges.push_back( Charge()[atidx] ); if (atom_voxel[atidx] > -1) { onGridCoords.push_back( coordsD_[xidx ] ); onGridCoords.push_back( coordsD_[xidx+1] ); @@ -360,7 +385,7 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, # ifdef DEBUG_GIST_PME mprintf("DEBUG: gistpme uv recip at %i erecip= %20.10g\n", onGridAt[i], Charge_[onGridAt[i]] * ongrid_potentialD(i, 0)); # endif - e_uv_elec[onGridAt[i]] += Charge_[onGridAt[i]] * ongrid_potentialD(i, 0); + e_uv_elec[onGridAt[i]] += Charge()[onGridAt[i]] * ongrid_potentialD(i, 0); } // VV recip. // NOTE: If we do not zero the potential matrix, it will be summed into @@ -370,7 +395,7 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, # ifdef DEBUG_GIST_PME mprintf("DEBUG: gistpme vv recip at %i erecip= %20.10g\n", onGridAt[i], Charge_[onGridAt[i]] * ongrid_potentialD(i, 0)); # endif - e_vv_elec[onGridAt[i]] += Charge_[onGridAt[i]] * ongrid_potentialD(i, 0); + e_vv_elec[onGridAt[i]] += Charge()[onGridAt[i]] * ongrid_potentialD(i, 0); } t_recip_.Stop(); @@ -378,7 +403,7 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, } /** The LJ PME reciprocal term for GIST*/ -double GIST_PME::LJ_Recip_ParticleMesh_GIST(Box const& boxIn, MatType& potential) +/*double GIST_PME::LJ_Recip_ParticleMesh_GIST(Box const& boxIn, MatType& potential) { t_recip_.Start(); int nfft1 = Nfft(0); @@ -402,7 +427,7 @@ double GIST_PME::LJ_Recip_ParticleMesh_GIST(Box const& boxIn, MatType& potential pme_vdw_.computePRec(0,cparamD,coordsD,coordsD,1,potential); t_recip_.Stop(); return evdwrecip; -} +}*/ /** Calculate full VDW long range correction from volume. */ double GIST_PME::Vdw_Correction_GIST(double volume, @@ -410,7 +435,7 @@ double GIST_PME::Vdw_Correction_GIST(double volume, std::vector const& atomIsSolute, Darray& e_uv_vdw, Darray& e_vv_vdw) { - double prefac = Constants::TWOPI / (3.0*volume*cutoff_*cutoff_*cutoff_); + double prefac = Constants::TWOPI / (3.0*volume*Cutoff()*Cutoff()*Cutoff()); //mprintf("VDW correction prefac: %.15f \n", prefac); double e_vdwr = -prefac * Vdw_Recip_Term(); @@ -458,7 +483,7 @@ double GIST_PME::Vdw_Correction_GIST(double volume, // } } - if (debug_ > 0) mprintf("DEBUG: gistpme Vdw correction %20.10f\n", e_vdwr); + if (Debug() > 0) mprintf("DEBUG: gistpme Vdw correction %20.10f\n", e_vdwr); return e_vdwr; } @@ -472,9 +497,9 @@ double GIST_PME::Direct_GIST(PairList const& PL, double& evdw_out, std::vector& Neighbor_in) { - if (lw_coeff_ > 0.0) - return Direct_VDW_LJPME_GIST(PL, evdw_out); - else + //if (lw_coeff_ > 0.0) + // return Direct_VDW_LJPME_GIST(PL, evdw_out); + //else return Direct_VDW_LongRangeCorrection_GIST(PL, evdw_out, atom_voxel, atomIsSolute, atomIsSolventO, E_UV_in, E_VV_in, @@ -575,7 +600,7 @@ void GIST_PME::Ekernel_NB(double& Eelec, double& Evdw, t_erfc_.Start(); # endif //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ErfcFxn(ew_coeff_ * rij); + double erfc = ErfcEW(rij); # ifndef _OPENMP t_erfc_.Stop(); # endif @@ -604,11 +629,10 @@ void GIST_PME::Ekernel_NB(double& Eelec, double& Evdw, e_vv[idx1] += e_elec; } - int nbindex = NB().GetLJindex(TypeIdx(idx0), - TypeIdx(idx1)); + int nbindex = NbIndex(idx0, idx1); if (nbindex > -1) { - double vswitch = SwitchFxn(rij2, cut2_0_, cut2_); - NonbondType const& LJ = NB().NBarray()[ nbindex ]; + double vswitch = Switch_Fn(rij2); + NonbondType const& LJ = GetLJ( nbindex ); double r2 = 1.0 / rij2; double r6 = r2 * r2 * r2; double r12 = r6 * r6; @@ -772,7 +796,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& it0 != thisCell.end(); ++it0) { Vec3 const& xyz0 = it0->ImageCoords(); - double q0 = Charge_[it0->Idx()]; + double q0 = Charge()[it0->Idx()]; // The voxel # of it0 int it0_voxel = atom_voxel[it0->Idx()]; bool it0_solute = atomIsSolute[it0->Idx()]; @@ -792,7 +816,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& bool it1_solventO = atomIsSolventO[it1->Idx()]; if (it0_voxel > -1 || it1_voxel > -1) { Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; + double q1 = Charge()[it1->Idx()]; Vec3 dxyz = xyz1 - xyz0; double rij2 = dxyz.Magnitude2(); # ifdef DEBUG_PAIRLIST @@ -802,7 +826,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& // If atom excluded, calc adjustment, otherwise calc elec. energy. if (excluded.find( it1->Idx() ) == excluded.end()) { - if ( rij2 < cut2_ ) { + if ( rij2 < Cut2() ) { Ekernel_NB(Eelec, Evdw, rij2, q0, q1, it0->Idx(), it1->Idx(), e_elec_direct, e_vdw_direct, interactionType,// it0_voxel, it1_voxel, // e_uv_vdw, e_uv_elec, e_vv_vdw, e_vv_elec); @@ -836,7 +860,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& bool it1_solventO = atomIsSolventO[it1->Idx()]; if (it0_voxel > -1 || it1_voxel > -1) { Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; + double q1 = Charge()[it1->Idx()]; Vec3 dxyz = xyz1 + tVec - xyz0; double rij2 = dxyz.Magnitude2(); # ifdef DEBUG_PAIRLIST @@ -849,7 +873,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& if (excluded.find( it1->Idx() ) == excluded.end()) { //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); - if ( rij2 < cut2_ ) { + if ( rij2 < Cut2() ) { Ekernel_NB(Eelec, Evdw, rij2, q0, q1, it0->Idx(), it1->Idx(), e_elec_direct, e_vdw_direct, interactionType,// it0_voxel, it1_voxel, // e_uv_vdw, e_uv_elec, e_vv_vdw, e_vv_elec); @@ -893,10 +917,10 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& } /** Direct space calculation with LJ PME for GIST. */ // TODO enable -double GIST_PME::Direct_VDW_LJPME_GIST(PairList const& PL, double& evdw_out) -{ - mprinterr("Error: LJPME does not yet work with GIST.\n"); - return 0; +//double GIST_PME::Direct_VDW_LJPME_GIST(PairList const& PL, double& evdw_out) +//{ +// mprinterr("Error: LJPME does not yet work with GIST.\n"); +// return 0; /* t_direct_.Start(); double Eelec = 0.0; @@ -1026,5 +1050,5 @@ double GIST_PME::Direct_VDW_LJPME_GIST(PairList const& PL, double& evdw_out) evdw_out = Evdw + Eljpme_correction + Eljpme_correction_excl; return Eelec + e_adjust; */ -} +//} #endif /* LIBPME */ diff --git a/src/GIST_PME.h b/src/GIST_PME.h index ca0baafe71..0c48743a3b 100644 --- a/src/GIST_PME.h +++ b/src/GIST_PME.h @@ -2,27 +2,31 @@ #define INC_GIST_PME_H #ifdef LIBPME #include -#include "Ewald_ParticleMesh.h" #include "AtomMask.h" -class Frame; +#include "Energy/EwaldParams.h" +#include "helpme_standalone.h" +#include "PairList.h" +#include "Timer.h" class Box; +class Frame; class Topology; /// Class implementing the PME version of the nonbonded energy calc. for GIST /** For more debug info, compile with: * -DDEBUG_GIST_PME : Details on breakdown of PME calculation for the UV/VV grids. * -DDEBUG_PAIRLIST : Details on the use of the pair list in the direct space calc. */ -class GIST_PME : private Ewald_ParticleMesh { +class GIST_PME : private Cpptraj::Energy::EwaldParams { public: GIST_PME(); // Expose definitions/functions from Ewald_ParticleMesh - using Ewald::Darray; - using Ewald_ParticleMesh::Init; - using Ewald::Timing; + using Cpptraj::Energy::EwaldParams::Darray; + //using Ewald_ParticleMesh::Init; + //using Ewald::Timing; typedef std::vector Farray; + int Init(Box const&, EwaldOptions const&, int); /// Setup PME calc. for top, all atoms. Allocate memory for internal arrays (# threads) int Setup_PME_GIST(Topology const&, unsigned int, double); /// Calculate nonbonded energy with PME for GIST @@ -78,12 +82,12 @@ class GIST_PME : private Ewald_ParticleMesh { /// Electrostatic self energy, decomposed onto atoms. double Self_GIST(double, Darray&, std::vector const&, std::vector const&, Darray&); /// Lennard-Jones self energy, decomposed onto atoms. - double Self6_GIST(Darray&); + //double Self6_GIST(Darray&); /// Reciprocal energy decomposed for every atom. double Recip_ParticleMesh_GIST(Box const&, std::vector const&, std::vector const&, Darray&, Darray&); /// LJ reciprocal term, decomposed for every atom. - double LJ_Recip_ParticleMesh_GIST(Box const&, MatType&); + //double LJ_Recip_ParticleMesh_GIST(Box const&, MatType&); /// VDW long range correction for GIST double Vdw_Correction_GIST(double, std::vector const&, Darray&, Darray&); @@ -102,7 +106,7 @@ class GIST_PME : private Ewald_ParticleMesh { std::vector&, std::vector&, std::vector&); /// Calculate direct space energy with LJ PME for GIST, decomposed for every atom. - double Direct_VDW_LJPME_GIST(PairList const&, double&); + //double Direct_VDW_LJPME_GIST(PairList const&, double&); // TODO could potentially make the calculation more efficient by skipping // the per-atom arrays below and just passing in the GIST PME @@ -123,6 +127,12 @@ class GIST_PME : private Ewald_ParticleMesh { AtomMask allAtoms_; ///< Select all atoms double NeighborCut2_; ///< Cutoff for the O-O neighbor calculation + Timer t_total_; + Timer t_recip_; + Timer t_direct_; + Timer t_self_; + PairList pairList_; + Darray coordsD_; }; #endif /* LIBPME */ #endif From 693c60aa18ad0283ade8a00fd6c9baad67ad52c8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 11:21:01 -0400 Subject: [PATCH 177/218] Add PME_RecipParams class --- src/Energy/CMakeLists.txt | 1 + src/Energy/PME_RecipParams.cpp | 119 +++++++++++++++++++++++++++++++++ src/Energy/PME_RecipParams.h | 35 ++++++++++ src/Energy/energydepend | 3 +- src/Energy/energyfiles | 1 + 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/Energy/PME_RecipParams.cpp create mode 100644 src/Energy/PME_RecipParams.h diff --git a/src/Energy/CMakeLists.txt b/src/Energy/CMakeLists.txt index d41cbefd44..d8fffe4717 100644 --- a/src/Energy/CMakeLists.txt +++ b/src/Energy/CMakeLists.txt @@ -12,5 +12,6 @@ target_sources(cpptraj_common_obj PRIVATE ${CMAKE_CURRENT_LIST_DIR}/EwaldParams_LJPME.cpp ${CMAKE_CURRENT_LIST_DIR}/Ewald_Recip.cpp ${CMAKE_CURRENT_LIST_DIR}/PME_Recip.cpp + ${CMAKE_CURRENT_LIST_DIR}/PME_RecipParams.cpp ${CMAKE_CURRENT_LIST_DIR}/VDW_LongRange_Correction.cpp ) diff --git a/src/Energy/PME_RecipParams.cpp b/src/Energy/PME_RecipParams.cpp new file mode 100644 index 0000000000..ed4d9971e7 --- /dev/null +++ b/src/Energy/PME_RecipParams.cpp @@ -0,0 +1,119 @@ +#include "PME_RecipParams.h" +#include "../Box.h" +#include "../CpptrajStdio.h" +#include "../EwaldOptions.h" + +using namespace Cpptraj::Energy; + +/** CONSTRUCTOR - NFFT=-1 means auto-assign. */ +PME_RecipParams::PME_RecipParams() : + order_(6), + debug_(0) +{ + nfft_[0] = -1; + nfft_[1] = -1; + nfft_[2] = -1; +} + +/** Initialize PME recip options. */ +int PME_RecipParams::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { + debug_ = debugIn; + nfft_[0] = pmeOpts.Nfft1(); + nfft_[1] = pmeOpts.Nfft2(); + nfft_[2] = pmeOpts.Nfft3(); + order_ = pmeOpts.SplineOrder(); + // Set defaults if necessary + if (order_ < 1) order_ = 6; + PrintRecipOpts(); + return 0; +} + +/** Print options to stdout. */ +void PME_RecipParams::PrintRecipOpts() const { + //mprintf("\tRecip opts (distance kernel exponent= %i\n", distKernelExponent_); + mprintf("\t Bspline order= %i\n", order_); + mprintf("\t "); + for (int i = 0; i != 3; i++) + if (nfft_[i] == -1) + mprintf(" NFFT%i=auto", i+1); + else + mprintf(" NFFT%i=%i", i+1, nfft_[i]); + mprintf("\n"); +} + +/** \return true if given number is a product of powers of 2, 3, or 5. */ +bool PME_RecipParams::check_prime_factors(int nIn) { + if (nIn == 1) return true; + int NL = nIn; + int NQ; + // First divide down by 2 + while (NL > 0) { + NQ = NL / 2; + if (NQ * 2 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + // Next try 3 + while (NL > 0) { + NQ = NL / 3; + if (NQ * 3 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + // Last try 5 + while (NL > 0) { + NQ = NL / 5; + if (NQ * 5 != NL) break; + if (NQ == 1) return true; + NL = NQ; + } + return false; +} + +/** Compute the ceiling of len that is also a product of powers of 2, 3, 5. + * Use check_prime_factors to get the smallest integer greater or equal + * than len which is decomposable into powers of 2, 3, 5. + */ +int PME_RecipParams::ComputeNFFT(double len) { + int mval = (int)len - 1; + for (int i = 0; i < 100; i++) { + mval += 1; + // Sanity check + if (mval < 1) { + mprinterr("Error: Bad box length %g, cannot get NFFT value.\n", len); + return 0; + } + if (check_prime_factors(mval)) + return mval; + } + mprinterr("Error: Failed to get good FFT array size for length %g Ang.\n", len); + return 0; +} + +/** Given a box, determine number of FFT grid points in each dimension. */ +int PME_RecipParams::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxIn) const +{ + // FIXME Should this be checking if NFFT would change instead? + nfft1 = nfft_[0]; + nfft2 = nfft_[1]; + nfft3 = nfft_[2]; + if (nfft1 < 1) { + // Need even dimension for X direction + nfft1 = ComputeNFFT( (boxIn.Param(Box::X) + 1.0) * 0.5 ); + nfft1 *= 2; + } + if (nfft2 < 1) + nfft2 = ComputeNFFT( boxIn.Param(Box::Y) ); + if (nfft3 < 1) + nfft3 = ComputeNFFT( boxIn.Param(Box::Z) ); + + if (nfft1 < 1 || nfft2 < 1 || nfft3 < 1) { + mprinterr("Error: Bad NFFT values: %i %i %i\n", nfft1, nfft2, nfft3); + return 1; + } + if (debug_ > 0) mprintf("DEBUG: NFFTs: %i %i %i\n", nfft1, nfft2, nfft3); + + return 0; +} + + diff --git a/src/Energy/PME_RecipParams.h b/src/Energy/PME_RecipParams.h new file mode 100644 index 0000000000..757467f47b --- /dev/null +++ b/src/Energy/PME_RecipParams.h @@ -0,0 +1,35 @@ +#ifndef INC_ENERGY_PME_RECIPPARAMS_H +#define INC_ENERGY_PME_RECIPPARAMS_H +class Box; +class EwaldOptions; +namespace Cpptraj { +namespace Energy { +/// Hold parameters for the reciprocal part of PME +/** NOTE: This is kept separate from PME_Recip so that classes that + * do the recip. calculation a little differently (like GIST_PME) + * can have access to the routines that assign NFFT etc. + */ +class PME_RecipParams { + public: + /// CONSTRUCTOR + PME_RecipParams(); + /// Initilize recip options + int InitRecip(EwaldOptions const&, int); + /// Print recip options to stdout + void PrintRecipOpts() const; + /// Determine FFT grid points in X, Y, Z from box lengths + int DetermineNfft(int&, int&, int&, Box const&) const; + + /// \return B-Spline order + int Order() const { return order_; } + private: + static bool check_prime_factors(int); + static int ComputeNFFT(double); + + int nfft_[3]; ///< Number of grid points for FFT in X, Y, Z + int order_; ///< B-Spline order + int debug_; +}; +} +} +#endif diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 77f95f9b6a..1d88d978f3 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -9,5 +9,6 @@ EwaldCalc_Regular.o : EwaldCalc_Regular.cpp ../Atom.h ../AtomMask.h ../Box.h ../ EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h Ewald_Recip.o : Ewald_Recip.cpp ../Box.h ../Constants.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../ParameterTypes.h ../SplineFxnTable.h ../StringRoutines.h ../Timer.h ../Vec3.h ErfcFxn.h EwaldParams.h Ewald_Recip.h -PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h +PME_Recip.o : PME_Recip.cpp ../Box.h ../CpptrajStdio.h ../Matrix_3x3.h ../Parallel.h ../Timer.h ../Vec3.h ../helpme_standalone.h PME_Recip.h PME_RecipParams.h +PME_RecipParams.o : PME_RecipParams.cpp ../Box.h ../CpptrajStdio.h ../EwaldOptions.h ../Matrix_3x3.h ../Parallel.h ../Vec3.h PME_RecipParams.h VDW_LongRange_Correction.o : VDW_LongRange_Correction.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h VDW_LongRange_Correction.h diff --git a/src/Energy/energyfiles b/src/Energy/energyfiles index acc799bc74..f60e63168b 100644 --- a/src/Energy/energyfiles +++ b/src/Energy/energyfiles @@ -12,4 +12,5 @@ ENERGY_SOURCES= \ EwaldParams_LJPME.cpp \ Ewald_Recip.cpp \ PME_Recip.cpp \ + PME_RecipParams.cpp \ VDW_LongRange_Correction.cpp From 34a47cc8ae37176d9af14c1205115e513c4eeb1f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 11:21:19 -0400 Subject: [PATCH 178/218] Use PME_RecipParams class --- src/Energy/PME_Recip.cpp | 129 +++++---------------------------------- src/Energy/PME_Recip.h | 17 +----- 2 files changed, 19 insertions(+), 127 deletions(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index 1a841a0147..aa55adb308 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -1,14 +1,13 @@ #include "PME_Recip.h" +#include "PME_RecipParams.h" #include "../Box.h" #include "../CpptrajStdio.h" -#include "../EwaldOptions.h" typedef helpme::Matrix Mat; using namespace Cpptraj::Energy; -PME_Recip::PME_Recip(Type typeIn) : - debug_(0) +PME_Recip::PME_Recip(Type typeIn) { switch (typeIn) { case COULOMB: @@ -22,103 +21,6 @@ PME_Recip::PME_Recip(Type typeIn) : } } -/** Init */ -int PME_Recip::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { - debug_ = debugIn; - nfft_[0] = pmeOpts.Nfft1(); - nfft_[1] = pmeOpts.Nfft2(); - nfft_[2] = pmeOpts.Nfft3(); - order_ = pmeOpts.SplineOrder(); - // Set defaults if necessary - if (order_ < 1) order_ = 6; - PrintRecipOpts(); - return 0; -} - -/** Print options to stdout. */ -void PME_Recip::PrintRecipOpts() const { - mprintf("\tRecip opts (distance kernel exponent= %i\n", distKernelExponent_); - mprintf("\t Bspline order= %i\n", order_); - mprintf("\t "); - for (int i = 0; i != 3; i++) - if (nfft_[i] == -1) - mprintf(" NFFT%i=auto", i+1); - else - mprintf(" NFFT%i=%i", i+1, nfft_[i]); - mprintf("\n"); -} - -/** \return true if given number is a product of powers of 2, 3, or 5. */ -bool PME_Recip::check_prime_factors(int nIn) { - if (nIn == 1) return true; - int NL = nIn; - int NQ; - // First divide down by 2 - while (NL > 0) { - NQ = NL / 2; - if (NQ * 2 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - // Next try 3 - while (NL > 0) { - NQ = NL / 3; - if (NQ * 3 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - // Last try 5 - while (NL > 0) { - NQ = NL / 5; - if (NQ * 5 != NL) break; - if (NQ == 1) return true; - NL = NQ; - } - return false; -} - -/** Compute the ceiling of len that is also a product of powers of 2, 3, 5. - * Use check_prime_factors to get the smallest integer greater or equal - * than len which is decomposable into powers of 2, 3, 5. - */ -int PME_Recip::ComputeNFFT(double len) { - int mval = (int)len - 1; - for (int i = 0; i < 100; i++) { - mval += 1; - // Sanity check - if (mval < 1) { - mprinterr("Error: Bad box length %g, cannot get NFFT value.\n", len); - return 0; - } - if (check_prime_factors(mval)) - return mval; - } - mprinterr("Error: Failed to get good FFT array size for length %g Ang.\n", len); - return 0; -} - -/** Given a box, determine number of FFT grid points in each dimension. */ -int PME_Recip::DetermineNfft(int& nfft1, int& nfft2, int& nfft3, Box const& boxIn) const -{ - if (nfft1 < 1) { - // Need even dimension for X direction - nfft1 = ComputeNFFT( (boxIn.Param(Box::X) + 1.0) * 0.5 ); - nfft1 *= 2; - } - if (nfft2 < 1) - nfft2 = ComputeNFFT( boxIn.Param(Box::Y) ); - if (nfft3 < 1) - nfft3 = ComputeNFFT( boxIn.Param(Box::Z) ); - - if (nfft1 < 1 || nfft2 < 1 || nfft3 < 1) { - mprinterr("Error: Bad NFFT values: %i %i %i\n", nfft1, nfft2, nfft3); - return 1; - } - if (debug_ > 0) mprintf("DEBUG: NFFTs: %i %i %i\n", nfft1, nfft2, nfft3); - - return 0; -} - /** \return 1 if the box type is invalid for helPME */ int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) { lattice = PMEInstanceD::LatticeType::XAligned; @@ -137,17 +39,17 @@ int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that -double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) +double PME_Recip::Recip_ParticleMesh(PME_RecipParams const& recipParams, + Darray& coordsDin, Box const& boxIn, + Darray& ChargeIn, double ew_coeffIn) { t_recip_.Start(); // This essentially makes coordsD and chargesD point to arrays. Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); - int nfft1 = nfft_[0]; - int nfft2 = nfft_[1]; - int nfft3 = nfft_[2]; + int nfft1, nfft2, nfft3; - if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + if ( recipParams.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; } @@ -163,7 +65,7 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(distKernelExponent_, ew_coeffIn, order_, nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; @@ -187,24 +89,25 @@ double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that -double PME_Recip::Recip_Decomp(Darray& atom_recip, - Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) +double PME_Recip::Recip_Decomp(PME_RecipParams const& recipParams, + Darray& atom_recip, + Darray& coordsDin, Box const& boxIn, + Darray& ChargeIn, double ew_coeffIn) { t_recip_.Start(); atom_recip.resize( ChargeIn.size() ); // This essentially makes coordsD and chargesD point to arrays. Mat coordsD(&coordsDin[0], ChargeIn.size(), 3); Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); - int nfft1 = nfft_[0]; - int nfft2 = nfft_[1]; - int nfft3 = nfft_[2]; + int nfft1, nfft2, nfft3; - if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + if ( recipParams.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; } + // Instantiate double precision PME object - pme_object_.setup(distKernelExponent_, ew_coeffIn, order_, nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 67d0a7f7e0..40df11bdf8 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -3,9 +3,9 @@ #include "../helpme_standalone.h" #include "../Timer.h" class Box; -class EwaldOptions; namespace Cpptraj { namespace Energy { +class PME_RecipParams; /// Do the reciprocal part of a PME calculation class PME_Recip { typedef std::vector Darray; @@ -13,29 +13,18 @@ class PME_Recip { enum Type { COULOMB = 0, LJ }; PME_Recip(Type); - /// Initialize - int InitRecip(EwaldOptions const& pmeOpts, int); - /// Print options to stdout - void PrintRecipOpts() const; - - double Recip_ParticleMesh(Darray&, Box const&, Darray&, double); - double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, double); + double Recip_ParticleMesh(PME_RecipParams const&, Darray&, Box const&, Darray&, double); + double Recip_Decomp(PME_RecipParams const&, Darray&, Darray&, Box const&, Darray&, double); Timer const& Timing_Total() const { return t_recip_; } //Timer const& Timing_Calc() const { return t_calc_; } private: - static bool check_prime_factors(int); - static int ComputeNFFT(double); - int DetermineNfft(int&, int&, int&, Box const&) const; static int set_lattice(PMEInstanceD::LatticeType&, Box const&); PMEInstanceD pme_object_; Timer t_recip_; ///< Recip calc timer //Timer t_calc_; - int nfft_[3]; ///< Number of grid points for FFT in X, Y, Z - int order_; ///< B-Spline order - int debug_; int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof }; From 7099669c4638fb44f02db5d93af2e6d92ec8dfc8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 11:32:28 -0400 Subject: [PATCH 179/218] Put PME_EwaldParams inside PME_Recip --- src/Energy/PME_Recip.cpp | 28 +++++++++++++++++++--------- src/Energy/PME_Recip.h | 18 ++++++++++++------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index aa55adb308..bca08da188 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -1,5 +1,4 @@ #include "PME_Recip.h" -#include "PME_RecipParams.h" #include "../Box.h" #include "../CpptrajStdio.h" @@ -21,6 +20,19 @@ PME_Recip::PME_Recip(Type typeIn) } } +/** Init */ +int PME_Recip::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { + if (recipParams_.InitRecip(pmeOpts, debugIn)) return 1; + PrintRecipOpts(); + return 0; +} + +/** Print options to stdout. */ +void PME_Recip::PrintRecipOpts() const { + mprintf("\tRecip opts (distance kernel exponent= %i\n", distKernelExponent_); + recipParams_.PrintRecipOpts(); +} + /** \return 1 if the box type is invalid for helPME */ int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) { lattice = PMEInstanceD::LatticeType::XAligned; @@ -39,8 +51,7 @@ int PME_Recip::set_lattice(PMEInstanceD::LatticeType& lattice, Box const& boxIn) /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that -double PME_Recip::Recip_ParticleMesh(PME_RecipParams const& recipParams, - Darray& coordsDin, Box const& boxIn, +double PME_Recip::Recip_ParticleMesh(Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) { t_recip_.Start(); @@ -49,7 +60,7 @@ double PME_Recip::Recip_ParticleMesh(PME_RecipParams const& recipParams, Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); int nfft1, nfft2, nfft3; - if ( recipParams.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + if ( recipParams_.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; } @@ -65,7 +76,7 @@ double PME_Recip::Recip_ParticleMesh(PME_RecipParams const& recipParams, // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams_.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; @@ -89,8 +100,7 @@ double PME_Recip::Recip_ParticleMesh(PME_RecipParams const& recipParams, /** \return Reciprocal space part of PME energy calc. */ // TODO currently helPME needs the coords/charge arrays to be non-const, need to fix that -double PME_Recip::Recip_Decomp(PME_RecipParams const& recipParams, - Darray& atom_recip, +double PME_Recip::Recip_Decomp(Darray& atom_recip, Darray& coordsDin, Box const& boxIn, Darray& ChargeIn, double ew_coeffIn) { @@ -101,13 +111,13 @@ double PME_Recip::Recip_Decomp(PME_RecipParams const& recipParams, Mat chargesD(&ChargeIn[0], ChargeIn.size(), 1); int nfft1, nfft2, nfft3; - if ( recipParams.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + if ( recipParams_.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine FFT grid spacing.\n"); return 0.0; } // Instantiate double precision PME object - pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); + pme_object_.setup(distKernelExponent_, ew_coeffIn, recipParams_.Order(), nfft1, nfft2, nfft3, scaleFac_, 0); // Check the unit cell vectors PMEInstanceD::LatticeType lattice; if (set_lattice(lattice, boxIn)) return 0; diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 40df11bdf8..9aca5e4330 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -2,10 +2,10 @@ #define INC_ENERGY_PME_RECIP_H #include "../helpme_standalone.h" #include "../Timer.h" +#include "PME_RecipParams.h" class Box; namespace Cpptraj { namespace Energy { -class PME_RecipParams; /// Do the reciprocal part of a PME calculation class PME_Recip { typedef std::vector Darray; @@ -14,8 +14,13 @@ class PME_Recip { PME_Recip(Type); - double Recip_ParticleMesh(PME_RecipParams const&, Darray&, Box const&, Darray&, double); - double Recip_Decomp(PME_RecipParams const&, Darray&, Darray&, Box const&, Darray&, double); + /// Initialize + int InitRecip(EwaldOptions const& pmeOpts, int); + /// Print options to stdout + void PrintRecipOpts() const; + + double Recip_ParticleMesh(Darray&, Box const&, Darray&, double); + double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, double); Timer const& Timing_Total() const { return t_recip_; } //Timer const& Timing_Calc() const { return t_calc_; } @@ -23,10 +28,11 @@ class PME_Recip { static int set_lattice(PMEInstanceD::LatticeType&, Box const&); PMEInstanceD pme_object_; - Timer t_recip_; ///< Recip calc timer + PME_RecipParams recipParams_; ///< Hold PME recip parameters + Timer t_recip_; ///< Recip calc timer //Timer t_calc_; - int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ - double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof + int distKernelExponent_; ///< Exponent of the distance kernel: 1 for Coulomb, 6 for LJ + double scaleFac_; ///< scale factor to be applied to all computed energies and derivatives thereof }; } } From e92f6939e94b2a650cdafa45b21f10886b42ebe5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 11:33:18 -0400 Subject: [PATCH 180/218] Dont call print inside the init --- src/Energy/PME_RecipParams.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Energy/PME_RecipParams.cpp b/src/Energy/PME_RecipParams.cpp index ed4d9971e7..0d8fc61e36 100644 --- a/src/Energy/PME_RecipParams.cpp +++ b/src/Energy/PME_RecipParams.cpp @@ -24,7 +24,6 @@ int PME_RecipParams::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { order_ = pmeOpts.SplineOrder(); // Set defaults if necessary if (order_ < 1) order_ = 6; - PrintRecipOpts(); return 0; } From c263b71f640482bb6540eba56552c917c712adc2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 14:04:52 -0400 Subject: [PATCH 181/218] Expose arrays needed by GIST_PME --- src/Energy/VDW_LongRange_Correction.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Energy/VDW_LongRange_Correction.h b/src/Energy/VDW_LongRange_Correction.h index 6a0cf3b593..ac10195406 100644 --- a/src/Energy/VDW_LongRange_Correction.h +++ b/src/Energy/VDW_LongRange_Correction.h @@ -7,6 +7,8 @@ class Topology; namespace Cpptraj { namespace Energy { class VDW_LongRange_Correction { + typedef std::vector Iarray; + typedef std::vector Darray; public: VDW_LongRange_Correction(); void SetDebug(int); @@ -20,9 +22,13 @@ class VDW_LongRange_Correction { } /// VDW correction decomposed per atom double Vdw_Decomp_Correction(std::vector&, double, double) const; + + // FIXME below are currently exposed for GIST_PME + double Vdw_Recip_Term() const { return Vdw_Recip_term_; } + Iarray const& VDW_Type() const { return vdw_type_; } + Darray const& Atype_VDW_Recip_Terms() const { return atype_vdw_recip_terms_; } + Iarray const& N_VDW_Type() const { return N_vdw_type_; } private: - typedef std::vector Iarray; - typedef std::vector Darray; double Vdw_Recip_term_; int debug_; // Below variables are needed for per-atom decomp From 7acd57240e60b1b08dcd221d7cfef44622639b77 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 14:10:02 -0400 Subject: [PATCH 182/218] Finish converting GIST_PME, add VDW long range, recip, and adjust stuff. --- src/GIST_PME.cpp | 45 +++++++++++++++++++++++++++++++++------------ src/GIST_PME.h | 8 ++++++++ src/cpptrajdepend | 19 ++++++++++--------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index 18c701694b..5b64f609f4 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -7,6 +7,7 @@ #include "ParameterTypes.h" #include "Topology.h" #include "EwaldOptions.h" +#include "Energy/Kernel_EwaldAdjust.h" /** CONSTRUCTOR */ GIST_PME::GIST_PME() : @@ -33,9 +34,14 @@ int GIST_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) } mprintf("\tGIST Particle Mesh Ewald params:\n"); if (InitEwald(boxIn, pmeOpts, debugIn)) { - mprinterr("Error: PME calculation init failed.\n"); + mprinterr("Error: GIST PME calculation init failed.\n"); return 1; } + if (recipParams_.InitRecip(pmeOpts, debugIn)) { + mprinterr("Error: GIST PME calculation recip init failed.\n"); + return 1; + } + VDW_LR_.SetDebug( debugIn ); // Ewald calcs need pairlist if (pairList_.InitPairList(pmeOpts.Cutoff(), pmeOpts.SkinNB(), debugIn)) return 1; @@ -57,6 +63,20 @@ int GIST_PME::Setup_PME_GIST(Topology const& topIn, unsigned int nthreads, doubl mprinterr("Error: GIST PME setup failed.\n"); return 1; } + // Set up VDW long range correction + if (VDW_LR_.Setup_VDW_Correction( topIn, allAtoms_ )) { + mprinterr("Error: GIST PME calculation long range VDW correction setup failed.\n"); + return 1; + } + // Setup exclusion list + // Use distance of 4 (up to dihedrals) + if (excluded_.SetupExcluded(topIn.Atoms(), allAtoms_, 4, + ExclusionArray::EXCLUDE_SELF, + ExclusionArray::FULL)) + { + mprinterr("Error: Could not set up exclusion list for GIST PME calculation.\n"); + return 1; + } // Allocate voxel arrays int natoms = topIn.Natom(); // TODO unsigned int? @@ -304,10 +324,8 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, // This essentially makes coordsD and chargesD point to arrays. MatType coordsD(&coordsD_[0], Charge().size(), 3); MatType chargesD(&SelectedCharges()[0], Charge().size(), 1); - int nfft1 = Nfft(0); - int nfft2 = Nfft(1); - int nfft3 = Nfft(2); - if ( DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { + int nfft1, nfft2, nfft3; + if ( recipParams_.DetermineNfft(nfft1, nfft2, nfft3, boxIn) ) { mprinterr("Error: Could not determine grid spacing.\n"); return 0.0; } @@ -323,7 +341,7 @@ double GIST_PME::Recip_ParticleMesh_GIST(Box const& boxIn, // NOTE: Scale factor for Charmm is 332.0716 // NOTE: The electrostatic constant has been baked into the Charge_ array already. //auto pme_object = std::unique_ptr(new PMEInstanceD()); - pme_object_.setup(1, EwaldCoeff(), Order(), nfft1, nfft2, nfft3, 1.0, 0); + pme_object_.setup(1, EwaldCoeff(), recipParams_.Order(), nfft1, nfft2, nfft3, 1.0, 0); // Sets the unit cell lattice vectors, with units consistent with those used to specify coordinates. // Args: 1 = the A lattice parameter in units consistent with the coordinates. // 2 = the B lattice parameter in units consistent with the coordinates. @@ -437,18 +455,18 @@ double GIST_PME::Vdw_Correction_GIST(double volume, { double prefac = Constants::TWOPI / (3.0*volume*Cutoff()*Cutoff()*Cutoff()); //mprintf("VDW correction prefac: %.15f \n", prefac); - double e_vdwr = -prefac * Vdw_Recip_Term(); + double e_vdwr = -prefac * VDW_LR_.Vdw_Recip_Term(); //mprintf("Cparam size: %i \n",Cparam_.size()); //mprintf("volume of the unit cell: %f", volume); - for ( unsigned int i = 0; i != vdw_type_.size(); i++) + for ( unsigned int i = 0; i != VDW_LR_.VDW_Type().size(); i++) { double term(0); - int v_type=vdw_type_[i]; + int v_type = VDW_LR_.VDW_Type()[i]; //v_type is the vdw_type of atom i, each atom has a atom type @@ -458,7 +476,7 @@ double GIST_PME::Vdw_Correction_GIST(double volume, - term = atype_vdw_recip_terms_[v_type] / N_vdw_type_[v_type]; + term = VDW_LR_.Atype_VDW_Recip_Terms()[v_type] / VDW_LR_.N_VDW_Type()[v_type]; //mprintf("for i = %i,vdw_type = %i, Number of atoms in this vdw_type_= %i, Total vdw_recip_terms_ for this type= %f, vdw_recip_term for atom i= %f \n",i,vdw_type_[i],N_vdw_type_[vdw_type_[i]],atype_vdw_recip_terms_[vdw_type_[i]],term); @@ -685,7 +703,10 @@ void GIST_PME::Ekernel_Adjust(double& e_adjust, double* e_uv_elec, double* e_vv_elec) { - double adjust = AdjustFxn(q0,q1,sqrt(rij2)); + //double adjust = AdjustFxn(q0,q1,sqrt(rij2)); + double rij = sqrt(rij2); + double erfcval = ErfcEW( rij ); + double adjust = Cpptraj::Energy::Kernel_EwaldAdjust( q0, q1, rij, erfcval ); e_adjust += adjust; @@ -806,7 +827,7 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& mprintf("DBG: Cell %6i (%6i atoms):\n", cidx+1, thisCell.NatomsInGrid()); # endif // Exclusion list for this atom - ExclusionArray::ExListType const& excluded = Excluded()[it0->Idx()]; + ExclusionArray::ExListType const& excluded = excluded_[it0->Idx()]; // Calc interaction of atom to all other atoms in thisCell. for (PairList::CellType::const_iterator it1 = it0 + 1; it1 != thisCell.end(); ++it1) diff --git a/src/GIST_PME.h b/src/GIST_PME.h index 0c48743a3b..47f15ab9d2 100644 --- a/src/GIST_PME.h +++ b/src/GIST_PME.h @@ -4,6 +4,9 @@ #include #include "AtomMask.h" #include "Energy/EwaldParams.h" +#include "Energy/PME_RecipParams.h" +#include "Energy/VDW_LongRange_Correction.h" +#include "ExclusionArray.h" #include "helpme_standalone.h" #include "PairList.h" #include "Timer.h" @@ -131,8 +134,13 @@ class GIST_PME : private Cpptraj::Energy::EwaldParams { Timer t_recip_; Timer t_direct_; Timer t_self_; + PairList pairList_; Darray coordsD_; + Cpptraj::Energy::PME_RecipParams recipParams_; ///< Hold parameters for recip part of PME + PMEInstanceD pme_object_; + Cpptraj::Energy::VDW_LongRange_Correction VDW_LR_; ///< For calculating the long range VDW correction + ExclusionArray excluded_; }; #endif /* LIBPME */ #endif diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 3dcfb1cc54..3171e54466 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -37,7 +37,7 @@ Action_Esander.o : Action_Esander.cpp Action.h ActionState.h Action_Esander.h Ar Action_FilterByData.o : Action_FilterByData.cpp Action.h ActionState.h Action_FilterByData.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FixAtomOrder.o : Action_FixAtomOrder.cpp Action.h ActionState.h ActionTopWriter.h Action_FixAtomOrder.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomTopType.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_FixImagedBonds.o : Action_FixImagedBonds.cpp Action.h ActionState.h Action_FixImagedBonds.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h -Action_GIST.o : Action_GIST.cpp Action.h ActionState.h Action_GIST.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_MatrixFlt.h Dimension.h DispatchObject.h DistRoutines.h EwaldOptions.h FileIO.h FileName.h FileTypes.h Frame.h GIST_PME.h GistEntropyUtils.h Grid.h GridBin.h GridMover.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh +Action_GIST.o : Action_GIST.cpp Action.h ActionState.h Action_GIST.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_MatrixFlt.h Dimension.h DispatchObject.h DistRoutines.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h GIST_PME.h GistEntropyUtils.h Grid.h GridBin.h GridMover.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h Action_Grid.o : Action_Grid.cpp Action.h ActionState.h Action_Grid.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskArray.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_GridFreeEnergy.o : Action_GridFreeEnergy.cpp Action.h ActionState.h Action_GridFreeEnergy.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_HydrogenBond.o : Action_HydrogenBond.cpp Action.h ActionState.h Action_HydrogenBond.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h DataSet_integer.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h @@ -190,7 +190,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h EwaldOptions.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_AddAtom.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_AvgBox.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_EneDecomp.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_MinMaxDist.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_ToroidalDiffusion.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_CalcDiffusion.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Project.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_TICA.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DiffusionResults.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy/Ecalc_Nonbond.h Energy/EnergyDecomposer.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h EwaldOptions.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CrdTransform.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_ExtendedComparison.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_ParseTiming.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_Sequence.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h Exec_Zmatrix.h ExtendedSimilarity.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h GridMover.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h InteractionData.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -276,18 +276,19 @@ DiffusionResults.o : DiffusionResults.cpp ArgList.h AssociatedData.h Atom.h Atom DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h -Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h -Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h -Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_LJPME.o : Energy/EwaldCalc_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h +Energy/EwaldCalc_PME.o : Energy/EwaldCalc_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Regular.o : Energy/EwaldCalc_Regular.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h Energy/EwaldParams.o : Energy/EwaldParams.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/EwaldParams_LJPME.o : Energy/EwaldParams_LJPME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h EwaldOptions.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Energy/Ewald_Recip.o : Energy/Ewald_Recip.cpp Box.h Constants.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/Ewald_Recip.h EwaldOptions.h Matrix_3x3.h Parallel.h ParameterTypes.h SplineFxnTable.h StringRoutines.h Timer.h Vec3.h -Energy/PME_Recip.o : Energy/PME_Recip.cpp Box.h CpptrajStdio.h Energy/PME_Recip.h EwaldOptions.h Matrix_3x3.h Parallel.h Timer.h Vec3.h helpme_standalone.h +Energy/PME_Recip.o : Energy/PME_Recip.cpp Box.h CpptrajStdio.h Energy/PME_Recip.h Energy/PME_RecipParams.h Matrix_3x3.h Parallel.h Timer.h Vec3.h helpme_standalone.h +Energy/PME_RecipParams.o : Energy/PME_RecipParams.cpp Box.h CpptrajStdio.h Energy/PME_RecipParams.h EwaldOptions.h Matrix_3x3.h Parallel.h Vec3.h Energy/VDW_LongRange_Correction.o : Energy/VDW_LongRange_Correction.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/VDW_LongRange_Correction.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -376,7 +377,7 @@ ForLoop_list.o : ForLoop_list.cpp Action.h ActionList.h ActionState.h Analysis.h ForLoop_mask.o : ForLoop_mask.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_mask.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h ForLoop_overSets.o : ForLoop_overSets.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_overSets.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Frame.o : Frame.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Unit.h Vec3.h -GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h +GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h GistEntropyUtils.o : GistEntropyUtils.cpp CpptrajFile.h FileIO.h FileName.h GistEntropyUtils.h Parallel.h Vec3.h Gpu.o : Gpu.cpp Gpu.h GridAction.o : GridAction.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 542c05aacd942fe8335a4e2d5acdb840245883e5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 15 Oct 2024 14:16:37 -0400 Subject: [PATCH 183/218] Add missing timing function --- src/GIST_PME.cpp | 13 +++++++++++++ src/GIST_PME.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index 5b64f609f4..379c5db2c2 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -1072,4 +1072,17 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& return Eelec + e_adjust; */ //} + +void GIST_PME::Timing(double total) const { + t_total_.WriteTiming(1, " GIST_PME_total:", total); + t_self_.WriteTiming(2, "Self: ", t_total_.Total()); + t_recip_.WriteTiming(2, "Recip: ", t_total_.Total()); + t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); +//# ifndef _OPENMP +// t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); +// t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); +//# endif + pairList_.Timing(total); +} + #endif /* LIBPME */ diff --git a/src/GIST_PME.h b/src/GIST_PME.h index 47f15ab9d2..065b60f881 100644 --- a/src/GIST_PME.h +++ b/src/GIST_PME.h @@ -32,6 +32,8 @@ class GIST_PME : private Cpptraj::Energy::EwaldParams { int Init(Box const&, EwaldOptions const&, int); /// Setup PME calc. for top, all atoms. Allocate memory for internal arrays (# threads) int Setup_PME_GIST(Topology const&, unsigned int, double); + /// Print timing data + void Timing(double) const; /// Calculate nonbonded energy with PME for GIST int CalcNonbondEnergy_GIST(Frame const&, std::vector const&, std::vector const&, From d86197286e33440d5c9cf564bd9ccc6f0f994120 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 09:35:43 -0400 Subject: [PATCH 184/218] Fix non-openmp compile --- src/GIST_PME.cpp | 8 +------- src/GIST_PME.h | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index 379c5db2c2..a409dbbdbb 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -610,18 +610,12 @@ void GIST_PME::Ekernel_NB(double& Eelec, double& Evdw, InteractionType interactionType,// int voxel0, int voxel1, double* e_uv,// double* e_uv_elec, double* e_vv)//, double* e_vv_elec) -//const Cannot be const because of the timer +const { double rij = sqrt( rij2 ); double qiqj = q0 * q1; -# ifndef _OPENMP - t_erfc_.Start(); -# endif //double erfc = erfc_func(ew_coeff_ * rij); double erfc = ErfcEW(rij); -# ifndef _OPENMP - t_erfc_.Stop(); -# endif double e_elec = qiqj * erfc / rij; Eelec += e_elec; diff --git a/src/GIST_PME.h b/src/GIST_PME.h index 065b60f881..2f6865515e 100644 --- a/src/GIST_PME.h +++ b/src/GIST_PME.h @@ -79,7 +79,7 @@ class GIST_PME : private Cpptraj::Energy::EwaldParams { /// Nonbond energy kernel inline void Ekernel_NB(double&, double&, double, double, double, int, int, double*, double*, - InteractionType, double*, double*); + InteractionType, double*, double*) const; // Adjust energy kernel inline void Ekernel_Adjust(double&, double, double, double, int, int, double*, InteractionType, double*, double*); From 3293676c019923957dddc9b5d699ac7801f5bf5f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 10:19:17 -0400 Subject: [PATCH 185/218] Start adding LJPME OptType --- src/Action_Energy.cpp | 4 ++-- src/Energy/EnergyDecomposer.cpp | 6 +++--- src/Energy/EwaldParams_LJPME.cpp | 1 + src/EwaldOptions.cpp | 26 ++++++++++++++++---------- src/EwaldOptions.h | 6 ++++-- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/Action_Energy.cpp b/src/Action_Energy.cpp index 29eef54adc..ad5c235f69 100644 --- a/src/Action_Energy.cpp +++ b/src/Action_Energy.cpp @@ -176,10 +176,10 @@ Action::RetType Action_Energy::Init(ArgList& actionArgs, ActionInit& init, int d # ifdef LIBPME elecType_ = PME; nbCalcType_ = Ecalc_Nonbond::PME; - if (actionArgs.Contains("ljpme")) - nbCalcType_ = Ecalc_Nonbond::LJPME; if (ewaldOpts_.GetOptions(EwaldOptions::PME, actionArgs, "energy")) return Action::ERR; + if (ewaldOpts_.Type() == EwaldOptions::LJPME) + nbCalcType_ = Ecalc_Nonbond::LJPME; # else mprinterr("Error: 'pme' requires compiling with LIBPME (FFTW3 and C++11 support).\n"); return Action::ERR; diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 27aa4c7880..377ad57e68 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -34,11 +34,11 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFil nbcalctype_ = Ecalc_Nonbond::SIMPLE; if (argIn.hasKey("pme")) nbcalctype_ = Ecalc_Nonbond::PME; - else if (argIn.Contains("ljpme")) // FIXME using Contains() since EwaldOptions parses ljpme - nbcalctype_ = Ecalc_Nonbond::LJPME; if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) { if (ewaldOpts_.GetOptions(EwaldOptions::PME, argIn, "enedecomp")) - return 1; + return 1; + if (ewaldOpts_.Type() == EwaldOptions::LJPME) + nbcalctype_ = Ecalc_Nonbond::LJPME; } // Get atom mask if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp index 9014387a93..ed6427266a 100644 --- a/src/Energy/EwaldParams_LJPME.cpp +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -15,6 +15,7 @@ EwaldParams_LJPME::EwaldParams_LJPME() : /** Set up LJPME parameters. */ int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { + mprintf("DEBUG: EwaldParams_LJPME::InitEwald()\n"); if (EwaldParams::InitEwald(boxIn, pmeOpts, debugIn)) return 1; lw_coeff_ = pmeOpts.LwCoeff(); diff --git a/src/EwaldOptions.cpp b/src/EwaldOptions.cpp index 05dbd53a20..17fc5a56b6 100644 --- a/src/EwaldOptions.cpp +++ b/src/EwaldOptions.cpp @@ -72,6 +72,10 @@ int EwaldOptions::GetCommaSeparatedArgs(ArgList& argIn, const char* keyword, int /** Parse Ewald options from ArgList. */ int EwaldOptions::GetOptions(OptType typeIn, ArgList& actionArgs, const char* desc) { + if (typeIn == NOT_SET) { + mprinterr("Internal Error: EwaldOptions::GetOptions(): Type is not set.\n"); + return 1; + } type_ = typeIn; // Common options cutoff_ = actionArgs.getKeyDouble("cut", 8.0); @@ -87,22 +91,26 @@ int EwaldOptions::GetOptions(OptType typeIn, ArgList& actionArgs, const char* de mprinterr("Error: LJ PME option 'ljpme' not allowed for '%s'\n", desc); return 1; } + type_ = LJPME; lwcoeff_ = 0.4; } lwcoeff_ = actionArgs.getKeyDouble("ewcoefflj", lwcoeff_); - if (!allowLjPme_ && lwcoeff_ >= 0) { - mprinterr("Error: LJ PME option 'ewcoefflj' not allowed for '%s'\n", desc); - return 1; + if (lwcoeff_ >= 0) { + if (!allowLjPme_) { + mprinterr("Error: LJ PME option 'ewcoefflj' not allowed for '%s'\n", desc); + return 1; + } + type_ = LJPME; } ljswidth_ = actionArgs.getKeyDouble("ljswidth", 0.0); // Regular Ewald options - if (type_ != PME) { + if (!IsPmeType()) { rsumtol_ = actionArgs.getKeyDouble("rsumtol", 5E-5); maxexp_ = actionArgs.getKeyDouble("maxexp", 0.0); if (GetCommaSeparatedArgs(actionArgs, "mlimits", mlimits1_, mlimits2_, mlimits3_, 0)) return 1; } // PME options - if (type_ != REG_EWALD) { + if (IsPmeType()) { npoints_ = actionArgs.getKeyInt("order", 6); if (GetCommaSeparatedArgs(actionArgs, "nfft", nfft1_, nfft2_, nfft3_, -1)) return 1; } @@ -124,7 +132,7 @@ void EwaldOptions::PrintOptions() const { if (skinnb_ > 0) mprintf("\tSize of non-bonded \"skin\"= %.4f\n", skinnb_); // Regular Ewald options - if (type_ != PME) { + if (!IsPmeType()) { if (rsumtol_ != 0.0) mprintf("\tReciprocal sum tolerance= %g\n", rsumtol_); if (maxexp_ == 0.0) @@ -138,16 +146,14 @@ void EwaldOptions::PrintOptions() const { mlimits1_, mlimits2_, mlimits3_); } // PME options - if (type_ != REG_EWALD) { + if (IsPmeType()) { mprintf("\tSpline order= %i\n", npoints_); if (nfft1_ < 1 && nfft2_ < 1 && nfft3_ < 1) mprintf("\tWill determine number of FFT grid points from box size.\n"); else mprintf("\tNumber of FFT grid points in each direction= {%i,%i,%i}\n", nfft1_, nfft2_, nfft3_); - } - // LJ options - if (type_ != REG_EWALD) { + // LJ options if (lwcoeff_ < 0) mprintf("\tUsing long range correction for nonbond VDW calc.\n"); else if (lwcoeff_ > 0.0) diff --git a/src/EwaldOptions.h b/src/EwaldOptions.h index c9ded8ee0f..25dd1bad6c 100644 --- a/src/EwaldOptions.h +++ b/src/EwaldOptions.h @@ -6,7 +6,7 @@ class EwaldOptions { public: EwaldOptions(); /// Type of options - enum OptType { NOT_SET = 0, REG_EWALD, PME }; + enum OptType { NOT_SET = 0, REG_EWALD, PME, LJPME }; static const char* KeywordsCommon1(); static const char* KeywordsCommon2(); @@ -20,8 +20,10 @@ class EwaldOptions { int GetOptions(OptType, ArgList&, const char*); /// Print options to stdout void PrintOptions() const; - + /// \return Current calculation type OptType Type() const { return type_; } + /// \return True if current calculation is a PME type + bool IsPmeType() const { return (type_ == PME) || (type_ == LJPME); } // Options common to all Ewald double Cutoff() const { return cutoff_; } From 8c11158422280091efaa9c8b37377784a117b4fe Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 10:27:48 -0400 Subject: [PATCH 186/218] Use IsPmeType where appropriate. Ensure GIST PME is only used with PME options for now. --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 4 ++-- src/Energy/EwaldCalc_Decomp_PME.cpp | 4 ++-- src/Energy/EwaldCalc_LJPME.cpp | 4 ++-- src/Energy/EwaldCalc_PME.cpp | 4 ++-- src/Energy/EwaldCalc_Regular.cpp | 4 ++-- src/GIST_PME.cpp | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index 13bb3f9bb2..56b3285b44 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -16,8 +16,8 @@ EwaldCalc_Decomp_LJPME::EwaldCalc_Decomp_LJPME() : int EwaldCalc_Decomp_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + if (!pmeOpts.IsPmeType()) { + mprinterr("Internal Error: EwaldCalc_Decomp_LJPME::Init(): Options were not set up for PME.\n"); return 1; } mprintf("\tDecomposable Particle Mesh Ewald (LJPME) params:\n"); diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 54a9e1c1cd..cc9f879fc3 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -15,8 +15,8 @@ EwaldCalc_Decomp_PME::EwaldCalc_Decomp_PME() : int EwaldCalc_Decomp_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + if (!pmeOpts.IsPmeType()) { + mprinterr("Internal Error: EwaldCalc_Decomp_PME::Init(): Options were not set up for PME.\n"); return 1; } mprintf("\tDecomposed Particle Mesh Ewald params:\n"); diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index 8b34f7a2ba..ab06696629 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -16,8 +16,8 @@ EwaldCalc_LJPME::EwaldCalc_LJPME() : int EwaldCalc_LJPME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + if (!pmeOpts.IsPmeType()) { + mprinterr("Internal Error: EwaldCalc_LJPME::Init(): Options were not set up for PME.\n"); return 1; } mprintf("\tParticle Mesh Ewald (LJPME) params:\n"); diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index b8f9f61b7c..88da50ce56 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -15,8 +15,8 @@ EwaldCalc_PME::EwaldCalc_PME() : int EwaldCalc_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + if (!pmeOpts.IsPmeType()) { + mprinterr("Internal Error: EwaldCalc_PME::Init(): Options were not set up for PME.\n"); return 1; } mprintf("\tParticle Mesh Ewald params:\n"); diff --git a/src/Energy/EwaldCalc_Regular.cpp b/src/Energy/EwaldCalc_Regular.cpp index f92f9449eb..788bdaa123 100644 --- a/src/Energy/EwaldCalc_Regular.cpp +++ b/src/Energy/EwaldCalc_Regular.cpp @@ -13,8 +13,8 @@ EwaldCalc_Regular::EwaldCalc_Regular() int EwaldCalc_Regular::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::PME) { - mprinterr("Internal Error: Options were set up for PME only.\n"); + if (pmeOpts.IsPmeType()) { + mprinterr("Internal Error: EwaldCalc_Regular::Init(): Options were set up for PME only.\n"); return 1; } mprintf("\tRegular Ewald params:\n"); diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index a409dbbdbb..ab69357e93 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -28,8 +28,8 @@ const char* GIST_PME::InteractionTypeStr_[] = { int GIST_PME::Init(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { // Sanity check - if (pmeOpts.Type() == EwaldOptions::REG_EWALD) { - mprinterr("Internal Error: Options were set up for regular Ewald only.\n"); + if (pmeOpts.Type() != EwaldOptions::PME) { + mprinterr("Internal Error: GIST_PME::Init(): Options were not set up for non-LJ PME.\n"); return 1; } mprintf("\tGIST Particle Mesh Ewald params:\n"); From 9fcfa99129f72a876bf02836ca3149ae6868cfd8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 10:33:15 -0400 Subject: [PATCH 187/218] Energy decomp with ljpme not yet allowed --- src/Energy/EnergyDecomposer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 377ad57e68..dab122e28a 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -35,10 +35,16 @@ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFil if (argIn.hasKey("pme")) nbcalctype_ = Ecalc_Nonbond::PME; if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) { +# ifdef LIBPME + ewaldOpts_.AllowLjPme(false); // TODO enable LJPME decomp if (ewaldOpts_.GetOptions(EwaldOptions::PME, argIn, "enedecomp")) return 1; if (ewaldOpts_.Type() == EwaldOptions::LJPME) nbcalctype_ = Ecalc_Nonbond::LJPME; +# else + mprinterr("Error: 'pme' with energy decomposition requires compilation with LIBPME.\n"); + return 1; +# endif } // Get atom mask if (selectedAtoms_.SetMaskString( argIn.GetMaskNext() )) From dd45c9d5d26ed80887016e41947e9337c233310a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 10:45:44 -0400 Subject: [PATCH 188/218] Allow LJPME to be directly set --- src/EwaldOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EwaldOptions.cpp b/src/EwaldOptions.cpp index 17fc5a56b6..868363b6ef 100644 --- a/src/EwaldOptions.cpp +++ b/src/EwaldOptions.cpp @@ -86,7 +86,7 @@ int EwaldOptions::GetOptions(OptType typeIn, ArgList& actionArgs, const char* de // LJ Options // NOTE: lwcoeff_ > 0 is LJPME on. An lwcoeff_ of -1 is off, and 0 is set from ewcoeff_. lwcoeff_ = -1; - if (actionArgs.hasKey("ljpme")) { + if (actionArgs.hasKey("ljpme") || type_ == LJPME) { if (!allowLjPme_) { mprinterr("Error: LJ PME option 'ljpme' not allowed for '%s'\n", desc); return 1; From d2d5b89efa04a57b9cdfded5013192564420d5fd Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 11:11:42 -0400 Subject: [PATCH 189/218] Remove debug message --- src/Energy/EwaldParams_LJPME.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Energy/EwaldParams_LJPME.cpp b/src/Energy/EwaldParams_LJPME.cpp index ed6427266a..9014387a93 100644 --- a/src/Energy/EwaldParams_LJPME.cpp +++ b/src/Energy/EwaldParams_LJPME.cpp @@ -15,7 +15,6 @@ EwaldParams_LJPME::EwaldParams_LJPME() : /** Set up LJPME parameters. */ int EwaldParams_LJPME::InitEwald(Box const& boxIn, EwaldOptions const& pmeOpts, int debugIn) { - mprintf("DEBUG: EwaldParams_LJPME::InitEwald()\n"); if (EwaldParams::InitEwald(boxIn, pmeOpts, debugIn)) return 1; lw_coeff_ = pmeOpts.LwCoeff(); From 554ed9cefb5f46d81f5a2f747113496af0514812 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 11:16:48 -0400 Subject: [PATCH 190/218] Make options printout more clear --- src/Energy/PME_Recip.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index bca08da188..df56b1c0f3 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -29,7 +29,12 @@ int PME_Recip::InitRecip(EwaldOptions const& pmeOpts, int debugIn) { /** Print options to stdout. */ void PME_Recip::PrintRecipOpts() const { - mprintf("\tRecip opts (distance kernel exponent= %i\n", distKernelExponent_); + if (distKernelExponent_ == 1) + mprintf("\tParticle Mesh Coulomb Reciprocal opts:\n"); + else if (distKernelExponent_ == 6) + mprintf("\tParticle Mesh LJ Reciprocal opts:\n"); + else + mprintf("\tReciprocal opts (distance kernel exponent= %i)\n", distKernelExponent_); recipParams_.PrintRecipOpts(); } From 749c08de899c6274b630dd0f314f9920898ad5c6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 11:48:22 -0400 Subject: [PATCH 191/218] Make sure printed Ewald options line up --- src/Energy/ErfcFxn.cpp | 4 ++-- src/Energy/EwaldParams.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Energy/ErfcFxn.cpp b/src/Energy/ErfcFxn.cpp index cb3a1e953f..5e086210ba 100644 --- a/src/Energy/ErfcFxn.cpp +++ b/src/Energy/ErfcFxn.cpp @@ -65,7 +65,7 @@ int ErfcFxn::FillErfcTable( double erfcTableDx, double beg, double end ) mprinterr("Error: Could not set up spline table for ERFC\n"); return 1; } - table_.PrintMemUsage("\t"); - table_.PrintTableInfo("\t"); + table_.PrintMemUsage("\t "); + table_.PrintTableInfo("\t "); return 0; } diff --git a/src/Energy/EwaldParams.cpp b/src/Energy/EwaldParams.cpp index 6f82ca3668..c52a410669 100644 --- a/src/Energy/EwaldParams.cpp +++ b/src/Energy/EwaldParams.cpp @@ -54,7 +54,7 @@ double EwaldParams::FindEwaldCoefficient(double cutoff, double dsum_tol) else xhi = xval; } - mprintf("\tEwald coefficient for cut=%g, direct sum tol=%g is %g\n", + mprintf("\t Ewald coefficient determined using cut=%g, direct sum tol=%g is %g\n", cutoff, dsum_tol, xval); return xval; } From 48782ec97e8aea18c55e1dfec7fe05ed00c052a7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 11:55:21 -0400 Subject: [PATCH 192/218] Make print private --- src/Energy/Ewald_Recip.h | 5 +++-- src/Energy/PME_Recip.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Energy/Ewald_Recip.h b/src/Energy/Ewald_Recip.h index 8b40091c04..cd7ca77bf2 100644 --- a/src/Energy/Ewald_Recip.h +++ b/src/Energy/Ewald_Recip.h @@ -18,8 +18,6 @@ class Ewald_Recip { /// Init with options, Ewald coeff, box, debug int InitRecip(EwaldOptions const&, double, Box const&, int); - /// print options to stdout - void PrintRecipOpts() const; /// Set up trig tables for the given number of selected atoms int SetupRecip(int); /// Regular Ewald recip energy (fractional cell vecs, volume, frac coords, charges) @@ -27,6 +25,9 @@ class Ewald_Recip { /// Print timing void PrintTiming(double) const; private: + /// print options to stdout + void PrintRecipOpts() const; + /// Determine max length for reciprocal calcs based on reciprocal limits static double FindMaxexpFromMlim(const int*, Matrix_3x3 const&); /// Determine max length for reciprocal calcs based on Ewald coefficient and recip tol. diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index 9aca5e4330..cf32de0ba8 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -16,8 +16,6 @@ class PME_Recip { /// Initialize int InitRecip(EwaldOptions const& pmeOpts, int); - /// Print options to stdout - void PrintRecipOpts() const; double Recip_ParticleMesh(Darray&, Box const&, Darray&, double); double Recip_Decomp(Darray&, Darray&, Box const&, Darray&, double); @@ -25,6 +23,9 @@ class PME_Recip { Timer const& Timing_Total() const { return t_recip_; } //Timer const& Timing_Calc() const { return t_calc_; } private: + /// Print options to stdout + void PrintRecipOpts() const; + static int set_lattice(PMEInstanceD::LatticeType&, Box const&); PMEInstanceD pme_object_; From 2e57168bbc22453fa7d55f8b99259fd3d278ceab Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 11:56:56 -0400 Subject: [PATCH 193/218] Clean up printout of regular ewald recip opts --- src/Energy/Ewald_Recip.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Energy/Ewald_Recip.cpp b/src/Energy/Ewald_Recip.cpp index 1f7fdbdff7..b9e9ac5f22 100644 --- a/src/Energy/Ewald_Recip.cpp +++ b/src/Energy/Ewald_Recip.cpp @@ -70,7 +70,7 @@ double Ewald_Recip::FindMaxexpFromTol(double ewCoeff, double rsumTol) { else xhi = xval; } - mprintf("\tMaxExp for Ewald coefficient %g, direct sum tol %g is %g\n", + mprintf("\t MaxExp determined from Ewald coefficient %g, direct sum tol %g is %g\n", ewCoeff, rsumTol, xval); return xval; } @@ -104,7 +104,7 @@ void Ewald_Recip::GetMlimits(int* mlimit, double maxexp, double eigmin, } } } - mprintf("\tNumber of reciprocal vectors: %i\n", nrecvecs); + mprintf("\t Number of reciprocal vectors: %i\n", nrecvecs); } /** Init */ @@ -133,6 +133,7 @@ int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, double ew_coeffIn, } // Set defaults if necessary + mprintf("\tRecip opts (regular Ewald):\n"); if (rsumTol_ < Constants::SMALL) rsumTol_ = 5E-5; if (maxmlim_ > 0) @@ -155,7 +156,6 @@ int Ewald_Recip::InitRecip(EwaldOptions const& ewOpts, double ew_coeffIn, /** Print options to stdout */ void Ewald_Recip::PrintRecipOpts() const { - mprintf("\tRecip opts (regular Ewald):\n"); mprintf("\t MaxExp= %g Recip. Sum Tol= %g\n", maxexp_, rsumTol_); //mprintf("\t Erfc table dx= %g, size= %zu\n", erfcTableDx_, erfc_table_.size()/4); mprintf("\t mlimits= {%i,%i,%i} Max=%i\n", mlimit_[0], mlimit_[1], mlimit_[2], maxmlim_); From a80ea737c3a64e53338387f49f8e42fbaa7dcd77 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 12:03:40 -0400 Subject: [PATCH 194/218] Since fftw3 is always on now by default, change -fftw3 to -pubfft in case user wants to force using pubfft. --- configure | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 3ea8373fb6..19a5cdad43 100755 --- a/configure +++ b/configure @@ -41,7 +41,7 @@ UsageFull() { echo " -debugon : Add -DDEBUG flag to activate additional internal debugging." echo " -nolfs : Do not enable large file support." echo " -shared : Configure for generating libcpptraj (implies -nosanderlib)." - echo " -fftw3 : Use FFTW instead of pubfft for FFT." + echo " -pubfft : Use pubfft instead of FFTW for FFT (disables PME functionality)." echo " -windows : Set up for use with MinGW compilers for a native Windows build." echo " LIBRARY OPTIONS" echo " - : Enable library." @@ -1038,7 +1038,7 @@ EOF if [ "${LIB_STAT[$LFFTW3]}" = 'optional' ] ; then WrnMsg "FFTW test failed. CPPTRAJ will use the built-in PubFFT routines." if [ $BUILD_LIBS -eq 1 ] ; then - echo "To force CPPTRAJ to build its own FFTW, reconfigure and specify '-fftw3'." + echo "To force CPPTRAJ to build its own FFTW, reconfigure and specify '--buildlibs'." fi LIB_STAT[$LFFTW3]='off' elif [ "${LIB_STAT[$LFFTW3]}" = 'enabled' ] ; then @@ -2605,6 +2605,7 @@ while [ ! -z "$1" ] ; do '-tune' ) USE_OPT=2 ;; '-noc++11' ) C11_SUPPORT='no' ;; '-windows' ) PLATFORM='windows' ;; + '-pubfft' ) LIB_STAT[$LFFTW3]='off' ;; # Cpptraj options '-nolfs' ) LFS='' ;; '-single-ensemble' ) USE_SINGLEENSEMBLE=1 ;; From 30a4275d7ee9b16af1254c585410e5f91f0c328e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 12:15:02 -0400 Subject: [PATCH 195/218] PME recip needs LIBPME --- src/Energy/PME_Recip.cpp | 3 ++- src/Energy/PME_Recip.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Energy/PME_Recip.cpp b/src/Energy/PME_Recip.cpp index df56b1c0f3..68cbe408d2 100644 --- a/src/Energy/PME_Recip.cpp +++ b/src/Energy/PME_Recip.cpp @@ -1,4 +1,5 @@ #include "PME_Recip.h" +#ifdef LIBPME #include "../Box.h" #include "../CpptrajStdio.h" @@ -146,4 +147,4 @@ double PME_Recip::Recip_Decomp(Darray& atom_recip, t_recip_.Stop(); return erecip; } - +#endif /* LIBPME */ diff --git a/src/Energy/PME_Recip.h b/src/Energy/PME_Recip.h index cf32de0ba8..328c185769 100644 --- a/src/Energy/PME_Recip.h +++ b/src/Energy/PME_Recip.h @@ -1,5 +1,6 @@ #ifndef INC_ENERGY_PME_RECIP_H #define INC_ENERGY_PME_RECIP_H +#ifdef LIBPME #include "../helpme_standalone.h" #include "../Timer.h" #include "PME_RecipParams.h" @@ -37,4 +38,5 @@ class PME_Recip { }; } } +#endif /* LIBPME */ #endif From 5620ed29e5487d9048386ca4806175bf269eda3e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 12:15:19 -0400 Subject: [PATCH 196/218] Add include of base Ewald decomp class when no LIBPME since no decomp for regular Ewald yet. --- src/Energy/Ecalc_Nonbond.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index d1d26eb7a7..d1281f8242 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -1,10 +1,15 @@ #include "Ecalc_Nonbond.h" #include "EwaldCalc_Regular.h" #ifdef LIBPME -#include "EwaldCalc_LJPME.h" -#include "EwaldCalc_PME.h" -#include "EwaldCalc_Decomp_LJPME.h" -#include "EwaldCalc_Decomp_PME.h" +# include "EwaldCalc_LJPME.h" +# include "EwaldCalc_PME.h" +# include "EwaldCalc_Decomp_LJPME.h" +# include "EwaldCalc_Decomp_PME.h" +#else +// TODO This is here for when LIBPME is not defined because there is +// currently no decomp version of regular Ewald. If there ever is +// this inlclude can be removed. +# include "EwaldCalc_Decomp.h" #endif #include "../CharMask.h" #include "../CpptrajStdio.h" From 880975f2636436ab339ddf8428b77acc287faf56 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 12:54:57 -0400 Subject: [PATCH 197/218] Add files for enedecomp test --- test/Test_EneDecomp/AFV.rst7 | 27 + test/Test_EneDecomp/RunTest.sh | 53 + test/Test_EneDecomp/Total.AFV.dat.save | 2 + test/Test_EneDecomp/Total.nacl.box.dat.save | 2 + test/Test_EneDecomp/decomp.AFV.dat.save | 50 + test/Test_EneDecomp/decomp.nacl.box.dat.save | 65 + test/Test_EneDecomp/ene.AFV.dat.save | 2 + test/Test_EneDecomp/ene.nacl.box.dat.save | 2 + test/Test_EneDecomp/test.out.save | 3045 ++++++++++++++++++ 9 files changed, 3248 insertions(+) create mode 100644 test/Test_EneDecomp/AFV.rst7 create mode 100755 test/Test_EneDecomp/RunTest.sh create mode 100644 test/Test_EneDecomp/Total.AFV.dat.save create mode 100644 test/Test_EneDecomp/Total.nacl.box.dat.save create mode 100644 test/Test_EneDecomp/decomp.AFV.dat.save create mode 100644 test/Test_EneDecomp/decomp.nacl.box.dat.save create mode 100644 test/Test_EneDecomp/ene.AFV.dat.save create mode 100644 test/Test_EneDecomp/ene.nacl.box.dat.save create mode 100644 test/Test_EneDecomp/test.out.save diff --git a/test/Test_EneDecomp/AFV.rst7 b/test/Test_EneDecomp/AFV.rst7 new file mode 100644 index 0000000000..91b6d93235 --- /dev/null +++ b/test/Test_EneDecomp/AFV.rst7 @@ -0,0 +1,27 @@ +NALA + 49 + 3.3257700 1.5479090 -0.0000016 4.0461540 0.8399910 -0.0000029 + 2.8230940 1.4995080 -0.8746870 2.8230970 1.4995070 0.8746850 + 3.9700480 2.8457950 -0.0000001 3.6716630 3.4001290 -0.8898200 + 3.5769650 3.6538380 1.2321430 3.8774840 3.1157950 2.1311970 + 4.0750590 4.6230170 1.2057860 2.4969950 3.8010750 1.2413790 + 5.4855410 2.7052070 -0.0000044 6.0088240 1.5931750 -0.0000084 + 6.1910071 3.8385836 -0.0000051 5.7152868 4.7295323 -0.0000028 + 7.6400076 3.8385837 -0.0000074 8.0038585 3.3248391 0.8898118 + 8.1890012 3.1272109 -1.2321515 7.8406894 2.0944027 -1.2413883 + 7.8406911 3.6356234 -2.1312048 9.6955048 3.0758575 -1.3210964 + 10.3114182 2.4472435 -2.4099003 9.7034770 1.9948914 -3.1934084 + 11.7081764 2.3996298 -2.4923651 12.1877101 1.9102104 -3.3400779 + 12.4890227 2.9806305 -1.4860270 13.5764985 2.9435606 -1.5502317 + 11.8731121 3.6092454 -0.3972211 12.4810564 4.0615971 0.3862850 + 10.4763538 3.6568613 -0.3147532 9.9968237 4.1462834 0.5329595 + 8.1879242 5.2585384 -0.0000020 7.4245351 6.2216985 0.0000034 + 9.5167782 5.3864922 -0.0000020 10.1032885 4.5642362 -0.0000053 + 10.1610562 6.6843782 0.0000012 9.8626701 7.2387139 -0.8898172 + 9.7679746 7.4924189 1.2321464 8.6880046 7.6396559 1.2413839 + 10.1887231 6.7390615 2.4895434 11.2687041 6.5918435 2.4812439 + 9.9079841 7.3162048 3.3705609 9.6906411 5.7699014 2.5168342 + 10.4651956 8.8481830 1.1945821 10.1647895 9.3870427 0.2959785 + 10.1845696 9.4261643 2.0750855 11.5452806 8.7017590 1.1857916 + 11.6765492 6.5437902 -0.0000051 12.1998322 5.4317582 -0.0000119 + 12.3954632 7.5405862 -0.0000021 diff --git a/test/Test_EneDecomp/RunTest.sh b/test/Test_EneDecomp/RunTest.sh new file mode 100755 index 0000000000..bee25efb95 --- /dev/null +++ b/test/Test_EneDecomp/RunTest.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +. ../MasterTest.sh + +TESTNAME='Energy decomposition tests' + +CleanFiles enedecomp.in ene.*.dat decomp.*.dat Total.*.dat + +TESTNAME='Particle mesh Ewald tests' +Requires maxthreads 1 + +INPUT='-i enedecomp.in' + +UNITNAME='NaCl box decomposition' +CheckFor libpme +if [ $? -eq 0 ] ; then + cat > enedecomp.in < enedecomp.in < Date: Thu, 17 Oct 2024 12:56:00 -0400 Subject: [PATCH 198/218] Enable enedecomp test --- test/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index d518104090..2931fb985c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -542,6 +542,9 @@ test.sequence: test.tica: @-cd Test_TICA && ./RunTest.sh $(OPT) +test.enedecomp: + @-cd Test_EneDecomp && ./RunTest.sh $(OPT) + # Every test target should go here. COMPLETETESTS=test.general \ test.strip \ @@ -713,7 +716,8 @@ COMPLETETESTS=test.general \ test.zmatrix \ test.readoff \ test.sequence \ - test.tica + test.tica \ + test.enedecomp test.all: $(MAKE) test.complete summary From bc2819d5fd86608f2edce6447665ef1b5f7639ba Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 14:07:07 -0400 Subject: [PATCH 199/218] Remove all references to PairListLoop and associated files --- src/EnergyKernel_Adjust.h | 13 ----- src/EnergyKernel_Nonbond.h | 43 ----------------- src/GIST_PME.cpp | 10 ++-- src/PairListLoop.h | 97 -------------------------------------- src/cpptrajdepend | 2 +- 5 files changed, 5 insertions(+), 160 deletions(-) delete mode 100644 src/EnergyKernel_Adjust.h delete mode 100644 src/EnergyKernel_Nonbond.h delete mode 100644 src/PairListLoop.h diff --git a/src/EnergyKernel_Adjust.h b/src/EnergyKernel_Adjust.h deleted file mode 100644 index 8ea81e953a..0000000000 --- a/src/EnergyKernel_Adjust.h +++ /dev/null @@ -1,13 +0,0 @@ - e_adjust += Adjust(q0, q1, sqrt(rij2)); -# ifdef CPPTRAJ_EKERNEL_LJPME - // LJ PME direct space correction - // NOTE: Assuming excluded pair is within cutoff - double kr2 = lw_coeff_ * lw_coeff_ * rij2; - double kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - double expterm = exp(-kr2); - double r4 = rij2 * rij2; - double r6 = rij2 * r4; - double Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction_excl += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) / r6 * Cij; -# endif diff --git a/src/EnergyKernel_Nonbond.h b/src/EnergyKernel_Nonbond.h deleted file mode 100644 index d8c58bd91b..0000000000 --- a/src/EnergyKernel_Nonbond.h +++ /dev/null @@ -1,43 +0,0 @@ - double rij = sqrt( rij2 ); - double qiqj = q0 * q1; -# ifndef _OPENMP - t_erfc_.Start(); -# endif - //double erfc = erfc_func(ew_coeff_ * rij); - double erfc = ERFC(ew_coeff_ * rij); -# ifndef _OPENMP - t_erfc_.Stop(); -# endif - double e_elec = qiqj * erfc / rij; - Eelec += e_elec; - //mprintf("EELEC %4i%4i%12.5f%12.5f%12.5f%3.0f%3.0f%3.0f\n", - //int ta0, ta1; - //if (it0->Idx() < it1->Idx()) { - // ta0=it0->Idx(); ta1=it1->Idx(); - //} else { - // ta1=it0->Idx(); ta0=it1->Idx(); - //} - //mprintf("PELEC %6i%6i%12.5f%12.5f%12.5f\n", ta0, ta1, rij, erfc, e_elec); - int nbindex = NB_->GetLJindex(TypeIndices_[it0->Idx()], - TypeIndices_[it1->Idx()]); - if (nbindex > -1) { - double vswitch = switch_fn(rij2, cut2_0_, cut2_); - NonbondType const& LJ = NB_->NBarray()[ nbindex ]; - double r2 = 1.0 / rij2; - double r6 = r2 * r2 * r2; - double r12 = r6 * r6; - double f12 = LJ.A() * r12; // A/r^12 - double f6 = LJ.B() * r6; // B/r^6 - double e_vdw = f12 - f6; // (A/r^12)-(B/r^6) - Evdw += (e_vdw * vswitch); - //mprintf("PVDW %8i%8i%20.6f%20.6f\n", ta0+1, ta1+1, e_vdw, r2); -# ifdef CPPTRAJ_EKERNEL_LJPME - // LJ PME direct space correction - double kr2 = lw_coeff_ * lw_coeff_ * rij2; - double kr4 = kr2 * kr2; - //double kr6 = kr2 * kr4; - double expterm = exp(-kr2); - double Cij = Cparam_[it0->Idx()] * Cparam_[it1->Idx()]; - Eljpme_correction += (1.0 - (1.0 + kr2 + kr4/2.0)*expterm) * r6 * vswitch * Cij; -# endif - } diff --git a/src/GIST_PME.cpp b/src/GIST_PME.cpp index ab69357e93..52c145d2a2 100644 --- a/src/GIST_PME.cpp +++ b/src/GIST_PME.cpp @@ -796,7 +796,6 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& neighbor = &(Neighbor_in[mythread][0]); # pragma omp for # endif -//# include "PairListLoop.h" for (cidx = 0; cidx < PL.NGridMax(); cidx++) { PairList::CellType const& thisCell = PL.Cell( cidx ); @@ -950,7 +949,6 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& { # pragma omp for # endif -//# include "PairListLoop.h" double Evdw_temp(0),Eljpme_correction_temp(0), Eljpme_correction_excl_temp(0); double Eelec_temp(0),E_adjust_temp(0); @@ -990,10 +988,10 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& if (excluded.find( it1->Idx() ) == excluded.end()) { if ( rij2 < cut2_ ) { -# include "EnergyKernel_Nonbond.h" +# incl ude "EnergyKernel_Nonbond.h" } } else { -# include "EnergyKernel_Adjust.h" +# incl ude "EnergyKernel_Adjust.h" } } // END loop over other atoms in thisCell // Loop over all neighbor cells @@ -1024,10 +1022,10 @@ double GIST_PME::Direct_VDW_LongRangeCorrection_GIST(PairList const& PL, double& { //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); if ( rij2 < cut2_ ) { -# include "EnergyKernel_Nonbond.h" +# incl ude "EnergyKernel_Nonbond.h" } } else { -# include "EnergyKernel_Adjust.h" +# incl ude "EnergyKernel_Adjust.h" } } // END loop over neighbor cell atoms diff --git a/src/PairListLoop.h b/src/PairListLoop.h deleted file mode 100644 index 1508fd9889..0000000000 --- a/src/PairListLoop.h +++ /dev/null @@ -1,97 +0,0 @@ - for (cidx = 0; cidx < PL.NGridMax(); cidx++) - { - PairList::CellType const& thisCell = PL.Cell( cidx ); - if (thisCell.NatomsInGrid() > 0) - { - // cellList contains this cell index and all neighbors. - PairList::Iarray const& cellList = thisCell.CellList(); - // transList contains index to translation for the neighbor. - PairList::Iarray const& transList = thisCell.TransList(); - // Loop over all atoms of thisCell. - for (PairList::CellType::const_iterator it0 = thisCell.begin(); - it0 != thisCell.end(); ++it0) - { - Vec3 const& xyz0 = it0->ImageCoords(); - double q0 = Charge_[it0->Idx()]; -# ifdef DEBUG_PAIRLIST - mprintf("DBG: Cell %6i (%6i atoms):\n", cidx, thisCell.NatomsInGrid()); -# endif - // Exclusion list for this atom - ExclusionArray::ExListType const& excluded = Excluded_[it0->Idx()]; - // Calc interaction of atom to all other atoms in thisCell. - for (PairList::CellType::const_iterator it1 = it0 + 1; - it1 != thisCell.end(); ++it1) - { - Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; - Vec3 dxyz = xyz1 - xyz0; - double rij2 = dxyz.Magnitude2(); -# ifdef DEBUG_PAIRLIST - mprintf("\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - // If atom excluded, calc adjustment, otherwise calc elec. energy. - if (excluded.find( it1->Idx() ) == excluded.end()) - { - - if ( rij2 < cut2_ ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif -# include "EnergyKernel_Nonbond.h" - } - } else { -# include "EnergyKernel_Adjust.h" - } - } // END loop over other atoms in thisCell - // Loop over all neighbor cells - for (unsigned int nidx = 1; nidx != cellList.size(); nidx++) - { - PairList::CellType const& nbrCell = PL.Cell( cellList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("\tto neighbor cell %6i\n", cellList[nidx]+1); -# endif - // Translate vector for neighbor cell - Vec3 const& tVec = PL.TransVec( transList[nidx] ); -# ifdef DEBUG_PAIRLIST - if (nbrCell.NatomsInGrid()>0) mprintf("DBG:\tto neighbor cell %6i (%6i atoms) tVec= %f %f %f\n", cellList[nidx], nbrCell.NatomsInGrid(), tVec[0], tVec[1], tVec[2]); -# endif - //mprintf("\tNEIGHBOR %i (idxs %i - %i)\n", nbrCell, beg1, end1); - // Loop over every atom in nbrCell - for (PairList::CellType::const_iterator it1 = nbrCell.begin(); - it1 != nbrCell.end(); ++it1) - { - Vec3 const& xyz1 = it1->ImageCoords(); - double q1 = Charge_[it1->Idx()]; - Vec3 dxyz = xyz1 + tVec - xyz0; - double rij2 = dxyz.Magnitude2(); - //mprintf("\t\tAtom %6i {%f %f %f} to atom %6i {%f %f %f} = %f Ang\n", it0->Idx()+1, xyz0[0], xyz0[1], xyz0[2], it1->Idx()+1, xyz1[0], xyz1[1], xyz1[2], sqrt(rij2)); -# ifdef DEBUG_PAIRLIST - mprintf("\t\tAtom %6i to atom %6i (%f)\n", it0->Idx()+1, it1->Idx()+1, sqrt(rij2)); -# endif - //mprintf("\t\tNbrAtom %06i\n",atnum1); - // If atom excluded, calc adjustment, otherwise calc elec. energy. - // TODO Is there better way of checking this? - if (excluded.find( it1->Idx() ) == excluded.end()) - { - - //mprintf("\t\t\tdist= %f\n", sqrt(rij2)); - if ( rij2 < cut2_ ) { -# ifdef NBDBG - if (it0->Idx() < it1->Idx()) - mprintf("NBDBG %6i%6i\n", it0->Idx()+1, it1->Idx()+1); - else - mprintf("NBDBG %6i%6i\n", it1->Idx()+1, it0->Idx()+1); -# endif -# include "EnergyKernel_Nonbond.h" - } - } else { -# include "EnergyKernel_Adjust.h" - } - } // END loop over neighbor cell atoms - } // END Loop over neighbor cells - } // Loop over thisCell atoms - } // END if thisCell is not empty - } // Loop over cells diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 3171e54466..9f212f63d4 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -377,7 +377,7 @@ ForLoop_list.o : ForLoop_list.cpp Action.h ActionList.h ActionState.h Analysis.h ForLoop_mask.o : ForLoop_mask.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_mask.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h ForLoop_overSets.o : ForLoop_overSets.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h ForLoop.h ForLoop_overSets.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Frame.o : Frame.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Unit.h Vec3.h -GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EnergyKernel_Adjust.h EnergyKernel_Nonbond.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h +GIST_PME.o : GIST_PME.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/ErfcFxn.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h GIST_PME.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h GistEntropyUtils.o : GistEntropyUtils.cpp CpptrajFile.h FileIO.h FileName.h GistEntropyUtils.h Parallel.h Vec3.h Gpu.o : Gpu.cpp Gpu.h GridAction.o : GridAction.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridAction.h GridBin.h GridMover.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h From 192276dc7d32f004a54f261ce75f783b8680106c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 17 Oct 2024 14:22:25 -0400 Subject: [PATCH 200/218] Update dependencies --- src/Energy/energydepend | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Energy/energydepend b/src/Energy/energydepend index 1d88d978f3..c6fb564234 100644 --- a/src/Energy/energydepend +++ b/src/Energy/energydepend @@ -1,10 +1,10 @@ -Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h EwaldCalc_Regular.h Ewald_Recip.h PME_Recip.h VDW_LongRange_Correction.h +Ecalc_Nonbond.o : Ecalc_Nonbond.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListEngine_Ewald_LJLR.h ../PairListEngine_Ewald_LJPME.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ../helpme_standalone.h Ecalc_Nonbond.h Ene_Decomp_Nonbond.h Ene_LJ_6_12.h Ene_Nonbond.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h EwaldCalc_Decomp_PME.h EwaldCalc_LJPME.h EwaldCalc_PME.h EwaldCalc_Regular.h Ewald_Recip.h PME_Recip.h PME_RecipParams.h VDW_LongRange_Correction.h EnergyDecomposer.o : EnergyDecomposer.cpp ../ArgList.h ../AssociatedData.h ../Atom.h ../AtomMask.h ../AtomType.h ../BaseIOtype.h ../Box.h ../CharMask.h ../Constants.h ../CoordinateInfo.h ../CpptrajFile.h ../CpptrajStdio.h ../DataFile.h ../DataFileList.h ../DataSet.h ../DataSetList.h ../DataSet_1D.h ../DataSet_Coords.h ../DataSet_Coords_REF.h ../DataSet_Mesh.h ../Dimension.h ../DistRoutines.h ../EwaldOptions.h ../ExclusionArray.h ../FileIO.h ../FileName.h ../FileTypes.h ../Frame.h ../ImageOption.h ../MaskToken.h ../Matrix_3x3.h ../MetaData.h ../Molecule.h ../NameType.h ../OnlineVarT.h ../PairList.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReferenceFrame.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../Spline.h ../SymbolExporting.h ../TextFormat.h ../Timer.h ../Topology.h ../TorsionRoutines.h ../TypeNameHolder.h ../Unit.h ../Vec3.h Ecalc_Nonbond.h Ene_Angle.h Ene_Bond.h Ene_LJ_6_12.h EnergyDecomposer.h Kernel_Fourier.h Kernel_Harmonic.h ErfcFxn.o : ErfcFxn.cpp ../CpptrajStdio.h ../SplineFxnTable.h ErfcFxn.h -EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h -EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h VDW_LongRange_Correction.h -EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h -EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h VDW_LongRange_Correction.h +EwaldCalc_Decomp_LJPME.o : EwaldCalc_Decomp_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_LJPME.h PME_Recip.h PME_RecipParams.h +EwaldCalc_Decomp_PME.o : EwaldCalc_Decomp_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_Decomp_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_Decomp.h EwaldCalc_Decomp_PME.h PME_Recip.h PME_RecipParams.h VDW_LongRange_Correction.h +EwaldCalc_LJPME.o : EwaldCalc_LJPME.cpp ../Atom.h ../AtomMask.h ../Box.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJPME_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/EwaldParams_LJPME.h ../Energy/Kernel_EwaldAdjust.h ../Energy/Kernel_LJPME_Adjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJPME.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_LJPME.h PME_Recip.h PME_RecipParams.h +EwaldCalc_PME.o : EwaldCalc_PME.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h ../helpme_standalone.h EwaldCalc.h EwaldCalc_PME.h PME_Recip.h PME_RecipParams.h VDW_LongRange_Correction.h EwaldCalc_Regular.o : EwaldCalc_Regular.cpp ../Atom.h ../AtomMask.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../Energy/../Constants.h ../Energy/../ParameterTypes.h ../Energy/../SplineFxnTable.h ../Energy/Ene_LJ_6_12.h ../Energy/ErfcFxn.h ../Energy/EwaldParams.h ../Energy/Kernel_EwaldAdjust.h ../EwaldOptions.h ../ExclusionArray.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../PairList.h ../PairListEngine_Ewald_LJLR.h ../PairListTemplate.h ../Parallel.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SymbolExporting.h ../Timer.h ../Unit.h ../Vec3.h EwaldCalc.h EwaldCalc_Regular.h Ewald_Recip.h VDW_LongRange_Correction.h EwaldParams.o : EwaldParams.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.o : EwaldParams_LJPME.cpp ../Atom.h ../AtomMask.h ../AtomType.h ../Box.h ../Constants.h ../CoordinateInfo.h ../CpptrajStdio.h ../EwaldOptions.h ../FileName.h ../Frame.h ../MaskToken.h ../Matrix_3x3.h ../Molecule.h ../NameType.h ../Parallel.h ../ParameterHolders.h ../ParameterSet.h ../ParameterTypes.h ../Range.h ../ReplicaDimArray.h ../Residue.h ../Segment.h ../SplineFxnTable.h ../SymbolExporting.h ../Topology.h ../TypeNameHolder.h ../Unit.h ../Vec3.h ErfcFxn.h EwaldParams.h EwaldParams_LJPME.h From 4e802cefee15d5ca4e08facd14d75cda6b00df0b Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:42:31 -0400 Subject: [PATCH 201/218] Add help text --- src/Action_EneDecomp.cpp | 2 +- src/Energy/EnergyDecomposer.cpp | 61 ++++++--------------------------- src/Energy/EnergyDecomposer.h | 4 +-- 3 files changed, 13 insertions(+), 54 deletions(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index 4d85c1cd42..8d4e6a81e1 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -3,7 +3,7 @@ // Action_EneDecomp::Help() void Action_EneDecomp::Help() const { - + Cpptraj::Energy::EnergyDecomposer::HelpText(); } // Action_EneDecomp::Init() diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index dab122e28a..375692d3b9 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -24,6 +24,16 @@ EnergyDecomposer::EnergyDecomposer() : currentTop_(0) { } +void EnergyDecomposer::HelpText() { + mprintf("\t[] [] [out ]\n" + "\t[ pme %s\n" + "\t %s\n" + "\t %s\n", + EwaldOptions::KeywordsCommon1(), + EwaldOptions::KeywordsCommon2(), + EwaldOptions::KeywordsPME()); +} + /** Initialize decomposer. */ int EnergyDecomposer::InitDecomposer(ArgList& argIn, DataSetList& DSLin, DataFileList& DFLin, int debugIn) @@ -305,40 +315,6 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { } } -/** Simple nonbonded energy calculation with no cutoff. */ -/* -void EnergyDecomposer::calcNB_simple(Frame const& frameIn) { - for (int atom1 = 0; atom1 < currentTop_->Natom(); atom1++) { - bool atom1_is_selected = selectedAtoms_.AtomInCharMask( atom1 ); - ExclusionArray::ExListType const& excludedAtoms = Excluded_[atom1]; - for (int atom2 = atom1 + 1; atom2 < currentTop_->Natom(); atom2++) { - bool atom2_is_selected = selectedAtoms_.AtomInCharMask( atom2 ); - if (atom1_is_selected || atom2_is_selected) { - ExclusionArray::ExListType::const_iterator it = excludedAtoms.find( atom2 ); - if (it == excludedAtoms.end()) { - // Either atom1 or atom2 is selected and the interaction is not excluded. - // vdw energy TODO image distances? - double rij2 = DIST2_NoImage( frameIn.XYZ(atom1), frameIn.XYZ(atom2) ); - NonbondType const& LJ = currentTop_->GetLJparam(atom1, atom2); - double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); - mprintf("DEBUG: VDW %f\n", e_vdw); - double ene_half = e_vdw * 0.5; - saveEne( atom1, ene_half ); - saveEne( atom2, ene_half ); - // Coulomb energy - double rij = sqrt(rij2); - double qiqj = QFAC_ * (*currentTop_)[atom1].Charge() * (*currentTop_)[atom2].Charge(); - double e_elec = qiqj / rij; - mprintf("DEBUG: ELE %f\n", e_elec); - ene_half = e_elec * 0.5; - saveEne( atom1, ene_half ); - saveEne( atom2, ene_half ); - } // END atom2 not excluded from atom1 - } // END atom1 or atom2 is selected - } // END inner loop over atoms - } // END outer loop over atoms -}*/ - /** Calculate and decompose energies. */ int EnergyDecomposer::CalcEne(Frame const& frameIn) { t_total_.Start(); @@ -361,23 +337,6 @@ int EnergyDecomposer::CalcEne(Frame const& frameIn) { mprinterr("Error: Decompose nonbond energy calc failed.\n"); return 1; } -/* if (nbcalctype_ != SIMPLE) { // FIXME atommask? - double e_elec, e_vdw; - std::vector atom_elec, atom_vdw; - if (nbcalctype_ == PME) - PME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), - e_elec, e_vdw, atom_elec, atom_vdw); - else if (nbcalctype_ == LJPME) - LJPME_.CalcDecomposedNonbondEnergy(frameIn, AtomMask(0, frameIn.Natom()), - e_elec, e_vdw, atom_elec, atom_vdw); - for (int at = 0; at < currentTop_->Natom(); at++) { - if (selectedAtoms_.AtomInCharMask(at)) { - saveEne( at, atom_elec[at] + atom_vdw[at] ); - } - } - } else { - calcNB_simple(frameIn); - }*/ // Accumulate the energies for (unsigned int idx = 0; idx != energies_.size(); idx++) { diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 45161dc8c7..501268439a 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -23,6 +23,8 @@ class EnergyDecomposer { public: /// CONSTRUCTOR EnergyDecomposer(); + /// Print help text to stdout + static void HelpText(); /// Initialize with arguments int InitDecomposer(ArgList&, DataSetList&, DataFileList&, int); /// Print options to stdout @@ -55,8 +57,6 @@ class EnergyDecomposer { void calcAngles(Frame const&); /// Calculate dihedral energies void calcDihedrals(Frame const&); - /// Calculate simple nonbonded energies, no cutoff - //void calcNB_simple(Frame const&); CharMask selectedAtoms_; ///< Mask of atoms that energy will be recorded for. DataSet* eneOut_; ///< Will hold the average energy of each selected entity for output. From 368313b4b74d4939a3035d54b6de7a5998dd06c1 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:46:56 -0400 Subject: [PATCH 202/218] Dont repeat the same timing data. Should clean that up eventually --- src/Action_Energy.cpp | 5 +++-- src/Energy/Ecalc_Nonbond.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Action_Energy.cpp b/src/Action_Energy.cpp index ad5c235f69..fe605e5d82 100644 --- a/src/Action_Energy.cpp +++ b/src/Action_Energy.cpp @@ -534,9 +534,10 @@ void Action_Energy::Print() { if (time_14_.Total() > 0.0) time_14_.WriteTiming(1, "1-4_NONBOND :", time_total_.Total()); if (time_NB_.Total() > 0.0) { - time_NB_.WriteTiming(1, "NONBOND :", time_total_.Total()); if (nbCalcType_ != Ecalc_Nonbond::UNSPECIFIED) - NB_.PrintTiming(time_NB_.Total()); + NB_.PrintTiming(time_total_.Total()); + else + time_NB_.WriteTiming(1, "NONBOND :", time_total_.Total()); } if (time_ke_.Total() > 0.0) time_ke_.WriteTiming(1, "KE :", time_total_.Total()); diff --git a/src/Energy/Ecalc_Nonbond.cpp b/src/Energy/Ecalc_Nonbond.cpp index d1281f8242..3de7a16a7f 100644 --- a/src/Energy/Ecalc_Nonbond.cpp +++ b/src/Energy/Ecalc_Nonbond.cpp @@ -192,9 +192,9 @@ int Ecalc_Nonbond::DecomposedNonbondEnergy(Frame const& frameIn, CharMask const& /** Print timing */ void Ecalc_Nonbond::PrintTiming(double total) const { + t_total_.WriteTiming(1, "NONBOND :", total); if (calc_ != 0) { calc_->Timing( t_total_.Total() ); pairList_.Timing( t_total_.Total() ); } - t_total_.WriteTiming(0, "Nonbond total:"); } From eacabe2ed479254b6574e59ecbde9afb448123c3 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:49:53 -0400 Subject: [PATCH 203/218] Use Ecalc_Nonbond interal timer only when it is active --- src/Action_Energy.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Action_Energy.cpp b/src/Action_Energy.cpp index fe605e5d82..2146d68be8 100644 --- a/src/Action_Energy.cpp +++ b/src/Action_Energy.cpp @@ -480,9 +480,9 @@ Action::RetType Action_Energy::DoAction(int frameNum, ActionFrame& frm) { break; case C_EWALD: case C_PME: // Elec must be enabled, vdw may not be - time_NB_.Start(); + //time_NB_.Start(); err = NB_.NonbondEnergy(frm.Frm(), Imask_, ene, ene2); - time_NB_.Stop(); + //time_NB_.Stop(); if (err != 0) return Action::ERR; Energy_[ELEC]->Add(frameNum, &ene); if (Energy_[VDW] != 0) Energy_[VDW]->Add(frameNum, &ene2); @@ -533,11 +533,10 @@ void Action_Energy::Print() { time_tors_.WriteTiming(1, "TORSION :", time_total_.Total()); if (time_14_.Total() > 0.0) time_14_.WriteTiming(1, "1-4_NONBOND :", time_total_.Total()); - if (time_NB_.Total() > 0.0) { - if (nbCalcType_ != Ecalc_Nonbond::UNSPECIFIED) - NB_.PrintTiming(time_total_.Total()); - else - time_NB_.WriteTiming(1, "NONBOND :", time_total_.Total()); + if (nbCalcType_ != Ecalc_Nonbond::UNSPECIFIED) + NB_.PrintTiming(time_total_.Total()); + else if (time_NB_.Total() > 0.0) { + time_NB_.WriteTiming(1, "NONBOND :", time_total_.Total()); } if (time_ke_.Total() > 0.0) time_ke_.WriteTiming(1, "KE :", time_total_.Total()); From b03176f4bbebe69cedf464730fbd61609db2de91 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:52:08 -0400 Subject: [PATCH 204/218] Hide some debug info --- src/Energy/EnergyDecomposer.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 375692d3b9..92c6357435 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -213,19 +213,21 @@ int EnergyDecomposer::SetupDecomposer(Topology const& topIn, Box const& boxIn) { } // DEBUG - mprintf("DEBUG: Saving energy for atoms:\n"); - for (int idx = 0; idx != topIn.Natom(); idx++) - if (selectedAtoms_.AtomInCharMask( idx )) - mprintf("\t%s\n", topIn.AtomMaskName( idx ).c_str()); - mprintf("DEBUG: Bonds:\n"); - for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) - mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); - mprintf("DEBUG: Angles:\n"); - for (AngArrayType::const_iterator ang = angles_.begin(); ang != angles_.end(); ++ang) - mprintf("\t%s - %s - %s\n", topIn.AtomMaskName(ang->A1()).c_str(), topIn.AtomMaskName(ang->A2()).c_str(), topIn.AtomMaskName(ang->A3()).c_str()); - mprintf("DEBUG: Dihedrals:\n"); - for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) - mprintf("\t%s - %s - %s - %s\n", topIn.AtomMaskName(dih->A1()).c_str(), topIn.AtomMaskName(dih->A2()).c_str(), topIn.AtomMaskName(dih->A3()).c_str(), topIn.AtomMaskName(dih->A4()).c_str()); + if (debug_ > 0) { + mprintf("DEBUG: Saving energy for atoms:\n"); + for (int idx = 0; idx != topIn.Natom(); idx++) + if (selectedAtoms_.AtomInCharMask( idx )) + mprintf("\t%s\n", topIn.AtomMaskName( idx ).c_str()); + mprintf("DEBUG: Bonds:\n"); + for (BndArrayType::const_iterator bnd = bonds_.begin(); bnd != bonds_.end(); ++bnd) + mprintf("\t%s - %s\n", topIn.AtomMaskName(bnd->A1()).c_str(), topIn.AtomMaskName(bnd->A2()).c_str()); + mprintf("DEBUG: Angles:\n"); + for (AngArrayType::const_iterator ang = angles_.begin(); ang != angles_.end(); ++ang) + mprintf("\t%s - %s - %s\n", topIn.AtomMaskName(ang->A1()).c_str(), topIn.AtomMaskName(ang->A2()).c_str(), topIn.AtomMaskName(ang->A3()).c_str()); + mprintf("DEBUG: Dihedrals:\n"); + for (DihArrayType::const_iterator dih = dihedrals_.begin(); dih != dihedrals_.end(); ++dih) + mprintf("\t%s - %s - %s - %s\n", topIn.AtomMaskName(dih->A1()).c_str(), topIn.AtomMaskName(dih->A2()).c_str(), topIn.AtomMaskName(dih->A3()).c_str(), topIn.AtomMaskName(dih->A4()).c_str()); + } currentTop_ = &topIn; From 9c802cd24f41635135aff8dd7c1c65872b7d38dd Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:56:13 -0400 Subject: [PATCH 205/218] Remove old code --- src/Energy/EwaldCalc_Decomp_LJPME.cpp | 3 --- src/Energy/EwaldCalc_Decomp_PME.cpp | 1 - src/Energy/EwaldCalc_LJPME.cpp | 3 --- src/Energy/EwaldCalc_PME.cpp | 26 ++------------------------ 4 files changed, 2 insertions(+), 31 deletions(-) diff --git a/src/Energy/EwaldCalc_Decomp_LJPME.cpp b/src/Energy/EwaldCalc_Decomp_LJPME.cpp index 56b3285b44..d69cba87ee 100644 --- a/src/Energy/EwaldCalc_Decomp_LJPME.cpp +++ b/src/Energy/EwaldCalc_Decomp_LJPME.cpp @@ -69,7 +69,6 @@ int EwaldCalc_Decomp_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask con // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); - // MapCoords(frameIn, ucell, recip, maskIn); Darray atom_recip; // FIXME helPME requires coords and charge arrays to be non-const double e_recip = Recip_.Recip_Decomp( atom_recip, @@ -140,9 +139,7 @@ int EwaldCalc_Decomp_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask con void EwaldCalc_Decomp_LJPME::Timing(double total) const { t_total_.WriteTiming(1, " LJPME Total:", total); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); - //Recip_.Timing_Calc().WriteTiming(3, "Recip. Calc :", Recip_.Timing_Total().Total()); LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); - //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } #endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index cc9f879fc3..41bd3c3fbb 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -63,7 +63,6 @@ int EwaldCalc_Decomp_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); - // MapCoords(frameIn, ucell, recip, maskIn); Darray atom_recip; // FIXME helPME requires coords and charge arrays to be non-const double e_recip = Recip_.Recip_Decomp( atom_recip, diff --git a/src/Energy/EwaldCalc_LJPME.cpp b/src/Energy/EwaldCalc_LJPME.cpp index ab06696629..ea376d5597 100644 --- a/src/Energy/EwaldCalc_LJPME.cpp +++ b/src/Energy/EwaldCalc_LJPME.cpp @@ -59,7 +59,6 @@ int EwaldCalc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& mas // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); - // MapCoords(frameIn, ucell, recip, maskIn); // FIXME helPME requires coords and charge arrays to be non-const double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), @@ -107,9 +106,7 @@ int EwaldCalc_LJPME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& mas void EwaldCalc_LJPME::Timing(double total) const { t_total_.WriteTiming(1, " LJPME Total:", total); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); - //Recip_.Timing_Calc().WriteTiming(3, "Recip. Calc :", Recip_.Timing_Total().Total()); LJrecip_.Timing_Total().WriteTiming(2,"LJRecip: ", t_total_.Total()); - //LJrecip_.Timing_Calc().WriteTiming(3,"LJ Recip. Calc:", LJrecip_.Timing_Total().Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); } #endif /* LIBPME */ diff --git a/src/Energy/EwaldCalc_PME.cpp b/src/Energy/EwaldCalc_PME.cpp index 88da50ce56..e61626eb67 100644 --- a/src/Energy/EwaldCalc_PME.cpp +++ b/src/Energy/EwaldCalc_PME.cpp @@ -59,7 +59,6 @@ int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskI // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); - // MapCoords(frameIn, ucell, recip, maskIn); // FIXME helPME requires coords and charge arrays to be non-const double e_recip = Recip_.Recip_ParticleMesh( NBengine_.ModifyEwaldParams().SelectedCoords(), frameIn.BoxCrd(), @@ -67,21 +66,8 @@ int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskI NBengine_.EwaldParams().EwaldCoeff() ); - // TODO branch - //double e_vdw6self, e_vdw6recip; - //if (lw_coeff_ > 0.0) { - // e_vdw6self = Self6(); - // e_vdw6recip = LJ_Recip_ParticleMesh( frameIn.BoxCrd() ); - // if (debug_ > 0) { - // mprintf("DEBUG: e_vdw6self = %16.8f\n", e_vdw6self); - // mprintf("DEBUG: Evdwrecip = %16.8f\n", e_vdw6recip); - // } - // e_vdw_lr_correction = 0.0; - //} else { - // e_vdw6self = 0.0; - // e_vdw6recip = 0.0; - double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); - //} + double e_vdw_lr_correction = VDW_LR_.Vdw_Correction( NBengine_.EwaldParams().Cutoff(), volume ); + t_direct_.Start(); Cpptraj::PairListTemplate(pairList_, Excluded_, NBengine_.EwaldParams().Cut2(), NBengine_); @@ -109,15 +95,7 @@ int EwaldCalc_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const& maskI void EwaldCalc_PME::Timing(double total) const { t_total_.WriteTiming(1, " PME Total:", total); - //t_self_.WriteTiming(2, "Self: ", t_total_.Total()); Recip_.Timing_Total().WriteTiming(2, "Recip: ", t_total_.Total()); - //Recip_.Timing_Calc().WriteTiming(3,"Recip. Calc:", Recip_.Timing_Total().Total()); -// if (t_trig_tables_.Total() > 0.0) -// t_trig_tables_.WriteTiming(3, "Calc trig tables:", t_recip_.Total()); t_direct_.WriteTiming(2, "Direct: ", t_total_.Total()); -//# ifndef _OPENMP -// t_erfc_.WriteTiming(3, "ERFC: ", t_direct_.Total()); -// t_adjust_.WriteTiming(3,"Adjust:", t_direct_.Total()); -//# endif } #endif /* LIBPME */ From 06a842e3d55aeee3ca8c99ccc0e0ecfe2950bbb6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 09:59:15 -0400 Subject: [PATCH 206/218] Hide some debug behind ifdef --- src/Energy/EnergyDecomposer.cpp | 10 ++++++++++ src/Energy/EnergyDecomposer.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 92c6357435..388a5b51a6 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -249,7 +249,9 @@ void EnergyDecomposer::calcBonds( Frame const& frameIn ) { double ene = Ene_Bond( frameIn.XYZ( bnd->A1() ), frameIn.XYZ( bnd->A2() ), BP.Req(), BP.Rk() ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: BND %f\n", ene); +# endif // Divide the energy equally between the two atoms. double ene_half = ene * 0.5; saveEne( bnd->A1(), ene_half ); @@ -266,7 +268,9 @@ void EnergyDecomposer::calcAngles( Frame const& frameIn ) { frameIn.XYZ( ang->A2() ), frameIn.XYZ( ang->A3() ), AP.Teq(), AP.Tk() ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: ANG %f\n", ene); +# endif // Divide the energy equally between the three atoms. double ene_third = ene / 3.0; saveEne( ang->A1(), ene_third ); @@ -287,7 +291,9 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { frameIn.XYZ(dih->A4()) ); double ene = Kernel_Fourier( theta, DP.Pk(), DP.Pn(), DP.Phase() ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: DIH %f\n", ene); +# endif // Divide the energy equally between the four atoms. double ene_fourth = ene / 4.0; saveEne( dih->A1(), ene_fourth ); @@ -300,7 +306,9 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { NonbondType const& LJ = currentTop_->GetLJparam(dih->A1(), dih->A4()); double e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); e_vdw /= DP.SCNB(); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: V14 %f\n", e_vdw); +# endif double ene_half = e_vdw * 0.5; saveEne( dih->A1(), ene_half ); saveEne( dih->A4(), ene_half ); @@ -309,7 +317,9 @@ void EnergyDecomposer::calcDihedrals( Frame const& frameIn ) { double qiqj = Constants::COULOMBFACTOR * (*currentTop_)[dih->A1()].Charge() * (*currentTop_)[dih->A4()].Charge(); double e_elec = qiqj / rij; e_elec /= DP.SCEE(); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: E14 %f\n", e_elec); +# endif ene_half = e_elec * 0.5; saveEne( dih->A1(), ene_half ); saveEne( dih->A4(), ene_half ); diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index 501268439a..caeab8c841 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -19,6 +19,9 @@ class Topology; namespace Cpptraj { namespace Energy { /// Used to break down pairwise-additive energy by atom +/** Comple with -DCPPTRAJ_DEBUG_ENEDECOMP for more details on the individual + * contributions. + */ class EnergyDecomposer { public: /// CONSTRUCTOR From 2d062f3956deb35745c10552200c5c8709279db5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 10:03:42 -0400 Subject: [PATCH 207/218] Fix up info output --- src/Energy/EnergyDecomposer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 388a5b51a6..1febff81f0 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -88,9 +88,10 @@ void EnergyDecomposer::PrintOpts() const { mprintf("\tData set name: %s\n", eneOut_->legend()); if (outfile_ != 0) mprintf("\tOutput file: %s\n", outfile_->DataFilename().full()); - if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) + if (nbcalctype_ != Ecalc_Nonbond::SIMPLE) { + mprintf("\tUsing PME.\n"); ewaldOpts_.PrintOptions(); - + } } // ----------------------------------------------------------------------------- @@ -376,6 +377,7 @@ int EnergyDecomposer::FinishCalc() { set.AddXY( idx+1, energies_[idx].mean() ); } } + mprintf("Timing for energy decomposition: '%s'\n", eneOut_->legend()); t_total_.WriteTiming(0, " Decomp total:"); NB_.PrintTiming(t_total_.Total()); return 0; From bacb58d5d0b660dcaeeb3603d2438848b56fc64f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 10:09:40 -0400 Subject: [PATCH 208/218] Hide debug info behind ifdef --- src/Energy/Ene_Decomp_Nonbond.h | 6 ++++++ src/Energy/EwaldCalc_Decomp_PME.cpp | 10 ++++++++-- src/Energy/EwaldCalc_Decomp_PME.h | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Energy/Ene_Decomp_Nonbond.h b/src/Energy/Ene_Decomp_Nonbond.h index c6d8d1092e..1bc0a6b0ec 100644 --- a/src/Energy/Ene_Decomp_Nonbond.h +++ b/src/Energy/Ene_Decomp_Nonbond.h @@ -8,6 +8,8 @@ namespace Energy { * Frame, CharMask, etc. It is assumed that before this file is * included there will be at least '#include "Topology.h" and * 'include ' (for the sqrt). + * Comple with -DCPPTRAJ_DEBUG_ENEDECOMP for more details on the individual + * contributions. */ template void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& selectedAtoms, @@ -37,7 +39,9 @@ void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& s // VDW NonbondType const& LJ = tIn.GetLJparam(atom1, atom2); T e_vdw = Ene_LJ_6_12( rij2, LJ.A(), LJ.B() ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: VDW %f\n", e_vdw); +# endif Evdw += e_vdw; T ene_half = e_vdw * 0.5; if (atom1_is_selected) atom_vdw[atom1] += ene_half; @@ -46,7 +50,9 @@ void Ene_Decomp_Nonbond(Frame const& fIn, Topology const& tIn, CharMask const& s T rij = sqrt(rij2); T qiqj = QFAC * tIn[atom1].Charge() * tIn[atom2].Charge(); T e_elec = qiqj / rij; +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: ELE %f\n", e_elec); +# endif Eelec += e_elec; ene_half = e_elec * 0.5; if (atom1_is_selected) atom_elec[atom1] += ene_half; diff --git a/src/Energy/EwaldCalc_Decomp_PME.cpp b/src/Energy/EwaldCalc_Decomp_PME.cpp index 41bd3c3fbb..1a3fce114f 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.cpp +++ b/src/Energy/EwaldCalc_Decomp_PME.cpp @@ -57,9 +57,10 @@ int EwaldCalc_Decomp_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const double volume = frameIn.BoxCrd().CellVolume(); Darray atom_self; double e_self = NBengine_.EwaldParams().DecomposedSelfEnergy( atom_self, volume ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: Total self energy: %f\n", e_self); mprintf("DEBUG: Sum of self array: %f\n", sumArray(atom_self)); - +# endif // TODO make more efficient NBengine_.ModifyEwaldParams().FillRecipCoords( frameIn, maskIn ); @@ -71,25 +72,30 @@ int EwaldCalc_Decomp_PME::CalcNonbondEnergy(Frame const& frameIn, AtomMask const NBengine_.ModifyEwaldParams().SelectedCharges(), NBengine_.EwaldParams().EwaldCoeff() ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: Recip energy : %f\n", e_recip); mprintf("DEBUG: Sum of recip array: %f\n", sumArray(atom_recip)); +# endif // TODO distribute Darray atom_vdwlr; double e_vdw_lr_correction = VDW_LR_.Vdw_Decomp_Correction( atom_vdwlr, NBengine_.EwaldParams().Cutoff(), volume ); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: VDW correction : %f\n", e_vdw_lr_correction); mprintf("DEBUG: Sum of VDW correction: %f\n", sumArray(atom_vdwlr)); +# endif t_direct_.Start(); Cpptraj::PairListTemplate(pairList_, Excluded_, NBengine_.EwaldParams().Cut2(), NBengine_); t_direct_.Stop(); +# ifdef CPPTRAJ_DEBUG_ENEDECOMP mprintf("DEBUG: Direct Elec. energy : %f\n", NBengine_.Eelec()); mprintf("DEBUG: Sum of elec. energy : %f\n", sumArray(NBengine_.Eatom_Elec())); mprintf("DEBUG: Direct VDW energy : %f\n", NBengine_.Evdw()); mprintf("DEBUG: Sum of VDW energy : %f\n", sumArray(NBengine_.Eatom_EVDW())); mprintf("DEBUG: Direct Adjust energy: %f\n", NBengine_.Eadjust()); mprintf("DEBUG: Sum of Adjust energy: %f\n", sumArray(NBengine_.Eatom_EAdjust())); - +# endif if (NBengine_.EwaldParams().Debug() > 0) { mprintf("DEBUG: Nonbond energy components:\n"); mprintf(" Evdw = %24.12f\n", NBengine_.Evdw() + e_vdw_lr_correction ); diff --git a/src/Energy/EwaldCalc_Decomp_PME.h b/src/Energy/EwaldCalc_Decomp_PME.h index 83344b85be..f3f5d9654d 100644 --- a/src/Energy/EwaldCalc_Decomp_PME.h +++ b/src/Energy/EwaldCalc_Decomp_PME.h @@ -7,6 +7,11 @@ #include "../PairListEngine_Ewald_Decomp_LJLR.h" namespace Cpptraj { namespace Energy { +/** Energy decomposition for nonbonded calculation using PME and VDW + * long-range correction. + * Comple with -DCPPTRAJ_DEBUG_ENEDECOMP for more details on the individual + * contributions. + */ class EwaldCalc_Decomp_PME : public EwaldCalc_Decomp { public: EwaldCalc_Decomp_PME(); From cad81d2c41b4aacc38226a6a403b0403576dffa8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 10:19:08 -0400 Subject: [PATCH 209/218] Version 6.29.4. Revision bump for addition of the 'enedecomp' action and rewrite of the Ewald classes. --- src/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.h b/src/Version.h index 2de71ea96e..7957c39291 100644 --- a/src/Version.h +++ b/src/Version.h @@ -12,7 +12,7 @@ * Whenever a number that precedes is incremented, all subsequent * numbers should be reset to 0. */ -#define CPPTRAJ_INTERNAL_VERSION "V6.29.3" +#define CPPTRAJ_INTERNAL_VERSION "V6.29.4" /// PYTRAJ relies on this #define CPPTRAJ_VERSION_STRING CPPTRAJ_INTERNAL_VERSION #endif From 39badde53e81839566c614e38d5ce695283516bc Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 10:27:28 -0400 Subject: [PATCH 210/218] Add documentation on how to use the pairlist template --- src/PairListTemplate.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/PairListTemplate.h b/src/PairListTemplate.h index 8f522fcee5..d91baeb1aa 100644 --- a/src/PairListTemplate.h +++ b/src/PairListTemplate.h @@ -4,6 +4,21 @@ #include "ExclusionArray.h" namespace Cpptraj { /// Template for doing pair list calculations +/** This template is designed to make it simpler to use the PairList class. + * It takes a PairList, an excluded atom array (ExclusionArray), a cutoff + * (squared), and an "Engine". + * The Engine determines what is done when the cutoff is satisfied vs + * when the interaction is excluded. It should also be a template and have + * the following functions: + * void FrameBeginCalc() : What to do at the beginning of each frame/calc. + * void SetupAtom0(int idx0) : What to do for the outer loop atom. + * void SetupAtom1(int idx1) : What to do for the inner loop atoms. + * void CutoffSatisfied(double rij2, int idx0, idx1) : What to do when the + * cutoff squared is satisfied for atom indices 0 and 1. + * void AtomPairExcluded(double rij2, int idx0, idx1) : What to do when the + * pair interaction between atom indices 0 and 1 is excluded. + * + */ template class EngineClass> void PairListTemplate(PairList const& PL, ExclusionArray const& Excluded, T cut2, EngineClass& engine) From c51cf8cb202a5fa11d141975d8f3cdfebd575970 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 10:41:15 -0400 Subject: [PATCH 211/218] Add longer test --- test/Test_EneDecomp/RunTest.sh | 30 +++- test/Test_EneDecomp/decomp.tz2.dat.save | 224 ++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 test/Test_EneDecomp/decomp.tz2.dat.save diff --git a/test/Test_EneDecomp/RunTest.sh b/test/Test_EneDecomp/RunTest.sh index bee25efb95..0b67978de2 100755 --- a/test/Test_EneDecomp/RunTest.sh +++ b/test/Test_EneDecomp/RunTest.sh @@ -7,12 +7,12 @@ TESTNAME='Energy decomposition tests' CleanFiles enedecomp.in ene.*.dat decomp.*.dat Total.*.dat TESTNAME='Particle mesh Ewald tests' -Requires maxthreads 1 +#Requires maxthreads 1 INPUT='-i enedecomp.in' UNITNAME='NaCl box decomposition' -CheckFor libpme +CheckFor libpme maxthreads 1 if [ $? -eq 0 ] ; then cat > enedecomp.in < enedecomp.in < enedecomp.in < enedecomp.in < Date: Fri, 18 Oct 2024 10:41:27 -0400 Subject: [PATCH 212/218] Add enedecomp to manual --- doc/cpptraj.lyx | 171 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 2 deletions(-) diff --git a/doc/cpptraj.lyx b/doc/cpptraj.lyx index a97dd7af40..60732e1e34 100644 --- a/doc/cpptraj.lyx +++ b/doc/cpptraj.lyx @@ -20478,7 +20478,7 @@ Mod \begin_layout Standard \align center \begin_inset Tabular - + @@ -21385,6 +21385,35 @@ Calculate secondary structure content using the DSSP algorithm \begin_inset Text +\begin_layout Plain Layout +enedecomp +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Perform per-atom energy decomposition. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + \begin_layout Plain Layout energy \end_layout @@ -27788,6 +27817,144 @@ nolink "false" . \end_layout +\begin_layout Subsection +enedecomp +\end_layout + +\begin_layout LyX-Code +enedecomp [] [] [out ] +\end_layout + +\begin_layout LyX-Code + [ pme [cut ] [dsumtol ] [ewcoeff ] +\end_layout + +\begin_layout LyX-Code + [erfcdx ] [skinnb ] [ljswidth ] +\end_layout + +\begin_layout LyX-Code + [order ] [nfft ,,] +\end_layout + +\begin_deeper +\begin_layout Description +[] Data set name. +\end_layout + +\begin_layout Description +[] Mask of atoms to calculate energy for. +\end_layout + +\begin_layout Description +[out +\begin_inset space ~ +\end_inset + +] File to write results to. +\end_layout + +\begin_layout Description +[pme] Use particle mesh Ewald for electrostatics; + van der Waals energy will be calculated using a long-range correction for periodicity. +\end_layout + +\begin_deeper +\begin_layout Description +cut +\begin_inset space ~ +\end_inset + + Direct space cutoff in Angstroms (default 8.0). +\end_layout + +\begin_layout Description +dsumtol +\begin_inset space ~ +\end_inset + + Direct sum tolerance (default 0.00001). + Used to determine Ewald coefficient. +\end_layout + +\begin_layout Description +ewcoeff +\begin_inset space ~ +\end_inset + + Ewald coefficient in 1/Ang. +\end_layout + +\begin_layout Description +erfcdx +\begin_inset space ~ +\end_inset + + Spacing to use for the ERFC splines (default 0.0002 Ang.). +\end_layout + +\begin_layout Description +skinnb Used to determine pairlist atoms (added to cut, + so pairlist cutoff is +\series bold +cut +\series default + + +\series bold +skinnb +\series default +); + included in order to maintain consistency with results from sander. +\end_layout + +\begin_layout Description +ljswidth +\begin_inset space ~ +\end_inset + + If specified, + use a force-switching form for the Lennard-Jones calculation from - to . +\end_layout + +\begin_layout Description +order +\begin_inset space ~ +\end_inset + + Spline order for charges. +\end_layout + +\begin_layout Description +nfft +\begin_inset space ~ +\end_inset + +,, Explicitly set the number of FFT grid points in each dimension. + Will be determined automatically from unit cell dimensions if not specified. +\end_layout + +\end_deeper +\begin_layout Standard +DataSets created: +\end_layout + +\begin_layout Description + Set containing atom index and the corresponding average energy over frames. +\end_layout + +\end_deeper +\begin_layout Standard +Perform per-atom energy decomposition for selected atoms. + The energy is calculated for the entire system but only the energies for selected atoms will be reported. + The energy is composed of the regular bond, + angle, + torsion, + 1-4 nonbonded, + and nonbonded terms. + If 'pme' is specified the non-bonded terms will us PME for electrostatics and a long-range periodic correction for van der Waals, + otherwise a simple model with no cutoff will be used. +\end_layout + \begin_layout Subsection energy \end_layout @@ -28154,7 +28321,7 @@ nfft \end_inset ,, Explicitly set the number of FFT grid points in each dimension. - Will be determined automatically if not specified. + Will be determined automatically from unit cell dimensions if not specified. \end_layout \begin_layout Description From e2cff2cc99703520affccc69464f41ccf59059b9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 12:25:27 -0400 Subject: [PATCH 213/218] Put functionality to reduce an array of Stats into a separate class to be used by PairDist and EnergyDecomposer --- src/Stats_Reduce.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/Stats_Reduce.h | 12 +++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/Stats_Reduce.cpp create mode 100644 src/Stats_Reduce.h diff --git a/src/Stats_Reduce.cpp b/src/Stats_Reduce.cpp new file mode 100644 index 0000000000..487e016b1c --- /dev/null +++ b/src/Stats_Reduce.cpp @@ -0,0 +1,51 @@ +#include "Stats_Reduce.h" + +int Cpptraj::Stats_Reduce(Parallel::Comm const& trajComm_, + std::vector< Stats >& histogram_, + unsigned long& maxbin_) +{ + if (trajComm_.Size() < 2) return 0; + std::vector buffer; + unsigned long rank_size; + if (trajComm_.Master()) { + for (int rank = 1; rank < trajComm_.Size(); rank++) { + // 1. Get size of histogram on rank. + trajComm_.SendMaster(&rank_size, 1, rank, MPI_UNSIGNED_LONG); + // 2. Receive histogram from rank. + buffer.resize(3*rank_size, 0.0); // mean, m2, N + unsigned long master_size = (unsigned long)histogram_.size(); + trajComm_.SendMaster(&buffer[0], buffer.size(), rank, MPI_DOUBLE); + unsigned long idx = 0; // Index into buffer + // Only sum for bins where master and rank both have data + unsigned long Nbins = std::min( master_size, rank_size ); + for (unsigned long i = 0; i < Nbins; i++, idx += 3) { + double mB = buffer[idx ]; + double sB = buffer[idx+1]; + double nB = buffer[idx+2]; + histogram_[i].Combine( Stats(nB, mB, sB) ); + } + // If rank had more data than master, fill in data + if (rank_size > master_size) { + histogram_.resize( rank_size ); + maxbin_ = (unsigned long)histogram_.size() - 1; + idx = master_size * 3; + for (unsigned long i = master_size; i < rank_size; i++, idx += 3) + histogram_[i] = Stats( buffer[idx+2], buffer[idx], buffer[idx+1] ); + } + } + } else { + // 1. Send size of histogram on this rank to master. + rank_size = (unsigned long)histogram_.size(); + trajComm_.SendMaster(&rank_size, 1, trajComm_.Rank(), MPI_UNSIGNED_LONG); + // 2. Place histogram data into a buffer and send to master. + buffer.reserve(3*histogram_.size()); // mean, m2, N + for (unsigned long i = 0; i < histogram_.size(); i++) { + buffer.push_back( (double)histogram_[i].mean() ); + buffer.push_back( (double)histogram_[i].M2() ); + buffer.push_back( (double)histogram_[i].nData() ); + } + trajComm_.SendMaster(&buffer[0], buffer.size(), trajComm_.Rank(), MPI_DOUBLE); + } + + return 0; +} diff --git a/src/Stats_Reduce.h b/src/Stats_Reduce.h new file mode 100644 index 0000000000..d4545222d3 --- /dev/null +++ b/src/Stats_Reduce.h @@ -0,0 +1,12 @@ +#ifndef INC_STATS_REDUCE_H +#define INC_STATS_REDUCE_H +#ifdef MPI +#include +#include "Parallel.h" +#include "OnlineVarT.h" +namespace Cpptraj { +/// Used to reduce an array of Stats down to master rank +int Stats_Reduce(Parallel::Comm const&, std::vector< Stats >&, unsigned long&); +} +#endif /* MPI */ +#endif From 7cd003ff6c1940b519cff3a76f439e62eb118623 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 14:12:06 -0400 Subject: [PATCH 214/218] Use Stats_Reduce --- src/Action_PairDist.cpp | 9 ++++++--- src/cpptrajdepend | 3 ++- src/cpptrajfiles | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Action_PairDist.cpp b/src/Action_PairDist.cpp index f27155d1d7..fd758db3f9 100644 --- a/src/Action_PairDist.cpp +++ b/src/Action_PairDist.cpp @@ -1,11 +1,12 @@ #include - #include "Action_PairDist.h" #include "CpptrajStdio.h" #include "StringRoutines.h" #include "DistRoutines.h" #include "DataSet_Mesh.h" - +#ifdef MPI +# include "Stats_Reduce.h" +#endif /** Calculate pair distribution function P(r) between two masks. * \author Hannes H. Loeffler. @@ -243,6 +244,8 @@ int Action_PairDist::SyncAction() { trajComm_.Barrier(); // END DEBUG */ + Cpptraj::Stats_Reduce(trajComm_, histogram_, maxbin_); +/* std::vector buffer; unsigned long rank_size; if (trajComm_.Master()) { @@ -283,7 +286,7 @@ int Action_PairDist::SyncAction() { buffer.push_back( (double)histogram_[i].nData() ); } trajComm_.SendMaster(&buffer[0], buffer.size(), trajComm_.Rank(), MPI_DOUBLE); - } + }*/ } return 0; } diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 9f212f63d4..e9acfc5a0d 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -62,7 +62,7 @@ Action_NMRrst.o : Action_NMRrst.cpp Action.h ActionState.h Action_NMRrst.h ArgLi Action_NativeContacts.o : Action_NativeContacts.cpp Action.h ActionState.h Action_NativeContacts.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h DataSet_integer.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_OrderParameter.o : Action_OrderParameter.cpp Action.h ActionState.h Action_OrderParameter.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Outtraj.o : Action_Outtraj.cpp Action.h ActionFrameCounter.h ActionState.h Action_Outtraj.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h -Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +Action_PairDist.o : Action_PairDist.cpp Action.h ActionState.h Action_PairDist.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DispatchObject.h DistRoutines.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h Stats_Reduce.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Pairwise.o : Action_Pairwise.cpp Action.h ActionFrameCounter.h ActionState.h Action_Pairwise.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h DispatchObject.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Action_Principal.o : Action_Principal.cpp Action.h ActionState.h Action_Principal.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ComplexArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mat3x3.h DataSet_Vector.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h Action_Projection.o : Action_Projection.cpp Action.h ActionFrameCounter.h ActionState.h Action_Projection.h ArgList.h Array1D.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Modes.h Dimension.h DispatchObject.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -454,6 +454,7 @@ SimplexMin.o : SimplexMin.cpp AssociatedData.h CpptrajFile.h CpptrajStdio.h Data SpaceGroup.o : SpaceGroup.cpp Matrix_3x3.h Parallel.h SpaceGroup.h Vec3.h Spline.o : Spline.cpp CpptrajStdio.h Spline.h SplineFxnTable.o : SplineFxnTable.cpp Constants.h CpptrajStdio.h Spline.h SplineFxnTable.h StringRoutines.h +Stats_Reduce.o : Stats_Reduce.cpp OnlineVarT.h Parallel.h Stats_Reduce.h StringRoutines.o : StringRoutines.cpp CpptrajStdio.h StringRoutines.h Structure/Builder.o : Structure/Builder.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h Structure/BuildAtom.h Structure/Builder.h Structure/Chirality.h Structure/InternalCoords.h Structure/StructureEnum.h Structure/Zmatrix.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h Structure/Chirality.o : Structure/Chirality.cpp Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h Structure/Chirality.h Structure/StructureEnum.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index b82dd96794..ddfc01d3fe 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -409,6 +409,7 @@ COMMON_SOURCES= \ SimplexMin.cpp \ Spline.cpp \ SplineFxnTable.cpp \ + Stats_Reduce.cpp \ StringRoutines.cpp \ StructureCheck.cpp \ StructureMapper.cpp \ From 30bb8f20491ea968194cb44292b253894b37b720 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 14:21:09 -0400 Subject: [PATCH 215/218] Ensure decomposed energy results are synced --- src/Action_EneDecomp.cpp | 9 +++++++++ src/Action_EneDecomp.h | 6 ++++++ src/Energy/EnergyDecomposer.cpp | 14 ++++++++++++++ src/Energy/EnergyDecomposer.h | 7 +++++++ src/cpptrajdepend | 2 +- 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Action_EneDecomp.cpp b/src/Action_EneDecomp.cpp index 8d4e6a81e1..370741747a 100644 --- a/src/Action_EneDecomp.cpp +++ b/src/Action_EneDecomp.cpp @@ -9,6 +9,9 @@ void Action_EneDecomp::Help() const { // Action_EneDecomp::Init() Action::RetType Action_EneDecomp::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { +# ifdef MPI + trajComm_ = init.TrajComm(); +# endif if (eneDecomp_.InitDecomposer( actionArgs, init.DSL(), init.DFL(), debugIn )) return Action::ERR; mprintf(" ENEDECOMP: Decomposing energy for selected atoms.\n"); @@ -36,6 +39,12 @@ Action::RetType Action_EneDecomp::DoAction(int frameNum, ActionFrame& frm) return Action::OK; } +#ifdef MPI +int Action_EneDecomp::SyncAction() { + return eneDecomp_.ReduceToMaster(trajComm_); +} +#endif + // Action_EneDecomp::Print() void Action_EneDecomp::Print() { eneDecomp_.FinishCalc(); diff --git a/src/Action_EneDecomp.h b/src/Action_EneDecomp.h index c0e1cc840b..e7383249d6 100644 --- a/src/Action_EneDecomp.h +++ b/src/Action_EneDecomp.h @@ -20,7 +20,13 @@ class Action_EneDecomp : public Action { Action::RetType DoAction(int, ActionFrame&); /// Print results/finish calculations void Print(); +# ifdef MPI + int SyncAction(); +# endif Cpptraj::Energy::EnergyDecomposer eneDecomp_; ///< Do the actual decomposition +# ifdef MPI + Parallel::Comm trajComm_; ///< Across-trajectory communicator +# endif }; #endif diff --git a/src/Energy/EnergyDecomposer.cpp b/src/Energy/EnergyDecomposer.cpp index 1febff81f0..0908ab6e76 100644 --- a/src/Energy/EnergyDecomposer.cpp +++ b/src/Energy/EnergyDecomposer.cpp @@ -12,6 +12,9 @@ #include "../DistRoutines.h" #include "../ParameterTypes.h" #include "../TorsionRoutines.h" +#ifdef MPI +# include "../Stats_Reduce.h" +#endif #include //std::sort using namespace Cpptraj::Energy; @@ -382,3 +385,14 @@ int EnergyDecomposer::FinishCalc() { NB_.PrintTiming(t_total_.Total()); return 0; } + +#ifdef MPI +/** Reduce the per-atom energy array to the master rank. + * Should be called before FinishCalc(). + */ +int EnergyDecomposer::ReduceToMaster(Parallel::Comm const& trajComm) { + unsigned long maxbin; + Stats_Reduce( trajComm, energies_, maxbin ); + return 0; +} +#endif diff --git a/src/Energy/EnergyDecomposer.h b/src/Energy/EnergyDecomposer.h index caeab8c841..4a0f514214 100644 --- a/src/Energy/EnergyDecomposer.h +++ b/src/Energy/EnergyDecomposer.h @@ -6,6 +6,9 @@ #include "../EwaldOptions.h" #include "../OnlineVarT.h" #include "../Timer.h" +#ifdef MPI +# include "../Parallel.h" +#endif class AngleType; class ArgList; class BondType; @@ -38,6 +41,10 @@ class EnergyDecomposer { int CalcEne(Frame const&); /// Finish the calculation by putting energies in output DataSet int FinishCalc(); +# ifdef MPI + /// Reduce the decomposed array to the master rank + int ReduceToMaster(Parallel::Comm const&); +# endif private: typedef std::vector Darray; typedef std::vector< Stats > EneArrayType; diff --git a/src/cpptrajdepend b/src/cpptrajdepend index e9acfc5a0d..f80b0a290f 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -277,7 +277,7 @@ DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/Ecalc_Nonbond.o : Energy/Ecalc_Nonbond.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ecalc_Nonbond.h Energy/Ene_Decomp_Nonbond.h Energy/Ene_LJPME_6_12.h Energy/Ene_LJ_6_12.h Energy/Ene_Nonbond.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldCalc_LJPME.h Energy/EwaldCalc_PME.h Energy/EwaldCalc_Regular.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Ewald_Recip.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListEngine_Ewald_Decomp_LJPME.h PairListEngine_Ewald_LJLR.h PairListEngine_Ewald_LJPME.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h helpme_standalone.h -Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy/EnergyDecomposer.o : Energy/EnergyDecomposer.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Mesh.h Dimension.h DistRoutines.h Energy/Ecalc_Nonbond.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Ene_LJ_6_12.h Energy/EnergyDecomposer.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EwaldOptions.h ExclusionArray.h FileIO.h FileName.h FileTypes.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h Stats_Reduce.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h Energy/ErfcFxn.o : Energy/ErfcFxn.cpp CpptrajStdio.h Energy/ErfcFxn.h SplineFxnTable.h Energy/EwaldCalc_Decomp_LJPME.o : Energy/EwaldCalc_Decomp_LJPME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJPME_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_LJPME.h Energy/EwaldParams.h Energy/EwaldParams_LJPME.h Energy/Kernel_EwaldAdjust.h Energy/Kernel_LJPME_Adjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJPME.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h Energy/EwaldCalc_Decomp_PME.o : Energy/EwaldCalc_Decomp_PME.cpp Atom.h AtomMask.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy/Ene_LJ_6_12.h Energy/ErfcFxn.h Energy/EwaldCalc.h Energy/EwaldCalc_Decomp.h Energy/EwaldCalc_Decomp_PME.h Energy/EwaldParams.h Energy/Kernel_EwaldAdjust.h Energy/PME_Recip.h Energy/PME_RecipParams.h Energy/VDW_LongRange_Correction.h EwaldOptions.h ExclusionArray.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h PairList.h PairListEngine_Ewald_Decomp_LJLR.h PairListTemplate.h Parallel.h ParameterTypes.h ReplicaDimArray.h Residue.h Segment.h SplineFxnTable.h SymbolExporting.h Timer.h Unit.h Vec3.h helpme_standalone.h From 17c8ab8cb096006f2837ffd9873aafc0ebd10d42 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 14:23:23 -0400 Subject: [PATCH 216/218] Add citation to code docs --- src/Stats_Reduce.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Stats_Reduce.cpp b/src/Stats_Reduce.cpp index 487e016b1c..f4384c6ad1 100644 --- a/src/Stats_Reduce.cpp +++ b/src/Stats_Reduce.cpp @@ -1,5 +1,10 @@ #include "Stats_Reduce.h" - +/** Calculate overall average/stdev for array elements using the parallel + * form of the Online algorithm ( Chan, T.F.; Golub, G.H.; LeVeque, R.J. + * (1979), "Updating Formulae and a Pairwise Algorithm for Computing Sample + * Variances.", Technical Report STAN-CS-79-773, Department of Computer + * Science, Stanford University ). + */ int Cpptraj::Stats_Reduce(Parallel::Comm const& trajComm_, std::vector< Stats >& histogram_, unsigned long& maxbin_) From 31b46b7fabac932d8843566baa94256769150984 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 18 Oct 2024 14:40:28 -0400 Subject: [PATCH 217/218] Update manual PDF and checksum --- doc/CpptrajManual.pdf | Bin 1130047 -> 1132365 bytes doc/DocumentChecksums.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CpptrajManual.pdf b/doc/CpptrajManual.pdf index 70719f82c0332119e8cd8a993ba05c9378ea3e3e..b6c344a580dc1a8866d1853450f5d3f2845d2dc5 100644 GIT binary patch delta 214506 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�rn;y#N-8b-uT_X9l9j~PlI!8tmk7mnPbbuQ>VDDUU_*(4v#3`+P z0%A*3;H4adutqv$n5-;A^l*uHZ3Vr5E#ntSif8=bShGea2^@HEOfx7lJ0LsVZ^+yg z=o!s!cY9md*9xT_;5AE9pYOaSFN`an4S}@|tPvM#*r09gb;e@oE{i&$)ka@# z%VRVG85!IXAaFFZFU92^iv2cfeCaL?_h1~~pk&W+#Bbvy+W^v>6=+v<7J%L>5K9GQ zR)ba^M?8q}{3M^^jkX=_3@}7zG>c_o2ShWATV6}k^yg!M{)-%2Fb){FG#01G`Nk2| z8mgEB9@DPiPDjE>a4yc*s`yD>F(V8lnbZ;-I}Sb+1xsIP{pFz2JOyX$6(qMpOdjb0g4ZmX>8$ z-J9;}-b@pVy8ug9W@f`GO6%F7hc1m@zYVMP>?5w0kWoAbQJ;+xg-I84?&Mvp|pgZuPYm3K1EkNAXE zk$4@5D~1ZHV(aX;C;-e+%V(JRcaIiOMG}Gy3-m3+I z_Aim<-|UIdRN<%dJFEBk%?L= zCDO`reBIwK*C0gn<8bI|-^PJNwI91{L*28BT0DzhZo&fh9~;oY2IoxS4-t;Y+(JkR zR8cu^=Z7QtzZ(M5ceqj_B)M;%=2HiJ<@MpeN_K1EC5a$H8>qESWA%j{dGctZ^Wm3=6M3GQ$FTelGX-);e7% zqPOKrj9jF2NP15KhgM&jRf;iGIA7pR{Exvgg71J_f6@@t>j_djDr%!}WvanuaB@;M z7@;JhKo|gAXic)O)(+h2wPh2?w#t#m()7KVTKbT6uQw#kb)gsF|?T@*;R_@ zu5h5CXfLkcce$}<) z&jvIOBq*Cm6$6L3Gpxog_=EZzJqLx*oX6T?=NrJ(``)MRqX~&khayog4_-*Zvwo$9 z6;K%fw#hlt(;7K(q*&$&G6aH^km80;sl^iRnT+`F7v}``)RfYA*e;(D!a0xe?p}N` zgi`$?_FS#f8lZ~;q1wQB5WW&u?KlcVpREpm6l`LCd0e>u%46arVC5VTa)%`Kocd*- zI{=vDZ$|hx>4j^ar!dIS+m4Rjid}t#vnG;G1~c;X<@ly70JHJ+EQ08s{D(^ z@qp9gDu^jlA7WkTub7!C)3|aY;a(KO;qYFmD=VIHC?-9 z+qS!G+qSFA=(1gPmu=g&ZQHhOyLUhD_wTbD>nL+%WUg2dam_iXL_zYzbg-K-UmOEL zEeiVRo*E18bomCF;}ObuAxq>7YZ|N%*e0u!61$m@3{(Q&^eAh+JZ)-tJg1pHSm0d> zj=x@{TbBhR!d9@Lm)48%X~XD!>GRVC0e5dqh@u2OyvZzRvAD==vlVx>j1dpE$DO?_ z5|u=Dkq~Dld!a+p74}$>%y~I`f!3_nVtg1ul^T{1MTY8`o_JJ1M?ZxHZC5A(>}}{@ zr7U(cJNUC8x13~XaxC2*pp+Zt>rkjE|HO#PV3?igDP;g>ppP3(38J$+=i0O{1dm53S+|!hYjVN^XnPUe@QR_H! zE`|2@^VTFtB_FA2m-ZG;qu#{;6v1yM(Y*6nBb%&QXfvpFJGJ)py;2%1$xh7Xa*zq{ zqO=>@rPLtHsxO}9kpmvlwY~96T??Wf$w~T{C<4SlWGxpA4)}=J3V+u=>?f$KXu3D7 zf;&^pA4Ea3%57KB27F)QO|4{?IMAdijYIkVREI~qyW?(ww%+I?3XclSeOb7iLvA<2)MUinK%)JfGUYK$_&1kJ$j3r9$w2!$gB z_yki^mac}0vaa^8c=`s#cTh(+Q?*$M884`s?}pnSpi~rc#^z}0r`z1e$eCUa1_pap zGup1{Vxg&|SkNIYepwX-NNL{Hj5UC~b}2j-Bluporez}{p;8bR5mhLf8>1fH7$@oz zd7P%%u>W!{6L1A{X^X&WQn%@o8%x0I5kHOcqQzrl7kE7eiz@sI#nuE$oOmVS#u>77 zF}Mg|uY&wF6!7dpY=bK=C3uZQuNifKTDs& z0#bw+$x_u6{?IrU+6VBZ$jAEdGGmpQU23^G&Kko?VO`i8I5w_0F-d{yTIj)gCLht& z3Iflfm!!(MQ6k=%o}x0C5@G~(CgaA2%>?hh)-1{gIj`qF*@l%^(vG1O=2>YQMqw1= z`l;^XswULm*9YJYz?E0mZEe^3W%}zx*S1J0`i>Y^cP?o#2L-u*k~0$&)1GJpeh@Jf zmR#wq%P|R6jQLI^ve9Y$r_aMC1)WRIamNo#HM{rMNASCx6O?APWp=B%P%&)wY{uMhA3cvz!$8Q4J4SIGiJxn7-&BeguCnfaBH9!3OKXK@hBUV7|G% z{J1WitLVl)RCHH@1u#RophEijC5YdaTFJuZ^7r|m9os~#YwjIqSIz8Z-h)p>xhM?A zRdNA40OF=fBbd37IW(3AAFsvPYa}wHA^=(Kmkg%67jHqoGRkS)k1_QWmP$!==Z1%@L@a@ z$J;R>tQ;uPDvaiB~L*!^0S znYs%JnCMtMuY+Cx)=Nf81A1C#1dUMKF+00`C}NW+i-p~(6p-yN&s1KzI-9HdrPOY! z3imbuXthCIY47OTcBFVT$PjHr28D}prv7Y$4&>;N8`R$%>Ywv=j2jW$5A?5sz1&=1 z(jv{#a?Br~cZm2+k@UpQPqUr1fNFTs{!Dk~^aG3+TrBtWk|IGZ-Rl zIBYRDYD8SM=O-dq1$5k$Z@lT5RJ1%Rdy$_4Aax!YfpUY7%V*YG_xK486m7K+bvC6A z8&;6-h~MjG7Cf@I)5S_8gmxK!2_0waX-*%qJ&~V4D`Y2#V&Vd;!#tV*GfYc4_@BT@ zk+)D@0{3{$tl&SxvkI)%|8~(ab#O7hJ<_2#8WaCJY1H~W@Cd*%ZthtjbWXJ0a@0gR z13(CR21u{|Cc|*X=kxqt)Z~T-Pd~x8CP1$^+++LqfsY>-b^~13ayP% zP^;0$)%pHS#F)}xswZm&+--|B__))~jMI-XiW>F|3&5pA@~rfrvyBEJ9Ds}I2mAZy z1(Z12rsO&gF!!(@9*^s8w3%%P>DePm86p){n95pw7!e)bFczZ4Tj)4EcOBlI@1z`S zt%LA~ja{~i^xd<&>;rBbqa0qG&g4fWh@Q#ew+zkfLUG?>5#-x2k-nss30sVcu<(pdD$qXvk6@6lg9QnK<^lZa?YoR&?NJCqvL2iheyW4 z<4uA!&5G)k3$-k@K`>6)a>(_i^8;=DdRSBQjQ~)UNkg9Stu>QO;zFN2D?oqz&mBlw zEdeBAl&6)W7gMVe-%U4*%eFM>`1Jg#7($kh4_t)OiJGO*J4r4HSUZ9*y28CDS#}-8 z_0q2&0H$$7$rvO4=zQ$w+R%yt7C!7rI2_N%Ey??zHUeFi={0zn)oRE4t|se9JM>x! zqgNm(`1Ie%-lLu0k1{n~VLPLZ9?~4n;CzD=p&R01yx11sXHHAFdfuCBs|Pm&bHsPS zw_yva9=2KJ>0K8e50yq-wGZz$S>bLTdL$FB0Fp!rMiXC2GS=2n^6Q`zq62UkoT_8< zm_y-_Zm@V0kYW&0Gre)rL@fv%FTsex4I+gY1jyVSHzTsKhcCMK23{7sbQxMo@GUp~ zViXfnD}C*nWoP0ORP0F%T-&D*LwC^1djbd$=}2IzE!>x$m!C7A3!{C=Fuz@!hPIed zK-6HY6~URuHG+%LcDNW0nx?hk%U!wwNEFBzl!DX-xCPyX*BvOgne@&`xb!iH2eG=~ zPDNQ3Mc3O^s=BZx4MopFbtBidGK)K48xR1X|#BbWs?*LTQGsi-F+h*}!m*u^EKpM5ePT&u`SB?D;5HOzO3XE$}h8_mFrXOjjJVA~jn zZZ21Fy(AjTp0LG*vTOrd#fgRo3|>LV7pjb9ZVW@L_V5T&00^HXG==5+O2ZQ7f*Pt> z#HQuq$sU_F(n07(tcjYFwD^IyS0E_g6 zJeFYpqCK}5(C}0wtYfIoMKEER#a>y~C}&QIKJpmsZ1R`eojp4Y^W&Hs@S#tu*V`CG zauuI#K8}~G+8Vw@XM4QJ*BrNLd++;dO^aF4dzvcwh<)oxvqDO4oPJnl5%4m6kIGro zA%Y$Z?AuONLE>CUd=)Z)uT{J_&G!b{8WT4731Xr>iuo#6G;n zYie+XT9Bk&v!i>ralRu2n-{@{{C^Ekwp0g7(0@{->>U3mMOv(-<+M45?7LcPkOQR_ z&UgZ0ootmIku9e@V@uoP(XIB6TB(x~g!M~F*3adKNM-%?>lo8$<|ZfSrnWP5+^AO) z10W#t^;&z`h;MJe4hlKZr>oz@!PUcAVp-t(o~jZ9^$4hFfr~cSteii!Uj#*+GwOuN)d$C_lAN ztp_#Zd!&XopvZLriuc!47>g~+@*x7m+ug0$fegst>KFnf-P1>?aqd|p`}nBulb)C( z#S&(U0lRGP^?RS@p?)JLORV6TANx6>7ZrBRr8+%~caU~P2A)z?{;N~!wMxJ0q^Rxd zaXU6KZ==%6S!R@%UJW+8ENoe{vbdKSCOGu8G!U!2j#aG}(AEMQg3K8L>Fw3MY}wHqv1SrfO{6+ukA~1X+=e9?mwsays~309#Om3KV_K`xK~rcC7SA@6vJ z2OIn``lT;}>3n69YLEoZAjt5x{Y+cF`r>L!<5SDSjbRCh`B+8@HUP@r_bXG>6CT@3-q7X%7di( z0V`7je$(Sa{NWPx>Zr9aK~Q<7_zMXR86L3~>s^s@;WTEb03u%LmC zlo6PwXFQZYS*8j(AQtJW(+W(#Ka52+*yW?Yk?)H^UWEBWhujRMF32#%XNJv5eP}zD z4NfjXMOzUBxx5gdp&-NEnR9@vmrR`I0mw9mkLYU_P2#cL)Z=g0TZr3dp$Oi22P15z zINwyk$z2zwxsZR0xI&fX z6KS)0XmAjZ-;HG9ie^S6FgG32m7eDjS%(hQGp8KF!y5&;4=D55f6+0GZ_Ax0q7%*H zl-dpNa>UKK%K2CuR^O%4qqpfM0HzUpZ|H1%rJ!J9$pOxN%kz*5hiV;a4Zf{=cCa1&G+ z*0X~fBdqnAAnKwSn^g4M4C9fCpol#1nHdQ19X_DtQNn|e1`pkgqnF}DaVf#bNH*my9F6MN7B0gC@KoA#XH^$8Gk1H0(j~B+Q~4N(uZzk zEPO-*kk(kq)6ih48li#hY)ub8V>Ka%E(-;6JJvpy3{-86)+Uk}`Gg3z^JD{q3-O`* z8}_bx%Kp6|pd8fqdGxkezwpT~PaaAi(J{{E>|6gD;eyBCcT~z*q{D`8j@gz4bXS%= z^bZ4c;{nV1)4NvkfU0(p529~O{$3>RnWmh`JH)PE)rFfP@(k44Vvu8D^6v!rm9^a# z-mYAArpmKIu@wy365|*M@Z%V+86>+8-a8LaALyx(#AEhxxEogvRflQmf5z~Z@jM8? z1T8X43tN%mN-K$pRyvV_fOx51zndh7xfhKoh>+`%Kx!;806`6G*0PGQmw*N!EVJkP z0RGa9UXf>gq&fLSN?_{rmNYiuk&5707-2ySk9X7~O5i_2-#~3McJW=ue55%`W}Yld zlvpQbh(2rL2VDeFTbp3RvE_P-MogviUNo;CXAzO9w66`A#&BB1uf$%w@s%DbR!~U& zQbA|CVi_MzfZqKWdo1ZU$Db*}6)@beGa^cNfsLg4CrKfNlqafj<2WuqYj8JjtTPvX z5h`D7OsozdjT`R+#luVp`X?UR>pe8EP&fGfhI9}ZXV%#qPC-O9={>O62`lc;CU%f- zYsVBgBHY@91!lpWkJ-8o&lYaUA77D+0aU zo|lc*Icd;8Cxbe9mby>3`YT)RPC4rq-;-W9-2kWHtH0n^wZek%>xt5#p*>jSOPZwH zja5H}=(a_o*2gb?2!9AMadXZXz&5`HzywX&0oo5(->ZH@T?OowOravwW zcK$2kKM)o{${biazYSjYy|Y@|v`+cwsq&-xC4E;6BDL24A=>fG z>Th!Q@*5d&hyKcZZI2P^bDT>h-3!0 zmwXq|&HeZY`| zytTy28WVDxqlWF7e$c-vnbRHZK8 zn^8?h!k;cFFu2nzvWWhrGzZJozdRK_;{3<>A3RBnPjks|oYJ$8Q0NX{TtZYHZ>8nI zTN_%k%lUWDHS8oTG7KX_8vy7y8dAhaq*i>t2iSM%tqZ@fI2zdh)*J?ERZ`?#D{$2Hd_eOY zpPBf%ETPjM>ix4H$``oAV=j=F-8V$W(%;DIf3JgA zPqY}W^S!B*r;kj>yZjycu;Lsnci~>G)f9;S#?QK0;?8~pXaWQP)I(*ODKS>!>Oj4F z^9bXImZ|UzAZsIlE2wIwWUcUS_5R3muwcATqv#`Dd8OftRe-ew$&o3(lEUfCstK+32xNYs zWJ$kC`zihraDE_{JEH;KPxnT_=q|9ezTj1&NYVW;sqh$6Y(LcDLZdzhxL(`+&hX!7Ct$Uiz*#8{)THLTK`y)&*nGd5w1fMIm%2 z?c7W-$-D!CaB@xdJ4aIFOKUM-4!V|*4qw|Jw}qTyhM6fpe*G@vjkChzZt6flS5;jG z#sNf;VS8Tj>Mox9e9D84 zi#}g>YjAM#HcU}B;y%S|?Qwv1x&CknJ3wKVGLdl*{@w?r=9b7puxr47Ra&u&ek;*N zYeYYC%ztCzfDPE6&{^XGcXqEF-Ott~eR1aaE@wxaT;@<|ZGRp-7UZKlRDZ&w`s^Db z1fCP?;&q-qryJ1wVSgXN?#fhoa+jdo*uR#)5kZmNU~A!}@^E&)?ns-wq_qt6Z_jYC z0lwh{c+(>tCh3gev7V}=rm0vZB?n-{fZ=KCfJZ8YVRXlfaln*OI@q=G>h2%!zu@4W z^c6HEr*KU{3@NX-5YeYBf9+>gfMP51uHkW1>C_oMalD79d1Rf5wkvT6wBfWrZ=o@} z165XFZx$&t4~H`~e1s#vcnN`P0%R~mXoMRih6qlSw};kU zZjkTuS1=reY5p$EJ^XC|K+jCXqf3>m%DQH^*WaUQLp60?SNSk9wP0fkIm6g|qkvI{ zo$joJCGgtPk%ocVR7%8tUY|Jry;x^$uMh5fjuOHSc(kh;0!u{b1|vV{^1LG3TT5k)31XonQvvyuzW212kVdgP-)26$%Zk+>?4z- zL0Zb8`SJTjrpb3wa>s2@Qd(^v_VkzCY9Es^k)zS8wR3Pe|DvPUDATYYD0n$7=L z(qT{S*8)KY;b2eA&jqIe=>5m!|0{MQ%|T9DOoySB$F4Bdv7Oi1YPOOKGPQZc*>I!N z=+uz$T&H}$>iKFXn9`MhqRf+c+#YkC{{B7ebb~khem=E0J8O=WlM{$9ONwT604C&j z!0CEY*?3-kN^9^?eMl@2ljYU!d>ogS2PB^E)=j4~Q&iYBz1 znc1CN3s=I6>ucBIPGdR}LtcwOdaieBv@f~2^lp}3iQK=Q-fXPQ%rFliCVA1rOXL*J zX;O3Y9-s7xx2<5+C*&?gBaQmDyW8>SUxT9hRDVi_4uC48M3&?W%8e+vT|I{dhQ$jc zCj?i@Q`9{fcDMk@yGoISfb^c>3k#zy?3qXtwG(4S0U?4bj#nNgc|(>44Uds3EuOP+CMWq3965CYW01Jz zw--eG+EtS(9qA-CwpA{IuH(Rssmr|QpUJ`Vg0wOSoWBE*?Jx#DABpY=`Vv6s7_daK z*%3Yx6S)Gix^DN<{YJxrWbrUT7yJnV6vXKomOPn$j z(yAQ4e|~N841r=p80ha4U&p#hF)5WSKGRSOl;2~$gzI}+c1T4e=V(#>s?irH8x=P( zte0Me{SjmET+s#YwVQ@ThJHaZbxvbX z#IMTXi^tu%1Aj`}(DGmm?f)BybDa@Ad;d}?R{*Jf3eckXT?%-F_*WgA2={Jpx|d#} z)m2(NcJ9%$X)Ka<+n94shryYU-dNYM01`k+<}ksZ*N>W{p{^LOEdQbg>l0It=)U#M zjoJr{9xYdA$gDmF)V_5n#}78Gft6coibIwAqwJJj0%`Q>Rj~Eyen0%n!nTkB{*CM&8!z}O79 zd;ECc2_s67vIU9o_OA7+)m%vF-!i_gF`@xf&_kx~NuhuGAJ6%RiCN>1gK3M9sa!bV z@(^H|KH}|Ew4+98a&_`qFA$0Rb!fjcPBVR^%i<;7koVie@3zF<=`UloDa;MeQ#Pw^ z{JeYBQhq__wrtWuxaN;r{xcB4T_wr(QB!CW?)cggD!`KIm{LjwtozlX;Jjm2YsUky zI6e+gD&0O77TU>`fuEHw|0qBEn0?@ZRV#>PuR-@Zqi9J7RwHzUV3VWNu2K5hW3uZ{9cQoXxT}Hg z=M2Vg!>mJoT8UzJ+83PHKC2*m6+{JuyOJ}HIbUiLSkU*7N{~as4E{9e;YrUnQtnK<>w_$!^#mG$vmKJry#$XlmKFr9X+3D0B&EzCx~) zwPMn*M0U9^mg**xfyqoYO`Sk-5~HT6N~Bov!r$!60dl9@d7q=4D;OYLq~euN#u|kZ z!Q2LIKD)VsR!y&5=7jddBROdPC`G_tEQzY7uQp=19BNwLn778?qi%xT&xt6p$=CzM zBg%%=6~LA?y|DL4*znskiE6@XE<|;LrDiL2Mk%<7Z%9b8M2N9y7ImP2&>d`78FJ1a3yuqVu>|w3 zS8bPlf05&)a%|GMNtnyN9EJFygPe5XU|R4Tg35@-{3{@L)pR&f47Ud$u3-C{VUZ!k zx_=24wgLqjp4d=Ih4eyEj)jOOPP0Ez8I#0xM)o3R-He&`XG3lN>a_pwL^VRn4UA3} ze}qIE<>A=F+fU(n!pkmZM>%@5+NI_R3KVoeXZNyY+HtddAJki2pdwW=Bu^f5U&uzP zE~JSf33!vndbi|=eg~a z^-p1XR^I_Jor#qz04aCoxFkl$E#sUl{bWa3V2o&U39l{8>0so0x3e;tbI*R{8uizo z=G~9#px!p^w@Ce*_r%-H=|&B6!-7_x4=to0@=e8UWn|In zj9@3t`yzG|A22pR-=uu0HjQjvW9O-yFxe+9zcRH|m-(s#CaHuL2hM^3oPG%bEq)#p zFxy!slh{UiDzK-z6seR7iih>1&QF%fA2_pf%wTgBP+)3;B>&5 zRO&`zO6Lhqb~rB9$S!k*(2nTs9c2%v-FczyYCUn5XJe^LXr)PCqFsR_wwovS3cb@t+4yE&)H z%?Yc#TZb91X~Gh@a23K)xKj`cojW#fXy%jMM(zeg>9RPhtS!@%nHcQxqTZFff$a{BMl&LufVPeeFhV6Ov;!5`i<;Uq?w@fEQ z{BY+|{Mgw}UFa>>kQ`5iH_84e$`mV*EtpnM3{1(ycM@G@h|9Ur>C7dNZM`q+fdo98 zA&K0U72K;64Sq)f2C^G2dXlzX8ZRvjq7xsfCvnHH1F*TLy-z`2?`enp&g|UiretGY zpe0L%g%^tSs)`gtmazA*RV&HhMr5PJa6%?Vl0#ssYG4l9SA2Kcj|gi5NJTymdyWj! zAG=98i>?lxe=!sjcZT!?aMt1QMn#X;LN}cBMF@cuO$Mw17-YAa$?OF&@1alv!n}|# zm1_Dp@lrhF+OK`9EzA?X8Z4CVdV!Eg@@s3{M2_Oi}*vSQ#<+_I^t`8%nuoP8lziT&_HM;L&-Qv=n#{S1bfeNfa)HZr=Sg1iJ9vkaS- z!b|xio+kMNJPCwbi`M(+hnrE>f~f@&Mv`;DSPEH3uBB(L?&k+B&WL5hFJMFb$H>G2EE=ccU&k~@fwPWf z_n(~>LuL;jIm;h;Q!{{u#pXu&Z0M$9{gB}aVaDLfB4wYYnC*d>LOtYCBKwOP36Vg< zTaq?Q*ckCKJ8%`4(msfU=c`0kXASd5QN8*opBr}r$=*7P^@q(%6he5nbKwiZL~{uq zb%77Cv_O!>pjt^)Ch}pCuxYMYD`A_KR*D8JUc2PD zh)ifVu1aZ|&O_4KLW(! zpqxzM&q4FoQS;(85?Ffr8SwGH?Sg0S32NF?(YhBf`VvJE!W^ovCDut9a|pfG729V4 zu4{4Wg0VKinlUw7%&{^7ksN1h?~g~2wKLPf`8o7G!^3~G3wxNXeFZ$scVp2I<^(hJ zNs5<@~|4H5XtfJUY&Zv;4JmEDO- z5?i-gzn!{=yeNq(JQ{2Hy>(-MPqDh&&Dq+Y2)SW-)i(fuC_scyGjGrkF+K@f;PW;R zQ2zSCvhg164afu>4oxOVxf>APm4%L=)DZ$iiOM;^`HR@F4_$rfHh#SWDOUVoe|4>K ze4!^SjviovrDK|}8$r*6ykN@piSzjG@P1+*8f1h0zf%&&e`=@yNMAOt|08`hZ2p~- zkbZXb4Qcyn?U+f!mm&j8G*>A^BJ<#J>@??JK>vxAaceO@C16hd=W`I>a8xe;5sv2J z#>@Y@g?|i}0&0FY$|4cltB{+m8)m?0nAisku{hiZPdSy_7TAZFKKkA7%>QQMvoU7G zhx3_Z$2WV#?JM+1hcJ+V{s>^Md19a1=J)$_IY{K(IR`GU<>630Gj}ZVBlHO#$3M*Ob|7;j=u1 z3b(8e;E1v=6>uiB;;m`mvrk2~;9P;%nda&PTOR}m#pL<}7~LnTf0EUD=v&3$=#$60 z2%?EQICpCvS#y^E=-Mig;X2G#B%Ay>!Pl4yV|oO^u#b(|J)whVwLIA!OD5Bqd?38W z$cf1fMb3Gf0_ML(;s+?@v4^2V5S!QFx*iUB^^QEnvMfaIYQX{#E=&-ONk+@O8pQWcbC61MGug5&7t>TQPi z_Zasw?QcJCATaYlVstvMikgNgi>9Yd3JfuSH#+e+xM6sandJM6upqZK6W5!Sv4|W-Hl8)TH)eqawLF8EayJ)^+73>ap(22BU~%WAdsI8?o*p?9@?bgiF_HtY z_!XsW`+e8VD&x#1Ktb1{#0RSDQ@|U7lXWA93A7D8K5l^MH2Vm55*8Hgyo^5d_{M+J zR^%{By&uyEuZTKKL)tht{t|$&&y!eA+njV62lp&kEm^oE%|&5hp)`6XLbB>CQh8^R zJqfUUD{5l4<+vtMo6uwVD4wNsEG|Y6@(k6rii-IIl;4A=eeC9QNr&nC zaqaFF#&{BwyeV*wqkq}S+Ls3!TR%v|RNQ5CK**osHl0u;)VpmTu?-xA0wp{i@yxOd~*>LO;4TW}~dVz8;UxIDIVyiknh%zFS-yVcldJpMc-T)xu zPnDJmY8;P+I}RM}wA%-MQ$WRrzm76)HvsQ*a0XeI?NB%`r{GwFXHEDV|ml-&w7waG{?_DWZk zM{`uijOe6n{8_N{AW!C3OPL05RwKNAor!ws{Ok#KGwUOfgarx~qY%$oMdr@s|3qx| zGfdnUM+0Hw_@8leBf}aZ^glxa)JCQKBbfhNlDz7N`p=`F5&!uDGL;7b7`+kidl5R( zL54CF0}>eFzjBh7J$W8Q( ztrB&ENx{!oK9Tisc5Uj;%WlMkwk3PcEH0;zqY=CUSb9gL(E}rdh*~53gR-Wat2FJx z4qZ|lCQhjp)WSqz`D~OB(b9>^G(BRAsv0O&G7Zvo1Bd0OlQDWg$cDBevejauE*blB zP_5|thXK^72^}guct$=QO%K%Ha?RFhRaw&(q2$1E4GCh6OBIQF_0$4VBUkFfR)|!h z_zjq_c^Z?B`O)E#Oy`vYEL3PSV+-W|gZWy`-ys;uW;Xt@8KbgJa%OZr%401@MQLpd zFePNtaxfH%f0WMvGRrIBrj#|%1i>EVoc(3GYt$d)Y+f+h8z#gm0n=01)!G_o^2s*e zvKDHIq1||aT7BsGuq&yc+FQ<0+H_Hj2`Y=3>r9pF!OizG``C_J?!|M&VVqND<0mX{ z{>|qSg6*1Tje-DhX*hAUOjnn_lxmz`pvu++{*P2RWOtbWx&mSPQiB)c?et7_Czp`r zW!-ISh`0v?PsQxwe{-1h0YwP=)8y-%@D}A-fwge@f&wX&^Lq(uS#fC$Fp8NK)foF2 zutsoq09yn_7m|4jK{(OPCrME1EeIs-;(cUNOXjviB@rj=uG)D;cu5P^AWiu>`eIrs zoUC6)nM-B>pqJ$3pJ28O=tv~Z0+gv~bW)(k<@NOnuN(Tfc<}U(1()8h4}CJJhZNwu z5=6nF>F-WAJ9T}Zo_vYqgEeD_zmIZ;>QTrU8qN8irqL6S0I%jvwI`7(ORMJern9RzX z8IY*!QhQU|a{V6K$^oe9sO4zwt+v~w-IsgSd-Zvp7PCe)TVqQRrFI7~3M$k93$=WK zzKH|CVKxfiba6c>WXK zf-imql#$CZ9!!TGH!VA#nw#4M+;mNEcVGDWzIXfdycu`;0A5X3zkggmN57MMcfOXh z|GG5ye9y+tc3!^Twzj7J^?I3?3`}JDCddMm^-GDoKq(>0fe!Fog_p$|Jj5@QzXgm% zCqk&X@7FKjq2))C77MlRNN;lf5geraVp7gn!}Y-%A64O6ot;q^B7r|5&8f2IZxCV_ zH9xhS3T=le$VsaF>pOb|Fq5Q7A+VgS5A|YXc1bUSE7|!P?Db4Ktl#3 z*}GS3r@sar45Im{6OT9lkuuTyCZ++&nr)#J9!JG&MA4vO5VSyIAMeYE8wHz%-hmfI1Wmko)ZU1_#-V{ zlHa7n$UHB39ySPb%B!xuhKb(_$|Dv1&H03wE`vn=XsDWYA`!e8RQB)DXGyQFGfb9# zj6t;MK=%Ee*e6l5*p3axL_+gOa$*Pr54UBG<}#?|;v#fGHNjWt)2USHJ8XiefQ0$ms!|Baox02rgN7 zRvc3PN(%NX=6K)(cfl_&4;R}TqsKR~oRQ`{03h&)LvAaf{rXR``}d>kcv|;xQ$?_q zauCz9G9@&ZwJ0M(ey3Cl$Wx+hWud01E=GZuhLfXawO&R-xtR4h2GG@h^6Asi0aV>p z)Ri+Uu_MjyBksx$+Ij#kH7K6qh@&9imU0TUCXMODWNQCvP#pVUOk1tKpTK(O6Nje{ z-bUnRteO?{(K7JSGVAWV%R^+?A!LH-3k3>7t1XJf2FmNDl#e&E(xkC5CQ%uDY_!-f zS=x(h9~g}XE*;T;o5BCvNYPq(aDew9QtJaD(OVgbfp5TpS^jHhp(Tdp{A&G839JVOoYmU( z3wQ|_Y;(IU_P@g%8Zc|B0~jdke|U#O11L@F869vm2w?4ZioB7EbygeJ0B^Ojo4L(& zsiG}i?(XtCRz^_Jm*PN|^_AfrpTNgV)vdWMC|L*^*YQCb(F7jmUmQli-;l=}w)@=E z-8KHt>hSO)Et|q}onk6YI;d8wiZuMT%gQZAprK+ua)0a2Gd}XzflyRqFsm;ngVKm) z8}t2kUjY@^a8}$qozi_jh5fILD#q5wX3E9-hP&qMy%m9(hLq-!-AaplEj z`2t^{w)VE?u8Jz$*DUmpXi#-)4VSgzZ)z*85|8gZt(2aWFd>E~POpW|d#! zlqVzpK3jj|`)hQZAw*~ITjTfu>xZG173;x3#E^s?rzr@uc$3FO-=9}81`)M4&&vIh z<^cFA4y{R%oZJ4E4~0A|OBbsH#307vKUOvzpqP)V8wWimx3{kI}3aNA*mW(_0_!)kc)5ysv@ zEl$t3a&vilZnmx4IYg%yvF@n2;O* zP-UJ?)&Gl7w*M(ev=XoY|3D@(EugkC@Bll3rp{abi})6PU{mP-7x9w7ZQ#Hh{|o2V zFFD{#i2riR)=yR7a`064f1%#mrVZ=^3C#JwZ=zM&2v`Lob;R!9dc6fO8f5B&%fF9l z!wwh=A`uyb3W~`UeW; z333B{&9C6v&qj=3Yw0qe*fpNhqP5qT@VF@K(8=p`D+D-vdQl1G`J7a2BFWOBU#VhQ zDJV|FUN=LK9wjqQSNbUIPOp)zZnD0cTHeWDus=CULsgGFBi~gE`B2k?;aVn#DL1q%)F~?!P8_kUpRP}$tD9$ zx&F5-4KmDDmfR0++rde^UY3M5xu z5gQ0@Xfp#0mjJOe)hzpFc3M%A%PF{|HStKm0ol5RoJHaA*^pmx7_lQL3k4-khHnU3 zW;>RM)g@4QNJ%L@guJG3gWQy605t9tsz}4WpH~vQHj3nY22IdLMnR;~1{e~KZyG(t z9}yGG#tjOxCL8vC@n0>YT#%ABo6IE@%Rs8B0rN7@!hvWi zLZFQ0&Co?#BXsmKP3?P7YmkK+0e-~LLtwfsvTBl+P6I7j%Oiaga|j^dvOul|0U+k< zbD-N!(-5}ArTH7GZ;G~5Nf&4`;u@R)H8Nv5kui3)ad{O|j2Cg-N0t`duXFhL?KjDnIn}>wbzg_JJKMay{AWrliy8QL+z<%>Q+FKx zbmSjE64B)DZ>F;DUq%_;n`kG{HpurNfCSaWn3<1d&EHM# zZrp&Tk1L!H*Dnjxy>}zum>mr0%=t}=B&NA!y|WDS)3LO-8?Nc1$3| z%GhGsC6Ar+@I0@s<8RuwyfZ?HbP++t5|5%-Z9r8LHP@iBPv4r-^5(QZBd18p94W@? zm)uNTEo#YZ86h741pUIuov&&??9_Uh$$#AI;nYgSwHc;k$-CHm-vO^u*a>!rw zqP@W;)X3OY(#_vCl~q?5hG{L!gkTYfOX6L7vY^e^XR!YtQ{NmNXZuClOl;d`W7~~w z+crC~t%=>(nwX8*q)8g9L1Q*mF}?FdghO&7jbSlC_8ZO zyB4~s1(~Pl&;AMf<`j6Qk=dXw<#ls>4zL^_VwQ-E8JPi$&DN-gQfS(%16uw~*JH;Q zRYSEBhG}tUx}a5liFaVIB{f=zo_4uZOSXmGe-`v@o;IM7`(6gD^|4$1-+ z)JzO{7Cr@P6cGZup*xVd$Q0Rd%wUvUC=oc2V+90oO^Tt=;6S%i5G)U=fMS4y99jQq zsss1dLA?Y1Mf;gXC=(Qr_AunlV!crKaG=f!$oJb1L#e=l77-C}z|#{@WH3Np2`>3- z<1$RcRDY%M@nirfyxxtt8`DewW$>%=uFVam!LG#2-@lYXyGhXoLKNB{beKu5cU&wA z*qaGEKYclpAWrHnb^BYHPt;bd8_%tD@|)A+^sRgNJ=AWjKvJI_l-*wG+ocP=Q@9!h4C*U$rO-kw)&ghbynKyTFtq_9>goLak*c`6Jd4G)JU8u&Jm&u)@^XorU7( zBJJHIDcfd;7Th_x*nyqsy=r={KB)bWfv7l13;n9i41@lG&0@(wh!+Tz8}VYr^fBte zCq}t(iG@Abi@rt5a9r`hEV6RJe1dMgMjthW^@FL;Jw;r4TOn=+Y^Ztb_O=A^I_k1L zQd`bOiG96Uj>Ofh`Xi}96YWrgO6EJ%!Zw~PwIZC&X#BQG-0y9crjhNNPD^grXkNe_ zQZ7ig@e_q<;q@`P8wT)??mG?40?mdpS^dwm5LzR}p?L2nP z3Q^S^HZJs!qRTGne#!Ej{S=C>tw@bLk>#HdFBiC|M==22KHP!G>(WdIf}e%${4?~a z;|^QF3zo9m=UtEUx$B0f`lJk0>Q>*H6z*K=t|c!)xE*sk#A>n8k;*R-HU6LNzOa`W30k- z^v)lmLAAgOD;ugYRA;O%sH=hfcc-()G-`_Ep31NL8q`UMBFNW#Dddv8OzBL0s= zJRL&;;6Qb^5Q>0y2?eQs0-hn8(BLf;G92}=>yW%*&p<4;Y}#=u!){lWR6i!?LZq;O z`b$&q6FH9_+seNe1aWdA;DHIAp&tG(N2mM?MF$7j*l@sxuz*L%J){qj(}My~04UJB zod07PiV&880U1?s{lkR8gNy`=9q==>4c4Go&cn{}DTQCsoVy80EaZOYk$B3U#S!mh(3oPG=1pjogK+hgwZPLy6U` z3~JUA02#GHCEv4Z^Gy?3xq#o&(cztVZVH$d6qz3L_LhLoGAClWdPD+h&WAN9xZ`wpNr>dcxkmFTW0Abg^k?VnOx%15je&woefZ9WYnI8{8=S}^_U z|MW?FHIi0M{cnf}8j4A1PVCvSVQr^$LRoIi)p+Ue0wVrq03}p@jxp8Xh}IiRlO@m{ znZTzhEPF7meV+g}nDTlhEK(v1aGI1aKUTxfhA_1(2+aSUJ3{$U&ZiwJX_ueH0mCB* z)dNXu2=gI#@M##)w%em%h(@QP`42{8Bz7i)0>jyo&K-6o&HOA( zNGgJO)CdU4pYSqS%_A7KF_)-3+AIbE1h6oGBaZ4B#wVrd5;nDQIlqn=Bc4wSM@se*tWL7GL>Qo@4;65lKCBjY#v6ACftk?qvdF1u;r_enSXaa za@KLSy4gGMkJ%)|nhLGOlCHg};b6E|R@HeE=8Wr^Td{xp>+q0hQw7M!vvBC|=0vZ@ zV!G4c^J`wr)aXyUo~WT|pQ*9;(J!axgWJkOPhs&sF3>Sa?oS8INzs^!_iOmQ#^ftBs=c8Ta)ur)`GMybfj!W~OOD9X1)fAa#c8atWpK2S&>fufn zoK`Fb7^-MnlCvFv9M$OWP0TksKxG|SEVz9z2TuIndld2uhEbA4+SWBv%Jxj7 zbOPToyr-J0XPRIB~B5wgL?Tp7-&bbL^H6hB|SdAEqMQ z=AJnMA#o*Tx@UZRS)kBtCTz>o{vyFUtCEHoCq7bKU3H|ZXe9} zwuWZc3(wA8mZ?{Mb;?Yg{gYqf3?wZ?UlD)Qz4*{nu}Qd6vO|$+St^*8i`D%y0-S%* zuIWJZksF@Cc1I7NIdX|U{ID!R9Q9zF9 zeml?*D<>f!1rCbiKdnrc0^kA%#rdBOw?+rJf`>eSD9hO3O;*6gKWBT6DOeovHa|ce z9#m`zk)Nf-0cCKYf5sbvUt|H0SSVQy050e^8szXluLSUe{a2bZ)BxDPgY?Y+IN)V{ zKsX!(od1!l!Oms?Hh7S~3*-~N+OW*vOcULOV^f`=0L2UF2_{yzbamkUJ61<7Wd)i-oB{Dc9C==d@I+j@S^navE) zmC~`Gksh(g`!wV(&Ca871G^5~aZO5JNz?r$kVb~m!E~T-&B#v~ z^bRVMkk79gYJ)Kk5;U~OYxyqDW6zLQu&XwkKT*=&h5==Yg}iTCsUU$9h-Hg`RGPwN z>01HZ$ML~-DMoOb;#a;=Kz;@7vfthrwP7N(8ds8mynx8 zjG%>lRwB*_y7lEZj7!78?~hFt5f?e)60V^ioZ>`~J6Z(E!ZY=a^x?E*j6aWk(=K66 zIap5{7@pz{J6NZ2*Dom%pO4g}P z&Umz4z9D49D6NR`2j)>2fFCXTsedu3>k979A*@^tb71uEZs>$|r~vMQApXqUk%t`` zlg{8un8o1&zESb>*UJW>#kly9VbyEqeUg28Dgv&phL(#X`<=L+>ED^_YC z4yOaP^^mj`6s9=NIqHnknrfK-UUUQfS7-zm&KUUN$H?m=AI%UO9wF%?G(}dTnZooQ zommo2_i!Y$Nh2c+vw}#UfU^{BB=b^`&z$DU@mDLq=bG!_^y*))r zt=NgOoyU6;2xDI_rNW!x4p^Y}pdM_W`Ig`_eLHf7#$;dFfvdYGYZ32B8xc` zx-0)pn4BhwznXa(QZ%l$EZG(m3#bsgEZ#RFLLKsN)ON)wMM>&q~#28BM_0-2L2VvXvy+8+C`BX#F!$Y-nk( zvZx3n;VDT>j4~{B@~Wt5)-9l~->)a4-<&`AK@jCC3%C{4s*IpIFZL0CL@~d^XlvU~ zfZg;;ZmaI9fh~*gG1DsOaq0Hp@Hzg$)EovsluYf%ht*%tJUYZbH0T4zR@#5M`$8Vw&X>6Kk=SJ`0LVc zwHDbZ@s^^fkIN?%VXaM|+%}JUqRGlPzrlkKN!%1-)V5>i%UVMR2BHX1_uQew>dbzkKc_qzbFF z-rwr-#jbnbt0wikg}TlVxXw@+wzGp`XI4Hq+RqWV0(efZ^7c9+&%ifbp;la5veRCm zS1h2g^W}(z%iHzq(Rm;zT?-}A18goss^LTImj?59a4zageHQzblwV&u6*C0vO}k@z zM>pv>JwI}+zDXMZ6)qCom|iWbJ;!J+66ke!UNV=sUGQXTCsko*=AKFqKd>Jsu&ooC zqRg0lsBrfj!K6}!Q9ARY7`qz`;y?cZG9OP8JeRBgkjx$q8M{(jf6U@RTXk2uFPOOx3HLKauke0-Pe2oHylv9TzmZHzCb3?1=}?MX5m1pJrLZJZwJ8s1IPc=YQYvgfL?ge<>ddc+IZw2tcK+C zK}@+|z!bm_a*=ciVr+oGf5B9st_1)Z6b@)&0YC{foI~!@8`*Q?zam^Os<-)bK8yYL zXQ1cf&tHxOvz%=4BYr;Md|36SAgj4dvz*|Cf*Y<#&_e+-x<06)R0wg-FHe`T6E7aW?IxYeRfB7e2k~}S?nLMQ$PmjM6Z+G3j_E$R#U<;m}(+g49{>k?{t1o zm&BBBp^AJM(_ErnXp&*BG$T4El`eM^!o-^2Yir){q2nXcgCuX4PKC!lmC`nM$roJgTo)0O9q6U5w zN=|viYESrh8y6Zlq{7h5jxoE@QuSm_xpP{Owh2QS$CLv~$Q zNITL;6pB5KXKpyo|3vJHzYT=6PO zYL$Lnw04F--Rr^cAFRM4iHq2=_~GNq>B)hX=S*ag>g+U8SrC8{$Ltrc zjE-Y!tHfh5WXRh?Q+|UZXD#Bc4TQ!WN}qL%-0#%( zLsjIG$0{#H%wgtq3haewuJ_F}wQb`xa8p-gwdy#Vrb%G~E9NT6q<@PVO>|rH9xGEG zJQaFrklW1fDP{4qE8{HI)pi%b`5c6P$ny#57GJdtb!*J{wX5_&h!X)AZ)ug>km~Mg zVU?QZYoNXs!w~U(0~*8@GB-|LclLJMhz7^cDE@Xbij(MoS;qkf>kYoolm&&6L+46i%;7m7gqD; z*?LJ5Wp|>A=boAbk~9p=iw;6AxOY&)#U2;j6RO$Q>MzQqnlxkZxg|q@y z8@Ks$BM!s+^G03?dW1!cT>nibDK4H;$`3AXX#J%oNh@FX=t7TZ9>=YoayI#@kct!m%G%Hd-fauB@aHaCb%r~3z2fSg{4poojZ|8n-`cUz@nKzreG&qMFRA!Z z4n|jg9fMPGaLQ}I;xC_`W9o-Mkeniz{g8NiGChp1`#(GWfll;drj?S7Ja*!4hbG_i$0yF&oWl zzQ+n-)5ZPpTdPpPT+=Otx`bp`9DcWt{3W<)gvu|;uMk5Hh-0><#OvxW)RsM__A)1v z-AU%!GiK<d)_)YpdZRQbXcu+(w7UJS3?89M+TxPL|q;DWag0TQqvl^X~l{u~53NSK}huK%Ub zp!qZiS5LYDsKWolf3d;WPk>NlPzxRcHh_yAMA-q)1gy_jOwW_U8ozpHz*X|m)gWR&=^hdg}mHptDJ!pOy7D9!D$f|e^U0a?;Cam$e#yT6VG zpi{MCfrIpA=~U+8dz%vqZ*M_&OMzoyIINYNexFgPs*|iK{3Wpn;pc02!K1fXbn(h) zH@JDHThZle`D5nqVP}(u4P~jZ z$FJ6s!!ff1m1Pkz{ILSELtGNn!~6EILQ%Fk7?`P4kh$i^lh~G9Z4c&aWT!zEAvZp1 zjInaBHodb`mnT1u$fM~@bD&(A@09O!oB2LX*EFENt`uAw*n+=V_y&@Hyqz4%cl_(e z4rJ54HVGrbcWVZ9#>EUPlye|jM|kjrVal5eQ!7|a%ynYi$*9|Ilxj!s%u)Nm<}u*Y z#MQab!@qE2Kwj-t(uD{s1yBeF;>@EFBseHX1EGm za?-CmhaHHfdYdokI)VCwsT?BMgD+c51;in-q{`e4XGGI#i-F^*puxl8qaTwFIlz>c zw43@^wNW#fw=x@*;ih&nA9aK>I;ATkzjEZwCBe3>#`L{hnEjr^wRKot}aM zV{6MFbD+^H%7d;^u$B(F&y>@s3kr5=S3^KMNZXK0{glga3ptgBk~{*Y$03gm9k|i! zu8Q`w<_t>)<{(=YRo_-FYJ(#ZYJ0}Hd+I-sSE5ON34R=KProG0+1N+ym5@Y;3X*N2 zdLayriS>-~JfcJqET-RU`zi(%4OeW6n->H-=Mfg%3zad>?$YKum{-BLk`(8WL5235EA)2Aou?`?c8@{PpdfxYD%Y{b09H zkqa}sXm4#n6_NihO^HY zt*Lam1f5Zo1(vM7R9-NFC!=Q-+E!UI{<8FN|G6g{zAMv13C#?lYnRJu9|eNmbjm|; z->MaWT+rAS2&ytaS$nuHRsw!s4{`pK4Cq(H#zJis`!tYq?$G4^rOvx>VEtk!4KzIN zj%cU^B??v@4>4`nUDFb?Y`LwCu^TL@JfImqbl)YSM$`ynFIry}_)0q+z$5X9o2%31 zUrN^Cvf=8zu>wsrxc&L%{t0+(wPmxij?g`6csx>DaJTy^wc&lP$uQd=%AtsWI1ly4 zisht~fUC}4trtDsnN8q0xv zus4QAmC8(XMNbs@<@n7-rJ!MxdissQy16LpMwS+WJ+k|(gp3JDsn@RJ!scz?G!>LD$z0+=i z$diTGi5c6_z+~CT{tUGiU~^Ud)wcheWdsJ+=O;_Fm@jfsO;ov*i2gY^a#8%LyOv!U zf>fL+)d?A-M1JM;1l>T%Gc9Y4UH!m%bOML7I;RAnyS>b+XnOAtr7hcCO@i5uzywUm zVeAh?l2jufA@_y=7y9Xk8?puIVH}Lza3o&Y)#31}U9O}`rpC5wz(h**hZ~cCDW!nZ zniJ7q!S!f96>VSC@+4Fxd0u75)F^3$(TgRht$sw}eN$6M)W-(4;2_50!&dl7(;OF8 z2dw^(w35Th_6sP9B{mCOBs{+!Q%5VnsR%xpQ-6eHc9vXK<>x2^4=WzMD}7w3nhE&H zwaic7a4i-*ej(+vKIKVzU(P1W_Zbaw$->G*B0{5ZzZFNNT$G;^olOYGAzG42pNVu} zBS-4m8P)Gcuv`N9{Uf1;?>uHvr8R^P{FEghyt3iV?zr@{K8WR!wjfO_xv8ZHLpubVYnPrt* zbyqxDF7e$XD^hlqFJf-C<#>Fwz3G#j)~ZTGu^%|RYXt+_tKyRky~0K|U#1UqmnUP5 zBzT8b&o_u}BGugN7!c#WBG;Du0&r7B8NK02hdElv%UL<$=jyUc8AcbQ(K~qPHig8+ z(BwaS%;qvA?>dMN*7-i$?52^?02z5h#;&s9vH5dXWuv$C)rKi5Ke)*9oK^RFLR>VP z(+VaQ@7pd=A|g{QXio)Ih@Y@&GHjLmRY=!SyU@(Ov;y(NP1Z>t9?OLx=ZB`r2ZLli%dzJ}`yEB*QU<*GFypH}d^Im%3~Lc55QT3?`Fz{`0J$5{JH+xHI#z48 zy(_1C`*m5TgJ6FzJ5HDKXsK2!mmqOznmBhXTZTc__Ps>7g4HtG$5Kor0VtTJ9QR@C z!P1Pc=06cNsJ+O@gL)k1Q8n+qHb?`SExpCby*y&UFd!Ge#n_&}t6!bsjiAbFf1A1(uXgrx4H?=UdbkwvMid!Tb=E!qZW_9k!sZ(*^A4=|xh znt{JGBLZilpwkX>_RISHxI2frQi)iG2s<_%FBT*ws^fwt`zZ@IJ1qY5^cC{frQK@Q zPVWwh36WWYZiRnYSpOFjcT)3OUn~ZGeT4{uBWmY^-s`DGs8yGGl?TaR`KMTbkzOEc z3nTyW?@59=$gk9OP}!gOf$_0)&k9pX4<(OrNsoXWFP=L8ZXhYG`2XgB85h|^eS_@pY!yI+V z@SsY$3JS#z>xZv~0r>TpyBc$2)0Qx|DZo-Fz}F{fxVLZaza7I>gm|0iL|5FIgkd1# zI+6KKN@nOU@3>%#YVQ|1|3#pR2qOm44mG*@mB?^QBceD)d_fST(Jc$(An zinOuMKf$P3tuy_5rc?av&I=TEd7SUA4cu(FEEu=x7_xMMtnL{J>iq4o2k2ch8E$^8 z7Us#6cvmJ3_*nuv6d_fo408Vdh`_>P<~CJI&0+^Pp$qie!^G`ja82f`fJmkfXNtGU z#cc;K8_^xPJk8P0C;@Xs1U-PeTpG^G4l@xqfi?FrPg4(k#w@(S(!j{K6JHO=$$&y_$xTk zvVOsN_asg*Mlom`{?27ncHXZiIcC8e^Sa(kWLlSWlcR6b0}J&a1n z+vfy5kVVZwfqAQs>-Y$aPk1eiEZI&5i3>70^OeV5Liu9e!+-q?)qu;>`Hz?WUquiy zju8hGMU2P{VFu308)KN`JFlA8holP|hL_M?FmZtDJUBVS!9>(H@ictlIC`!Mxyqj`IuP*gmu<|#nbh01~=oN-<+t_-DuYDIGhn`*C-aG?AAHP{#x zIb&;(I~`zRTk`91{nE05+n>I7zmwZn zc*d*G%<&}`H7%z5t`EjDp^|b5>>;w$aQ^=-D|Sh$p3eQ;uOdmfstYW6&tzT7iX`_2pYKY+G6*gi)$UM0&_UUtIYGZJF) z1oAfO5>x{an^|s9?JQ)tb2Si$?V}{Q%p(*qCsAzF$H-=b+wFUl*No}z;W`NGR5>k6 zE)YvrkfEnVSJlxzJcKq}2&?b9h-o-&Z>;)5*lZb2A@tF+QeCET*Aju4w|^@Es_xDq z3V%eHt&HN=iBa5Ib2mi>wDt%Dwb17jU|2!Q3Vt5!oSQ6R^f8JFoQ^7?WfJ-8;sG2R z^yco))y|*U{-;QVm+_*V=7Be;MvK=%8}(K^`lj7$cDw-p;+6&TJ4+Lu!Od`t{mUNc z@|b5eTz}&pc0*^1x?$_^#N2nr1I6+N!b*WJtHFWgio@7S%`p}-C}kvtzgcA6flQP% zbRh`|hzG3j8;2b;C()N`DA6wF7yY5gC>nb>7CO7b0|u@6E;Y8FroQ2WMWJ~v%Yp_P zP0cyl|E_D1Pb-5~f14IvQR2>=g@1CiL+wV)E>E|9dqdjJ3~m=-8CQNIcw(X>2%pxT zafrA50D}m1hM8nh2MH{s3uTU)1`1e~7Mo?VgjyN-#l5N`@9x*1(i%td?s&7ddbI_6 z@gS>tRl$#&y`HDAp0z9-&T_y8FPeVtGqUm2wAnbx!-Ddc4r%JQ#&-fXp{E2U(8+(T zIE|)bn~JXN<%7-Y5eEWO@7u$9=^q0kF$Gg%a6hHR<9_>jTA4MhTyhH|2ShG`%gT_b z5mh-@&^Bdl4TSCy)Rr4EG4oAJI?6IWRt{-^e$`-`$WU&)EVKV&!t)ybi$z)iYm834 z({0m7jVzR2k-LE`iZBrY7ClW3F@h|#4D+LfUBoG!GEJN;RI^ffY6wxGrm3h_ViJCG z&s+STo)Fq?C^|+Z1Z2`|GoS#Rwp$%%=B)Yg8NKQ`=oQ;Io8XiPV$6qxu0{n zzjma?1*=23?C#q!Y;q4?=~D@>xmW5+dl^^d1LRk6r=-M6FUH|=w4EBjGHE#pG@3=w z8o}+{wdn|LG501gZgYm$=_{eAGI+aHP=_mT2oJ_xQE-ZO+Yv4x0;2@1uqB{?g!7)t zkFEA2DhD|`(4{Y<^nWd4SKCLpkN>#>Pl_4V8lg-)fyrK>MXE(0K;dqRGmT-jJmUHr zdG|4_(M=TLJVnja!ga(d*mesikFLb|_3S zf$!qS5fPJV?Q8;&HEOASgme5ZATqU%KooD{lEFawU{YHaXPoEKn>(CGR}GP|yKJeh z^g%6A`$0yUg$;)i|(?M^zh!8mHE)YX!Ke;{%?A z{WjEwe=qaP__t)WCfeJ@h#(-*%5KX2nMuH=9N=qKN*-#$wmds_DSaAb0Hg6*( z>w5KZ*AJR4NQ~!tA7>()te{1FSO|~i!q|0(zXxO``is=O0@*F$3-=xJE2nR*t2-K* zq(uZAcednFh8?Dq36=8O;6?OVqCdf=H2%b;utfUC?*o7fANwp;pFgA2(iMvGmgmN^ z@S^l!Xd{;7#z z-yositXmBW(6o%lI|ioYI}WP2TS%Wz#yk4C2FPy*D8J>jJsvj>#l4}=l*IjK_7`4&m$+Xe90+Fp!sCZ&mjWc@J)byE27@Z?c|JvE#Tbboa8Y3*k!bpNq+GOjIMiuT{7uBXXQgBI z$cuV~M8-(8r+fQQKnNk$eOrQh5{pJy4^t|6SDMKxS_cEkJb7{^-@N_aOIuUx^~?4u z5LM}nTf`iDX$e&yn9;U%Hs~QNo4LBo%kO!$<3btCdu+VhpC+&IxtA^Q24uZ?4L(8d zf&u$Ir%Xe((@p?lL&^rc9VRqA7(URgWY%Yy5Z?;L+1OFDb&<@fKj8$GWMRW(S9*6) z=;{Mb3tbp)cq8RV;+rPTe5QwW`^P-sK{Iek%y8fR;e7^5N-n`I1ny_H+;9_BRFfWN zrp*a?I0IBIy(QgQOAINJ2z8Ol=S26M7GnOP8A5(cL5|pnf-~fp1tH&FdnaN9%@0pI zsU*n=;@NHV2D`65&-LdV-(~i7b~f_)BfcUa+tEyXq_2xQ`Zx!Z+PSPVY$taCM5T2< z-={+Mg~-`B!XR@xib<)fLivUdYXK_L>Z0f5G*O6UKoo10$wEYL#!y^{np} zw6Uc@G_6yPsz)~F(|_<-Pcrm?RV-e6D0#fWJuQEXu1-iuBfj!q6-zXWaZ1J$_*p4% z)-2GUX1+f(-2ddx^U-}b$({Rc?Q}i%Adfz`H24y@7N zgpagsHC<{t{IAN+ifHW8bmc|S(E2cafhkbVg(Ggybw`(=5)AAb)N{TDqIglHYCy&( z8hlM*rb*SH7%`EhSv62AMg;F{W%dN^9Up<4YR{1778fp64@X#cikx6O+nX4a8QeR2K`Yt9v@UT|?(v6#n8N+7|a{JdS&gi8a{Ea}HtH03c^n zKBIPZw5zEuEQ_CvKHELe)Wxh2QG%1f0s2nN|E{6IjtQ)7w)uS8tZ42bRkS0a;WzWb zt8L5d(_@I|DH(}kdBnkSzqqs$dY?{?H$cLt@OCs|_E}J@1L1xwW?wN{K?nUX|NIPB zmQErpPWxT_?_d8J+bm5a^okf9mc&@%4Hhoy-2oWt8{obTRU{IK$^r`OpBnwYPC7mk zXhGzEoOI%lf`IrQ91|E4-meJ<&Ck#ApPP;6|Fxs?a{kZFrtC_>hthY|xX|2ZN2@_Y zJBW~i-uZC>Ad@C#NDV)(k0T51x`$5j{urF!o@adZqcEqS7!9M*Mq2&nL7B9DoV#2} zc4R4~?i=s0>tTxFZ4^umPev{@*MTm;aD?qodgljouisIy_8sD7u+GLHIOc}(L$zwZ z@DeiUH(lVYX|a&?Z#>!EBJhF);!97I*THqProkYcoLlXmhDesRO_c=QiCEv70awI; z`WWzL+G5v13$4`5&Io@mQz+KRUX~_>(jM1$aV;bH3UQ-&Fuz)fio4Xbk;IBPRRM`? z)nM>do3w<{w!(wxuC2@GG87tO^C%+#y~6eez!rEBAizH4^%&DNNa*pEv?gK#M{|kuiOTD!ZsfsYH=of2GpRX4 z0;YUYZg%O9=Hho|@$(;svwaHYkPc8gz6b;prNG055Ty@O%RpaaNV1WA(BP}uwdbN= z$eIP_!&>;oBEone3C5kZxX_fNP*Y-*yTI*N*I54CbKQ5438#C*l$MrYt(vs!w87;j z>hVESI4`tJXbBLH3=`z?yn~uDW`-sB*1llq$p>}6!fMyhm?MS6Y1ndUjF{y)Lh@ln zT(ei|Gl6y``3&DB0{oY;<%dw^-8e@Mqz(xnNm5=#1MJ5+dw1`nuh*$7i~A>b%|X~I zDQ&onZ@etP*LQRp_)qZi%T#h?tS+L!KTUo&`|kEkw49P{)WN;|ooJsvnfs$yr8u+^ z`ko`hroCPwqJ>R>Rnds#Rz)OcZ&#-u)_Rt``4Oj0cSxcSUzb5=*E=Xzf1d**la|DQ z5G%RkOhKEr+-KHIt$lUkEu@4oT_R4Kty^3K2llTH+UtlfY@*S zVa_mMk%rz24sSBUwCpzcLgT&4!Si&yaBe*zrQDjaVNTc==cX%o$rKztm&=!$$1l($ z8iB*5@DZa?k%!C#=$@!()cQf={1c-<*;iHB*r*&vmLIl;? z*Xs!ahyd)*E_W9mK zvFEsGp6!nTi)lTZSUs!I;jfX~@k7<=Rr;<#x4^kw`3^{DDlQ18InQ+^C<7aa6Hk2G z5`J#1_owOe09wdfPiI^zjZ5@z)TT{Tg>6U0Q@~We?O~q)irEYyS-=&{C&GXf3(vBt|#`6XR%vG*>Ktv%N{ zoCO?IcvO;fi&67Rw?uxv=U?PNyDcdu>tG>6Lznh#gEMdt z{NOP2$afW`WyQ2Dev*8dl@m)p0U`U2X~mbT65JuYJE6SS*?tnw(YA&Yooz0?`SZNa z79x9NzhO@1-rr9jl;^VEWU5-TPcH2uC|D0qnpfyt*UEY~h`*iArgn5F!~{_%kc;S` zJ(M0hXT6o~Us#hpVsn9~I3CE7%sK&5LW;Cn0aYe;0qlyREZK}dFU-=$BK*5DPrwN% z(vw&A>5X{rwcppCADH@$A$1`5+nql*m zB$b#!nQ+;B|9BW<%{J!xK3HQ4;lwx6H66R0Arf8ze;U(zLEJtK>m7O$<^=2tdh9qW z2t3iB!vD2aY<&V(-wW!L1RpjX32=2Xgghjx@3sLK8FVZ;gt1R8Rw{ox#0#79Y&N4t zOTcct@uxZ_t(dRZJNuV^Bt}bQBrdOXx(=tL&)d87dDI-oQ>WKd3S@6gE- z`fQje|B6NsJGD6rE|`!NItUh2FAj|d4i<#wfcw|L1|AlNhD88yvj5WniUZz~gRVjR z&xxI<0WAy%Dgh#5gHQFKx8XpW_7LmZhAH$G0uVN+Ep_f|jwcE%qE`u?{YrZy;&k~1 zg9-!kJH=EMpSzGi7>j2$?t>PbY%J_Txy|k!*|6FgZ(57mYZ}Ofky?pMES8#{aZJnY zG=sr~j^x|2uZpr}`5#!D|QlRAH#%$YnQ6n*Tk)Oow*M`CZs@(iMp*uRl% zo)J6gYf5pV+idm2V13+&lcJ|DK+sr>WmY8n`@UL4=r&0|hxvFtH&tOvE->n|-iai! zGg$NE_e>906!Di2ZV@j_w*V=p6SE#lrZ6YCwu}{Hja=H1_ zK>ts-HpexE^(SkFw2?fL+)o=ZpBm?%Z0A6=t(EwKu^w6UoUuB2a@h&A)v;LVoYhKg zOr_I5wmVl`wk+(+V*^(ooJ@`OKuMTSO)tNGMQXrnWC1l=^DEtuvf?w!>+o{o@%b9?r>BMduV;fcslRL}TYnfD zC4lf1#d)07SMbi!&0)~iH^p7vY9Svb!yF&0#kVjwmrZz2E#KO@EsARAzTfu0iTigAs>Kk%6js-0!zg)MDbX(hg_Yy@cOMP5G()}+`H1fjo{3S)eR z1VDT@-Y54*o;@5wO?}=d`@rSR)Gm;o98UQ$2J73)Zz&3qr~4pHofy&Y@Bz2bA}3$W zyXa6QYQk>CQUbh!Iavj45r2j)z2is6lALmuyI<7AxnUR)2YiR6R!4kIi=9@V{Hj5e zXUC8@$+nSWS5Zzd+sjbv-oWiOEF86e0u5Z5>oTWvp#YOw``wjUt9jTRJ?>sLHe8J@ zj_GR*ZrT2&rw_9dw%X_XzKAa}t3j7RCi31~9fw_XU#H4TP<^SD-PGYa^!=9A&o&!p zvW=0wz{#cNG{SmOsd9+fus(VUU2_DsPe1Bz$v*D88D&a%WC(Sk_f8vW>RX1Cf`Slbc24EMP*y?KtFB)WpC?o_A3WoEm4aL`nH=1dkeQZ|JlN|~d~ z8L?H^uGergXlgNJd-(nlYHQ!Vi1eD#!c~sqZ|$6H+Em2^#9s|3)Q1->f$O)f`mPM< z`8|dxuz~mPOdKdN+h%lmq`_}*(?~$5lOd02EOtg~O?aJ!sL;g&gU~_T3-pPgPe#Vi zs>KqoghBUj795s`fi8Z>MtUd>#@VI&#YQ+Q=Xxzt!5gefWE<~F=Js<+q8?F|=kj*& zWU*DFh2pzgXRRk`J{V1rORp;t$1Yb8(v4%WsASbhKy1*$EyDB+q3f~4BtT~i3cpQX z7ScbcHyE=O^r2^hc9CoCSZytyyhXFBVFkZ!)gi=k39YUW9{i{KVlS{1$U%Z^YHzmN#B05O~Z&@m`82V=$OMc z=#6sh`V-3c&HqExIYrkQZeKsij&0kv&BnHE+kJz^Mq}Hy8as`XhK(AlF`DGdIp;sd zceQW!e#U-p-u0}t=KReLfGNyM+`d#DFo%$%FeX>byVccgUiIin9WVW+5C>0Cu)sJU zrKOui<-SOZHVw;``{jpvCIj9fI7CKm+t~>S-#BVB-P>HE3cR;miquH z&qbVUB=49v6D9IrC^EiZh35rLYCYl;x!16Xx;d9DU)zFf_wwaWeajxu0wG@kU`@!{ z_~Fd94_3!QPE9fj;1SCTmm~-uKPeYMkr3x$e64M7V5y=;srB+A@36cZ?yS1}3Z1 zROQv)WiBCBe3pBIsrHdj1MKlyX}jqZU(Z;I3ZR%E>0{KvCa6yt2%fN^ug zn_J%xoamZWH{;Z>e_q~S#?-iB%G>Ft3H*6G!NPm$wfBs^a>zwHQDy`=aj53JphP`i zjmsGFNof9#ugem1QpZmr{f6;Xe2=&7lC`};LeAjf>P!QJt{9vM9ASRe} z_J~i`LvSDn68e)__9=D8XwM7<&BFdqIPV_|68XGssD0ulJ|%J4P~dy*_8FiNa7c7~ zlDq#L^;uSV(@ix#k1)ytDZ$FoQ0(viPORsJSz1^fBz&JKdg>^S%qk^c)_Bspw<3w_P)cWchh7{4{rm6f>89JC)^L(y zP%!L&)OT3zt<|8i|8g;gKL4n56X=u6_Fp%gStkev>a)%N&jWzidHK?VePQX^EBip0 zkO20x%j`#y7_Mz;8a`z}t9(Ff{*ZQeQ8vrdB#}$`vgs~Cs$@#&TF-{jTHz%cCO{3r*Rr8M6scvnlElzEzX+hHz#F8CcxeX2 zjHb?>L{}vt_Ay9MqEgAxzP|jD?|}fDTi?>{Sv0PEsN$ zZ68up6D(Z5f41p)5;Ve_X|O}QRoO-|0nH@OQIJ6ZJF>5>Q-&oOLi*q-OH97-4&e4E zn5L0&ps2IWrR&~JO4Q8hNS9LdD5Z2^X-^EwB=n%GmEny#*ajU@a>~s%o~7^5%1?s?L#}am zsgIeFYs?D7D0TL*J897a>iE%h0G*EoJ@BM3B_VJo((=fCC_R}zQxC!}%Ro*s^s%-4 z5<61Nk5@rdXr>pw)Jn`YS%)5bImF9(2pO!5>f4$$N|bFuiuv6<8WKJlEuTw5pX#as z6~KSkn05O`1Iy$tNMvjBr2YMV4UNR4ERL70b-u?Aj9p_>;R@cPq_5x*qym8KMBCkM~jrkCUn;oHsESgh@*X5y)(S@k!P@gfg#^-Vv#X!n@wpa|`#gR3>Iq+Z~6=z$(oDz&~U^$38$s zGP)V!c)xXz&1EG$4~W7BFbX+go$zQ;)Yb{$FvhuR3IF;Y$_|4)yUj)njKU;CYMOql zc(KXSQ?OTk`h5Z2;}V}_-@3i5IPe76%rUZo<4TAtuVYeNQTh>5<|(`ikW(kZStnfu zj3$cxoiW7%M;8r33+M^tmiVy;D~nm?rT1$;ycoq#P=&u`E%a^)Sp6rA69Q@OYLX)% zTvb{bZ+)gyMj}wbv#VkJQ?2ehKT2MU1Mt{>v=#I`v^6!Ne|x*8a)x%ejoryf)j@J7 zfbHH&(dHQCQKk%5|?tiZ) zBdaoNh~7|gQGFz56`{&acCxi9Yovr1nVy@x|BT?gdXk2?i0I-#S>Hg|5)z}MA91}g zZXzPunA73XmV39@aP^wj>WEu<{X$DiwRBcP zVNZt1{-pM-8C_aO*+(C;pq`-i!$_4%GJHA@!w{%-_sHk+ETq01-C=zh;7KgMU#h!_ za6nM<|8Zd0nhOWrEiSkqYh(I&B4y9heauMo3Uhzf`u$T+K{16;AwU{fL&{*bVqs^X ziW`dIXkNezRIYqu%5KPHjUH7Ru3w7Qpbwi;tKcuUC~S9etBBtoc&9si-pj6z$!AIR zV7iWh(jX&1qEVt~Un64q`j2k?+!Q@IZO-E4Fij^x1vYHyy^8ya`Rgo6o>eyiMi{pz z0g`lkWhRkD9!0fA*iSN8UQ+tQe<}6Q>Am>ZFSj%yKx+{~GK}Q5Y@KOb{fh!-;w(yP zeDr;bVDK86+oe1hH0RzW!}+kq%{{DD86W#DB08T~dDzJ_)CZnIpSk~6ytu|aMo$9k zAjFum=?N{R@^LHqIHWLP(d0lFR3QJjC$rAlc~Qa>=XD*Okg$*4|OvV?T8 z%dEN70QDR~o7#Nb2zt-vdiI9hrthIgaRE`X#y3{q*?7@vF!0*X({h?E4M_J9V$}Xx z35p}r@xGqtm0t^leJHrjIukYAE967&irJN6KL5GTvF<9m^7&?0N=fqUw9$0cDLVOi z6$ljSm|o_a9Zq(=pGxKE8~Lkpq7*i|=6hx$1Q3GbqY` z=&87F*NB2(`|!QqxZ<)lYY{f<=zAB=rOTGG;0CqU^4v-%IHq91T_@4=b> zE3CZ#vwx=(O@aggs*iQ#kcTdw5h7&6f{Y@l1+hZK)ZzAcN1dNaM_I3*85p)>KP}3) z+WTUuJeCf7XL$kZ1;Yt+rV{Jhl5A#7;P+G8t>GXD5k1S$w(Lotd6y{E(=bE)CHI&(XEax zcz6x*Z@lzJR24BO$fj8J1*x}!R1G_yhu(fzAyi7$aRro)n|rm@iMp1Bthz8Rh4O5t z&??g$774<&dCDVPnoK5#Zx8I75|<9ZB$fm_64fs0zhu=3Hyk$>m`DB2hDsZjYHi=I z_QQZBg5l*MQ>*StrRkrm zGuj(%de{_*4w2K$JH;nj2p(1F`*C{L6o?8yAnKr5T?_3vycHQB$qf%8HH)I)7#u$D z;leb3+4~GyGUsub#Z^OK3R>XtZY2CspaYLrW-^(rGrLcibDz&f{JwK=LRBf#{QisQ zJ6*nkvzH+WDJMbJKlD*D;s|ZRp9eJ~<*}h8eg04|mXw$m6co);lpINxbiW06ZN%^a zFhMye)e>ETWk?-JgkR7)&0$%)?;(Jl@!U1fe<1 zS;;)!Bf-+1`l678QkU!MKZd+7F)+N$&D@ZYl}_BD8-0K+D#c1Tg#9Ir=q9){Bt^RP zZ6&a?AI_H^?C>=4m_;mZnMpsg&AKgt6tQS(ek#FUPTSCN8HPd1z)NO zpb1|Q>27HqnxyY+f#94_Mgvo)<|*-&my$2fX|lAnhI*aarEGggVbtH3R z49P`C9Z%)B(&8W4O>5bUFdM-fhbK!oPC)xEfx5MA-i^Th6kx)_$b*%Ajvuia$IrT-oMiBT#M7yoTdb9qWZL(UDtFGLodnV(); zs1q=zeRb3+AY4Yp98kaWlo=sUKEa%yzm0wEf!va?6Wj28PX5<3nqH!yrh@OZ8+S&Q zZq(tyELE{+KW@&4?2R1{mpBuMH-jDv^!iRV;I*)fxIZNN~JvrnoX5%97A;{d z1Ml%qf&Sf5_}2}+RzS0UP1Mvb()`XZniUFzqT`26{w1mT$bflV(?kA6EM%L?VvI%F zL-GZQd3FVT-m9uCqc&uxf{Ja{({poAgY-0Zq$VFj7eW(?ummn;n;06gj*qevtWz=5 z#gNW-r2eK3ai9sCA59n2Jyvbu<)Rbb7SB&6X%MVt*s3Kp5POe*g@<$hQB7F2btq6F znZE=rPhMwAU+A%)=@Vh1AjY4-RVB_WRUY+qA6>+O5PP|Vh^p9*Iepy6Z23`FB<5$F z)=7?vI)C=L>RaAlxL!4!PQ65H8cJz{^3EOxbBd1RxFaRY9nzP$SLuj!U>ZY)cIJKMGcs zEB>fCOQ4v9Ws4iyc`bZ<`cQf{DZhTzF@hxUlj68gw@`zl&6E*8jgq{ZFvO zXa5Dv=ovce^B@L3*3a!fkjIqB$cm~IkQ{THfTG(_HbMmNhH#^?{w9`)K3;j#3K$ap zrhZ)aHiV!|3ZRST7sRA9RA<0eE70OYZRBw?krR`Lt2rf6NtE1fAg%Q+4&Rhh5uBfX zs(-3|7Y&s)QnAO3?r5Vfgl}2KwsUo43L6D5d8zVM{1{-&oVEu!4Vu~ul-A}#m@INa z#j!G5p@`E&!hMD-)^U6l&1%OTq^H6yv#yQB zgQc%UF@ZB!Qgo}fM{};E2x+AzO=g4&O%ktUFmFliT@GouPoj#{Ac?w9Ni0+U}`h+NaZ@Q{2_Y6!peSbih%k=DuM?wl~$2s*fjc zwK0?t#McB97~Vw_%*5MK}blxHzVlIc!nb`aQC`U(vV|vR7Onb=NA2exJdfHk zvvYwsJ81hmsmt@n`-4B}uFg(UGAH@;Pm#cXK3)+G9;Ob)jUiS73m+k^2;| zXS>&_;65Idf(3)bg4|HV8xb&QxJY7xN?G!8N^kW+od~~}Gum~00nkI}z~*!df|Yzk zsIOwEs>vn1^Ug%syk2gwy^MEHBdXAY#mbH6th>RYW5NqZ_gAZJhSlCYyLxL;WQnVo zpLw>60h{4%y>nNc|3tm-)=g3ctYCa_h6Q%8e}79sh6r%yk(zCP^bkT`i@uA=ZQt}5 zVvFc5Lh2|Y+>Pev2iTnuoXI6*i_H8#vi84RcDEY}N=%Ap^7QNThqMo4^cMxEelHz~ zwsYEK_J=w0F3g6h0k@i$v|=L3&#y1M@KBHL7V1TR9IbusJ}`SeUEHYN{&*gG&X4(% zazFCAER|1{%LEv_w*>gf_3nrF4kc&s;cFxZd&_hs&%roJ0mW7_LYFFi@KYo!^{e1@ zPnS1~8}f*64Z;bMjU`t^#kvj?vgE}I5ez0Ee_f&(6yYuI-qkG3`!Y6ybp<#Xe0Z5g z+L{QL^ST!|Z{yrB*PKVZF~Mk8)E1#pwi!9jS{M3wyVT;n*dPj{I}j#vplWAqfu6ko zwq@qdmf`LNfUHKf!mWiLyygf*W;d6BU#(K~7$4pVlhZz=FeFZ|DDTZXGdGP+Qv|R$ z{(f|fzSILCHbxd@eHptZC1@60nQ}~LsU1V&*UWKG|v3))cvaDB%5+jNfLtEPZg*PhOtbH0ciuJ{Oan~qG zQ2O5~Aj+&FkW*0Qe#5RGO&ix>r!tMNBuZ7J0!_U`mq3@=a_Md=*R>GrF~Y0Mh3`AP z-P`m$8sS9n>#M`wgF6ONHu{$@65Sjlaui{2G6w?3ygA-x=8R1ojnTEpwXLNfbvUg+iTyfdwFCu8!|~l_@3&2Z3_m%WYF4w^g3XAxHg5|a zw^H0!>#9ARFt1;RYNeG5owt`)@$LBC&T^LlPkb>2 z4(CR9SFHWj2C9(D8I3HswAu`D6%m%gRi4zOWti3rTK~*)%x|6jJ@!9+Qz--fAMYqQ zBaI_JydkI&LK^jkzp$4HPQUi#s}ZjhZp6mA$HacO0#UNFmpOfBrckc;foAHGC3qa3 z5pm`pTl{a+_PNvj4>>Dv9#jDVF^AVqvjnOIfz~Vi(_Pg*XQgbc|0Rup*tog>yNgW! z)FMHpSNsNX0*6nBC4~0Yd@B(g);F(*FXwwg3AGs`g*bYv`cp{c*vt?Nh}hG&pfmnf ztp_{p2@i_s%&WDy3M+S!n~SL#(>1k(tUb}U-k!`YgO5#Fu!r5qz-frF2#T2}oK{)< z%IG!0YY2VEzv&yaGv`4HiI4DndhV;n4W#fvF1mz?fL-M;>em{!RZBrd>E%C$tHRgFs-W9(v%6A7inBDkd1V1vGW@<@m#a4~}nz?0h($~k$nk9_< z9JXv72Zqbg?)=_t0<1Xwg9WO3-uIq*o_|AsLAwoUXuV3QXseo(buXUMTbc=ApsS)^ z7KB^)sTZx~=zz=qJ7IM6(q8wR`pE%IsI*E0Tb9DE*&8ucR3DU{KQNL>s+RFffxVMK zi5%@|I?g9%SlL3?Fgk8iE~zi8Y(I3GT>>k*AJ9cG@1E5~y>7hto*_YP_HXX>3tqfl zbDE{QeMP%0l+E}zgdoS|GhfXuz*NRs9GyE zkgC1(_x{$j^SYP9^VUMgk8M9`BmB>DKVy=EQ`|#ovJ{6>+PMrzu)0FqkUGVb9E1zL znGHjsh->F*VUXa~iRd01q%9j_;Qpmv39xT+_`v6>fa?7ol4XS|42M1(Hr7r5R&7^% zIUo*Go*~&KQPizOFOE1C-BSQa?)0)gSzRFoF1{e+!&T&~7f49+SYrPh!Pyr#xx@F< zn&LbCQUTLT@CaHC-@=xd1@?e^0!j)wBx1_C428y`CtujF zdZ9#iT}w7k!l~TTt}`xmp>dB{S$ryURk@PHH3Q${r0&}aeK(FHX?CUc+>uAGP%X(s z=1->x=Cw$A&l60|?D$zl7czugVG^jA*v(H2zO0S75faG!Ik3DlbAuP5c!U>TCAYp* zE8SxsL<4S;p7Z$utnd6SUJFD1<~<``I}ljJhGsD^M{qmw@1}d&GEJ2JcJ32(y$vG) zbCbarQ>We<=x#zqYrA<*HK5^;F z2OwPl8m)wMG8QU`xCKuC(aj(*l}=%|!5w`5oo<6dw^)<#F66XML#@8F?eh{`Ik?u!;zgs)Ks{q8v^Y#dzro}(U?bZQNX}z{sfD3P{!sI4H?gT12Em|@3fbo4PR$|R~l&hl)_kSIzNA-$; zsv9l}b+1pW)@z90o@E)aWNQhZRl^UKLM88h?LAS;4|KYUe@~^I=NG8PXJu+5P8}&R z8kepw_)fx+2bYJL@$&RTiHFG}nAGJFnL$#jo2`tW0E^Mt3#Y^-^^uIVioGwwq3l8t zSCJJ+2CMtUI9GME?@-6r2O0m15b_EIA*b72e2REv4nZu?;34Tg=b$BozTF;v;D!b9 z#G~^+^#LP& zV}B+9Hu*7+|Naz$jqSgyuFvAZ_kThb9r={ckn+A)?dcf@%XtX&dLR4hV>mr=xE5K_%LQ-QN>R(>xuG@m``O-CU&b z^^;bFK0BnT(+M`etY3)6nybLpTA-f7LN*W~tr_>I#Ur7QH-P59rQOtSfG7lae7f!n zGjV;oDM;~pFziB{8-PtDvd<`so`~ISpkqo+`1>nQf*oNq`cd#7f>aj>(iyN<{ZBu_nlKnt?82ApHr()Ji3zgp$g=xER07NAmRNgf(<5~ffMF2ZVdihsPPm1(zwM_k6L04_uV`ZwXNBjM2(MH#m=Whz~ zDber1`U|>(nS?!BKmS#5(_RFF4+_qkyb2`QQsJ8E# zx9v^>K?xhdg3(wk2UF3He37AYD^NROeG@uh{=58E1(Y=7k)eQW8@suf;C_;IbW!6B z<_K4J)3-3&uM5mOQadC6>?kFRTjnzu9BSm$uww%727{ok5hhSY)d+n^*y=4?r!(c^ zo18Ui5?tUfhntXGzi&P5*Nr=*_(@8ql7fiQht7(GHuN499LOz%IOOv)^-9VSJbl0i zj8>P}4Xf<3QJ{cxTg^(yaX~k^K(J#)--CahB&@3OZWcY>mv2WeC=nabIhQ7IhHO!3 z;Qyf0sEg3nV$4OCVsqM~;7oonvhL)&k?`68CBYW>6~#j*xPfcrXKb14p@M;^%98r_UEqeu+92 zrbd(|x(aD)dZ;WRh0$t6C6NKKD3~{SfMJ7>+u>`ZkU9t%d4sGbpb&2r?eu$_@2;Eg z`UO8AP~xslo7>O}-_1;?O-DD?3%*{1flS_GObG~kU*s`|OG8UETTj4J5lz((g4r3y z+eL+F#X2JVBNq(mMKi1*$IE4}R=2pXN}ib37eps-5px1*eS@-qr}wZBt5o=SmVn6X z)mIwRuXio^bI-=km1Oe{tI=+%THVQdibV6;7jE#eaMMKYw zM`EBsF@}V37gp*i{^UY7AG;DF=pQKq~TU;}cQOeeHplg2bK9#j?Wlr2Jk*a}j$;I?J zL#&1ChUV>h3`X27-0o3)%eL#T>5R0GeT_5|VQEM&&~_57=a$*5XtCB&&tt*LfUVTY z-coip&IdSG*yHX0m9PJS6d^eN51xo~4?+Vj;JFZ6Y>7B+7D&0~VwzE!Bz^JZOGsV4 zdn4bjh@vHQ(JlC7=Oc8Mk_FwZ4qd{d&o+7MZV!h?j+E1B>Y2r73sZ;51X}lY&hi@g0*xl=}S+8Ep<>h)^1|X}Q0`ztD1sWy8@=cnRksbMx(r%*1bwR} z{!)bH9B1yViv3Q?vZQ9tulUs3_(PY+r0vWi6;F-TP`t}QUtuTcM*F$t}O@Tor<82f!rU0uLSRJ9I@+e zli5`kL*wA=!|x2CFzO9YCr^rYA3%J54TlzmoWNJXE?+0ZB?)-41!a`{cUaVAs5X+& zZ*|x^_txL&g^S0sjZ%lmDgl^gFOCWWmBu}z5xpPf$(vWuEM+CoVV3mTEnP#Sz4$hVyqR&MH+hEJN_)Q+8At_aJFOoZB}*8*1);f z${2{Q8I5rDpSJTI8t#!NJ})>+;x3r6P4~FUPPY~fX^6S4AFr>}nRNfjKE#Hm({Bts zxjg?JYd;J#A6M7aN(4v@{C8Afrd4lcj>jYtzD79xyClM2)BIkuEZ^+BYSQx}KbpJ* zQ%a)Au4%q4&tTZvN{G^Bj-^9hO8c3?pshv~R%m_=^h=P(tA{(S{RQJfRMe=^f`bu& z;JTK{kBPnVZIh2~qzvKqQ)Asyq*0*cQo}%>l4?@cGfqB(umeVuy9&EI5_QxX+c0|u zgzcfU#T35nr3KYsrkgDkty51zOBd+rrjsv;WgmFm4Q|#O^|WZ#Dkh=joT-$rR4s-k zI4k8;dm+JY9fD6#@f?@_Ahy9e4v4tx9ui~-5FsB}KYhPffqC(Huw+#pBt@c!H^M)f zu9pGxKDK?mcmSM9O&XvPiJhz5BYuZY`CoscWyI273+?hx)S+EiL1T|NsQ}D6i4Qhemf)+a%tCYb->hkZ}I(71MP~M{dUW^ zB6dv}(<@ZDwRJj6Ntah%TqvD8M|oDQgxV4x`Nf?MLk|$)wtN$Qf~#6#^)Q@@+`F%U zTtDP^U}rUgzr2T|VK;$ZUVHXPCG>s{{ zUSvafka*CaM5`YqiC>f>`yTjvpIpC9n)sFcG%Dci5&M6b+ga=Pf!pPqwR^+VS+`^w zF?M||4t#4$*?nE~a!T0!wWgfFJYc)!-`U>T&6W$Q5|w}XV9@YaSmV2gglLu?-bmnx zVCCL({`fOk$gP$8ZUbf|)k=5bC!^0$OkYZsbzpD7t$0$H^xLoeAGInsh(Xh)O(@>{vbeZ|r9gUAEJw+f~{PWxw{ER@|$RITF4^e_v&5+|z3l zNz)sz16kVBec_h8MY^)nU6I-np-=f_C(||_Qt^2lf5lZXQ(zC6M{j={L}+$-htRr- zAqnSE-<1hWmXhGzUaF`?tLLt1*cDaMv>b13Jt)Dp%YR0}1^iNKr=Qf#}RT+P2Isj`;9ME17aU0V~ z#~JfaJ+Ldt9C02MTA%dym?J5#GGvOj(&rCE{94p`9-e%5?x4%$cL)Y($rOqrF*jtO z{An=GN1u0v3T{5tQ~_$t6oL|CidO>EQ9R+25#{dv&?|fu{xQ0P2k7%n|1GL3P%*}H zY^$qg!${&JQ_YD(0!PHz1pN(cY%@tn{3Q(i_eTe64MVT@!oUVey8c#if!IaX%uXH- zbq7x#hbt!1Emn^4mVq9S<>=7*c<0yk@br!Pgn1?#{1Eh|DEH4umM25qPYvQBH%!f7 zsX0%vTXE;Qb9!8@MbG3>HrZPr+EfuS{o|Fmk@CGZIkNzTbuqWa1CvwKjfd@EW4)Hm zt>Ef(tKL()Y$gIYy24SRv}QBMl2p$rGT9Q+^5nh6`SYMHn37{aeD4qo)(znpEQ6PV zP_&?H&`R|)p*MI7E(q!K^2|`2llUe^Yye+;NDv!mT{g;CkZ`#5GgAH5BET+>Q)Oim&0A4lx|Rd@oAK^HqKPQ3&QC4 zPg@DuoCONc2bQm4^GC9BxK8Fw{ZvPnm0wv)HYPUAL+=kEByr>S#|vZ^{X|2HC1!hs z?!cl)@veJ3hOEyaagTUev*M*B-T0>uuV$hUP)*_!YA-Ekvuv9wlEXm|X&oOjhxdlK zmod@qw2eVPThJf}Cynt2KXN8P_>zLU=`qS`AmyoFl%#+W1(H5%vQdjdU_>MAd8Eg0 zv7*E@0)^8_;)@!{R$WoYTnY1#XyTJ3)CoiZPA5)lB~I5FGMRENE&C)D^hONwdEHMEr8@dV+dk1Z*hwhBAT0t`MEe)S(=7&Zxa3WWsX1LP zv=YrjU~t(6G^p7P^-BZ~{gf95_%oJ!zoX| zYFGFOFZ7wJRC2RqWMf`rFuC)^fH(XN;^Vej0^5Tp~1Q^S|?uhg!74bn)++FAR$GkwAXtapI;wxrOoImsVsvO_q z>ar6&Lfnr17>HdOi2SzH4Oo6(JaIGxmx!~w%q6$;ha&iTJ80DII=J^loB4hb@h(@7 zmGR64*~6lK^~cxHe7&<|yma#p9s33#{p)S+YnW1zKp=w27-Zp0^@aj{CniplmxDgr zvef173r$LDApo#0toVT+G#4ur0LKmyJi8*Oc8QX6@!q#G5ac%bu-%DJE>HdO#hj@O z!$_OWd8?OpiEI6M=ghgb&bdrbGMEWc_*U!9X9*=tM}wEAgAek&vxjp6n&)>L=|495 z7qrsl4K@6^T?<((hLcH4rWkRH5GJ(v{2NV9S6fPTcd)nBLXg$uJkx~@o{bD+mw^=Wd*Wg{rv+*28eE++FZSEV zJ>&}_n9Vm=Apewv$fheJBtJ+kRM_|(*LtK%o{U!Kxg(gvhI+k ze{UYGggEoW#*aW2=z|wFwrl9IqpOaI<~=b+8_p=WgEH=qA?X7vxnPYUMrDa%0Wt88 z)|WdopgHG|Dl(KN@{UtORT(XKiE011Q<7Ugh#o@{Vl-d54q7psyIJQB_8UrnPF*jf zbU=hQk&-pE2t;CJk8_Jt{yxIy+%f8m=hA>a(htwPUEkl85&bip>Q%LJq0xv)9qeHH z;Ci-zk)U4H3TCmm7(HB=6sGB1C5+aNCeU%l%qZQ}VIC0Cf!5U}a$sF0=rUj0f=jL$P&^66Zb-~IFMD(U#g_I9;JQX?Z8 z96Uy}rD~VXRHQ7G>`Grl`6}D^i&y*9Mh_d4(lUEJ$?wGobJc|%DK2qAY2F7dI zM&HZk%lO+bVK+^-fwJCgb`kt`wRT(Uy6OU%`Z9Yp=wiZMoAy;Nm=0!LPCPgJ9_k^{+EH9Vl--S|PSVcg+%P zzh1Qa@H|OEl$o9(!Kdf}O^PU)Nr2?E9p29qlK? z9SU+z)lD-oO<-<1%}*J^T##QdYCKc{wpO@2wIo9PbP6-8N21*5zxdXb0~88t?N zq@=on$SF_&f9yM^{A4@_?s#fxBcZscUPi#{!2-(Du=!kux)JCR#aL)Id*uMR+3xCe za91=aNEqJ^9XxrC$nhSqS*HOIpa-yv;jV069um}yMaRxccP#&c)iFf;BTReL-2 zqyt+Irjlq9rEBP?Nv_mDa;=cN;*>V#Z$hvvLl~!aj)CTML0$v$HsE7UiETO#cN*Es zFe>uPcScUbQgftv@Tmlh8=1;jeWfhiZKBEF85`oum}_P%hg-oXv1b{rR3{^__166; z9z8uND}|7S2+037annqDJhv503Wi@TD`=p_EJsHDYBITNH_U{UXDOA08qxkSJT7n8 z5)b@&ej0&cz_kYE7eXwHm1YR1=TmDbmgtauvfPz z@&51+Ppb&~MpF;nfAzi|6V^Bs!KZqwIUqd1lXn}<;gqhaAq{JSf4rX3<4G)l>;tyl z8;}RP{&GdBgl%bFoN`5Y2u_bm{P2)^SEnSuL63cEP|*Z3`dFmQw{s{!klD%Keu$37 zN*M;eJC1WUk%ZbzLd-V$V!a{F9v^eO$osj0tL^Cuq3Hbf^Fy9Mc0I*CvApNXGCcq& z_8z@Qocahxv1KP$Z`n#z2$+RP9nh{7lhGy6^|%PfvbgIv=8|4o;5W~<1uz7!S~DWIa*(;g;F*uI{xdc@%Hpr&f~BMAP@(L5RA!Jemm2^gAy?W@Uiz}T(J{Hr$}OP+3}WKB zVgmJvWLnNf6^hiQsR)|as($}?*yT=J+r#T(*-LB`>c`*J3knq@QV=tN59m4ec;F&+ z#8N2@H?b!zG=Ft@Ju%5qQF%eV^99&ClpKms8g>Wpx;6WKBdlkP;fB8ZZ3kMDt8^o% zDs_NSlO{Fe8E1DcYKhJx5WKq4UM5K;uuv`jZY535k2V7{#SU^+RUZkRGwW&PY$G*%dD58Of^s|Yj=UatiOS9 zQ0u$M1?h5R2As*{GJqy(L2W1+rO-KwwW<{|<%-U)ne$6B3N*f(A(UssjVirhuy3~? zr3|9581`8JU-SnliWRH*q>T%6J`7^eoe6$ZEQ|fbnE&7`d`^zST}b?P6gS&z5IxYA zPqO_6az3%``M)U?=YKW9UF zeW=?w=|fB%TYp)-EJ50JdUU`4CQ|PI{!yM_%iWz*vdcXQXcHt3@D_KI#Lgcc-G|c% zK56D>!Kd5Kog~?OCoHwqq_N#N{gPHbdZD3Rzb~4t6)Wd0S>0MV;A4DU2D zAS@|w?A!V`jmmYr4N4cgj>i@s>hVmGkZ`$SyMYo}ZmVsF*(rIaKC;yML}|D}pWI$u zwzvy)0j+oh?5oB~qA9xfvZE?`N_M^Az!)_oDJB1VrR+vpN15LmcJ26c3H5~v-<}2K zG9g(|p`8O|kusJYd6ltSIIcHoellh2kf#oQ#Pc%O_d~?p0U!TNbV8`MY zA`P0kst{ecSEyBom!{2ED|hfeSf+h}R8RZ(2PVvHZAb^YErArjhnS&amT?GDIc+&QJp+79>5+NMHzUpjT{2sEvWOMDS~t)`cM+ZG~Ceu7e`wsZ{p`GIOO zV+xK$DVeE@RBwl592<<5{~bg_;t$c85$W3E0n}<)55uHOD3P49p~pw=8TiRpD~{ul zWZCw90A$zdy(;0Zm`xUE^2c@3F7Q<}uhz?(Op!-|)3|Q!cE`4D+qT`YwPQQ!>~w6~9oy*G z>ezNV`Eozk`{VmvH5SHLt7g@l=R8g`h!{+=o1?3gf;jZUj7|fcLe_L5VzZ{7->4%c zfhq$NA%)MRpd2hTFE+zbxSjo>ACzoJyB@lI{6u5s60B$l6w>l8$2N?`yP*e(k1WPP z7q1nVFgA9a!|^QdusEWP<`RNIspuBP+I8N6y()?VTao@hlaASu;Sb3T8m}4tF{c%I zA2#kG8&mmT8!IP<^e>$nW8pJ@@P+nL07YRxKvFt_Ow)lp^2LA-KyN~16BM&{?LPVC zNxri?hPEp^ioUlA8N+EW&NA2dP4wJxpUkmi5)PB^E++Dn7$^^5ZFqRFgu*fr7S;*5!`98yR<*-WTpQV%sueNKBG6Gqp5EZK*)-)g6$P86m#~OSuPZYCc#*HA4&7C3Ui8Sz9wp)6kom6>g06WgC6{aw@^uF$ zrFyTT;EO+ThKM(Reb*!UZd7d51^mnx<9iz>dQ>>ce4DO$N@!Wr{N~n_y6wS^La}HC zbobKy7a^4)e150|gh-K~;L~E}Q}aii+F~>1dfe6!HJ6zsuZJ zUxrJcal}#O(v5XLYx`6?L05m~YGY1?;|;ISctKR#iahKwOzFBSpnZpKWT`ZI~)(QqPtcL>@^W68rv(N>M1sM|J?R5l0v@p?mb1b zx_#9Z8z}$ozK5Y+mxZR=ovOQ3qjG-kb4v@SX4pALqhO%<;a+(cpebVTwC_6VK>09r zWJ0Lg5in4!Q+;*rqxxs@A=R%g_UY;Z`1j*iQj6P31Ztj7Dp z>4-PaPe{tnsmuSuWC80}nB?U6?;HjF#n%F+K-GR%vRu>OxX-^F%;;YEg&-cxiiY+l zF_oe8q{mZ4-z!RV^)d!3c?ZJx@q87qIb^xZ$f&e2_UTxea`zr2KN*F!7(KyK}19|jpl&Ivp6VAn}(qq-}e ztyYII!u?w~KS!i#G?3Bl>Uylfhnj}mVCDNsx#%Qkdp#)ld-kji-ce;@Xn$w#VC?U( z>)%;I<6r51i zgp3zG_F4vNcM#RuM09U<7v8d)-hB9Nn)9{kd{6mtpbEi|8A|)4F4Ap`^Eb+B8Ok6V z1n@N&S#KpCe{z5wV8o|h)h^MZoJa(hi$4!2pZ?a~U->02>(^ZV?`-`)TB;BH5Dj8CtVxkM^%l=zmQMG%rvRa^_XqKYGkkc3 zgE0v_YfGlSz4I@KHuGkWOHHHYgVL7v+1t4i;8pJAHYD4o_K(j=SWP8B{(1JqrF8Sv zy+nz?r<(VQ`cywZ3l64bnOKo&N}pkN8a5S?2UEX7(YhDEVxw)p4}%2Q8LGdlOR6tk zg>@tcBoJb(GUTWWx_J?Inl1&$4?#AUf%3)#$FUd`fLf=9_VqM)I&08%>(S`_{5q7vO!OJ4Z zYX%A^c&hZrw)LDjSX$40faK>`lSJ!t7%ZQW>)+XB%I7akZJ=5&T3ttDnOWSBN3|sCj!Eg}(=SzMG&A zjwq3atQAYZOv;%o9WWmUPkS!<2%`>B2uW~fu&db(XSyyzp-7* z`*Lc#iZ_9kxeNb<9BA7K3r+Fj)Ps1bP);#>ZL)`QjY~p}|*h)4g@Lxh*pJWcHc`xgMpU0`5b1`go|my$yRWuQdkt zO>pDfmxkyAa|q~$Ek@PlccjCqE}Y56eG_3Hh8J&T&B#1Eu-xy^-3LF3P>%PCVJ~5V zwdX#>0=@m9aJW?l%P*p8J*unc0dxv^7t3JGy1g=@6u+qw47L)c-bZKkmOZ(YJ$AQK zx~A{+Io2efD3@d_4p1)3{dllmF(k@8N5#nAf*v@41kbh?XDcJr@i*w55-*0l>lQ^v z{6aPTx4LCr)6FJ?x1?u!jdaAkwGR<7XP363C($_FMgeVxt4w@&Xo%uRj)|l~>Cbe1 zEH1bC>1DlbWk^%9jAK_Y_f{M&Z-$E}iQMD|rP$G)wV-jzaSOGrobEvBM6`V3A1dw& z>HRN1a`n&iB;L2oV=E40$0oY|1bLoDZrLX-C!smpfHrBSC3*&rqIT_{!NKa+t_*m?4Ga%VgjRL3uw zbnDJV2k^qk!IL#U_@k(m=n?4qAbAK((O^YR;SXnE@Lsj|42D^IkC3*4x#kZoj=$~E z%K^OZ5(+8k&7qcr)J}%9pV$cR-k1K!f*Mypt(n{P03DKgEze*#wOdbH8GzO<7P#11 z+}5tl-$s^Fy_ym2(HrQ$%uC?!R-EpUj4}KxsUT^a~HiKDAKLtDfsXJ!ir9Kln zM^&^BZwcyd;M*u78UT0>>q`5T(A=yvG}?>n_tF5w;BC|(9Vf2)_@;_T9ItQ&pUnyg zCh^AhrHk3)>1x(|q_1XP-d{kh%5I+dXy5q`7P%xv8p9eEC&zO{Rjd%-(Z z%w@IV!d+{yp1n?(@mO`*U!fa(m5`yPHnR<42hRbqlTezJs+sKNVFNig=*(DG_7tgn zAya!MhaawOEo_|fD=a~Ohx$CKJUw6Yv^|0JO$NEG*# z$Jj3F3<&U@_9XnZ27KdAF-bjurv_UO_a_Vq6242x!D%sX`h9YY*DR=cXk9g?=X*d3 z512VZu4`=wjHtkWy9G|;eMeeZCRdC{ULZ0W7+*(f3vXsv$6K62!VZJJBk>;qcbxwN z)puV~#%_SJGEkKOd!bN%2m8HiqeqNX9EHI8^c0)| z`y-qS%sPS7ex9`3Y%kZ*s25Rt{}A@kWdG|fL6=~OF{#_iM8J43oLA>#ra-iW?HN}( z@6kKIcKHT+?gG4!NtB#lVWb2Cbc5;y*4BD_uYza|bMbYIHp(hJ)?giQ`>S0zH3DsH zuoGo!6^06}u3w+eqR>BHPb6IlG(fRnS^jBxAp36QhO*LZscpO+<4^jK_gTE0 z_dj`DKfNW}%=DrKo8d`!=sOi{v*{GI*+ZCC#ZQ6u{nbAIsRg&H@Q2=)6=8x&Bnqw+ViiWg>}=$>ak#g1zAr0HzbJ$$Q^{^Px4Y&-XzYE zBVq!CMQg{e&dnL?g(%ao=L-VA*VV7#h09Et+@!I*;}Zdrx*jDsVLZU}Y~`>vQHkQ^ zD5}tm^>cqOWNgH;4ZBv)**O>|WI(N-A_lr<{c^NjfJN!^ z{{BJA$ffogzhcvjyqO=OY1L!ME-^29?0*9kA%NC}3PDg+Yl-~#epfguEV7J)?wnrK zGm@^)9R5~w6B?w*fAEcnGj5nVc%=SF94!|%pUPF|w>EVBIfLEDTqc7!5?W4FR!Cv` zpHB+~y#i*-F@{qtzk_3L^PBg5j@j_w;`zM~`WsQs#nWc^K;6=Jcx@BA&dKTc0r~)7 zRTZJ+j*is*qp=(fBDEzn6}ihLWl6M6id@W1I@We4gU1i%Nqfs??XC0S=G=q>|MI<2%BQdcJyh& zOf4ZI9#p#I8 zQM|0&vXHd+%ST=qs)#Q9t}%)Navx|C9#r`d7S~MT-e$WTrO1Oa;@1oBSH)jr z(wF=0s;y~m$%#8VOQ%Ucj;$9cVXi55h0O?4W;gm~a|q%p87PTGDj5FmPy_fUN~n0! zr1{iHd=75NHTnenb<{v-9BTMdRFfJCdCr>6zn}kpxqW<7@U&^B?MPVy3Lv%({w_4M zI94codetR1Ya3{L+MY6~1VSMtn_?#PsA-tY3w%RRlGOoJ=v>G~jPI4XSagf2Y1~5? za8FDabwwRCY&4ZE^&G|gT_QD^DIG$iM>kpyHtR(aTq5yw>u@|_TR7Y^Hb}dp&JOQ} zwA0{W+N)@jGGf#)u!?U6GIqfeOH%1_u~e{B0Hd$6q2wn}*1;gXZ!u$yV(L*kh6C`T zsg3G@4@^?wfxCU$RFp-DTtr&dM(pWgW71y+q#`yezNkZ-+dgS;7tij$D0j{5nUm6xV6V$_jo$bxbhl=ePHkY^C-{M8HOy1&haJhJdszW5kD@ZvWQ9=bI)JB@ssaq-~+ z7%zjRHvUL1u55*?8tsCQr8Kq*A2$p}PMRoIq!E+65&N8I$c^-c_^dpwEz57%pO6lj zTqXavq5Z0XgC~EHzI7L%XurXakrr2GdVaz_|8LsYV;FouR{t%m^IA|N!ZR!mgJd_ro7Q2*b1V0<;e_Y%<{{r^lgxVbq&&cd*? zK!pT+F0`&Qt?M=(`XN)y7;doO4hJ_lzMKw08zY+h*kRWO8g8s8Sj| zIcJ{AW^t|Z$)=s!2LE!T%?f{2DU2~$U~nBWXu;-fTDy>g1#(KGGAt4 zkd56$_Q!-&?95^b`!~7f6Vj4Og$V8MFqLR2X3;Hz2xCQ@!K*h8I*Rc>RuS-7fLeWM zvB^y`+5cnr>9KlH*%t=AQM;?n?K^z2ceiy>CSaB z#v~?XDJHOe32Y(J>UsvOD3$|E5>#vQ)WSlo2SHs6C0O@~YYPykG-cI^6>{dvYN{Yp z=I^P>tc0r(gFg`Sl0p^SaQG?MfCA-hMPo~g`>Hk7p*psW;?MykQdL0|?h!Q7C9_VH zbt=E?4H6}Ino-Bfq3r0aW|mLEV7l1f zV&XVhN#*4hSHp9SM*XmKBD340e@??!Bl9BznVN}|qe0kX2KliJ6jT?O0~>I7;JGb| z&*4D!6wVU%md^=vW5&=r1}Zi`(v|dta0<++L(n=PJktfdSu=ayuiyHodV0KD)2DK4 zwAP1geeH76caCPP?v7&CA2tuC{(2mZRbL3jv`%E!E(6=n0--664fZN=DOZizd9haA z-))<9&05Y3dWGj1jkR|df#(xU$V-j_R(IH*wXM}37cLJI_8$*EcOLaNm7!X9z?q(3 zLR}@AEPY${n;aXxa-2T(R^qtReIYYZgKDC+wHql^4j=tfpUnZkJ?^Y7iCR5t9a-Fd z8+w!G?!&`~P$o%;-dma{?Z=@et1QD=$q?>du-G(|dQnfZd4BiY1wQ`H{Jh>%iu9kg zY7;{m8`#wH?D=>-4VvEI9iS8FAN`eGFB-a^y`@Dgk@5z2hjI}lK1J$A^M*%?JxjR$ zf~lVi#lO8wD#~`zZ8G=rl=+Z}4X=&R>FaTD$b=2FPx$66FAcXKHtGXTGLgz3s~^O| zuY|jzjbUYEe>U114ZKI7bP<5w=A3No6FTi2KzCj}bG}mXYVrR`HN=*?W7F}X&Cj5a z&RU~<1A8`#$@&-GVGN*@d1cD0aDsaSw!#HMO{d}%0rbt z_R<{nedEy^iT|*Pte-2dR|nVVTGoz`CBmg zSkzmh4;C1Ap_mp-ef2VQ!5jOF(jfJEesh-Z*%`QXBkzO!bU91wa;#FXpJ)2-T|HF| zlP6v)$s25}1DNeeuC$_rgSTy#=&%srbeBUK?s~$KU}&7fKgj>$ngHHkdWgz9&!4Pl z+7>Ef#?9IjSS6B7tWodB-Yl=I-Zfgt(s@7V6a{&G=CPHF1^5P^95-?D{hYNvpxs{G z7P-Y6r{%j{DoF`lX~|x&nm13YXVp2wChyE2WbW~#d>|i^hxOxZxT1h!Dx))L*JMUDRl)AMJG6EWn{!e2RH6?$j-I=tNeYV}J! zi?TZ;(X!5-*6|+-B@RaBr?ldUow7_I`gnV_5(6$k2i#=}Jf7DsUvglz_X#Qyap<1# zjHYr=T1QM9_HT{AE1d4>`}gxOA4Kw_1OO!A_vI;`$6vlUMD@`mb8d`;_2%>&IflUk z{}zwQkhn}|#Gc@9KQ3Fhxnhv195lkS-etGPltPe4e~tX1$Da~3T##&D8!_jOUVH?> zYXKL0KKy5>9zPU7zwL?%4;ODPzgo(k-O7f=_-Je&fv_Z-d)a#nSHEE@ShsFGkW17` zY9G5JtJh$lH06vKyvQ!SRPcUwFZFS0NM#N}I=QE;-g$2V9up7Dg5m@cBGk_Sy=gX( z<-}jjr;@&I6gzgIU1An^x`XU-t*l_N7q7Y3b9?N~;S zmC*;N%x`B&E_#&<7fb&Xe*Ai>cm8Z&Qt2@)30T&-5}JwCYJ<6Q%}o@f_1g)46rxva zH>U7i4nrJVPF(k8Qlty=uVUY6y2UQ?5byafQa8~8Fj|+90aOU!E}&0*KqbP7{aEFh z)h8f5p+(~V=0LFizeL?{a=8HHu zRUI{a9akJnkKvABF_MW3Pqf=ED$i&azDFG3z1Y$%2_>INHn zUFj|HJif@mW6ve_>9dEST$^F#jYZ&3SVOB5YoJjw zQbRk_QNiz_5o8dCz+)`xxgxfp58%)`aT**RFD$Qz!=~O+)BA~i5KTa@l`2t0R+4s| zkqQhR*SCK9B=JqV+<)c+_L|L>!g(It*_+;l4Mxuh*01u{bJvGuW(f_Gsk$4~7Qt~{m-W+63^ z?q!UFoX#9F71=SWhj2j!g;RW&gR3Jhi4WkCPq{J^#k)j^LVC>i$TLiVBxyygv3m3XDzNm zMWfxbMnJUFuY8pb*b!fupVRM+NGoF21&iF&#}<&CxDuz(LqV^of$TIo#sbA)yY9#jA^}U5ys+J`FqiUVRQ*H8k!thRV^48 zoI&4tl0=wVuDl{s1fwrzFQ zi8Cq_bVQ!)*QC`Bq%>Q)uI4b1X>rkTY)KA!Qthn43rhbTbx49cd6NYyWK;Nhz>Nrh zvp4ikY)O*FHE|!tE3Z9!ro&M&+R~KtWcRG{01{V8lnktBQ*y3BX#E==Z;Gy|)KUA> zGX0_H5E#8nR!diZt)%nweEU1tXvU{HR_ujGjpC{ulK0Z1Y|(WZNK8e!)dWU&K8?Zw zshKH|?Tv-=b#~DJrGPuJB7&0Of}M{i`j2UlN%6L;lpgK7b^5)bCM&O

6%-(@hG+ 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 B(_sJr delta 212100 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ⅆ1V}QG9ge1e3Nze7xH8G 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

}8xs~$i(82A_FTL0f^ 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 z19⪙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 ar? Date: Fri, 18 Oct 2024 15:10:20 -0400 Subject: [PATCH 218/218] Fix non-MPI compile (oops) --- src/Stats_Reduce.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stats_Reduce.cpp b/src/Stats_Reduce.cpp index f4384c6ad1..06c7890fc5 100644 --- a/src/Stats_Reduce.cpp +++ b/src/Stats_Reduce.cpp @@ -1,4 +1,5 @@ #include "Stats_Reduce.h" +#ifdef MPI /** Calculate overall average/stdev for array elements using the parallel * form of the Online algorithm ( Chan, T.F.; Golub, G.H.; LeVeque, R.J. * (1979), "Updating Formulae and a Pairwise Algorithm for Computing Sample @@ -54,3 +55,4 @@ int Cpptraj::Stats_Reduce(Parallel::Comm const& trajComm_, return 0; } +#endif /* MPI */