From f90508efb06303a1c173333fd0833fb845cc0565 Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Fri, 17 Jun 2016 13:26:41 +0200 Subject: [PATCH 01/16] initial commit for feature_interaction development * contains FeatureNNInteraction draft * contains FeaturePariInteraction draft * contains testproject --- .../analyzer/AnalyzerLatticeOccupation.h | 68 +++ .../LeMonADE/feature/FeatureNNInteraction.h | 417 ++++++++++++++++++ .../LeMonADE/feature/FeaturePairInteraction.h | 319 ++++++++++++++ .../LeMonADE/feature/NNInteractionReadWrite.h | 110 +++++ include/LeMonADE/utility/PairPotentials.h | 237 ++++++++++ projects/CMakeLists.txt | 2 + projects/testproject/CMakeLists.txt | 4 + .../ChainSimulatorINT/CMakeLists.txt | 14 + .../testproject/ChainSimulatorINT/main.cpp | 78 ++++ src/LeMonADE/feature/FeatureNNInteraction.cpp | 120 +++++ 10 files changed, 1369 insertions(+) create mode 100644 include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h create mode 100644 include/LeMonADE/feature/FeatureNNInteraction.h create mode 100644 include/LeMonADE/feature/FeaturePairInteraction.h create mode 100644 include/LeMonADE/feature/NNInteractionReadWrite.h create mode 100644 include/LeMonADE/utility/PairPotentials.h create mode 100644 projects/testproject/CMakeLists.txt create mode 100644 projects/testproject/ChainSimulatorINT/CMakeLists.txt create mode 100644 projects/testproject/ChainSimulatorINT/main.cpp create mode 100644 src/LeMonADE/feature/FeatureNNInteraction.cpp diff --git a/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h b/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h new file mode 100644 index 0000000..165c35e --- /dev/null +++ b/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h @@ -0,0 +1,68 @@ +#ifndef LATTICE_OCCUPATION_ANALYZER_H +#define LATTICE_OCCUPATION_ANALYZER_H + +#include +#include + +template +class LatticeOccupationAnalyzer:public IngredientsAnalyzer +{ +public: + LatticeOccupationAnalyzer(const IngredientsType& ing) + :IngredientsAnalyzer(ing) + {} + + virtual ~LatticeOccupationAnalyzer(){} + + + virtual bool execute(); + virtual void initialize(); + virtual void cleanup(){} +}; + + +/************ implementation ******************/ + +template +bool LatticeOccupationAnalyzer::execute() +{ + int32_t boxX=this->getIngredients().getBoxX(); + int32_t boxY=this->getIngredients().getBoxY(); + int32_t boxZ=this->getIngredients().getBoxZ(); + VectorInt3 pos; + int32_t latticeOccupation=0; + for(int32_t x=0;xgetIngredients().getLatticeEntry(pos)>0) + latticeOccupation++; + } + } + } + + std::cout<<"********LatticeOccupationAnalyzer *******************\n"; + std::cout<<"lattice occupation "<getIngredients().getMolecules().size(); + + if(8*this->getIngredients().getMolecules().size()==latticeOccupation) + std::cout<<"...ok"< +void LatticeOccupationAnalyzer::initialize() +{ + std::cout<<"LatticeOccupationAnalyzer:checking initial lattice occupation......"; + execute(); +} + +#endif diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureNNInteraction.h new file mode 100644 index 0000000..4182638 --- /dev/null +++ b/include/LeMonADE/feature/FeatureNNInteraction.h @@ -0,0 +1,417 @@ +#ifndef FEATURE_NN_INTERACTION_H +#define FEATURE_NN_INTERACTION_H + + +#include +#include +#include +#include +#include +#include + +#include + + + +/****************************************************************************** + *this feature implements nearest neighbour contact interactions. + *in the bfm file, as well as in the code, the interactions are defined as + *for each nearest neighbor contact between two types A,B in kT. + *bfm-command example: + *#!interaction 1 2 1.6 + *defines an interaction of 1.6 kT per contact for monomer types 1,2 + * + *as default the feature is implemented for use with ExcludedVolumeSC (writes + *8 points per monomer on the lattice), but code for ExcludedVolume (writing only + *1 point) is also there. just un-comment the marked regions. + * + *the feature provides two #! bfm-commands: #!interaction_base and #!interaction + * + *****************************************************************************/ +class FeatureNNInteraction:public Feature +{ +public: + + FeatureNNInteraction(); + ~FeatureNNInteraction(); + + //excluded volume needs to be in front, because it pre-initializes the lattice + //and this feature re-initializes it (overwriting the values from excluded volume) + typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; + + ///////// for use with FeatureExcludedVolumeSc ///////////////////////////// + typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolumeSc >) required_features_front; + ///////// end version with Feature ExcludedVolumeSc //////////////////////// + + ///////////for use with FeatureExcludedVolume ////////////////////////////// + //typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolume) required_features_front; + ///////// end version with Feature ExcludedVolume ////////////////////////// + + //check- and apply-functions for different types of moves + template + bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; + + template + bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move) const; + + template + void applyMove(IngredientsType& ing, const MoveBase& move){} + + template + void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); + + //synchronize initializes the lattice with the attribute-tags of the monomers + template + void synchronize(IngredientsType& ingredients); + + //add interaction between two types of monomers + void setInteraction(uint32_t typeA,uint32_t typeB,double energy); + + //returns the interaction between two types of monomers in units of interactionBase + double getInteraction(uint32_t typeA,uint32_t typeB) const; + + //export read and write functionality + template + void exportRead(FileImport & fileReader); + + template + void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; + +private: + + double interactionTable[11][11]; + double probabilityLookup[11][11]; + + template + double calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const; + + template + void fillLattice(IngredientsType& ingredients); + + //defined inline in the header (turns out to be faster) + double getProbabilityFactor(uint32_t typeA,uint32_t typeB) const; + +//////////// for use with FeatureExcludedVolume uncomment the block below/////// +// +// static const VectorInt3 contactShell_1[24]; +// static const VectorInt3 contactShell_2[24]; +// static const VectorInt3 contactShell_4[6]; +///////// end version with Feature ExcludedVolume ////////////////////////////// +}; + + + + + +/******************************************************************************* + *implementation of template and inline members + *(non-template members in FeatureNNInteraction.cpp) + ******************************************************************************/ +inline double FeatureNNInteraction::getProbabilityFactor(uint32_t typeA,uint32_t typeB) const +{ +#if DEBUG + if(0 +void FeatureNNInteraction::exportRead(FileImport< IngredientsType >& fileReader) +{ + fileReader.registerRead("#!nn_interaction",new ReadInteraction(*this)); +} + +template +void FeatureNNInteraction::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +{ + fileWriter.registerWrite("#!nn_interaction",new WriteInteraction(*this)); +} + + +/******************************************************************************* + *checkMove for unknown moves: does nothing + ******************************************************************************/ +template +bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, const MoveBase& move) const +{ + return true; +} + +/******************************************************************************* + *checkMove for MoveLocalSc: gets the transition probability and adds it to + *the move. the metropolis step is performed later in FeatureBoltzmann (in + *case other features also add some probability) + ******************************************************************************/ +template +bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) const +{ + double prob=calculateAcceptanceProb(ingredients,move); + move.multiplyProbability(prob); + return true; +} + + + +/******************************************************************************* + *synchronize: + ******************************************************************************/ +template +void FeatureNNInteraction::synchronize(IngredientsType& ingredients) +{ + + //refill the lattice with attribute tags + //caution: this overwrites, what is currently written on the lattice + fillLattice(ingredients); + +} + +//////////////// version for use with FeatureExcludedVolumeSc ////////////////// + +/******************************************************************************* + *applyMove for MoveAddScMonomer: updates the lattice with attribute tag of the + *added monomer + *works only when 8 positions are written on the lattice per monomer. for + *the other case use the function in the lower part of this file + ******************************************************************************/ +template +void FeatureNNInteraction::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) +{ + //get the position and attribute tag of the monomer to be inserted + VectorInt3 pos=move.getPosition(); + VectorInt3 dx(1,0,0); + VectorInt3 dy(0,1,0); + VectorInt3 dz(0,0,1); + int32_t type=move.getType(); + + //update lattice + ing.setLatticeEntry(pos,type); + ing.setLatticeEntry(pos+dx,type); + ing.setLatticeEntry(pos+dy,type); + ing.setLatticeEntry(pos+dx+dy,type); + ing.setLatticeEntry(pos+dz,type); + ing.setLatticeEntry(pos+dz+dx,type); + ing.setLatticeEntry(pos+dz+dy,type); + ing.setLatticeEntry(pos+dz+dx+dy,type); +} + +/******************************************************************************* + *fillLattice: fills the lattice with attribute tags of the monomers. + *this is the version for use with ExcludedVolumeSC (it writes 8 positions + *per monomer) + *if you want to use a version where only one position is written per monomer, + *comment this function and uncomment the appropriate one in the section at the + *end of this file. + ******************************************************************************/ +template +void FeatureNNInteraction::fillLattice(IngredientsType& ingredients) +{ + const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); + for(size_t n=0;n +double FeatureNNInteraction::calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const +{ + //stupid implementation for now. + VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; + VectorInt3 direction=move.getDir(); + + + + double prob=1.0; + uint32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); + + /*get two directions perpendicular to vector directon of the move*/ + VectorInt3 perp1,perp2; + /* first perpendicular direction is either (0 1 0) or (1 0 0)*/ + int32_t x1=((direction.getX()==0) ? 1 : 0); + int32_t y1=((direction.getX()!=0) ? 1 : 0); + perp1.setX(x1); + perp1.setY(y1); + perp1.setZ(0); + + /* second perpendicular direction is either (0 0 1) or (0 1 0)*/ + int32_t y2=((direction.getZ()==0) ? 0 : 1); + int32_t z2=((direction.getZ()!=0) ? 0 : 1); + perp2.setX(0); + perp2.setY(y2); + perp2.setZ(z2); + + //the probability is calculated by going through all possible lattice sites + //at which the contacts may have changed. At every site the type of the + //monomer sitting there is retrieved from the lattice. the additional + //factor for the probability (exp(-deltaE/kT)) is retrieved from the + //lookup using getProbabilityFactor. For new contacts this factor is multiplied + //with the probability, for contacts taken away the probability is devided. + VectorInt3 actual=oldPos; + + //first check front,i.e newly acquired contacts + if(direction.getX()>0 || direction.getY()>0 || direction.getZ()>0) actual+=direction; + actual+=direction; + + actual-=perp1; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp2+perp1; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp1; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp1-perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual-perp1-perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp1; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp2+direction; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp1; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp2; + prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + + //now check back side (contacts taken away) + double prob_div=1.0; + actual=oldPos; + if(direction.getX()<0 || direction.getY()<0 || direction.getZ()<0) actual-=direction; + actual-=perp1; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp2+perp1; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp1; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp1-perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual-perp1-perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp1; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual=actual+perp2-direction; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual+=perp1; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + actual-=perp2; + prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + + prob/=prob_div; + return prob; + +} + +///////////////// end version with FeatureExcludedVolumeSc //////////////////// + + +//////////////// version with FeatureExcludedVolume //////////////////////////// +// +// +// template +// double FeatureNNInteraction::calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const +// { +// //stupid implementation for now. +// VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; +// VectorInt3 newPos=oldPos+move.getDir(); +// +// double prob=1.0; +// double prob_divide=1.0; +// uint32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); +// +// +// for(size_t n=0;n<24;n++) +// { +// prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_1[n]))); +// prob_divide/=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_1[n]))); +// } +// for(size_t n=0;n<24;n++) +// { +// prob*=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_2[n]))),2.0); +// prob_divide/=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_2[n]))),2.0); +// } +// for(size_t n=0;n<6;n++) +// { +// prob*=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_4[n]))),4.0); +// prob_divide/=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_4[n]))),4.0); +// } +// +// +// +// return prob/prob_divide; +// +// } +// +// +// +// +// template +// void FeatureNNInteraction::fillLattice(IngredientsType& ingredients) +// { +// const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); +// for(size_t n=0;n +// void FeatureNNInteraction::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) +// { +// //get the position and attribute tag of the monomer to be inserted +// VectorInt3 pos=move.getPosition(); +// int32_t type=move.getType(); +// +// //update lattice +// ing.setLatticeEntry(pos,type); +// +// } +//////////////// end version with FeatureExcludedVolume///////////////////////// + +/****************************************************************************** + *implementation of read and write classes + ******************************************************************************/ + + +#endif /*FEATURE_NN_INTERACTION_H*/ diff --git a/include/LeMonADE/feature/FeaturePairInteraction.h b/include/LeMonADE/feature/FeaturePairInteraction.h new file mode 100644 index 0000000..6252516 --- /dev/null +++ b/include/LeMonADE/feature/FeaturePairInteraction.h @@ -0,0 +1,319 @@ +#ifndef FEATURE_PAIR_INTERACTION_H +#define FEATURE_PAIR_INTERACTION_H + + +#include +#include +#include +#include +#include +#include + + +template +class FeaturePairInteraction:public Feature +{ + +public: + typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; + typedef LOKI_TYPELIST_2(FeatureBox,FeatureAttributes) required_features_front; + + FeaturePairInteraction() + :verletSkin(0.0),useVerletList(false),verletListIsOutdated(true){}; + + virtual ~FeaturePairInteraction(){} + + //configureing the potential /////////////////////////////////////////// + Potential& modifyPairPotential(){return potential;} + const Potential& getPairPotential() const {return potential;} + + // configure the verlet list /////////////////////////////////////////// + void setUseVerletList(bool val){useVerletList=val;} + void setVerletSkin(double s){verletSkin=s;} + double getVerletSkin() const {return verletSkin;} + + //for debugging + size_t getVerletListLength() const {return verletList.size();} + + //check- and apply-functions for different types of moves ///////////// + template + bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; + + template + bool checkMove(const IngredientsType& ingredients, MoveLocalBase& move); + + template + bool checkMove(const IngredientsType& ingredients, const MoveAddScMonomer& move) const; + + template + void applyMove(IngredientsType& ing, const MoveBase& move){} + + template + void applyMove(IngredientsType& ingredients,const MoveLocalBase& move); + + template + void synchronize(IngredientsType& ingredients); + + //export read and write functionality ////////////////////////////////// + template + void exportRead(FileImport & fileReader){} + + template + void exportWrite(AnalyzerWriteBfmFile & fileWriter) const{} + + +private: + + // stuff for potential ///////////////////////////////////////////////// + Potential potential; + + // stuff for verlet list /////////////////////////////////////////////// + template + void updateVerletList(const IngredientsType& ingredients); + + bool useVerletList; + bool verletListIsOutdated; + double verletSkin; + + std::vector verletList; + std::map verletNeigborsMap; + std::map verletIndexMap; + std::map movedDistanceSinceListUpdate; + + + +}; + + +/////////////////////////////////////////////////////////////////////////////// + + +template +template +bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, const MoveBase& move) const +{ + return true; +} + +template +template +bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, const MoveAddScMonomer& move) const +{ + VectorInt3 myPos=move.getPosition(); + int32_t myType=move.getType(); + + for(size_t n=0;n::infinity()) return false; + } + + //if still here we reuturn true + return true; +} + +template +template +bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, MoveLocalBase& move) +{ + + if (useVerletList==false) + { + + double exp_oldEnergy=1.0; + double exp_newEnergy=1.0; + + size_t myIdx=move.getIndex(); + VectorInt3 myPos=ingredients.getMolecules()[myIdx]; + VectorInt3 myPosPlusDelta=ingredients.getMolecules()[myIdx]+move.getDir(); + int32_t myType=ingredients.getMolecules()[myIdx].getAttributeTag(); + + for(size_t monoIdx=0;monoIdx::infinity()) return false; + + exp_oldEnergy*=potential.getExpEnergy(myPos,monoPos,myType,monoType,ingredients); + exp_newEnergy*=potential.getExpEnergy(myPosPlusDelta,monoPos,myType,monoType,ingredients); + + } + } + + double moveProb=exp_newEnergy/exp_oldEnergy; + move.multiplyProbability( moveProb); + return true; + } + else //if useVerletList==true + { + if(verletListIsOutdated==true) + { + updateVerletList(ingredients); + verletListIsOutdated=false; + } + + double exp_oldEnergy=1.0; + double exp_newEnergy=1.0; + + double oldEnergy=0.0; + double newEnergy=0.0; + size_t myIdx=move.getIndex(); + VectorInt3 myPos=ingredients.getMolecules()[myIdx]; + VectorInt3 myPosPlusDelta=ingredients.getMolecules()[myIdx]+move.getDir(); + int32_t myType=ingredients.getMolecules()[myIdx].getAttributeTag(); + + + size_t numberOfNeighbors=verletNeigborsMap[myIdx]; + size_t verletListIndex=verletIndexMap[myIdx]; + size_t neighborIndex; + int32_t neighborType; + + for(size_t n=0;n::infinity()) return false; + + exp_oldEnergy*=potential.getExpEnergy(myPos,neighborPos,myType,neighborType,ingredients); + + exp_newEnergy*=potential.getExpEnergy(myPosPlusDelta,neighborPos,myType,neighborType,ingredients); + + } + + double moveProb=exp_newEnergy/exp_oldEnergy; + + move.multiplyProbability( moveProb); + return true; + } +} + + +template +template +void FeaturePairInteraction::applyMove(IngredientsType& ing, const MoveLocalBase& move) +{ + + if(useVerletList==true) + { + + movedDistanceSinceListUpdate[move.getIndex()]+=move.getDir(); + + double distanceMovedSquared=double(movedDistanceSinceListUpdate[move.getIndex()]*movedDistanceSinceListUpdate[move.getIndex()]); + if(distanceMovedSquared >= verletSkin*verletSkin/4.0) + { + verletListIsOutdated=true; + } + + } +} + +template +template +void FeaturePairInteraction::synchronize(IngredientsType& ingredients) +{ + + potential.synchronize(ingredients); + + + if(useVerletList==true) + { + std::cout<<"FeaturePairInteraction::synchronize()...start setting up Verlet list...\n"; + updateVerletList(ingredients); + verletListIsOutdated=false; + std::cout<<"FeaturePairInteraction::synchronize()...done setting up Verlet list...\n"; + } + else + { + verletIndexMap.clear(); + verletNeigborsMap.clear(); + movedDistanceSinceListUpdate.clear(); + verletList.clear(); + } + + for(size_t n=0;n +template +void FeaturePairInteraction::updateVerletList(const IngredientsType& ingredients) +{ + + //reset all list related containers + verletIndexMap.clear(); + verletNeigborsMap.clear(); + movedDistanceSinceListUpdate.clear(); + verletList.clear(); + + + VectorInt3 distanceVector, posN,posM; + + double verletListRadiusSquared=(potential.getRange()+verletSkin)*(potential.getRange()+verletSkin); + + size_t neighborCount=0; + + for(size_t n=0;n0) + { + verletIndexMap.insert(std::make_pair(n,verletList.size()-neighborCount)); + } + + neighborCount=0; + + movedDistanceSinceListUpdate.insert(std::make_pair(n,VectorInt3(0,0,0))); + } + +} + + + +#endif // FEATURE diff --git a/include/LeMonADE/feature/NNInteractionReadWrite.h b/include/LeMonADE/feature/NNInteractionReadWrite.h new file mode 100644 index 0000000..94f3605 --- /dev/null +++ b/include/LeMonADE/feature/NNInteractionReadWrite.h @@ -0,0 +1,110 @@ +#ifndef NNINTERACTIONREADWRITE_H +#define NNINTERACTIONREADWRITE_H + +#include + +/****************************************************************************** + *definition of read and write classes used by FeatureNNInteraction + *and FeatureNNInteractionPartialEV + ******************************************************************************/ +template < class IngredientsType> +class ReadInteraction: public ReadToDestination +{ +public: + ReadInteraction(IngredientsType& i):ReadToDestination(i){} + virtual ~ReadInteraction(){} + virtual void execute(); +}; + + +template +class WriteInteraction:public AbstractWrite +{ +public: + WriteInteraction(const IngredientsType& i) + :AbstractWrite(i){this->setHeaderOnly(true);} + + virtual ~WriteInteraction(){} + + virtual void writeStream(std::ostream& strm); +}; + +/////////////////////////////////////////////////////////////////////////////// +template +void ReadInteraction::execute() +{ + IngredientsType& ingredients=this->getDestination(); + std::istream& file=this->getInputStream(); + + + uint32_t typeA,typeB; + double interactionConstant; + + + file>>typeA; + + if(file.fail()) + { + std::stringstream messagestream; + messagestream<<"ReadInteraction::execute()\n" + <<"Could not read first type\n"; + throw std::runtime_error(messagestream.str()); + } + + //now read second type + file>>typeB; + + if(file.fail()) + { + std::stringstream messagestream; + messagestream<<"ReadInteraction::execute()\n" + <<"Could not read second type\n"; + throw std::runtime_error(messagestream.str()); + } + + //now read interactionConstant + file>>interactionConstant; + + if(file.fail()) + { + std::stringstream messagestream; + messagestream<<"ReadInteraction::execute()\n" + <<"Could not read interaction constant.\n"; + throw std::runtime_error(messagestream.str()); + } + + + //now save the interaction tuple just read from the file + ingredients.setInteraction(typeA,typeB,interactionConstant); + + +} + + + +template +void WriteInteraction::writeStream(std::ostream& stream) +{ + size_t nSpecies=10; + stream<<"## nearest neighbor interactions between types in kT (default 0.0kT)\n"; + + for(size_t typeA=1;typeA<=nSpecies;typeA++) + { + for(size_t typeB=1;typeBgetSource().getInteraction(typeA,typeB)!=0.0) + { + stream<<"#!nn_interaction "<getSource().getInteraction(typeB,typeA)<<"\n"; + } + + } + + } + stream<<"\n\n"; + +} + + + + +#endif // NNINTERACTIONREADWRITE_H diff --git a/include/LeMonADE/utility/PairPotentials.h b/include/LeMonADE/utility/PairPotentials.h new file mode 100644 index 0000000..2ff1895 --- /dev/null +++ b/include/LeMonADE/utility/PairPotentials.h @@ -0,0 +1,237 @@ +#ifndef PAIR_POTENTIALS_H +#define PAIR_POTENTIALS_H + +#include + +#include + +class PairPotentialSquare{ +public: + PairPotentialSquare():rangeSquared(0) + { + energy.resize(10,std::vector(10,0.0)); + probability.resize(10,std::vector(10,1.0)); + + } + + void setInteraction(int32_t typeA,int32_t typeB,double nrg) + { + energy.at(typeA-1).at(typeB-1)=nrg; + energy.at(typeB-1).at(typeA-1)=nrg; + } + + double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} + + void setRange(double r){rangeSquared=int32_t(r*r);} + double getRange() const {return std::sqrt(rangeSquared);} + + template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + + if(distVector*distVector<=rangeSquared){ + return energy.at(typeA-1).at(typeB-1); + } + + else return 0.0; + } + + template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + + if(distVector*distVector<=rangeSquared){ + return probability.at(typeA-1).at(typeB-1); + } + + else return 1.0; + + } + + template void synchronize(const IngredientsType& ing) + { + std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; + std::vector > probability; + + int32_t rangeSquared; + + +}; + +class PairPotentialSquareEV{ +public: + PairPotentialSquareEV():rangeSquared(0) + { + energy.resize(10,std::vector(10,0.0)); + probability.resize(10,std::vector(10,1.0)); + + } + + void setInteraction(int32_t typeA,int32_t typeB,double nrg) + { + energy.at(typeA-1).at(typeB-1)=nrg; + energy.at(typeB-1).at(typeA-1)=nrg; + } + + double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} + + void setRange(double r){rangeSquared=int32_t(r*r);} + double getRange() const {return std::sqrt(rangeSquared);} + + template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + int32_t dist2=distVector*distVector; + + if(dist2<4){ + return std::numeric_limits< double >::infinity(); + } + else if(dist2<=rangeSquared){ + return energy.at(typeA-1).at(typeB-1); + } + + else return 0.0; + } + + template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + int32_t dist2=distVector*distVector; + + if(dist2<4){ + return 0.0; + } + else if(dist2<=rangeSquared){ + return probability.at(typeA-1).at(typeB-1); + } + + else return 1.0; + + } + + template void synchronize(const IngredientsType& ing) + { + std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; + std::vector > probability; + + int32_t rangeSquared; + + +}; + +class PairPotentialSquareNNI{ +public: + PairPotentialSquareNNI() + :rangeSquared(0),nnEnergy(0.0) + ,expNNEnergy(1.0),exp2NNEnergy(1.0),exp4NNEnergy(1.0) + { + energy.resize(10,std::vector(10,0.0)); + probability.resize(10,std::vector(10,1.0)); + + } + + void setInteraction(int32_t typeA,int32_t typeB,double nrg) + { + energy.at(typeA-1).at(typeB-1)=nrg; + energy.at(typeB-1).at(typeA-1)=nrg; + } + + double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} + + void setRange(double r){rangeSquared=int32_t(r*r);} + double getRange() const {return std::sqrt(rangeSquared);} + + void setNNRepulsion(double nrg){nnEnergy=nrg;} + double getNNRepultion()const{return nnEnergy;} + + template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + int32_t dist2=distVector*distVector; + + if(dist2<4){ + return std::numeric_limits< double >::infinity(); + } + else if(dist2==4){ + return 4*nnEnergy; + } + else if(dist2==5){ + return 2*nnEnergy; + } + else if(dist2==6){ + return nnEnergy; + } + else if(dist2<=rangeSquared){ + return energy.at(typeA-1).at(typeB-1); + } + + else return 0.0; + } + + template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const + { + VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); + int32_t dist2=distVector*distVector; + + if(dist2<4){ + return 0.0; + } + else if(dist2==4){ + return exp4NNEnergy; + } + else if(dist2==5){ + return exp2NNEnergy; + } + else if(dist2==6){ + return expNNEnergy; + } + else if(dist2<=rangeSquared){ + return probability.at(typeA-1).at(typeB-1); + } + + else return 1.0; + + } + + template void synchronize(const IngredientsType& ing) + { + std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; + std::vector > probability; + + int32_t rangeSquared; + double nnEnergy; + double expNNEnergy; + double exp2NNEnergy; + double exp4NNEnergy; +}; +#endif /*PAIR_POTENTIALS_H*/ \ No newline at end of file diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index ac955d9..f64ce04 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -1,3 +1,5 @@ add_subdirectory(SimpleSimulator) add_subdirectory(Examples) + +add_subdirectory(testproject) diff --git a/projects/testproject/CMakeLists.txt b/projects/testproject/CMakeLists.txt new file mode 100644 index 0000000..4895d4b --- /dev/null +++ b/projects/testproject/CMakeLists.txt @@ -0,0 +1,4 @@ +ADD_SUBDIRECTORY(ChainSimulatorINT) + + + diff --git a/projects/testproject/ChainSimulatorINT/CMakeLists.txt b/projects/testproject/ChainSimulatorINT/CMakeLists.txt new file mode 100644 index 0000000..7d4e48a --- /dev/null +++ b/projects/testproject/ChainSimulatorINT/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.8) + +if (NOT DEFINED LEMONADE_INCLUDE_DIR) +message("LEMONADE_INCLUDE_DIR is not provided. If build fails, use -DLEMONADE_INCLUDE_DIR=/path/to/LeMonADE/headers/ or install to default location") +endif() + +if (NOT DEFINED LEMONADE_LIBRARY_DIR) +message("LEMONADE_LIBRARY_DIR is not provided. If build fails, use -DLEMONADE_LIBRARY_DIR=/path/to/LeMonADE/lib/ or install to default location") +endif() + +include_directories (${LEMONADE_INCLUDE_DIR}) +link_directories (${LEMONADE_LIBRARY_DIR}) +ADD_EXECUTABLE(ChainSimulatorINT main.cpp) +TARGET_LINK_LIBRARIES(ChainSimulatorINT LeMonADE) diff --git a/projects/testproject/ChainSimulatorINT/main.cpp b/projects/testproject/ChainSimulatorINT/main.cpp new file mode 100644 index 0000000..9e29001 --- /dev/null +++ b/projects/testproject/ChainSimulatorINT/main.cpp @@ -0,0 +1,78 @@ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char* argv[]) +{ + try{ + std::string infile; + std::string outfile; + uint32_t max_mcs=0; + uint32_t save_interval=0; + + outfile="outfile.bfm"; + + if(!(argc==4 || argc==5 )|| (argc==2 && strcmp(argv[1],"--help")==0 )) + { + std::string errormessage; + errormessage="usage: ./SimpleSimulator input_file max_mcs save_interval(mcs) [output_file]\n"; + errormessage+="\nSimple Simulator for the ScBFM with Ex.Vol and BondCheck\n"; + errormessage+="maximum number of connections per monomer is 6\n"; + errormessage+="If output_filename specified, the results are written to the new file\n"; + errormessage+="otherwise the results are appended to the old input file\n"; + errormessage+="Updaters used: ReadFullBFMFile, SimpleSimulator\n"; + errormessage+="Analyzers used: WriteBfmFile\n"; + throw std::runtime_error(errormessage); + + } + else + { + infile=argv[1]; + max_mcs=atoi(argv[2]); + save_interval=atoi(argv[3]); + + if(argc==5) outfile=argv[4]; + else outfile=argv[1]; + } + + //seed the globally available random number generators + RandomNumberGenerators rng; + rng.seedAll(); + + // FeatureExcludedVolume<> is equivalent to FeatureExcludedVolume > + typedef LOKI_TYPELIST_4(FeatureMoleculesIO, FeatureFixedMonomers,FeatureAttributes,FeatureNNInteraction) Features; + + typedef ConfigureSystem Config; + typedef Ingredients Ing; + Ing myIngredients; + + TaskManager taskmanager; + taskmanager.addUpdater(new UpdaterReadBfmFile(infile,myIngredients,UpdaterReadBfmFile::READ_LAST_CONFIG_SAVE),0); + taskmanager.addUpdater(new UpdaterSimpleSimulator(myIngredients,save_interval)); + + taskmanager.addAnalyzer(new AnalyzerWriteBfmFile(outfile,myIngredients)); + //taskmanager.addAnalyzer(new LatticeOccupationAnalyzer(myIngredients)); + + taskmanager.initialize(); + taskmanager.run(max_mcs/save_interval); + taskmanager.cleanup(); + + } + catch(std::exception& err){std::cerr< + +/******************************************************************************* + *constructor: initializes the lookup arrays + ******************************************************************************/ +FeatureNNInteraction::FeatureNNInteraction() +{ + for(size_t n=0;n<11;n++) + { + for(size_t m=0;m<11;m++) + { + interactionTable[m][n]=0.0; + probabilityLookup[m][n]=1.0; + } + } +} + +/******************************************************************************* + *destructor + ******************************************************************************/ +FeatureNNInteraction::~FeatureNNInteraction(){} + + +void FeatureNNInteraction::setInteraction(uint32_t typeA,uint32_t typeB,double energy) +{ + if(0 Date: Sat, 18 Jun 2016 14:35:18 +0200 Subject: [PATCH 02/16] *made FeatureNNInteraction a template of the underlying excluded volume feature *changed the max number of types in FeatureNNInteraction to 255, according to underlying 8 bit lattice *renamed FeatureNNInteraction to FeatureNNInteractionSc --- .../LeMonADE/feature/FeatureNNInteraction.h | 323 +++++++++--------- .../LeMonADE/feature/NNInteractionReadWrite.h | 10 +- .../testproject/ChainSimulatorINT/main.cpp | 4 +- src/LeMonADE/feature/FeatureNNInteraction.cpp | 119 ------- 4 files changed, 172 insertions(+), 284 deletions(-) diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureNNInteraction.h index 4182638..b704011 100644 --- a/include/LeMonADE/feature/FeatureNNInteraction.h +++ b/include/LeMonADE/feature/FeatureNNInteraction.h @@ -1,6 +1,7 @@ #ifndef FEATURE_NN_INTERACTION_H #define FEATURE_NN_INTERACTION_H +#include #include #include @@ -28,24 +29,38 @@ *the feature provides two #! bfm-commands: #!interaction_base and #!interaction * *****************************************************************************/ -class FeatureNNInteraction:public Feature +template class FeatureLatticeType> +class FeatureNNInteractionSc:public Feature { + +private: + typedef uint8_t lattice_value_type; + + double interactionTable[256][256]; + double probabilityLookup[256][256]; + + template + double calculateAcceptanceProbability(const IngredientsType& ingredients, const MoveLocalSc& move) const; + + template + void fillLattice(IngredientsType& ingredients); + + double getProbabilityFactor(int32_t typeA,int32_t typeB) const; + + public: - FeatureNNInteraction(); - ~FeatureNNInteraction(); + FeatureNNInteractionSc(); + ~FeatureNNInteractionSc(); - //excluded volume needs to be in front, because it pre-initializes the lattice + //and this feature re-initializes it (overwriting the values from excluded volume) typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; - ///////// for use with FeatureExcludedVolumeSc ///////////////////////////// - typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolumeSc >) required_features_front; - ///////// end version with Feature ExcludedVolumeSc //////////////////////// + //FeatureExcludedVulumeSc needs to be in front, because FeatureNNInteractionSc + //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written + typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolumeSc >) required_features_front; - ///////////for use with FeatureExcludedVolume ////////////////////////////// - //typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolume) required_features_front; - ///////// end version with Feature ExcludedVolume ////////////////////////// //check- and apply-functions for different types of moves template @@ -65,10 +80,10 @@ class FeatureNNInteraction:public Feature void synchronize(IngredientsType& ingredients); //add interaction between two types of monomers - void setInteraction(uint32_t typeA,uint32_t typeB,double energy); + void setContactInteraction(int32_t typeA,int32_t typeB,double energy); //returns the interaction between two types of monomers in units of interactionBase - double getInteraction(uint32_t typeA,uint32_t typeB) const; + double getContactInteraction(int32_t typeA,int32_t typeB) const; //export read and write functionality template @@ -77,26 +92,6 @@ class FeatureNNInteraction:public Feature template void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; -private: - - double interactionTable[11][11]; - double probabilityLookup[11][11]; - - template - double calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const; - - template - void fillLattice(IngredientsType& ingredients); - - //defined inline in the header (turns out to be faster) - double getProbabilityFactor(uint32_t typeA,uint32_t typeB) const; - -//////////// for use with FeatureExcludedVolume uncomment the block below/////// -// -// static const VectorInt3 contactShell_1[24]; -// static const VectorInt3 contactShell_2[24]; -// static const VectorInt3 contactShell_4[6]; -///////// end version with Feature ExcludedVolume ////////////////////////////// }; @@ -107,44 +102,52 @@ class FeatureNNInteraction:public Feature *implementation of template and inline members *(non-template members in FeatureNNInteraction.cpp) ******************************************************************************/ -inline double FeatureNNInteraction::getProbabilityFactor(uint32_t typeA,uint32_t typeB) const +template class LatticeClassType> +inline double FeatureNNInteractionSc::getProbabilityFactor(int32_t typeA,int32_t typeB) const { -#if DEBUG - if(0255 || typeB<0 || typeB>255){ + std::stringstream errormessage; + errormessage<<"***FeatureNaNInteractionSc::getInteraction(typeA,typeB)***\n"; + errormessage<<"probability undefined between types "< class LatticeClassType> template -void FeatureNNInteraction::exportRead(FileImport< IngredientsType >& fileReader) +void FeatureNNInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) { - fileReader.registerRead("#!nn_interaction",new ReadInteraction(*this)); + typedef FeatureNNInteractionSc my_type; + fileReader.registerRead("!nn_interaction",new ReadInteraction(*this)); } +template class LatticeClassType> template -void FeatureNNInteraction::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +void FeatureNNInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const { - fileWriter.registerWrite("#!nn_interaction",new WriteInteraction(*this)); + typedef FeatureNNInteractionSc my_type; + fileWriter.registerWrite("!nn_interaction",new WriteInteraction(*this)); } /******************************************************************************* *checkMove for unknown moves: does nothing ******************************************************************************/ +template class LatticeClassType> template -bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, const MoveBase& move) const +bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, const MoveBase& move) const { return true; } @@ -154,10 +157,11 @@ bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, const M *the move. the metropolis step is performed later in FeatureBoltzmann (in *case other features also add some probability) ******************************************************************************/ +template class LatticeClassType> template -bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) const +bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) const { - double prob=calculateAcceptanceProb(ingredients,move); + double prob=calculateAcceptanceProbability(ingredients,move); move.multiplyProbability(prob); return true; } @@ -167,8 +171,9 @@ bool FeatureNNInteraction::checkMove(const IngredientsType& ingredients, MoveLoc /******************************************************************************* *synchronize: ******************************************************************************/ +template class LatticeClassType> template -void FeatureNNInteraction::synchronize(IngredientsType& ingredients) +void FeatureNNInteractionSc::synchronize(IngredientsType& ingredients) { //refill the lattice with attribute tags @@ -177,7 +182,6 @@ void FeatureNNInteraction::synchronize(IngredientsType& ingredients) } -//////////////// version for use with FeatureExcludedVolumeSc ////////////////// /******************************************************************************* *applyMove for MoveAddScMonomer: updates the lattice with attribute tag of the @@ -185,8 +189,10 @@ void FeatureNNInteraction::synchronize(IngredientsType& ingredients) *works only when 8 positions are written on the lattice per monomer. for *the other case use the function in the lower part of this file ******************************************************************************/ +//////////////// version for use with FeatureExcludedVolumeSc ////////////////// +template class LatticeClassType> template -void FeatureNNInteraction::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) +void FeatureNNInteractionSc::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) { //get the position and attribute tag of the monomer to be inserted VectorInt3 pos=move.getPosition(); @@ -214,22 +220,32 @@ void FeatureNNInteraction::applyMove(IngredientsType& ing, const MoveAddScMonome *comment this function and uncomment the appropriate one in the section at the *end of this file. ******************************************************************************/ +template class LatticeClassType> template -void FeatureNNInteraction::fillLattice(IngredientsType& ingredients) +void FeatureNNInteractionSc::fillLattice(IngredientsType& ingredients) { const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); for(size_t n=0;n class LatticeClassType> template -double FeatureNNInteraction::calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const +double FeatureNNInteractionSc::calculateAcceptanceProbability( + const IngredientsType& ingredients, + const MoveLocalSc& move) const { - //stupid implementation for now. + VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; VectorInt3 direction=move.getDir(); - - double prob=1.0; - uint32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); + int32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); /*get two directions perpendicular to vector directon of the move*/ VectorInt3 perp1,perp2; @@ -283,135 +300,125 @@ double FeatureNNInteraction::calculateAcceptanceProb(const IngredientsType& ingr actual+=direction; actual-=perp1; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp2+perp1; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp1; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp1-perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual-perp1-perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp1; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp2+direction; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp1; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp2; - prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); //now check back side (contacts taken away) double prob_div=1.0; actual=oldPos; if(direction.getX()<0 || direction.getY()<0 || direction.getZ()<0) actual-=direction; actual-=perp1; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp2+perp1; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp1; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp1-perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual-perp1-perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp1; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual=actual+perp2-direction; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=perp1; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=perp2; - prob_div*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); prob/=prob_div; return prob; } -///////////////// end version with FeatureExcludedVolumeSc //////////////////// - - -//////////////// version with FeatureExcludedVolume //////////////////////////// -// -// -// template -// double FeatureNNInteraction::calculateAcceptanceProb(const IngredientsType& ingredients, const MoveLocalSc& move) const -// { -// //stupid implementation for now. -// VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; -// VectorInt3 newPos=oldPos+move.getDir(); -// -// double prob=1.0; -// double prob_divide=1.0; -// uint32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); -// -// -// for(size_t n=0;n<24;n++) -// { -// prob*=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_1[n]))); -// prob_divide/=getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_1[n]))); -// } -// for(size_t n=0;n<24;n++) -// { -// prob*=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_2[n]))),2.0); -// prob_divide/=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_2[n]))),2.0); -// } -// for(size_t n=0;n<6;n++) -// { -// prob*=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(newPos+contactShell_4[n]))),4.0); -// prob_divide/=pow(getProbabilityFactor(monoType,uint32_t(ingredients.getLatticeEntry(oldPos+contactShell_4[n]))),4.0); -// } -// -// -// -// return prob/prob_divide; -// -// } -// -// -// -// -// template -// void FeatureNNInteraction::fillLattice(IngredientsType& ingredients) -// { -// const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); -// for(size_t n=0;n -// void FeatureNNInteraction::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) -// { -// //get the position and attribute tag of the monomer to be inserted -// VectorInt3 pos=move.getPosition(); -// int32_t type=move.getType(); -// -// //update lattice -// ing.setLatticeEntry(pos,type); -// -// } -//////////////// end version with FeatureExcludedVolume///////////////////////// -/****************************************************************************** - *implementation of read and write classes +/******************************************************************************* + *constructor: initializes the lookup arrays + ******************************************************************************/ +template class LatticeClassType> +FeatureNNInteractionSc::FeatureNNInteractionSc() +{ + for(size_t n=0;n<256;n++) + { + for(size_t m=0;m<256;m++) + { + interactionTable[m][n]=0.0; + probabilityLookup[m][n]=1.0; + } + } +} + +/******************************************************************************* + *destructor ******************************************************************************/ +template class LatticeClassType> +FeatureNNInteractionSc::~FeatureNNInteractionSc(){} + +template class LatticeClassType> +void FeatureNNInteractionSc::setContactInteraction(int32_t typeA,int32_t typeB,double energy) +{ + if(0 class LatticeClassType> +double FeatureNNInteractionSc::getContactInteraction(int32_t typeA, + int32_t typeB) const +{ + + if(0::execute() std::istream& file=this->getInputStream(); - uint32_t typeA,typeB; + int32_t typeA,typeB; double interactionConstant; @@ -75,7 +75,7 @@ void ReadInteraction::execute() //now save the interaction tuple just read from the file - ingredients.setInteraction(typeA,typeB,interactionConstant); + ingredients.setContactInteraction(typeA,typeB,interactionConstant); } @@ -85,16 +85,16 @@ void ReadInteraction::execute() template void WriteInteraction::writeStream(std::ostream& stream) { - size_t nSpecies=10; + size_t nSpecies=255; stream<<"## nearest neighbor interactions between types in kT (default 0.0kT)\n"; for(size_t typeA=1;typeA<=nSpecies;typeA++) { for(size_t typeB=1;typeBgetSource().getInteraction(typeA,typeB)!=0.0) + if(this->getSource().getContactInteraction(typeA,typeB)!=0.0) { - stream<<"#!nn_interaction "<getSource().getInteraction(typeB,typeA)<<"\n"; + stream<<"!nn_interaction "<getSource().getContactInteraction(typeB,typeA)<<"\n"; } } diff --git a/projects/testproject/ChainSimulatorINT/main.cpp b/projects/testproject/ChainSimulatorINT/main.cpp index 9e29001..f74961d 100644 --- a/projects/testproject/ChainSimulatorINT/main.cpp +++ b/projects/testproject/ChainSimulatorINT/main.cpp @@ -12,7 +12,7 @@ #include #include #include - +#include #include int main(int argc, char* argv[]) @@ -53,7 +53,7 @@ int main(int argc, char* argv[]) rng.seedAll(); // FeatureExcludedVolume<> is equivalent to FeatureExcludedVolume > - typedef LOKI_TYPELIST_4(FeatureMoleculesIO, FeatureFixedMonomers,FeatureAttributes,FeatureNNInteraction) Features; + typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureNNInteractionSc) Features; typedef ConfigureSystem Config; typedef Ingredients Ing; diff --git a/src/LeMonADE/feature/FeatureNNInteraction.cpp b/src/LeMonADE/feature/FeatureNNInteraction.cpp index 322289a..4eb2144 100644 --- a/src/LeMonADE/feature/FeatureNNInteraction.cpp +++ b/src/LeMonADE/feature/FeatureNNInteraction.cpp @@ -1,120 +1 @@ #include - -/******************************************************************************* - *constructor: initializes the lookup arrays - ******************************************************************************/ -FeatureNNInteraction::FeatureNNInteraction() -{ - for(size_t n=0;n<11;n++) - { - for(size_t m=0;m<11;m++) - { - interactionTable[m][n]=0.0; - probabilityLookup[m][n]=1.0; - } - } -} - -/******************************************************************************* - *destructor - ******************************************************************************/ -FeatureNNInteraction::~FeatureNNInteraction(){} - - -void FeatureNNInteraction::setInteraction(uint32_t typeA,uint32_t typeB,double energy) -{ - if(0 Date: Sat, 18 Jun 2016 17:45:27 +0200 Subject: [PATCH 03/16] *renamed FeatureNNInteractionSc to FeatureContactInteractionSc *started adding doxygen comments --- .../LeMonADE/feature/FeatureNNInteraction.h | 421 ++++++++++-------- src/LeMonADE/feature/FeatureNNInteraction.cpp | 1 - 2 files changed, 243 insertions(+), 179 deletions(-) delete mode 100644 src/LeMonADE/feature/FeatureNNInteraction.cpp diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureNNInteraction.h index b704011..1e9dcb9 100644 --- a/include/LeMonADE/feature/FeatureNNInteraction.h +++ b/include/LeMonADE/feature/FeatureNNInteraction.h @@ -1,7 +1,40 @@ -#ifndef FEATURE_NN_INTERACTION_H -#define FEATURE_NN_INTERACTION_H +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers (see AUTHORS) + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + + +#ifndef FEATURE_CONTACT_INTERACTION_H +#define FEATURE_CONTACT_INTERACTION_H + + +/// @file +/// @date 2016/06/18 +/// @author Hauke Rabbel +/// @brief Definition and implementation of class template FeatureContactInteractionSc -#include #include #include @@ -9,190 +42,190 @@ #include #include #include +#include + + +/// @class FeatureContactInteractionSc +/// @brief Provides interaction of monomers on distances d<=sqrt(6) for standard BFM +/// +/// @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or +/// FeatureLatticePowerOfTwo (template template parameter) +/// +/// @details +/// The interaction energy can be set for pairs of monomer-types A,B, where +/// the type can be any integer between 1 and 255. +/// The feature automatically adds FeatureExcludedVolumeSc +/// to the system. Given an energy E in kT between two types, the interaction potential +/// as a function of the distance d is: +/// - inf d<2 (implicitly through excluded volume) +/// - 4*E d=2 +/// - 2*E d=sqrt(5) +/// - 1*E d=sqrt(6) +/// - 0 d>sqrt(6) +/// . +/// Usage: In the feature list defining Ingredients use this feature as +/// FeatureContactInteractionSc (arbitrary lattices), or as +/// FeatureContactInteractionSc (2**n lattices) +/// The feature adds the bfm-file command !contact_interaction A B E +/// for monomers of types A B with interaction energy of E in kT. + -#include - - - -/****************************************************************************** - *this feature implements nearest neighbour contact interactions. - *in the bfm file, as well as in the code, the interactions are defined as - *for each nearest neighbor contact between two types A,B in kT. - *bfm-command example: - *#!interaction 1 2 1.6 - *defines an interaction of 1.6 kT per contact for monomer types 1,2 - * - *as default the feature is implemented for use with ExcludedVolumeSC (writes - *8 points per monomer on the lattice), but code for ExcludedVolume (writing only - *1 point) is also there. just un-comment the marked regions. - * - *the feature provides two #! bfm-commands: #!interaction_base and #!interaction - * - *****************************************************************************/ template class FeatureLatticeType> -class FeatureNNInteractionSc:public Feature +class FeatureContactInteractionSc:public Feature { private: + //! Type for the underlying lattice, used as template parameter for FeatureLatticeType<...> typedef uint8_t lattice_value_type; + //! Interaction energies between monomer types. Max. type=255 given by max(uint8_t)=255 double interactionTable[256][256]; - double probabilityLookup[256][256]; + + //! Lookup table for exp(-interactionTable[a][b]) + double probabilityLookup[256][256]; - template - double calculateAcceptanceProbability(const IngredientsType& ingredients, const MoveLocalSc& move) const; + //! Returns this feature's factor for the acceptance probability for the given Monte Carlo move + template + double calculateAcceptanceProbability(const IngredientsType& ingredients, + const MoveLocalSc& move) const; - template - void fillLattice(IngredientsType& ingredients); + //! Occupies the lattice with the attribute tags of all monomers + template + void fillLattice(IngredientsType& ingredients); - double getProbabilityFactor(int32_t typeA,int32_t typeB) const; + //! Access to array probabilityLookup with extra checks in Debug mode + double getProbabilityFactor(int32_t typeA,int32_t typeB) const; public: - FeatureNNInteractionSc(); - ~FeatureNNInteractionSc(); + FeatureContactInteractionSc(); + ~FeatureContactInteractionSc(){} - //and this feature re-initializes it (overwriting the values from excluded volume) - typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; + //This feature adds interaction energies, so it requires FeatureBoltzmann + typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; - //FeatureExcludedVulumeSc needs to be in front, because FeatureNNInteractionSc - //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written - typedef LOKI_TYPELIST_2(FeatureAttributes,FeatureExcludedVolumeSc >) required_features_front; + //FeatureExcludedVolumeSc needs to be in front, because FeatureContactInteractionSc + //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written. + //FeatureAttributes needs to be in front, because when a monomer is added to the system + //by a MoveAddScMonomer, its attribute has to be set before it is written to the lattice. + typedef LOKI_TYPELIST_2( + FeatureAttributes, + FeatureExcludedVolumeSc >) + required_features_front; - //check- and apply-functions for different types of moves - template - bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; + //! check for all Monte Carlo moves without special check functions (always true) + template + bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; - template - bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move) const; + //! check for standard sc-BFM local move + template + bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move) const; - template - void applyMove(IngredientsType& ing, const MoveBase& move){} + //! check move for bcc-BFM local move. always throws std::runtime_error + template + bool checkMove(const IngredientsType& ingredients,const MoveLocalBcc& move) const; - template - void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); + //TODO should we implement a check for MoveAddScMonomer (needs calculation of partition function)? - //synchronize initializes the lattice with the attribute-tags of the monomers - template - void synchronize(IngredientsType& ingredients); + //! apply function for all Monte Carlo moves without special apply functions (does nothing) + template + void applyMove(const IngredientsType& ing, const MoveBase& move); - //add interaction between two types of monomers - void setContactInteraction(int32_t typeA,int32_t typeB,double energy); + //! apply function for bcc-BFM local move (always throws std::runtime_error) + template + void applyMove(const IngredientsType& ing, const MoveLocalBcc& move); - //returns the interaction between two types of monomers in units of interactionBase - double getContactInteraction(int32_t typeA,int32_t typeB) const; + //! apply function for adding a monomer in sc-BFM + template + void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); - //export read and write functionality - template - void exportRead(FileImport & fileReader); + //note: apply function for sc-BFM local move is not necessary, because + //job of moving lattice entries is done by the underlying FeatureLatticeType - template - void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; + //! guarantees that the lattice is properly occupied with monomer attributes + template + void synchronize(IngredientsType& ingredients); -}; + //!adds interaction energy between two types of monomers + void setContactInteraction(int32_t typeA,int32_t typeB,double energy); + //!returns the interaction energy between two types of monomers + double getContactInteraction(int32_t typeA,int32_t typeB) const; + //!export bfm-file read command !contact_interaction + template + void exportRead(FileImport & fileReader); + //!export bfm-file write command !contact_interaction + template + void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; +}; -/******************************************************************************* - *implementation of template and inline members - *(non-template members in FeatureNNInteraction.cpp) - ******************************************************************************/ -template class LatticeClassType> -inline double FeatureNNInteractionSc::getProbabilityFactor(int32_t typeA,int32_t typeB) const -{ -#ifdef DEBUG - - if(typeA<0 || typeA>255 || typeB<0 || typeB>255){ - std::stringstream errormessage; - errormessage<<"***FeatureNaNInteractionSc::getInteraction(typeA,typeB)***\n"; - errormessage<<"probability undefined between types "< class LatticeClassType> -template -void FeatureNNInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) +FeatureContactInteractionSc::FeatureContactInteractionSc() { - typedef FeatureNNInteractionSc my_type; - fileReader.registerRead("!nn_interaction",new ReadInteraction(*this)); + //initialize the energy and probability lookups with default values + for(size_t n=0;n<256;n++) + { + for(size_t m=0;m<256;m++) + { + interactionTable[m][n]=0.0; + probabilityLookup[m][n]=1.0; + } + } } -template class LatticeClassType> -template -void FeatureNNInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const -{ - typedef FeatureNNInteractionSc my_type; - fileWriter.registerWrite("!nn_interaction",new WriteInteraction(*this)); -} -/******************************************************************************* - *checkMove for unknown moves: does nothing - ******************************************************************************/ template class LatticeClassType> template -bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, const MoveBase& move) const +bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, + const MoveBase& move) const { return true; } -/******************************************************************************* - *checkMove for MoveLocalSc: gets the transition probability and adds it to - *the move. the metropolis step is performed later in FeatureBoltzmann (in - *case other features also add some probability) - ******************************************************************************/ + template class LatticeClassType> template -bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) const +bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, + MoveLocalSc& move) const { - double prob=calculateAcceptanceProbability(ingredients,move); - move.multiplyProbability(prob); - return true; + //add the probability factor coming from this feature, then return true, + //because the total probability is evaluated by FeatureBoltzmann at the end + double prob=calculateAcceptanceProbability(ingredients,move); + move.multiplyProbability(prob); + return true; } - - -/******************************************************************************* - *synchronize: - ******************************************************************************/ template class LatticeClassType> template -void FeatureNNInteractionSc::synchronize(IngredientsType& ingredients) +bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, + const MoveLocalBcc& move) const { + //throw exception in case someone accidentaly uses a bcc-BFM move with this feature + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionSc::checkMove(...):\n"; + errormessage<<"attempting to use bcc-BFM move, which is not allowed\n"; + throw std::runtime_error(errormessage.str()); - //refill the lattice with attribute tags - //caution: this overwrites, what is currently written on the lattice - fillLattice(ingredients); - + return false; } -/******************************************************************************* - *applyMove for MoveAddScMonomer: updates the lattice with attribute tag of the - *added monomer - *works only when 8 positions are written on the lattice per monomer. for - *the other case use the function in the lower part of this file - ******************************************************************************/ -//////////////// version for use with FeatureExcludedVolumeSc ////////////////// + template class LatticeClassType> template -void FeatureNNInteractionSc::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) +void FeatureContactInteractionSc::applyMove(IngredientsType& ing, + const MoveAddScMonomer& move) { //get the position and attribute tag of the monomer to be inserted VectorInt3 pos=move.getPosition(); @@ -212,19 +245,77 @@ void FeatureNNInteractionSc::applyMove(IngredientsType& ing, c ing.setLatticeEntry(pos+dz+dx+dy,type); } -/******************************************************************************* - *fillLattice: fills the lattice with attribute tags of the monomers. - *this is the version for use with ExcludedVolumeSC (it writes 8 positions - *per monomer) - *if you want to use a version where only one position is written per monomer, - *comment this function and uncomment the appropriate one in the section at the - *end of this file. - ******************************************************************************/ + +template class LatticeClassType> +template +void FeatureContactInteractionSc::applyMove(const IngredientsType& ing, + const MoveLocalBcc& move) +{ + //throw exception in case someone accidentaly uses a bcc-BFM move with this feature + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionSc::applyMove(...):\n"; + errormessage<<"attempting to use bcc-BFM move, which is not allowed\n"; + throw std::runtime_error(errormessage.str()); + +} + +template class LatticeClassType> +template +void FeatureContactInteractionSc::synchronize(IngredientsType& ingredients) +{ + + //refill the lattice with attribute tags + //caution: this overwrites, what is currently written on the lattice + fillLattice(ingredients); + +} + + +template class LatticeClassType> +inline double FeatureContactInteractionSc::getProbabilityFactor(int32_t typeA, + int32_t typeB) const +{ +#ifdef DEBUG + //extra checks only in debug mode, because this is very frequently called + //and this costs performance + if(typeA<0 || typeA>255 || typeB<0 || typeB>255){ + std::stringstream errormessage; + errormessage<<"***FeatureNaNInteractionSc::getInteraction(typeA,typeB)***\n"; + errormessage<<"probability undefined between types "< class LatticeClassType> +template +void FeatureContactInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) +{ + typedef FeatureContactInteractionSc my_type; + fileReader.registerRead("!contact_interaction",new ReadInteraction(*this)); +} + + +template class LatticeClassType> +template +void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +{ + typedef FeatureContactInteractionSc my_type; + fileWriter.registerWrite("!contact_interaction",new WriteInteraction(*this)); +} + + template class LatticeClassType> template -void FeatureNNInteractionSc::fillLattice(IngredientsType& ingredients) +void FeatureContactInteractionSc::fillLattice(IngredientsType& ingredients) { const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); + for(size_t n=0;n::fillLattice(IngredientsType& ingr } -/******************************************************************************* - *calculateAcceptanceProb: - *calculates the probability of acceptance for the move based on change of contacts - *with surrounding monomers - *this function works only when 8 positions are written per monomer. For other - *case comment it out and use the function in the lower section of this file. - ******************************************************************************/ + template class LatticeClassType> template -double FeatureNNInteractionSc::calculateAcceptanceProbability( +double FeatureContactInteractionSc::calculateAcceptanceProbability( const IngredientsType& ingredients, const MoveLocalSc& move) const { @@ -359,52 +444,32 @@ double FeatureNNInteractionSc::calculateAcceptanceProbability( } -/******************************************************************************* - *constructor: initializes the lookup arrays - ******************************************************************************/ template class LatticeClassType> -FeatureNNInteractionSc::FeatureNNInteractionSc() -{ - for(size_t n=0;n<256;n++) - { - for(size_t m=0;m<256;m++) - { - interactionTable[m][n]=0.0; - probabilityLookup[m][n]=1.0; - } - } -} - -/******************************************************************************* - *destructor - ******************************************************************************/ -template class LatticeClassType> -FeatureNNInteractionSc::~FeatureNNInteractionSc(){} - -template class LatticeClassType> -void FeatureNNInteractionSc::setContactInteraction(int32_t typeA,int32_t typeB,double energy) +void FeatureContactInteractionSc::setContactInteraction(int32_t typeA, + int32_t typeB, + double energy) { if(0 class LatticeClassType> -double FeatureNNInteractionSc::getContactInteraction(int32_t typeA, +double FeatureContactInteractionSc::getContactInteraction(int32_t typeA, int32_t typeB) const { @@ -413,7 +478,7 @@ double FeatureNNInteractionSc::getContactInteraction(int32_t t else { std::stringstream errormessage; - errormessage<<"FeatureNNInteractionSc::getContactInteraction(typeA,typeB).\n"; + errormessage<<"FeatureContactInteractionSc::getContactInteraction(typeA,typeB).\n"; errormessage<<"typeA "<::getContactInteraction(int32_t t } -#endif /*FEATURE_NN_INTERACTION_H*/ +#endif /*FEATURE_CONTACT_INTERACTION_H*/ diff --git a/src/LeMonADE/feature/FeatureNNInteraction.cpp b/src/LeMonADE/feature/FeatureNNInteraction.cpp deleted file mode 100644 index 4eb2144..0000000 --- a/src/LeMonADE/feature/FeatureNNInteraction.cpp +++ /dev/null @@ -1 +0,0 @@ -#include From 7c868c2393c7ba7d7d35a982630210aac6668307 Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Sun, 19 Jun 2016 19:02:15 +0200 Subject: [PATCH 04/16] added comments and more readable code in NNInteractionReadWrite.h --- .../LeMonADE/feature/FeatureNNInteraction.h | 23 ++- .../LeMonADE/feature/NNInteractionReadWrite.h | 158 +++++++++++------- .../testproject/ChainSimulatorINT/main.cpp | 2 +- 3 files changed, 109 insertions(+), 74 deletions(-) diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureNNInteraction.h index 1e9dcb9..ba04a68 100644 --- a/include/LeMonADE/feature/FeatureNNInteraction.h +++ b/include/LeMonADE/feature/FeatureNNInteraction.h @@ -42,7 +42,7 @@ along with LeMonADE. If not, see . #include #include #include -#include +#include /// @class FeatureContactInteractionSc @@ -118,29 +118,27 @@ class FeatureContactInteractionSc:public Feature //! check for all Monte Carlo moves without special check functions (always true) template - bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; + bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; //! check for standard sc-BFM local move template - bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move) const; + bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move) const; //! check move for bcc-BFM local move. always throws std::runtime_error template - bool checkMove(const IngredientsType& ingredients,const MoveLocalBcc& move) const; - - //TODO should we implement a check for MoveAddScMonomer (needs calculation of partition function)? + bool checkMove(const IngredientsType& ingredients,const MoveLocalBcc& move) const; //! apply function for all Monte Carlo moves without special apply functions (does nothing) template - void applyMove(const IngredientsType& ing, const MoveBase& move); + void applyMove(const IngredientsType& ing, const MoveBase& move){} //! apply function for bcc-BFM local move (always throws std::runtime_error) template - void applyMove(const IngredientsType& ing, const MoveLocalBcc& move); + void applyMove(const IngredientsType& ing, const MoveLocalBcc& move); //! apply function for adding a monomer in sc-BFM template - void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); + void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); //note: apply function for sc-BFM local move is not necessary, because //job of moving lattice entries is done by the underlying FeatureLatticeType @@ -297,7 +295,7 @@ template void FeatureContactInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) { typedef FeatureContactInteractionSc my_type; - fileReader.registerRead("!contact_interaction",new ReadInteraction(*this)); + fileReader.registerRead("!contact_interaction",new ReadContactInteraction(*this)); } @@ -306,7 +304,7 @@ template void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const { typedef FeatureContactInteractionSc my_type; - fileWriter.registerWrite("!contact_interaction",new WriteInteraction(*this)); + fileWriter.registerWrite("!contact_interaction",new WriteContactInteraction(*this)); } @@ -323,7 +321,7 @@ void FeatureContactInteractionSc::fillLattice(IngredientsType& if(int32_t(attribute)!=molecules[n].getAttributeTag()){ std::stringstream errormessage; - errormessage<<"***FeatureNaNInteractionSc::fillLattice()***\n"; + errormessage<<"***FeatureContactInteractionSc::fillLattice()***\n"; errormessage<<"type "<::getContactInteraction(int3 } +//TODO: rename files, change IO, tests, comments for doxygen #endif /*FEATURE_CONTACT_INTERACTION_H*/ diff --git a/include/LeMonADE/feature/NNInteractionReadWrite.h b/include/LeMonADE/feature/NNInteractionReadWrite.h index b5d246e..50d9fed 100644 --- a/include/LeMonADE/feature/NNInteractionReadWrite.h +++ b/include/LeMonADE/feature/NNInteractionReadWrite.h @@ -1,110 +1,146 @@ -#ifndef NNINTERACTIONREADWRITE_H -#define NNINTERACTIONREADWRITE_H +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers (see AUTHORS) + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + +#ifndef FEATURE_CONTACT_INTERACTION_READ_WRITE_H +#define FEATURE_CONTACT_INTERACTION_READ_WRITE_H + +/** + * @file + * @date 2016/06/18 + * @author Hauke Rabbel + * @brief Def. and impl. of class templates ReadContactInteraction and WriteContactInteraction +**/ #include +#include -/****************************************************************************** - *definition of read and write classes used by FeatureNNInteraction - *and FeatureNNInteractionPartialEV - ******************************************************************************/ +/** + * @class ReadContactInteraction + * @brief Handles BFM-file read command !contact_interaction + * @tparam IngredientsType Ingredients class storing all system information. +**/ template < class IngredientsType> -class ReadInteraction: public ReadToDestination +class ReadContactInteraction: public ReadToDestination { public: - ReadInteraction(IngredientsType& i):ReadToDestination(i){} - virtual ~ReadInteraction(){} + ReadContactInteraction(IngredientsType& i):ReadToDestination(i){} + virtual ~ReadContactInteraction(){} virtual void execute(); }; - +/** + * @class WriteContactInteraction + * @brief Handles BFM-file write command !contact_interaction + * @tparam IngredientsType Ingredients class storing all system information. +**/ template -class WriteInteraction:public AbstractWrite +class WriteContactInteraction:public AbstractWrite { public: - WriteInteraction(const IngredientsType& i) + + //constructor sets the headerOnly tag, such that the interaction + //is written only once at the beginning of the output file. + WriteContactInteraction(const IngredientsType& i) :AbstractWrite(i){this->setHeaderOnly(true);} - virtual ~WriteInteraction(){} + virtual ~WriteContactInteraction(){} virtual void writeStream(std::ostream& strm); }; -/////////////////////////////////////////////////////////////////////////////// +/////////////MEMBER IMPLEMENTATIONS //////////////////////////////////////////// + +/** + * @brief Executes the reading routine to extract \b !contact_interaction. + * + * @throw fail to read monomer types or interaction energy. + **/ template -void ReadInteraction::execute() +void ReadContactInteraction::execute() { IngredientsType& ingredients=this->getDestination(); std::istream& file=this->getInputStream(); - int32_t typeA,typeB; double interactionConstant; - - file>>typeA; - - if(file.fail()) - { - std::stringstream messagestream; - messagestream<<"ReadInteraction::execute()\n" - <<"Could not read first type\n"; - throw std::runtime_error(messagestream.str()); - } - - //now read second type - file>>typeB; - - if(file.fail()) - { - std::stringstream messagestream; - messagestream<<"ReadInteraction::execute()\n" - <<"Could not read second type\n"; - throw std::runtime_error(messagestream.str()); - } - - //now read interactionConstant - file>>interactionConstant; - - if(file.fail()) - { - std::stringstream messagestream; - messagestream<<"ReadInteraction::execute()\n" - <<"Could not read interaction constant.\n"; - throw std::runtime_error(messagestream.str()); - } - - + //set stream to throw exception on fail + file.exceptions(file.exceptions() | std::ifstream::failbit); + + try + { + file>>typeA; + file>>typeB; + file>>interactionConstant; + } + catch(std::ifstream::failure e) + { + std::stringstream errormessage; + errormessage<<"ReadContactInteraction::execute().\n"; + errormessage<<"Could not read interaction from file\n"; + errormessage<<"Previous error: "< -void WriteInteraction::writeStream(std::ostream& stream) +void WriteContactInteraction::writeStream(std::ostream& stream) { - size_t nSpecies=255; - stream<<"## nearest neighbor interactions between types in kT (default 0.0kT)\n"; + int32_t nSpecies=255; //number must fit into 8 bit (uint8_t based lattice) + stream<<"## nearest neighbor interactions between types in kT (default 0.0kT)\n"; - for(size_t typeA=1;typeA<=nSpecies;typeA++) + for(int32_t typeA=1;typeA<=nSpecies;typeA++) { - for(size_t typeB=1;typeBgetSource().getContactInteraction(typeA,typeB)!=0.0) + if(this->getSource().getContactInteraction(typeA,typeB)!=0.0) { - stream<<"!nn_interaction "<getSource().getContactInteraction(typeB,typeA)<<"\n"; + stream<<"!contact_interaction "<getSource().getContactInteraction(typeB,typeA)<<"\n"; } } } - stream<<"\n\n"; + stream<<"\n\n"; } -#endif // NNINTERACTIONREADWRITE_H +#endif // FEATURE_CONTACT_INTERACTION_READ_WRITE_H diff --git a/projects/testproject/ChainSimulatorINT/main.cpp b/projects/testproject/ChainSimulatorINT/main.cpp index f74961d..5df0af0 100644 --- a/projects/testproject/ChainSimulatorINT/main.cpp +++ b/projects/testproject/ChainSimulatorINT/main.cpp @@ -53,7 +53,7 @@ int main(int argc, char* argv[]) rng.seedAll(); // FeatureExcludedVolume<> is equivalent to FeatureExcludedVolume > - typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureNNInteractionSc) Features; + typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureContactInteractionSc) Features; typedef ConfigureSystem Config; typedef Ingredients Ing; From 2e9fe7a822037044571821649ea6b7e187715c0c Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Sun, 19 Jun 2016 20:01:23 +0200 Subject: [PATCH 05/16] comments for FeatureContactInteractionSc --- .../LeMonADE/feature/FeatureNNInteraction.h | 197 ++++++++++++++---- 1 file changed, 154 insertions(+), 43 deletions(-) diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureNNInteraction.h index ba04a68..48c373b 100644 --- a/include/LeMonADE/feature/FeatureNNInteraction.h +++ b/include/LeMonADE/feature/FeatureNNInteraction.h @@ -29,12 +29,12 @@ along with LeMonADE. If not, see . #ifndef FEATURE_CONTACT_INTERACTION_H #define FEATURE_CONTACT_INTERACTION_H - -/// @file -/// @date 2016/06/18 -/// @author Hauke Rabbel -/// @brief Definition and implementation of class template FeatureContactInteractionSc - +/** + * @file + * @date 2016/06/18 + * @author Hauke Rabbel + * @brief Definition and implementation of class template FeatureContactInteractionSc +**/ #include #include @@ -44,31 +44,31 @@ along with LeMonADE. If not, see . #include #include - -/// @class FeatureContactInteractionSc -/// @brief Provides interaction of monomers on distances d<=sqrt(6) for standard BFM -/// -/// @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or -/// FeatureLatticePowerOfTwo (template template parameter) -/// -/// @details -/// The interaction energy can be set for pairs of monomer-types A,B, where -/// the type can be any integer between 1 and 255. -/// The feature automatically adds FeatureExcludedVolumeSc -/// to the system. Given an energy E in kT between two types, the interaction potential -/// as a function of the distance d is: -/// - inf d<2 (implicitly through excluded volume) -/// - 4*E d=2 -/// - 2*E d=sqrt(5) -/// - 1*E d=sqrt(6) -/// - 0 d>sqrt(6) -/// . -/// Usage: In the feature list defining Ingredients use this feature as -/// FeatureContactInteractionSc (arbitrary lattices), or as -/// FeatureContactInteractionSc (2**n lattices) -/// The feature adds the bfm-file command !contact_interaction A B E -/// for monomers of types A B with interaction energy of E in kT. - +/** + * @class FeatureContactInteractionSc + * @brief Provides interaction of monomers on distances d<=sqrt(6) for standard BFM + * + * @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or + * FeatureLatticePowerOfTwo (template template parameter) + * + * @details + * The interaction energy can be set for pairs of monomer-types A,B, where + * the type can be any integer between 1 and 255. + * The feature automatically adds FeatureExcludedVolumeSc + * to the system. Given an energy E in kT between two types, the interaction potential + * as a function of the distance d is: + * - inf d<2 (implicitly through excluded volume) + * - 4*E d=2 + * - 2*E d=sqrt(5) + * - 1*E d=sqrt(6) + * - 0 d>sqrt(6) + * . + * Usage: In the feature list defining Ingredients use this feature as + * FeatureContactInteractionSc (arbitrary lattices), or as + * FeatureContactInteractionSc (2**n lattices) + * The feature adds the bfm-file command !contact_interaction A B E + * for monomers of types A B with interaction energy of E in kT. +**/ template class FeatureLatticeType> class FeatureContactInteractionSc:public Feature @@ -166,7 +166,9 @@ class FeatureContactInteractionSc:public Feature ////////////////// IMPLEMENTATION OF MEMBERS ////////////////////////////////// - +/** + * @brief Constructor + **/ template class LatticeClassType> FeatureContactInteractionSc::FeatureContactInteractionSc() { @@ -181,8 +183,13 @@ FeatureContactInteractionSc::FeatureContactInteractionSc() } } - - +/** + * @details Returns true for all moves other than the ones that have specialized versions of this function. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move other than moves with specialized functions. + * @return true (always) + **/ template class LatticeClassType> template bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, @@ -191,7 +198,14 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT return true; } - +/** + * @details calculates the factor for the acceptance probability of the move + * arising from the contact interactions and adds it to the move. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalSc + * @return true (always) + **/ template class LatticeClassType> template bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, @@ -204,6 +218,16 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT return true; } +/** + * @details Because moves of type MoveLocalBcc must not be used with this + * feature, this function always throws an exception when called. The function + * is only implemented for savety purposes. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalBcc + * @throw std::runtime_error + * @return false always throws exception before returning + **/ template class LatticeClassType> template bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, @@ -219,7 +243,15 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT } - +/** + * @details When a new monomer is added to the system, the lattice sites occupied + * by this monomer must be filled with the attribute tag. This function takes care + * of this. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveAddScMonomer + * @throw std::runtime_error if attribute tag is not in range [1,255] + **/ template class LatticeClassType> template void FeatureContactInteractionSc::applyMove(IngredientsType& ing, @@ -230,8 +262,18 @@ void FeatureContactInteractionSc::applyMove(IngredientsType& i VectorInt3 dx(1,0,0); VectorInt3 dy(0,1,0); VectorInt3 dz(0,0,1); - int32_t type=move.getType(); + lattice_value_type type=lattice_value_type(move.getType()); + //the feature is based on a uint8_t lattice, thus the max type must not + //exceed the max value of uint8_t (255) + if(int32_t(type) != move.getType()) + { + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionSc::applyMove(MoveAddScMonomer)\n"; + errormessage<<"Trying to add monomer with type "<maxType=255\n"; + throw std::runtime_error(errormessage.str()); + } + //update lattice ing.setLatticeEntry(pos,type); ing.setLatticeEntry(pos+dx,type); @@ -243,7 +285,15 @@ void FeatureContactInteractionSc::applyMove(IngredientsType& i ing.setLatticeEntry(pos+dz+dx+dy,type); } - +/** + * @details Because moves of type MoveLocalBcc must not be used with this + * feature, this function always throws an exception when called. The function + * is only implemented for savety purposes. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalBcc + * @throw std::runtime_error + **/ template class LatticeClassType> template void FeatureContactInteractionSc::applyMove(const IngredientsType& ing, @@ -257,6 +307,10 @@ void FeatureContactInteractionSc::applyMove(const IngredientsT } +/** + * @tparam IngredientsType The type of the system including all features + * @param [in] ingredients A reference to the IngredientsType - mainly the system + **/ template class LatticeClassType> template void FeatureContactInteractionSc::synchronize(IngredientsType& ingredients) @@ -269,6 +323,14 @@ void FeatureContactInteractionSc::synchronize(IngredientsType& } +/** + * @details If not compiled with DEBUG flag this function only returns the content + * of the lookup table probabilityLookup. If compiled with DEBUG flag it checks + * that the attribute tags typeA, typeB are within the allowed range. + * @param typeA monomer attribute type in range [1,255] + * @param typeB monomer attribute type in range [1,255] + * @throw std::runtime_error In debug mode, if types are not in range [1,255] + **/ template class LatticeClassType> inline double FeatureContactInteractionSc::getProbabilityFactor(int32_t typeA, int32_t typeB) const @@ -289,7 +351,17 @@ inline double FeatureContactInteractionSc::getProbabilityFacto } - +/** + * @details The function is called by the Ingredients class when an object of type Ingredients + * is associated with an object of type FileImport. The export of the Reads is thus + * taken care automatically when it becomes necessary.\n + * Registered Read-In Commands: + * - !contactInteraction + * . + * + * @tparam IngredientsType The type of the system including all features + * @param fileReader File importer for the bfm-file + **/ template class LatticeClassType> template void FeatureContactInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) @@ -299,6 +371,16 @@ void FeatureContactInteractionSc::exportRead(FileImport< Ingre } +/** + * The function is called by the Ingredients class when an object of type Ingredients + * is associated with an object of type AnalyzerWriteBfmFile. The export of the Writes is thus + * taken care automatically when it becomes necessary.\n + * Registered Write-Out Commands: + * - !contact_interaction + * + * @tparam IngredientsType The type of the system including all features + * @param fileWriter File writer for the bfm-file. + */ template class LatticeClassType> template void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const @@ -307,7 +389,15 @@ void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfm fileWriter.registerWrite("!contact_interaction",new WriteContactInteraction(*this)); } - +/** + * @details occupies the lattice with the attribute tags of the monomers + * as this is required to determine the contact interactions in this feature. + * An additional check is performed asserting that the tags are in the range [1,255] + * + * @tparam IngredientsType The type of the system including all features + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @throw std::runtime_error In case a monomer has attribute tag not in [1,255] + **/ template class LatticeClassType> template void FeatureContactInteractionSc::fillLattice(IngredientsType& ingredients) @@ -341,6 +431,18 @@ void FeatureContactInteractionSc::fillLattice(IngredientsType& } +/** + * @details The function calculates the factor for the acceptance probability + * for the local move given as argument. The calculation is based on the lattice + * entries in the vicinity of the monomer to be moved. If the move is accepted, + * 12 new contacts can potentially be made, and 12 contacts are lost. Thus a number + * of 24 lattice positions around the monomer have to be checked. + * + * @tparam IngredientsType The type of the system including all features + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move reference to the local move for which the calculation is performed + * @return acceptance probability factor for the move arising from nearest neighbor contacts + **/ template class LatticeClassType> template double FeatureContactInteractionSc::calculateAcceptanceProbability( @@ -441,7 +543,12 @@ double FeatureContactInteractionSc::calculateAcceptanceProbabi } - +/** + * @param typeA monomer attribute tag in range [1,255] + * @param typeB monomer attribute tag in range [1,255] + * @param interaction energy between typeA and typeB + * @throw std::runtime_error In case typeA or typeB exceed range [1,255] + **/ template class LatticeClassType> void FeatureContactInteractionSc::setContactInteraction(int32_t typeA, int32_t typeB, @@ -465,7 +572,12 @@ void FeatureContactInteractionSc::setContactInteraction(int32_ } } - +/** + * @param typeA monomer attribute tag in range [1,255] + * @param typeB monomer attribute tag in range [1,255] + * @throw std::runtime_error In case typeA or typeB exceed range [1,255] + * @return interaction energy per nearest neighbor contact for typeA,typeB + **/ template class LatticeClassType> double FeatureContactInteractionSc::getContactInteraction(int32_t typeA, int32_t typeB) const @@ -483,6 +595,5 @@ double FeatureContactInteractionSc::getContactInteraction(int3 } -//TODO: rename files, change IO, tests, comments for doxygen #endif /*FEATURE_CONTACT_INTERACTION_H*/ From 5a97e8e3d0b9ac3682ad705120b980368fe74a32 Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Sun, 19 Jun 2016 20:04:58 +0200 Subject: [PATCH 06/16] Renamed files FeatureNNInteraction.h and NNInteractionReadWrite.h into more consisten FeatureContactInteractionSc.h and FeatureContactInteractionReadWrite.h . The latter will also be used in FeatureContactInteractionBcc --- ...eractionReadWrite.h => FeatureContactInteractionReadWrite.h} | 0 .../{FeatureNNInteraction.h => FeatureContactInteractionSc.h} | 2 +- projects/testproject/ChainSimulatorINT/main.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename include/LeMonADE/feature/{NNInteractionReadWrite.h => FeatureContactInteractionReadWrite.h} (100%) rename include/LeMonADE/feature/{FeatureNNInteraction.h => FeatureContactInteractionSc.h} (99%) diff --git a/include/LeMonADE/feature/NNInteractionReadWrite.h b/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h similarity index 100% rename from include/LeMonADE/feature/NNInteractionReadWrite.h rename to include/LeMonADE/feature/FeatureContactInteractionReadWrite.h diff --git a/include/LeMonADE/feature/FeatureNNInteraction.h b/include/LeMonADE/feature/FeatureContactInteractionSc.h similarity index 99% rename from include/LeMonADE/feature/FeatureNNInteraction.h rename to include/LeMonADE/feature/FeatureContactInteractionSc.h index 48c373b..5d4f1be 100644 --- a/include/LeMonADE/feature/FeatureNNInteraction.h +++ b/include/LeMonADE/feature/FeatureContactInteractionSc.h @@ -42,7 +42,7 @@ along with LeMonADE. If not, see . #include #include #include -#include +#include /** * @class FeatureContactInteractionSc diff --git a/projects/testproject/ChainSimulatorINT/main.cpp b/projects/testproject/ChainSimulatorINT/main.cpp index 5df0af0..5994547 100644 --- a/projects/testproject/ChainSimulatorINT/main.cpp +++ b/projects/testproject/ChainSimulatorINT/main.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include int main(int argc, char* argv[]) { From 63f0ec4474057480b904cae6e1936415f19117dc Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Thu, 14 Jul 2016 12:39:36 +0200 Subject: [PATCH 07/16] removed PairInteracton from project. --- .../FeatureContactInteractionReadWrite.h | 1 + .../LeMonADE/feature/FeaturePairInteraction.h | 319 ------------------ 2 files changed, 1 insertion(+), 319 deletions(-) delete mode 100644 include/LeMonADE/feature/FeaturePairInteraction.h diff --git a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h b/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h index 50d9fed..f2601ce 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h +++ b/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h @@ -37,6 +37,7 @@ along with LeMonADE. If not, see . #include #include +#include /** * @class ReadContactInteraction diff --git a/include/LeMonADE/feature/FeaturePairInteraction.h b/include/LeMonADE/feature/FeaturePairInteraction.h deleted file mode 100644 index 6252516..0000000 --- a/include/LeMonADE/feature/FeaturePairInteraction.h +++ /dev/null @@ -1,319 +0,0 @@ -#ifndef FEATURE_PAIR_INTERACTION_H -#define FEATURE_PAIR_INTERACTION_H - - -#include -#include -#include -#include -#include -#include - - -template -class FeaturePairInteraction:public Feature -{ - -public: - typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; - typedef LOKI_TYPELIST_2(FeatureBox,FeatureAttributes) required_features_front; - - FeaturePairInteraction() - :verletSkin(0.0),useVerletList(false),verletListIsOutdated(true){}; - - virtual ~FeaturePairInteraction(){} - - //configureing the potential /////////////////////////////////////////// - Potential& modifyPairPotential(){return potential;} - const Potential& getPairPotential() const {return potential;} - - // configure the verlet list /////////////////////////////////////////// - void setUseVerletList(bool val){useVerletList=val;} - void setVerletSkin(double s){verletSkin=s;} - double getVerletSkin() const {return verletSkin;} - - //for debugging - size_t getVerletListLength() const {return verletList.size();} - - //check- and apply-functions for different types of moves ///////////// - template - bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; - - template - bool checkMove(const IngredientsType& ingredients, MoveLocalBase& move); - - template - bool checkMove(const IngredientsType& ingredients, const MoveAddScMonomer& move) const; - - template - void applyMove(IngredientsType& ing, const MoveBase& move){} - - template - void applyMove(IngredientsType& ingredients,const MoveLocalBase& move); - - template - void synchronize(IngredientsType& ingredients); - - //export read and write functionality ////////////////////////////////// - template - void exportRead(FileImport & fileReader){} - - template - void exportWrite(AnalyzerWriteBfmFile & fileWriter) const{} - - -private: - - // stuff for potential ///////////////////////////////////////////////// - Potential potential; - - // stuff for verlet list /////////////////////////////////////////////// - template - void updateVerletList(const IngredientsType& ingredients); - - bool useVerletList; - bool verletListIsOutdated; - double verletSkin; - - std::vector verletList; - std::map verletNeigborsMap; - std::map verletIndexMap; - std::map movedDistanceSinceListUpdate; - - - -}; - - -/////////////////////////////////////////////////////////////////////////////// - - -template -template -bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, const MoveBase& move) const -{ - return true; -} - -template -template -bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, const MoveAddScMonomer& move) const -{ - VectorInt3 myPos=move.getPosition(); - int32_t myType=move.getType(); - - for(size_t n=0;n::infinity()) return false; - } - - //if still here we reuturn true - return true; -} - -template -template -bool FeaturePairInteraction::checkMove(const IngredientsType& ingredients, MoveLocalBase& move) -{ - - if (useVerletList==false) - { - - double exp_oldEnergy=1.0; - double exp_newEnergy=1.0; - - size_t myIdx=move.getIndex(); - VectorInt3 myPos=ingredients.getMolecules()[myIdx]; - VectorInt3 myPosPlusDelta=ingredients.getMolecules()[myIdx]+move.getDir(); - int32_t myType=ingredients.getMolecules()[myIdx].getAttributeTag(); - - for(size_t monoIdx=0;monoIdx::infinity()) return false; - - exp_oldEnergy*=potential.getExpEnergy(myPos,monoPos,myType,monoType,ingredients); - exp_newEnergy*=potential.getExpEnergy(myPosPlusDelta,monoPos,myType,monoType,ingredients); - - } - } - - double moveProb=exp_newEnergy/exp_oldEnergy; - move.multiplyProbability( moveProb); - return true; - } - else //if useVerletList==true - { - if(verletListIsOutdated==true) - { - updateVerletList(ingredients); - verletListIsOutdated=false; - } - - double exp_oldEnergy=1.0; - double exp_newEnergy=1.0; - - double oldEnergy=0.0; - double newEnergy=0.0; - size_t myIdx=move.getIndex(); - VectorInt3 myPos=ingredients.getMolecules()[myIdx]; - VectorInt3 myPosPlusDelta=ingredients.getMolecules()[myIdx]+move.getDir(); - int32_t myType=ingredients.getMolecules()[myIdx].getAttributeTag(); - - - size_t numberOfNeighbors=verletNeigborsMap[myIdx]; - size_t verletListIndex=verletIndexMap[myIdx]; - size_t neighborIndex; - int32_t neighborType; - - for(size_t n=0;n::infinity()) return false; - - exp_oldEnergy*=potential.getExpEnergy(myPos,neighborPos,myType,neighborType,ingredients); - - exp_newEnergy*=potential.getExpEnergy(myPosPlusDelta,neighborPos,myType,neighborType,ingredients); - - } - - double moveProb=exp_newEnergy/exp_oldEnergy; - - move.multiplyProbability( moveProb); - return true; - } -} - - -template -template -void FeaturePairInteraction::applyMove(IngredientsType& ing, const MoveLocalBase& move) -{ - - if(useVerletList==true) - { - - movedDistanceSinceListUpdate[move.getIndex()]+=move.getDir(); - - double distanceMovedSquared=double(movedDistanceSinceListUpdate[move.getIndex()]*movedDistanceSinceListUpdate[move.getIndex()]); - if(distanceMovedSquared >= verletSkin*verletSkin/4.0) - { - verletListIsOutdated=true; - } - - } -} - -template -template -void FeaturePairInteraction::synchronize(IngredientsType& ingredients) -{ - - potential.synchronize(ingredients); - - - if(useVerletList==true) - { - std::cout<<"FeaturePairInteraction::synchronize()...start setting up Verlet list...\n"; - updateVerletList(ingredients); - verletListIsOutdated=false; - std::cout<<"FeaturePairInteraction::synchronize()...done setting up Verlet list...\n"; - } - else - { - verletIndexMap.clear(); - verletNeigborsMap.clear(); - movedDistanceSinceListUpdate.clear(); - verletList.clear(); - } - - for(size_t n=0;n -template -void FeaturePairInteraction::updateVerletList(const IngredientsType& ingredients) -{ - - //reset all list related containers - verletIndexMap.clear(); - verletNeigborsMap.clear(); - movedDistanceSinceListUpdate.clear(); - verletList.clear(); - - - VectorInt3 distanceVector, posN,posM; - - double verletListRadiusSquared=(potential.getRange()+verletSkin)*(potential.getRange()+verletSkin); - - size_t neighborCount=0; - - for(size_t n=0;n0) - { - verletIndexMap.insert(std::make_pair(n,verletList.size()-neighborCount)); - } - - neighborCount=0; - - movedDistanceSinceListUpdate.insert(std::make_pair(n,VectorInt3(0,0,0))); - } - -} - - - -#endif // FEATURE From 3f9c330b39b981f0c800f7bbbf6e83611c2265c7 Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Thu, 14 Jul 2016 14:54:19 +0200 Subject: [PATCH 08/16] added contact interaction feature for bcc bfm. tests still missing. --- .../feature/FeatureContactInteractionBcc.h | 603 ++++++++++++++++++ 1 file changed, 603 insertions(+) create mode 100644 include/LeMonADE/feature/FeatureContactInteractionBcc.h diff --git a/include/LeMonADE/feature/FeatureContactInteractionBcc.h b/include/LeMonADE/feature/FeatureContactInteractionBcc.h new file mode 100644 index 0000000..d3aca80 --- /dev/null +++ b/include/LeMonADE/feature/FeatureContactInteractionBcc.h @@ -0,0 +1,603 @@ +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers (see AUTHORS) + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + + +#ifndef FEATURE_CONTACT_INTERACTION_BCC_H +#define FEATURE_CONTACT_INTERACTION_BCC_H + +/** + * @file + * @date 2016/06/18 + * @author Hauke Rabbel + * @brief Definition and implementation of class template FeatureContactInteractionBcc + * + * @todo MoveAddBccMonomer is used here, which might be obsolete. +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @class FeatureContactInteractionBcc + * @brief Provides interaction of monomers on distances d<=sqrt(12)a for bccBFM + * + * @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or + * FeatureLatticePowerOfTwo (template template parameter) + * + * @details + * The interaction energy can be set for pairs of monomer-types A,B, where + * the type can be any integer between 1 and 255. + * The feature automatically adds FeatureExcludedVolumeBcc + * to the system. Given an energy E in kT between two types, the interaction potential + * as a function of the distance d is: + * - inf d < sqrt(3) (implicitly through excluded volume) + * - E sqrt(3)< d <= sqrt(12) + * - 0 d>sqrt(12) + * . + * Usage: In the feature list defining Ingredients use this feature as + * FeatureContactInteractionBcc (arbitrary lattices), or as + * FeatureContactInteractionBcc (2**n lattices) + * The feature adds the bfm-file command !contact_interaction A B E + * for monomers of types A B with interaction energy of E in kT. +**/ + +template class FeatureLatticeType> +class FeatureContactInteractionBcc:public Feature +{ + +private: + //! Type for the underlying lattice, used as template parameter for FeatureLatticeType<...> + typedef uint8_t lattice_value_type; + + //! Interaction energies between monomer types. Max. type=255 given by max(uint8_t)=255 + double interactionTable[256][256]; + + //! Lookup table for exp(-interactionTable[a][b]) + double probabilityLookup[256][256]; + + //! Returns this feature's factor for the acceptance probability for the given Monte Carlo move + template + double calculateAcceptanceProbability(const IngredientsType& ingredients, + const MoveLocalBcc& move) const; + + //! Occupies the lattice with the attribute tags of all monomers + template + void fillLattice(IngredientsType& ingredients); + + //! Access to array probabilityLookup with extra checks in Debug mode + double getProbabilityFactor(int32_t typeA,int32_t typeB) const; + + +public: + + FeatureContactInteractionBcc(); + ~FeatureContactInteractionBcc(){} + + + //This feature adds interaction energies, so it requires FeatureBoltzmann + typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; + + //FeatureExcludedVolumeSc needs to be in front, because FeatureContactInteractionBcc + //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written. + //FeatureAttributes needs to be in front, because when a monomer is added to the system + //by a MoveAddScMonomer, its attribute has to be set before it is written to the lattice. + typedef LOKI_TYPELIST_2( + FeatureAttributes, + FeatureExcludedVolumeBcc >) + required_features_front; + + + //! check for all Monte Carlo moves without special check functions (always true) + template + bool checkMove(const IngredientsType& ingredients,const MoveBase& move) const; + + //! check move for bcc-BFM local move. always throws std::runtime_error + template + bool checkMove(const IngredientsType& ingredients,const MoveLocalSc& move) const; + + //! check move for bcc-BFM local move + template + bool checkMove(const IngredientsType& ingredients,MoveLocalBcc& move) const; + + //! apply function for all Monte Carlo moves without special apply functions (does nothing) + template + void applyMove(const IngredientsType& ing, const MoveBase& move){} + + //! apply function for sc-BFM local move (always throws std::runtime_error) + template + void applyMove(const IngredientsType& ing, const MoveLocalSc& move); + + //! apply function for adding a monomer in bcc-BFM + template + void applyMove(IngredientsType& ing, const MoveAddBccMonomer& move); + + //note: apply function for bcc-BFM local move is not necessary, because + //job of moving lattice entries is done by the underlying FeatureLatticeType + + //! guarantees that the lattice is properly occupied with monomer attributes + template + void synchronize(IngredientsType& ingredients); + + //!adds interaction energy between two types of monomers + void setContactInteraction(int32_t typeA,int32_t typeB,double energy); + + //!returns the interaction energy between two types of monomers + double getContactInteraction(int32_t typeA,int32_t typeB) const; + + //!export bfm-file read command !contact_interaction + template + void exportRead(FileImport & fileReader); + + //!export bfm-file write command !contact_interaction + template + void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; + +}; + + +////////////////// IMPLEMENTATION OF MEMBERS ////////////////////////////////// + +/** + * @brief Constructor + **/ +template class LatticeClassType> +FeatureContactInteractionBcc::FeatureContactInteractionBcc() +{ + //initialize the energy and probability lookups with default values + for(size_t n=0;n<256;n++) + { + for(size_t m=0;m<256;m++) + { + interactionTable[m][n]=0.0; + probabilityLookup[m][n]=1.0; + } + } +} + +/** + * @details Returns true for all moves other than the ones that have specialized versions of this function. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move other than moves with specialized functions. + * @return true (always) + **/ +template class LatticeClassType> +template +bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, + const MoveBase& move) const +{ + return true; +} + +/** + * @details calculates the factor for the acceptance probability of the move + * arising from the contact interactions and adds it to the move. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalSc + * @return true (always) + **/ +template class LatticeClassType> +template +bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, + MoveLocalBcc& move) const +{ + //add the probability factor coming from this feature, then return true, + //because the total probability is evaluated by FeatureBoltzmann at the end + double prob=calculateAcceptanceProbability(ingredients,move); + move.multiplyProbability(prob); + return true; +} + +/** + * @details Because moves of type MoveLocalSc must not be used with this + * feature, this function always throws an exception when called. The function + * is only implemented for savety purposes. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalBcc + * @throw std::runtime_error + * @return false always throws exception before returning + **/ +template class LatticeClassType> +template +bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, + const MoveLocalSc& move) const +{ + //throw exception in case someone accidentaly uses a bcc-BFM move with this feature + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionBcc::checkMove(...):\n"; + errormessage<<"attempting to use sc-BFM move, which is not allowed\n"; + throw std::runtime_error(errormessage.str()); + + return false; +} + + +/** + * @details When a new monomer is added to the system, the lattice site occupied + * by this monomer must be filled with the attribute tag. This function takes care + * of this. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveAddBccMonomer + * @throw std::runtime_error if attribute tag is not in range [1,255] + **/ +template class LatticeClassType> +template +void FeatureContactInteractionBcc::applyMove(IngredientsType& ing, + const MoveAddBccMonomer& move) +{ + //get the position and attribute tag of the monomer to be inserted + VectorInt3 pos=move.getPosition(); + lattice_value_type type=lattice_value_type(move.getType()); + + //the feature is based on a uint8_t lattice, thus the max type must not + //exceed the max value of uint8_t (255) + if(int32_t(type) != move.getType()) + { + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionBcc::applyMove(MoveAddBccMonomer)\n"; + errormessage<<"Trying to add monomer with type "<maxType=255\n"; + throw std::runtime_error(errormessage.str()); + } + + //update lattice + ing.setLatticeEntry(pos,type); +} + +/** + * @details Because moves of type MoveLocalSc must not be used with this + * feature, this function always throws an exception when called. The function + * is only implemented for savety purposes. + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move Monte Carlo move of type MoveLocalSc + * @throw std::runtime_error + **/ +template class LatticeClassType> +template +void FeatureContactInteractionBcc::applyMove(const IngredientsType& ing, + const MoveLocalSc& move) +{ + //throw exception in case someone accidentaly uses a sc-BFM move with this feature + std::stringstream errormessage; + errormessage<<"FeatureContactInteractionBcc::applyMove(...):\n"; + errormessage<<"attempting to use sc-BFM move, which is not allowed\n"; + throw std::runtime_error(errormessage.str()); + +} + +/** + * @tparam IngredientsType The type of the system including all features + * @param [in] ingredients A reference to the IngredientsType - mainly the system + **/ +template class LatticeClassType> +template +void FeatureContactInteractionBcc::synchronize(IngredientsType& ingredients) +{ + + //refill the lattice with attribute tags + //caution: this overwrites, what is currently written on the lattice + fillLattice(ingredients); + +} + + +/** + * @details If not compiled with DEBUG flag this function only returns the content + * of the lookup table probabilityLookup. If compiled with DEBUG flag it checks + * that the attribute tags typeA, typeB are within the allowed range. + * @param typeA monomer attribute type in range [1,255] + * @param typeB monomer attribute type in range [1,255] + * @throw std::runtime_error In debug mode, if types are not in range [1,255] + **/ +template class LatticeClassType> +inline double FeatureContactInteractionBcc::getProbabilityFactor(int32_t typeA, + int32_t typeB) const +{ +#ifdef DEBUG + //extra checks only in debug mode, because this is very frequently called + //and this costs performance + if(typeA<0 || typeA>255 || typeB<0 || typeB>255){ + std::stringstream errormessage; + errormessage<<"***FeatureContactInteractionBcc::getInteraction(typeA,typeB)***\n"; + errormessage<<"probability undefined between types "< class LatticeClassType> +template +void FeatureContactInteractionBcc::exportRead(FileImport< IngredientsType >& fileReader) +{ + typedef FeatureContactInteractionBcc my_type; + fileReader.registerRead("!contact_interaction",new ReadContactInteraction(*this)); +} + + +/** + * The function is called by the Ingredients class when an object of type Ingredients + * is associated with an object of type AnalyzerWriteBfmFile. The export of the Writes is thus + * taken care automatically when it becomes necessary.\n + * Registered Write-Out Commands: + * - !contact_interaction + * + * @tparam IngredientsType The type of the system including all features + * @param fileWriter File writer for the bfm-file. + */ +template class LatticeClassType> +template +void FeatureContactInteractionBcc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +{ + typedef FeatureContactInteractionBcc my_type; + fileWriter.registerWrite("!contact_interaction",new WriteContactInteraction(*this)); +} + +/** + * @details occupies the lattice with the attribute tags of the monomers + * as this is required to determine the contact interactions in this feature. + * An additional check is performed asserting that the tags are in the range [1,255] + * + * @tparam IngredientsType The type of the system including all features + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @throw std::runtime_error In case a monomer has attribute tag not in [1,255] + **/ +template class LatticeClassType> +template +void FeatureContactInteractionBcc::fillLattice(IngredientsType& ingredients) +{ + const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); + + for(size_t n=0;n class LatticeClassType> +template +double FeatureContactInteractionBcc::calculateAcceptanceProbability( + const IngredientsType& ingredients, + const MoveLocalBcc& move) const +{ + + VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; + VectorInt3 direction=move.getDir(); + + double prob=1.0; + int32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); + + //get three directions that define which lattice sites have to be checked + //these directions are v1=(2*deltaX,0,0), v2=(0,2*deltaY,0), v3=(0,0,2*deltaZ) + //the idea is that the relative positions v1,v1+v2,v1+v3,... do not have to + //be checked here, as they cannot be occupied due to excluded volume restrictions + VectorInt3 v1(2*direction.getX(),0,0); + VectorInt3 v2(0,2*direction.getY(),0); + VectorInt3 v3(0,0,2*direction.getZ()); + + + //the probability is calculated by going through all possible lattice sites + //at which the contacts may have changed. At every site the type of the + //monomer sitting there is retrieved from the lattice. the additional + //factor for the probability (exp(-deltaE/kT)) is retrieved from the + //lookup using getProbabilityFactor. For new contacts this factor is multiplied + //with the probability, for contacts taken away the probability is devided. + VectorInt3 actual=oldPos; + + actual-=v2; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v2; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v2; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + + //now check back side (contacts taken away) + //again, not the complete contact shell has to be checked. the sites + //-v1,-v1-v2,-v1-v3,... relative to the new position cannot be occupied + //because they were previously blocked by the excluded volume of the monomer + //to be moved. + double prob_div=1.0; + actual=oldPos+direction; + + actual+=v2; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v2; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v2; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual+=v1; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + actual-=v3; + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + + prob/=prob_div; + return prob; + +} + +/** + * @param typeA monomer attribute tag in range [1,255] + * @param typeB monomer attribute tag in range [1,255] + * @param interaction energy between typeA and typeB + * @throw std::runtime_error In case typeA or typeB exceed range [1,255] + **/ +template class LatticeClassType> +void FeatureContactInteractionBcc::setContactInteraction(int32_t typeA, + int32_t typeB, + double energy) +{ + if(0 class LatticeClassType> +double FeatureContactInteractionBcc::getContactInteraction(int32_t typeA, + int32_t typeB) const +{ + + if(0 Date: Fri, 12 Aug 2016 12:21:04 +0200 Subject: [PATCH 09/16] initial commit on FeatureWall with original code from Cornelia S --- include/LeMonADE/feature/FeatureWall.h | 310 ++++++++++++++++++++++++ tests/feature/TestFeatureWall.cpp | 315 +++++++++++++++++++++++++ 2 files changed, 625 insertions(+) create mode 100644 include/LeMonADE/feature/FeatureWall.h create mode 100644 tests/feature/TestFeatureWall.cpp diff --git a/include/LeMonADE/feature/FeatureWall.h b/include/LeMonADE/feature/FeatureWall.h new file mode 100644 index 0000000..325f055 --- /dev/null +++ b/include/LeMonADE/feature/FeatureWall.h @@ -0,0 +1,310 @@ +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers (see AUTHORS) + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + +#ifndef LEMONADE_FEATURE_WALL_H +#define LEMONADE_FEATURE_WALL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +//#include +#include +#include + + + +class Wall +{ + +public: + + Wall(): base(), normal() {} + + const VectorInt3 getBase() const { + return base; + } + + VectorInt3 setBase(uint32_t basX_, uint32_t basY_, uint32_t basZ_) { + base.setAllCoordinates(basX_,basY_,basZ_); + } + + const VectorInt3 getNormal() const { + return normal; + } + + VectorInt3 setNormal(uint32_t norX_, uint32_t norY_, uint32_t norZ_) { + normal.setAllCoordinates(norX_,norY_,norZ_); + } + +private: + + VectorInt3 base; + + VectorInt3 normal; + +}; + + + +class FeatureWall: public Feature +{ +public: + + //constructor + FeatureWall() {} + + //destructor + virtual ~FeatureWall(){} + + //read and write wall in/from bfm-file + template + void exportRead(FileImport& fileReader); + + template + void exportWrite(AnalyzerWriteBfmFile& fileWriter) const; + + //checks if move is allowed by the Metropolis-criterion. + template + bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move); + + template + bool checkMove(const IngredientsType& ingredients,MoveAddScMonomer& addmove); + + template + void synchronize(const IngredientsType& ingredients); + + std::vector getWalls() const + { + return walls; + } + + void addWall(Wall wall) + { + walls.push_back(wall); + } + + void clearAllWalls() + { + walls.clear(); + } + + +private: + + std::vector walls; + +}; + + + +template +class WriteWall: public AbstractWrite +{ + public: + + WriteWall(const IngredientsType& src):AbstractWrite(src){this->setHeaderOnly(true);} + + void writeStream(std::ostream& strm) + { + const IngredientsType& ingredients=(this->getSource()); + + for (size_t i=0; i +class ReadWall : public ReadToDestination < IngredientsType > +{ + public: + + ReadWall(IngredientsType& destination):ReadToDestination< IngredientsType > (destination){} + + void execute(); +}; + + + + + + + +/* checkMove */ + +template +bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) +{ + uint32_t counter(0); + + for (size_t i = 0; i < ingredients.getWalls().size(); i++) { //check all walls in the system + + uint8_t direction; + VectorInt3 unitX(1,0,0); + VectorInt3 unitY(0,1,0); + VectorInt3 unitZ(0,0,1); + + if (ingredients.getWalls()[i].getNormal() == unitX) { direction = 0; } //points direction of normal and sets variable direction to look only on this part of the new position vector later + if (ingredients.getWalls()[i].getNormal() == unitY) { direction = 1; } + if (ingredients.getWalls()[i].getNormal() == unitZ) { direction = 2; } + + if ((ingredients.getMolecules()[move.getIndex()] + move.getDir()).getCoordinate(direction) != ingredients.getWalls()[i].getBase().getCoordinate(direction)-1) { //if new position has NOT the same value in "direction" as the wall -1, permit the move + counter++; + } + } + + if (counter == ingredients.getWalls().size()) {return true;} + + return false; +} + + + +/* checkMove for addmove */ + +template +bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveAddScMonomer& addmove) +{ + uint32_t counter(0); + + for (size_t i = 0; i < ingredients.getWalls().size(); i++) { //check all walls in the system + + uint8_t direction; + VectorInt3 unitX(1,0,0); + VectorInt3 unitY(0,1,0); + VectorInt3 unitZ(0,0,1); + + if (ingredients.getWalls()[i].getNormal() == unitX) { direction = 0; } //points direction of normal and sets variable direction to look only on this part of the new position vector later + if (ingredients.getWalls()[i].getNormal() == unitY) { direction = 1; } + if (ingredients.getWalls()[i].getNormal() == unitZ) { direction = 2; } + + if (addmove.getPosition().getCoordinate(direction) != ingredients.getWalls()[i].getBase().getCoordinate(direction)-1) { //if new molecule has NOT the same value in "direction" as the wall -1, permit the move + counter++; + } + } + + if (counter == ingredients.getWalls().size()) {return true;} + + return false; +} + + + + + +/* synchronize */ + +template +void FeatureWall::synchronize(const IngredientsType& ingredients) +{ + uint8_t direction; + VectorInt3 unitX(1,0,0); + VectorInt3 unitY(0,1,0); + VectorInt3 unitZ(0,0,1); + + for (size_t i=0; i +void ReadWall::execute() +{ + std::cout << "reading #!wall..."; + + + uint32_t baseX, baseY, baseZ, normalX, normalY, normalZ; + + this->getInputStream() >> baseX >> baseY >> baseZ >> normalX >> normalY >> normalZ; + + if(!this->getInputStream().fail()) + { + Wall wall; + wall.setBase(baseX,baseY,baseZ); + wall.setNormal(normalX,normalY,normalZ); + this->getDestination().addWall(wall); + + std::cout << "Base: " << baseX << " " << baseY << " " << baseZ << ", Normal: " << normalX << " " << normalY << " " << normalZ << std::endl; + } + else + throw std::runtime_error("ReadWall::execute()\n Could not read wall"); +} + + + +/* exportRead wall */ + +template < class IngredientsType > +void FeatureWall::exportRead(FileImport& fileReader) +{ + IngredientsType& destination=fileReader.getDestination(); + fileReader.registerRead("#!wall:", new ReadWall< IngredientsType > (destination)); +} + + + +/* exportWrite wall */ + +template < class IngredientsType > +void FeatureWall::exportWrite(AnalyzerWriteBfmFile& fileWriter) const +{ + const IngredientsType& source=fileWriter.getIngredients_(); + fileWriter.registerWrite("#!wall:", new WriteWall (source)); +} + + + +#endif //LEMONADE_FEATURE_WALL_H diff --git a/tests/feature/TestFeatureWall.cpp b/tests/feature/TestFeatureWall.cpp new file mode 100644 index 0000000..a7f37ce --- /dev/null +++ b/tests/feature/TestFeatureWall.cpp @@ -0,0 +1,315 @@ +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers (see AUTHORS) + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + +#include +#include + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include + + + +class TestFeatureWall: public ::testing::Test{ +public: + //redirect cout output + virtual void SetUp(){ + originalBuffer=std::cout.rdbuf(); + std::cout.rdbuf(tempStream.rdbuf()); + }; + + //restore original output + virtual void TearDown(){ + std::cout.rdbuf(originalBuffer); + }; + +private: + std::streambuf* originalBuffer; + std::ostringstream tempStream; +}; + + + + +TEST(TestFeatureWall,Moves) +{ + + typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureWall) Features; + + typedef ConfigureSystem Config; + typedef Ingredients IngredientsType; + IngredientsType ingredients; + + //prepare ingredients + ingredients.setBoxX(32); + ingredients.setBoxY(32); + ingredients.setBoxZ(32); + ingredients.setPeriodicX(1); + ingredients.setPeriodicY(1); + ingredients.setPeriodicZ(1); + + //one move of every type + MoveLocalSc scmove; + MoveAddScMonomer addmove; + + ingredients.modifyMolecules().resize(3); + ingredients.modifyMolecules()[0].setAllCoordinates(0,0,0); + ingredients.modifyMolecules()[1].setAllCoordinates(2,0,0); + ingredients.modifyMolecules()[2].setAllCoordinates(2,2,0); + + EXPECT_NO_THROW(ingredients.synchronize(ingredients)); + + + //************ scmove *************** + + //build wall in y-z-plane at x=2 -> x=1 should be forbidden + Wall wall1; + wall1.setBase(2,0,0); + wall1.setNormal(1,0,0); + ingredients.addWall(wall1); +/* + std::cout << "getWalls(): " << ingredients.getWalls()[0].getBase().getX() << " " << ingredients.getWalls()[0].getBase().getY() << " " << ingredients.getWalls()[0].getBase().getZ() << " " << ingredients.getWalls()[0].getNormal().getX() << " " << ingredients.getWalls()[0].getNormal().getY() << " " << ingredients.getWalls()[0].getNormal().getZ() << std::endl; +*/ + + //check monomer 0 movement to backside of wall + while((scmove.getDir().getX()!=1) || (scmove.getIndex()!=0)) scmove.init(ingredients); //init(ingredients) searches randomly one monomer in ingredients and one direction for the move -> while you have not the right monomer and the prefered direction, keep on searching randomly + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check monomer 1 movement to frontside of wall + while((scmove.getDir().getX()!=-1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check monomer 2 movement to frontside of wall + while((scmove.getDir().getX()!=-1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 0 movements + while((scmove.getDir().getX()==1) || (scmove.getIndex()!=0)) scmove.init(ingredients); //search randomly for any direction except direction to the wall (x=1) for monomer 0 + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 1 movements + while((scmove.getDir().getX()==-1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 2 movements + while((scmove.getDir().getX()==-1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + + + //build additional wall in x-z-plane at y=2 -> x=1 and y=1 should be forbidden now + Wall wall2; + wall2.setBase(0,2,0); + wall2.setNormal(0,1,0); + ingredients.addWall(wall2); +/* + for(size_t i=0; i< ingredients.getWalls().size(); i++){ + std::cout << "getWalls()[" << i << "]: " << ingredients.getWalls()[i].getBase().getX() << " " << ingredients.getWalls()[i].getBase().getY() << " " << ingredients.getWalls()[i].getBase().getZ() << " " << ingredients.getWalls()[i].getNormal().getX() << " " << ingredients.getWalls()[i].getNormal().getY() << " " << ingredients.getWalls()[i].getNormal().getZ() << std::endl; + } +*/ + //check monomer 0 movement to backside of both walls + while((scmove.getDir().getY()!=1) || (scmove.getIndex()!=0)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check monomer 1 movement to frontside of wall1 and backside of wall2 + while((scmove.getDir().getY()!=1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check monomer 2 movement to frontside of both walls + while((scmove.getDir().getY()!=-1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 0 movements + while((scmove.getDir().getX()==1) || (scmove.getDir().getY()==1) || (scmove.getIndex()!=0)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 1 movements + while((scmove.getDir().getX()==-1) || (scmove.getDir().getY()==1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 2 movements + while((scmove.getDir().getX()==-1) || (scmove.getDir().getY()==-1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + + + ingredients.clearAllWalls(); + + //add former wall1 again + ingredients.addWall(wall1); + + //build second wall in y-z-plane at x=4 -> x=3 should be forbidden + Wall wall3; + wall3.setBase(4,0,0); + wall3.setNormal(1,0,0); + ingredients.addWall(wall3); + + //check monomer 1 movement to backside of wall3 (wall1 was already checked above) + while((scmove.getDir().getX()!=1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check monomer 2 movement to backside of wall3 + while((scmove.getDir().getX()!=1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_FALSE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 1 movements + while((scmove.getDir().getX()==-1) || (scmove.getDir().getX()==1) || (scmove.getIndex()!=1)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + //check possible monomer 2 movements + while((scmove.getDir().getX()==-1) || (scmove.getDir().getX()==1) || (scmove.getIndex()!=2)) scmove.init(ingredients); + EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); + + + + + //************ addmove *************** + + ingredients.clearAllWalls(); + + //add former walls again + ingredients.addWall(wall1); + ingredients.addWall(wall2); + ingredients.addWall(wall3); + + //create random system and check it by synchronize + std::cout << "create random config by addmove and check by snychronize"< Config; + typedef Ingredients IngredientsType; + IngredientsType ingredients1; //to write bfm-file + + typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureWall) Features; + typedef ConfigureSystem Config; + typedef Ingredients IngredientsType; + IngredientsType ingredients2; //to read bfm-file + + //prepare ingredients1 to write bfm-file + ingredients1.setBoxX(32); + ingredients1.setBoxY(32); + ingredients1.setBoxZ(32); + ingredients1.setPeriodicX(1); + ingredients1.setPeriodicY(1); + ingredients1.setPeriodicZ(1); + + Wall wall4; + wall4.setBase(5,0,0); + wall4.setNormal(1,0,0); + ingredients1.addWall(wall4); + + Wall wall5; + wall5.setBase(0,4,0); + wall5.setNormal(0,1,0); + ingredients1.addWall(wall5); + + EXPECT_NO_THROW(ingredients1.synchronize()); + + TaskManager taskmanager; + taskmanager.addAnalyzer(new AnalyzerWriteBfmFile("test_wall.bfm",ingredients1,AnalyzerWriteBfmFile::NEWFILE)); + + taskmanager.initialize(); + taskmanager.run(); + taskmanager.cleanup(); + + TaskManager taskmanager1; + taskmanager1.addUpdater(new UpdaterReadBfmFile("test_wall.bfm",ingredients2,UpdaterReadBfmFile::READ_LAST_CONFIG_SAVE)); + + taskmanager1.initialize(); + taskmanager1.run(); + taskmanager1.cleanup(); + + remove("test_wall.bfm"); + + EXPECT_TRUE(ingredients1.getWalls()[0].getBase().getX()==ingredients2.getWalls()[0].getBase().getX()); + EXPECT_TRUE(ingredients1.getWalls()[1].getBase().getX()==ingredients2.getWalls()[1].getBase().getX()); + + EXPECT_NO_THROW(ingredients1.synchronize()); + EXPECT_NO_THROW(ingredients2.synchronize()); + +} From 42fb9756f4cfc26bb3fd9587d3d7b9f32de43fda Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Mon, 10 Oct 2016 18:12:15 +0200 Subject: [PATCH 10/16] * bugfix in WriteContactInteraction leading to missing file output * extra check for attributeTag>0 in applyMove(MoveAddScMonomer) of interaction feature * finished FeatureContactInteractionBcc * added tests for FeatureContactInteractionSc/Bcc --- .../feature/FeatureContactInteractionBcc.h | 85 +- .../FeatureContactInteractionReadWrite.h | 2 +- .../feature/FeatureContactInteractionSc.h | 2 +- include/LeMonADE/feature/FeatureMoleculesIO.h | 2 + .../TestFeatureContactInteractionBcc.cpp | 1192 +++++++++ .../TestFeatureContactInteractionSc.cpp | 2370 +++++++++++++++++ 6 files changed, 3608 insertions(+), 45 deletions(-) create mode 100644 tests/feature/TestFeatureContactInteractionBcc.cpp create mode 100644 tests/feature/TestFeatureContactInteractionSc.cpp diff --git a/include/LeMonADE/feature/FeatureContactInteractionBcc.h b/include/LeMonADE/feature/FeatureContactInteractionBcc.h index d3aca80..df1a005 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionBcc.h +++ b/include/LeMonADE/feature/FeatureContactInteractionBcc.h @@ -264,7 +264,7 @@ void FeatureContactInteractionBcc::applyMove(IngredientsType& //the feature is based on a uint8_t lattice, thus the max type must not //exceed the max value of uint8_t (255) - if(int32_t(type) != move.getType()) + if(int32_t(type) != move.getType() || int32_t(type)==0) { std::stringstream errormessage; errormessage<<"FeatureContactInteractionBcc::applyMove(MoveAddBccMonomer)\n"; @@ -435,8 +435,6 @@ double FeatureContactInteractionBcc::calculateAcceptanceProbab VectorInt3 oldPos=ingredients.getMolecules()[move.getIndex()]; VectorInt3 direction=move.getDir(); - - double prob=1.0; int32_t monoType=ingredients.getMolecules()[move.getIndex()].getAttributeTag(); //get three directions that define which lattice sites have to be checked @@ -455,92 +453,93 @@ double FeatureContactInteractionBcc::calculateAcceptanceProbab //lookup using getProbabilityFactor. For new contacts this factor is multiplied //with the probability, for contacts taken away the probability is devided. VectorInt3 actual=oldPos; - + double prob_div=1.0; + actual-=v2; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v2; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v2; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); //now check back side (contacts taken away) //again, not the complete contact shell has to be checked. the sites //-v1,-v1-v2,-v1-v3,... relative to the new position cannot be occupied //because they were previously blocked by the excluded volume of the monomer //to be moved. - double prob_div=1.0; + double prob=1.0; actual=oldPos+direction; actual+=v2; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v2; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v2; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual+=v1; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); actual-=v3; - prob_div*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); + prob*=getProbabilityFactor(monoType,int32_t(ingredients.getLatticeEntry(actual))); prob/=prob_div; return prob; diff --git a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h b/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h index f2601ce..b4b471a 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h +++ b/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h @@ -127,7 +127,7 @@ void WriteContactInteraction::writeStream(std::ostream& stream) for(int32_t typeA=1;typeA<=nSpecies;typeA++) { - for(int32_t typeB=1;typeBgetSource().getContactInteraction(typeA,typeB)!=0.0) { diff --git a/include/LeMonADE/feature/FeatureContactInteractionSc.h b/include/LeMonADE/feature/FeatureContactInteractionSc.h index 5d4f1be..764644d 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionSc.h +++ b/include/LeMonADE/feature/FeatureContactInteractionSc.h @@ -266,7 +266,7 @@ void FeatureContactInteractionSc::applyMove(IngredientsType& i //the feature is based on a uint8_t lattice, thus the max type must not //exceed the max value of uint8_t (255) - if(int32_t(type) != move.getType()) + if(int32_t(type) != move.getType() || int32_t(type)==0) { std::stringstream errormessage; errormessage<<"FeatureContactInteractionSc::applyMove(MoveAddScMonomer)\n"; diff --git a/include/LeMonADE/feature/FeatureMoleculesIO.h b/include/LeMonADE/feature/FeatureMoleculesIO.h index 8ffa6d0..2ecc667 100644 --- a/include/LeMonADE/feature/FeatureMoleculesIO.h +++ b/include/LeMonADE/feature/FeatureMoleculesIO.h @@ -28,6 +28,8 @@ along with LeMonADE. If not, see . #ifndef LEMONADE_FEATURE_FEATUREMOLECULESIO_H #define LEMONADE_FEATURE_FEATUREMOLECULESIO_H +#include + #include #include #include diff --git a/tests/feature/TestFeatureContactInteractionBcc.cpp b/tests/feature/TestFeatureContactInteractionBcc.cpp new file mode 100644 index 0000000..b45b988 --- /dev/null +++ b/tests/feature/TestFeatureContactInteractionBcc.cpp @@ -0,0 +1,1192 @@ +#include + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class ContactInteractionBccTest: public ::testing::Test{ + /* suppress cout output for better readability -->un-/comment here:*/ +public: + //redirect cout output + virtual void SetUp(){ + originalBuffer=cout.rdbuf(); + cout.rdbuf(tempStream.rdbuf()); + }; + //restore original output + virtual void TearDown(){ + cout.rdbuf(originalBuffer); + }; +private: + std::streambuf* originalBuffer; + std::ostringstream tempStream; + /* ** */ +}; + + +TEST_F(ContactInteractionBccTest,CheckApplyBccMovePowerOfTwoLattice) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + + + //prepare myIngredients1 + myIngredients1.setBoxX(64); + myIngredients1.setBoxY(64); + myIngredients1.setBoxZ(64); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + //set interaction between types 1,2 + myIngredients1.setContactInteraction(1,2,0.8); + double epsilon0=0.8; + + //add two monomers. the test then proceeds like this: monomer 1 is moved + //to all positions around monomer 0 that give contributions to the + //acceptance probability. the probability is checked using a testmove + //and compared with the expected value. in the testmove, monomer 0 is + //simply moved one step in positive x-direction, and then back to its + //original position. + //the reverse move is checked using + //a different testmove (backmove) and also compared with the expectation. + //the monomer is then moved to a new position using updatemove. + //all used moves are of type MoveLocalBcc + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(10,10,10); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + molecules1[1].setAllCoordinates(13,7,7); + myIngredients1.synchronize(myIngredients1); + + //define moves in all possible directions for later use + MoveLocalBcc DXDYDZ,DXDYmDZ,DXmDYDZ,DXmDYmDZ,mDXDYDZ,mDXDYmDZ,mDXmDYDZ,mDXmDYmDZ; + + DXDYDZ.init(myIngredients1); + while((DXDYDZ.getDir()[0]!=1 ) ||(DXDYDZ.getDir()[1]!=1 ) ||(DXDYDZ.getDir()[2]!=1 ) || (DXDYDZ.getIndex()!=1)){ DXDYDZ.init(myIngredients1);} + + DXDYmDZ.init(myIngredients1); + while((DXDYmDZ.getDir()[0]!=1 ) ||(DXDYmDZ.getDir()[1]!=1 ) ||(DXDYmDZ.getDir()[2]!=-1 ) || (DXDYmDZ.getIndex()!=1)){ DXDYmDZ.init(myIngredients1);} + + DXmDYDZ.init(myIngredients1); + while((DXmDYDZ.getDir()[0]!=1 ) ||(DXmDYDZ.getDir()[1]!=-1 ) ||(DXmDYDZ.getDir()[2]!=1 ) || (DXmDYDZ.getIndex()!=1)){ DXmDYDZ.init(myIngredients1);} + + DXmDYmDZ.init(myIngredients1); + while((DXmDYmDZ.getDir()[0]!=1 ) ||(DXmDYmDZ.getDir()[1]!=-1 ) ||(DXmDYmDZ.getDir()[2]!=-1 ) || (DXmDYmDZ.getIndex()!=1)){ DXmDYmDZ.init(myIngredients1);} + + mDXDYDZ.init(myIngredients1); + while((mDXDYDZ.getDir()[0]!=-1 ) ||(mDXDYDZ.getDir()[1]!=1 ) ||(mDXDYDZ.getDir()[2]!=1 ) || (mDXDYDZ.getIndex()!=1)){ mDXDYDZ.init(myIngredients1);} + + mDXDYmDZ.init(myIngredients1); + while((mDXDYmDZ.getDir()[0]!=-1 ) ||(mDXDYmDZ.getDir()[1]!=1 ) ||(mDXDYmDZ.getDir()[2]!=-1 ) || (mDXDYmDZ.getIndex()!=1)){ mDXDYmDZ.init(myIngredients1);} + + mDXmDYDZ.init(myIngredients1); + while((mDXmDYDZ.getDir()[0]!=-1 ) ||(mDXmDYDZ.getDir()[1]!=-1 ) ||(mDXmDYDZ.getDir()[2]!=1 ) || (mDXmDYDZ.getIndex()!=1)){ mDXmDYDZ.init(myIngredients1);} + + mDXmDYmDZ.init(myIngredients1); + while((mDXmDYmDZ.getDir()[0]!=-1 ) ||(mDXmDYmDZ.getDir()[1]!=-1 ) ||(mDXmDYmDZ.getDir()[2]!=-1 ) || (mDXmDYmDZ.getIndex()!=1)){ mDXmDYmDZ.init(myIngredients1);} + + //now start checking moves of monomer 1 around the position of monomer 0 + + ///--- first move upwards in a zig-zag line from (3,-3,-3) to (3,-1,3) relative to monomer 0 + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),12); + + //last step to the next row + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),13); + + //----- now move downwards in zig-zag from (3,-1,3) to (3,1,-3) + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(-epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(-epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(-epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),7); + + //------ now move upwards in zig-zag to (1,1,3) + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + //last step to the next row + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),13); + + //--- now again zig-za downwards to (-1,3,-3) + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(-epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),7); + + //---move up again to (-3,1,3) relative to monomer 0 + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(-epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(-epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(-epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),13); + + //---move down to (-2,0,-2), which has a contact, then move to (-1,1,-3), which doesn't + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),7); + + //-- now check the position below monomer 0, i.e. (0,0,-2) + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(-epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--now check the position (0,-2,-2), go there in a first step + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),7); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(-epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--now check (-2,-2,-2), go there in a first step + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),7); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--check -2,-2,0, go there in a first step + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(-epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + //-- check (0,-2,0), go there first + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + //--now check (0,-2,2), go there in one step first + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),12); + + //-- now the last unchecked position with a contact is (0,0,2) + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),13); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); +} + +//same test but with any lattice + +TEST_F(ContactInteractionBccTest,CheckApplyBccMoveAnyLattice) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + + + //prepare myIngredients1 + myIngredients1.setBoxX(65); + myIngredients1.setBoxY(65); + myIngredients1.setBoxZ(65); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + //set interaction between types 1,2 + myIngredients1.setContactInteraction(1,2,0.8); + double epsilon0=0.8; + + //add two monomers. the test then proceeds like this: monomer 1 is moved + //to all positions around monomer 0 that give contributions to the + //acceptance probability. the probability is checked using a testmove + //and compared with the expected value. in the testmove, monomer 0 is + //simply moved one step in positive x-direction, and then back to its + //original position. + //the reverse move is checked using + //a different testmove (backmove) and also compared with the expectation. + //the monomer is then moved to a new position using updatemove. + //all used moves are of type MoveLocalBcc + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(10,10,10); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + molecules1[1].setAllCoordinates(13,7,7); + myIngredients1.synchronize(myIngredients1); + + //define moves in all possible directions for later use + MoveLocalBcc DXDYDZ,DXDYmDZ,DXmDYDZ,DXmDYmDZ,mDXDYDZ,mDXDYmDZ,mDXmDYDZ,mDXmDYmDZ; + + DXDYDZ.init(myIngredients1); + while((DXDYDZ.getDir()[0]!=1 ) ||(DXDYDZ.getDir()[1]!=1 ) ||(DXDYDZ.getDir()[2]!=1 ) || (DXDYDZ.getIndex()!=1)){ DXDYDZ.init(myIngredients1);} + + DXDYmDZ.init(myIngredients1); + while((DXDYmDZ.getDir()[0]!=1 ) ||(DXDYmDZ.getDir()[1]!=1 ) ||(DXDYmDZ.getDir()[2]!=-1 ) || (DXDYmDZ.getIndex()!=1)){ DXDYmDZ.init(myIngredients1);} + + DXmDYDZ.init(myIngredients1); + while((DXmDYDZ.getDir()[0]!=1 ) ||(DXmDYDZ.getDir()[1]!=-1 ) ||(DXmDYDZ.getDir()[2]!=1 ) || (DXmDYDZ.getIndex()!=1)){ DXmDYDZ.init(myIngredients1);} + + DXmDYmDZ.init(myIngredients1); + while((DXmDYmDZ.getDir()[0]!=1 ) ||(DXmDYmDZ.getDir()[1]!=-1 ) ||(DXmDYmDZ.getDir()[2]!=-1 ) || (DXmDYmDZ.getIndex()!=1)){ DXmDYmDZ.init(myIngredients1);} + + mDXDYDZ.init(myIngredients1); + while((mDXDYDZ.getDir()[0]!=-1 ) ||(mDXDYDZ.getDir()[1]!=1 ) ||(mDXDYDZ.getDir()[2]!=1 ) || (mDXDYDZ.getIndex()!=1)){ mDXDYDZ.init(myIngredients1);} + + mDXDYmDZ.init(myIngredients1); + while((mDXDYmDZ.getDir()[0]!=-1 ) ||(mDXDYmDZ.getDir()[1]!=1 ) ||(mDXDYmDZ.getDir()[2]!=-1 ) || (mDXDYmDZ.getIndex()!=1)){ mDXDYmDZ.init(myIngredients1);} + + mDXmDYDZ.init(myIngredients1); + while((mDXmDYDZ.getDir()[0]!=-1 ) ||(mDXmDYDZ.getDir()[1]!=-1 ) ||(mDXmDYDZ.getDir()[2]!=1 ) || (mDXmDYDZ.getIndex()!=1)){ mDXmDYDZ.init(myIngredients1);} + + mDXmDYmDZ.init(myIngredients1); + while((mDXmDYmDZ.getDir()[0]!=-1 ) ||(mDXmDYmDZ.getDir()[1]!=-1 ) ||(mDXmDYmDZ.getDir()[2]!=-1 ) || (mDXmDYmDZ.getIndex()!=1)){ mDXmDYmDZ.init(myIngredients1);} + + //now start checking moves of monomer 1 around the position of monomer 0 + + ///--- first move upwards in a zig-zag line from (3,-3,-3) to (3,-1,3) relative to monomer 0 + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),12); + + //last step to the next row + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),13); + + //----- now move downwards in zig-zag from (3,-1,3) to (3,1,-3) + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(-epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(-epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(-epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),7); + + //------ now move upwards in zig-zag to (1,1,3) + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),13); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),12); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + //last step to the next row + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),13); + + //--- now again zig-za downwards to (-1,3,-3) + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(-epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + mDXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYmDZ.getProbability(),exp(epsilon0)); + mDXDYmDZ.apply(myIngredients1); + mDXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),13); + EXPECT_EQ(molecules1[1].getZ(),7); + + //---move up again to (-3,1,3) relative to monomer 0 + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(-epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),8); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(-epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYDZ.getProbability(),exp(-epsilon0)); + DXDYDZ.apply(myIngredients1); + DXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),12); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),13); + + //---move down to (-2,0,-2), which has a contact, then move to (-1,1,-3), which doesn't + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(-epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),10); + + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),11); + EXPECT_EQ(molecules1[1].getZ(),7); + + //-- now check the position below monomer 0, i.e. (0,0,-2) + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(-epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--now check the position (0,-2,-2), go there in a first step + DXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYmDZ.getProbability(),exp(epsilon0)); + DXmDYmDZ.apply(myIngredients1); + DXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),7); + + mDXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYDZ.getProbability(),exp(-epsilon0)); + mDXmDYDZ.apply(myIngredients1); + mDXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--now check (-2,-2,-2), go there in a first step + mDXmDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXmDYmDZ.getProbability(),exp(epsilon0)); + mDXmDYmDZ.apply(myIngredients1); + mDXmDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),7); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),8); + + //--check -2,-2,0, go there in a first step + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),7); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),9); + + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(-epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),8); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + //-- check (0,-2,0), go there first + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),10); + + //--now check (0,-2,2), go there in one step first + DXmDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXmDYDZ.getProbability(),exp(epsilon0)); + DXmDYDZ.apply(myIngredients1); + DXmDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),11); + EXPECT_EQ(molecules1[1].getY(),7); + EXPECT_EQ(molecules1[1].getZ(),11); + + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(-epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),8); + EXPECT_EQ(molecules1[1].getZ(),12); + + //-- now the last unchecked position with a contact is (0,0,2) + mDXDYDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(mDXDYDZ.getProbability(),exp(epsilon0)); + mDXDYDZ.apply(myIngredients1); + mDXDYDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),9); + EXPECT_EQ(molecules1[1].getY(),9); + EXPECT_EQ(molecules1[1].getZ(),13); + + DXDYmDZ.check(myIngredients1); + EXPECT_DOUBLE_EQ(DXDYmDZ.getProbability(),exp(-epsilon0)); + DXDYmDZ.apply(myIngredients1); + DXDYmDZ.resetProbability(); + EXPECT_EQ(molecules1[1].getX(),10); + EXPECT_EQ(molecules1[1].getY(),10); + EXPECT_EQ(molecules1[1].getZ(),12); +} + + + + + +TEST_F(ContactInteractionBccTest,getSetInteraction) +{ + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients; + + for(int32_t i=1;i<=255;i++) + { + for(int32_t j=1;j<=255;j++) + { + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),0.0); + } + } + EXPECT_THROW(myIngredients.getContactInteraction(-1,5),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(1,-5),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(0,1),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(1,0),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(0,256),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(256,0),std::runtime_error); + + //set interaction between types 1,2 + myIngredients.setContactInteraction(1,2,0.8); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.8); + + myIngredients.setContactInteraction(1,2,-0.8); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),-0.8); + + + myIngredients.setContactInteraction(1,2,0.0); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.0); +} + +TEST_F(ContactInteractionBccTest,Synchronize) +{ + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + //prepare myIngredients1 + myIngredients1.setBoxX(32); + myIngredients1.setBoxY(32); + myIngredients1.setBoxZ(32); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[1].setAllCoordinates(1,1,1); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + myIngredients1.synchronize(myIngredients1); + + VectorInt3 pos; + //go through lattice and count contacts at each position + for(int32_t x=0;x<32;x++) + { + for(int32_t y=0;y<32;y++) + { + for(int32_t z=0;z<32;z++) + { + //get the lattice entry + pos.setAllCoordinates(x,y,z); + if(pos==VectorInt3(9,10,10)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(1,1,1)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else + EXPECT_EQ(0,myIngredients1.getLatticeEntry(pos)); + + + } + } + } + + molecules1.resize(3); + molecules1[2].setAllCoordinates(1,1,1); + molecules1[2].setAttributeTag(2); + EXPECT_THROW(myIngredients1.synchronize(myIngredients1),std::runtime_error); + + +} + +TEST_F(ContactInteractionBccTest,ReadWrite) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients; + + + //set interaction between types 1,2 + myIngredients.setContactInteraction(1,2,0.8); + myIngredients.setContactInteraction(1,3,-0.8); + myIngredients.setContactInteraction(2,3,0.0); + myIngredients.setContactInteraction(9,4,10.0); + + //prepare myIngredients + myIngredients.setBoxX(32); + myIngredients.setBoxY(32); + myIngredients.setBoxZ(32); + myIngredients.setPeriodicX(1); + myIngredients.setPeriodicY(1); + myIngredients.setPeriodicZ(1); + + typename Ing1::molecules_type& molecules1=myIngredients.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[1].setAllCoordinates(1,1,1); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + myIngredients.synchronize(myIngredients); + + AnalyzerWriteBfmFile outfile("./interactionRW.test",myIngredients,AnalyzerWriteBfmFile::NEWFILE); + outfile.initialize(); + outfile.execute(); + + Ing1 myIngredients2; + UpdaterReadBfmFile infile("./interactionRW.test",myIngredients2,UpdaterReadBfmFile::READ_LAST_CONFIG_FAST); + infile.initialize(); + + for(int32_t i=1;i<=255;i++) + { + for(int32_t j=1;j<=255;j++) + { + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),myIngredients2.getContactInteraction(i,j)); + } + } + + outfile.closeFile(); + infile.closeFile(); + //remove the temporary file + EXPECT_EQ(0,remove("./interactionRW.test")); + + +} + + +TEST_F(ContactInteractionBccTest,ApplyMoveAddBccMonomer) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + //prepare myIngredients1 + myIngredients1.setBoxX(65); + myIngredients1.setBoxY(65); + myIngredients1.setBoxZ(65); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + myIngredients1.synchronize(); + + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + + MoveAddBccMonomer addMonomer; + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(256); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(0); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(-1); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(2); + addMonomer.apply(myIngredients1); + + EXPECT_EQ(2,myIngredients1.getLatticeEntry(5,6,7)); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(255); + addMonomer.apply(myIngredients1); + + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(5,6,7))); + +} diff --git a/tests/feature/TestFeatureContactInteractionSc.cpp b/tests/feature/TestFeatureContactInteractionSc.cpp new file mode 100644 index 0000000..7fe7fba --- /dev/null +++ b/tests/feature/TestFeatureContactInteractionSc.cpp @@ -0,0 +1,2370 @@ +#include + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class ContactInteractionScTest: public ::testing::Test{ + /* suppress cout output for better readability -->un-/comment here:*/ +public: + //redirect cout output + virtual void SetUp(){ + originalBuffer=cout.rdbuf(); + cout.rdbuf(tempStream.rdbuf()); + }; + //restore original output + virtual void TearDown(){ + cout.rdbuf(originalBuffer); + }; +private: + std::streambuf* originalBuffer; + std::ostringstream tempStream; + /* ** */ +}; + + +TEST_F(ContactInteractionScTest,CheckApplyScMovePowerOfTwoLattice) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + + + //prepare myIngredients1 + myIngredients1.setBoxX(64); + myIngredients1.setBoxY(64); + myIngredients1.setBoxZ(64); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + //set interaction between types 1,2 + myIngredients1.setContactInteraction(1,2,0.8); + double epsilon0=0.8; + + //add two monomers. the test then proceeds like this: monomer 1 is moved + //to all positions around monomer 0 that give contributions to the + //acceptance probability. the probability is checked using a testmove + //and compared with the expected value. in the testmove, monomer 0 is + //simply moved one step in positive x-direction, and then back to its + //original position. + //the reverse move is checked using + //a different testmove (backmove) and also compared with the expectation. + //the monomer is then moved to a new position using updatemove. + //all used moves are of type MoveLocalSc + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + + //now check EV for move in positive x-direction + MoveLocalSc testmove,backmove,updateMove; + + molecules1[1].setAllCoordinates(12,9,10); + myIngredients1.synchronize(myIngredients1); + + //cout<<"-------------> checking single Interaction same hight <--------------------"< checking single Interaction above <--------------------"< checking single Interaction below <--------------------"< checking single Interaction twice below <--------------------"< checking single Interaction twice above <--------------------"<,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + + + //prepare myIngredients1 + myIngredients1.setBoxX(65); + myIngredients1.setBoxY(65); + myIngredients1.setBoxZ(65); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + //set interaction between types 1,2 + myIngredients1.setContactInteraction(1,2,0.8); + double epsilon0=0.8; + + //add two monomers. the test then proceeds like this: monomer 1 is moved + //to all positions around monomer 0 that give contributions to the + //acceptance probability. the probability is checked using a testmove + //and compared with the expected value. in the testmove, monomer 0 is + //simply moved one step in positive x-direction, and then back to its + //original position. + //the reverse move is checked using + //a different testmove (backmove) and also compared with the expectation. + //the monomer is then moved to a new position using updatemove. + //all used moves are of type MoveLocalSc + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + + //now check EV for move in positive x-direction + MoveLocalSc testmove,backmove,updateMove; + + molecules1[1].setAllCoordinates(12,9,10); + myIngredients1.synchronize(myIngredients1); + + //cout<<"-------------> checking single Interaction same hight <--------------------"< checking single Interaction above <--------------------"< checking single Interaction below <--------------------"< checking single Interaction twice below <--------------------"< checking single Interaction twice above <--------------------"<,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients; + + for(int32_t i=1;i<=255;i++) + { + for(int32_t j=1;j<=255;j++) + { + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),0.0); + } + } + EXPECT_THROW(myIngredients.getContactInteraction(-1,5),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(1,-5),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(0,1),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(1,0),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(0,256),std::runtime_error); + EXPECT_THROW(myIngredients.getContactInteraction(256,0),std::runtime_error); + + //set interaction between types 1,2 + myIngredients.setContactInteraction(1,2,0.8); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.8); + + myIngredients.setContactInteraction(1,2,-0.8); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),-0.8); + + + myIngredients.setContactInteraction(1,2,0.0); + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.0); +} + +TEST_F(ContactInteractionScTest,Synchronize) +{ + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + //prepare myIngredients1 + myIngredients1.setBoxX(32); + myIngredients1.setBoxY(32); + myIngredients1.setBoxZ(32); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[1].setAllCoordinates(1,1,1); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + myIngredients1.synchronize(myIngredients1); + + VectorInt3 pos; + //go through lattice and count contacts at each position + for(int32_t x=0;x<32;x++) + { + for(int32_t y=0;y<32;y++) + { + for(int32_t z=0;z<32;z++) + { + //get the lattice entry + pos.setAllCoordinates(x,y,z); + if(pos==VectorInt3(9,10,10)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(9,11,10)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(9,10,11)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(9,11,11)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(10,10,10)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(10,11,10)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(10,10,11)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(10,11,11)) + EXPECT_EQ(1,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(1,1,1)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(1,2,1)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(1,1,2)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(1,2,2)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(2,1,1)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(2,2,1)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(2,1,2)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else if(pos==VectorInt3(2,2,2)) + EXPECT_EQ(2,myIngredients1.getLatticeEntry(pos)); + else + EXPECT_EQ(0,myIngredients1.getLatticeEntry(pos)); + + + } + } + } + + molecules1.resize(3); + molecules1[2].setAllCoordinates(1,1,1); + molecules1[2].setAttributeTag(2); + EXPECT_THROW(myIngredients1.synchronize(myIngredients1),std::runtime_error); + + +} + +TEST_F(ContactInteractionScTest,ReadWrite) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients; + + + //set interaction between types 1,2 + myIngredients.setContactInteraction(1,2,0.8); + myIngredients.setContactInteraction(1,3,-0.8); + myIngredients.setContactInteraction(2,3,0.0); + myIngredients.setContactInteraction(9,4,10.0); + + //prepare myIngredients + myIngredients.setBoxX(32); + myIngredients.setBoxY(32); + myIngredients.setBoxZ(32); + myIngredients.setPeriodicX(1); + myIngredients.setPeriodicY(1); + myIngredients.setPeriodicZ(1); + + typename Ing1::molecules_type& molecules1=myIngredients.modifyMolecules(); + molecules1.resize(2); + molecules1[0].setAllCoordinates(9,10,10); + molecules1[1].setAllCoordinates(1,1,1); + molecules1[0].setAttributeTag(1); + molecules1[1].setAttributeTag(2); + + myIngredients.synchronize(myIngredients); + + AnalyzerWriteBfmFile outfile("./interactionRW.test",myIngredients,AnalyzerWriteBfmFile::NEWFILE); + outfile.initialize(); + outfile.execute(); + + Ing1 myIngredients2; + UpdaterReadBfmFile infile("./interactionRW.test",myIngredients2,UpdaterReadBfmFile::READ_LAST_CONFIG_FAST); + infile.initialize(); + + for(int32_t i=1;i<=255;i++) + { + for(int32_t j=1;j<=255;j++) + { + EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),myIngredients2.getContactInteraction(i,j)); + } + } + + outfile.closeFile(); + infile.closeFile(); + //remove the temporary file + EXPECT_EQ(0,remove("./interactionRW.test")); + + +} + + +TEST_F(ContactInteractionScTest,ApplyMoveAddScMonomer) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef ConfigureSystem Config1; + typedef Ingredients Ing1; + Ing1 myIngredients1; + + //prepare myIngredients1 + myIngredients1.setBoxX(65); + myIngredients1.setBoxY(65); + myIngredients1.setBoxZ(65); + myIngredients1.setPeriodicX(1); + myIngredients1.setPeriodicY(1); + myIngredients1.setPeriodicZ(1); + + myIngredients1.synchronize(); + + typename Ing1::molecules_type& molecules1=myIngredients1.modifyMolecules(); + + MoveAddScMonomer addMonomer; + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(256); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(0); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(-1); + EXPECT_THROW(addMonomer.apply(myIngredients1),std::runtime_error); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(2); + addMonomer.apply(myIngredients1); + + EXPECT_EQ(2,myIngredients1.getLatticeEntry(5,6,7)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(6,6,7)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(5,7,7)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(6,7,7)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(5,6,8)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(6,6,8)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(5,7,8)); + EXPECT_EQ(2,myIngredients1.getLatticeEntry(6,7,8)); + + addMonomer.init(myIngredients1); + addMonomer.setPosition(5,6,7); + addMonomer.setType(255); + addMonomer.apply(myIngredients1); + + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(5,6,7))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(6,6,7))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(5,7,7))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(6,7,7))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(5,6,8))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(6,6,8))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(5,7,8))); + EXPECT_EQ(255,int32_t(myIngredients1.getLatticeEntry(6,7,8))); + + +} From f072daa5a87e92de32845038be167d6987692c06 Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Mon, 10 Oct 2016 18:41:27 +0200 Subject: [PATCH 11/16] renamed ContactInteraction back to NNInteraction, mostly for reasons of backwards compatibility. --- ...ractionBcc.h => FeatureNNInteractionBcc.h} | 88 +++++++++---------- ...rite.h => FeatureNNInteractionReadWrite.h} | 44 +++++----- ...teractionSc.h => FeatureNNInteractionSc.h} | 80 ++++++++--------- ...cc.cpp => TestFeatureNNInteractionBcc.cpp} | 68 +++++++------- ...nSc.cpp => TestFeatureNNInteractionSc.cpp} | 68 +++++++------- 5 files changed, 174 insertions(+), 174 deletions(-) rename include/LeMonADE/feature/{FeatureContactInteractionBcc.h => FeatureNNInteractionBcc.h} (87%) rename include/LeMonADE/feature/{FeatureContactInteractionReadWrite.h => FeatureNNInteractionReadWrite.h} (70%) rename include/LeMonADE/feature/{FeatureContactInteractionSc.h => FeatureNNInteractionSc.h} (88%) rename tests/feature/{TestFeatureContactInteractionBcc.cpp => TestFeatureNNInteractionBcc.cpp} (95%) rename tests/feature/{TestFeatureContactInteractionSc.cpp => TestFeatureNNInteractionSc.cpp} (97%) diff --git a/include/LeMonADE/feature/FeatureContactInteractionBcc.h b/include/LeMonADE/feature/FeatureNNInteractionBcc.h similarity index 87% rename from include/LeMonADE/feature/FeatureContactInteractionBcc.h rename to include/LeMonADE/feature/FeatureNNInteractionBcc.h index df1a005..d541b0d 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionBcc.h +++ b/include/LeMonADE/feature/FeatureNNInteractionBcc.h @@ -26,14 +26,14 @@ along with LeMonADE. If not, see . --------------------------------------------------------------------------------*/ -#ifndef FEATURE_CONTACT_INTERACTION_BCC_H -#define FEATURE_CONTACT_INTERACTION_BCC_H +#ifndef FEATURE_NN_INTERACTION_BCC_H +#define FEATURE_NN_INTERACTION_BCC_H /** * @file * @date 2016/06/18 * @author Hauke Rabbel - * @brief Definition and implementation of class template FeatureContactInteractionBcc + * @brief Definition and implementation of class template FeatureNNInteractionBcc * * @todo MoveAddBccMonomer is used here, which might be obsolete. **/ @@ -45,10 +45,10 @@ along with LeMonADE. If not, see . #include #include #include -#include +#include /** - * @class FeatureContactInteractionBcc + * @class FeatureNNInteractionBcc * @brief Provides interaction of monomers on distances d<=sqrt(12)a for bccBFM * * @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or @@ -65,14 +65,14 @@ along with LeMonADE. If not, see . * - 0 d>sqrt(12) * . * Usage: In the feature list defining Ingredients use this feature as - * FeatureContactInteractionBcc (arbitrary lattices), or as - * FeatureContactInteractionBcc (2**n lattices) - * The feature adds the bfm-file command !contact_interaction A B E + * FeatureNNInteractionBcc (arbitrary lattices), or as + * FeatureNNInteractionBcc (2**n lattices) + * The feature adds the bfm-file command !nn_interaction A B E * for monomers of types A B with interaction energy of E in kT. **/ template class FeatureLatticeType> -class FeatureContactInteractionBcc:public Feature +class FeatureNNInteractionBcc:public Feature { private: @@ -100,14 +100,14 @@ class FeatureContactInteractionBcc:public Feature public: - FeatureContactInteractionBcc(); - ~FeatureContactInteractionBcc(){} + FeatureNNInteractionBcc(); + ~FeatureNNInteractionBcc(){} //This feature adds interaction energies, so it requires FeatureBoltzmann typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; - //FeatureExcludedVolumeSc needs to be in front, because FeatureContactInteractionBcc + //FeatureExcludedVolumeSc needs to be in front, because FeatureNNInteractionBcc //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written. //FeatureAttributes needs to be in front, because when a monomer is added to the system //by a MoveAddScMonomer, its attribute has to be set before it is written to the lattice. @@ -149,16 +149,16 @@ class FeatureContactInteractionBcc:public Feature void synchronize(IngredientsType& ingredients); //!adds interaction energy between two types of monomers - void setContactInteraction(int32_t typeA,int32_t typeB,double energy); + void setNNInteraction(int32_t typeA,int32_t typeB,double energy); //!returns the interaction energy between two types of monomers - double getContactInteraction(int32_t typeA,int32_t typeB) const; + double getNNInteraction(int32_t typeA,int32_t typeB) const; - //!export bfm-file read command !contact_interaction + //!export bfm-file read command !nn_interaction template void exportRead(FileImport & fileReader); - //!export bfm-file write command !contact_interaction + //!export bfm-file write command !nn_interaction template void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; @@ -171,7 +171,7 @@ class FeatureContactInteractionBcc:public Feature * @brief Constructor **/ template class LatticeClassType> -FeatureContactInteractionBcc::FeatureContactInteractionBcc() +FeatureNNInteractionBcc::FeatureNNInteractionBcc() { //initialize the energy and probability lookups with default values for(size_t n=0;n<256;n++) @@ -193,7 +193,7 @@ FeatureContactInteractionBcc::FeatureContactInteractionBcc() **/ template class LatticeClassType> template -bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionBcc::checkMove(const IngredientsType& ingredients, const MoveBase& move) const { return true; @@ -209,7 +209,7 @@ bool FeatureContactInteractionBcc::checkMove(const Ingredients **/ template class LatticeClassType> template -bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionBcc::checkMove(const IngredientsType& ingredients, MoveLocalBcc& move) const { //add the probability factor coming from this feature, then return true, @@ -231,12 +231,12 @@ bool FeatureContactInteractionBcc::checkMove(const Ingredients **/ template class LatticeClassType> template -bool FeatureContactInteractionBcc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionBcc::checkMove(const IngredientsType& ingredients, const MoveLocalSc& move) const { //throw exception in case someone accidentaly uses a bcc-BFM move with this feature std::stringstream errormessage; - errormessage<<"FeatureContactInteractionBcc::checkMove(...):\n"; + errormessage<<"FeatureNNInteractionBcc::checkMove(...):\n"; errormessage<<"attempting to use sc-BFM move, which is not allowed\n"; throw std::runtime_error(errormessage.str()); @@ -255,7 +255,7 @@ bool FeatureContactInteractionBcc::checkMove(const Ingredients **/ template class LatticeClassType> template -void FeatureContactInteractionBcc::applyMove(IngredientsType& ing, +void FeatureNNInteractionBcc::applyMove(IngredientsType& ing, const MoveAddBccMonomer& move) { //get the position and attribute tag of the monomer to be inserted @@ -267,7 +267,7 @@ void FeatureContactInteractionBcc::applyMove(IngredientsType& if(int32_t(type) != move.getType() || int32_t(type)==0) { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionBcc::applyMove(MoveAddBccMonomer)\n"; + errormessage<<"FeatureNNInteractionBcc::applyMove(MoveAddBccMonomer)\n"; errormessage<<"Trying to add monomer with type "<maxType=255\n"; throw std::runtime_error(errormessage.str()); } @@ -287,12 +287,12 @@ void FeatureContactInteractionBcc::applyMove(IngredientsType& **/ template class LatticeClassType> template -void FeatureContactInteractionBcc::applyMove(const IngredientsType& ing, +void FeatureNNInteractionBcc::applyMove(const IngredientsType& ing, const MoveLocalSc& move) { //throw exception in case someone accidentaly uses a sc-BFM move with this feature std::stringstream errormessage; - errormessage<<"FeatureContactInteractionBcc::applyMove(...):\n"; + errormessage<<"FeatureNNInteractionBcc::applyMove(...):\n"; errormessage<<"attempting to use sc-BFM move, which is not allowed\n"; throw std::runtime_error(errormessage.str()); @@ -304,7 +304,7 @@ void FeatureContactInteractionBcc::applyMove(const Ingredients **/ template class LatticeClassType> template -void FeatureContactInteractionBcc::synchronize(IngredientsType& ingredients) +void FeatureNNInteractionBcc::synchronize(IngredientsType& ingredients) { //refill the lattice with attribute tags @@ -323,7 +323,7 @@ void FeatureContactInteractionBcc::synchronize(IngredientsType * @throw std::runtime_error In debug mode, if types are not in range [1,255] **/ template class LatticeClassType> -inline double FeatureContactInteractionBcc::getProbabilityFactor(int32_t typeA, +inline double FeatureNNInteractionBcc::getProbabilityFactor(int32_t typeA, int32_t typeB) const { #ifdef DEBUG @@ -331,7 +331,7 @@ inline double FeatureContactInteractionBcc::getProbabilityFact //and this costs performance if(typeA<0 || typeA>255 || typeB<0 || typeB>255){ std::stringstream errormessage; - errormessage<<"***FeatureContactInteractionBcc::getInteraction(typeA,typeB)***\n"; + errormessage<<"***FeatureNNInteractionBcc::getInteraction(typeA,typeB)***\n"; errormessage<<"probability undefined between types "<::getProbabilityFact * is associated with an object of type FileImport. The export of the Reads is thus * taken care automatically when it becomes necessary.\n * Registered Read-In Commands: - * - !contactInteraction + * - !nnInteraction * . * * @tparam IngredientsType The type of the system including all features @@ -355,10 +355,10 @@ inline double FeatureContactInteractionBcc::getProbabilityFact **/ template class LatticeClassType> template -void FeatureContactInteractionBcc::exportRead(FileImport< IngredientsType >& fileReader) +void FeatureNNInteractionBcc::exportRead(FileImport< IngredientsType >& fileReader) { - typedef FeatureContactInteractionBcc my_type; - fileReader.registerRead("!contact_interaction",new ReadContactInteraction(*this)); + typedef FeatureNNInteractionBcc my_type; + fileReader.registerRead("!nn_interaction",new ReadNNInteraction(*this)); } @@ -367,17 +367,17 @@ void FeatureContactInteractionBcc::exportRead(FileImport< Ingr * is associated with an object of type AnalyzerWriteBfmFile. The export of the Writes is thus * taken care automatically when it becomes necessary.\n * Registered Write-Out Commands: - * - !contact_interaction + * - !nn_interaction * * @tparam IngredientsType The type of the system including all features * @param fileWriter File writer for the bfm-file. */ template class LatticeClassType> template -void FeatureContactInteractionBcc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +void FeatureNNInteractionBcc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const { - typedef FeatureContactInteractionBcc my_type; - fileWriter.registerWrite("!contact_interaction",new WriteContactInteraction(*this)); + typedef FeatureNNInteractionBcc my_type; + fileWriter.registerWrite("!nn_interaction",new WriteNNInteraction(*this)); } /** @@ -391,7 +391,7 @@ void FeatureContactInteractionBcc::exportWrite(AnalyzerWriteBf **/ template class LatticeClassType> template -void FeatureContactInteractionBcc::fillLattice(IngredientsType& ingredients) +void FeatureNNInteractionBcc::fillLattice(IngredientsType& ingredients) { const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); @@ -402,7 +402,7 @@ void FeatureContactInteractionBcc::fillLattice(IngredientsType if(int32_t(attribute)!=molecules[n].getAttributeTag()){ std::stringstream errormessage; - errormessage<<"***FeatureContactInteractionBcc::fillLattice()***\n"; + errormessage<<"***FeatureNNInteractionBcc::fillLattice()***\n"; errormessage<<"type "<::fillLattice(IngredientsType **/ template class LatticeClassType> template -double FeatureContactInteractionBcc::calculateAcceptanceProbability( +double FeatureNNInteractionBcc::calculateAcceptanceProbability( const IngredientsType& ingredients, const MoveLocalBcc& move) const { @@ -553,7 +553,7 @@ double FeatureContactInteractionBcc::calculateAcceptanceProbab * @throw std::runtime_error In case typeA or typeB exceed range [1,255] **/ template class LatticeClassType> -void FeatureContactInteractionBcc::setContactInteraction(int32_t typeA, +void FeatureNNInteractionBcc::setNNInteraction(int32_t typeA, int32_t typeB, double energy) { @@ -569,7 +569,7 @@ void FeatureContactInteractionBcc::setContactInteraction(int32 else { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionBcc::setContactInteraction(typeA,typeB,energy).\n"; + errormessage<<"FeatureNNInteractionBcc::setNNInteraction(typeA,typeB,energy).\n"; errormessage<<"typeA "<::setContactInteraction(int32 * @return interaction energy per nearest neighbor contact for typeA,typeB **/ template class LatticeClassType> -double FeatureContactInteractionBcc::getContactInteraction(int32_t typeA, +double FeatureNNInteractionBcc::getNNInteraction(int32_t typeA, int32_t typeB) const { @@ -591,7 +591,7 @@ double FeatureContactInteractionBcc::getContactInteraction(int else { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionBcc::getContactInteraction(typeA,typeB).\n"; + errormessage<<"FeatureNNInteractionBcc::getNNInteraction(typeA,typeB).\n"; errormessage<<"typeA "<::getContactInteraction(int } -#endif /*FEATURE_CONTACT_INTERACTION_BCC_H*/ +#endif /*FEATURE_NN_INTERACTION_BCC_H*/ diff --git a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h b/include/LeMonADE/feature/FeatureNNInteractionReadWrite.h similarity index 70% rename from include/LeMonADE/feature/FeatureContactInteractionReadWrite.h rename to include/LeMonADE/feature/FeatureNNInteractionReadWrite.h index b4b471a..3b6b11d 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionReadWrite.h +++ b/include/LeMonADE/feature/FeatureNNInteractionReadWrite.h @@ -25,14 +25,14 @@ along with LeMonADE. If not, see . --------------------------------------------------------------------------------*/ -#ifndef FEATURE_CONTACT_INTERACTION_READ_WRITE_H -#define FEATURE_CONTACT_INTERACTION_READ_WRITE_H +#ifndef FEATURE_NN_INTERACTION_READ_WRITE_H +#define FEATURE_NN_INTERACTION_READ_WRITE_H /** * @file * @date 2016/06/18 * @author Hauke Rabbel - * @brief Def. and impl. of class templates ReadContactInteraction and WriteContactInteraction + * @brief Def. and impl. of class templates ReadNNInteraction and WriteNNInteraction **/ #include @@ -40,35 +40,35 @@ along with LeMonADE. If not, see . #include /** - * @class ReadContactInteraction - * @brief Handles BFM-file read command !contact_interaction + * @class ReadNNInteraction + * @brief Handles BFM-file read command !nn_interaction * @tparam IngredientsType Ingredients class storing all system information. **/ template < class IngredientsType> -class ReadContactInteraction: public ReadToDestination +class ReadNNInteraction: public ReadToDestination { public: - ReadContactInteraction(IngredientsType& i):ReadToDestination(i){} - virtual ~ReadContactInteraction(){} + ReadNNInteraction(IngredientsType& i):ReadToDestination(i){} + virtual ~ReadNNInteraction(){} virtual void execute(); }; /** - * @class WriteContactInteraction - * @brief Handles BFM-file write command !contact_interaction + * @class WriteNNInteraction + * @brief Handles BFM-file write command !nn_interaction * @tparam IngredientsType Ingredients class storing all system information. **/ template -class WriteContactInteraction:public AbstractWrite +class WriteNNInteraction:public AbstractWrite { public: //constructor sets the headerOnly tag, such that the interaction //is written only once at the beginning of the output file. - WriteContactInteraction(const IngredientsType& i) + WriteNNInteraction(const IngredientsType& i) :AbstractWrite(i){this->setHeaderOnly(true);} - virtual ~WriteContactInteraction(){} + virtual ~WriteNNInteraction(){} virtual void writeStream(std::ostream& strm); }; @@ -76,12 +76,12 @@ class WriteContactInteraction:public AbstractWrite /////////////MEMBER IMPLEMENTATIONS //////////////////////////////////////////// /** - * @brief Executes the reading routine to extract \b !contact_interaction. + * @brief Executes the reading routine to extract \b !nn_interaction. * * @throw fail to read monomer types or interaction energy. **/ template -void ReadContactInteraction::execute() +void ReadNNInteraction::execute() { IngredientsType& ingredients=this->getDestination(); std::istream& file=this->getInputStream(); @@ -101,14 +101,14 @@ void ReadContactInteraction::execute() catch(std::ifstream::failure e) { std::stringstream errormessage; - errormessage<<"ReadContactInteraction::execute().\n"; + errormessage<<"ReadNNInteraction::execute().\n"; errormessage<<"Could not read interaction from file\n"; errormessage<<"Previous error: "<::execute() /** - * @brief Executes the routine to write \b !contact_interaction. + * @brief Executes the routine to write \b !nn_interaction. * @arg stream file stream to write into **/ template -void WriteContactInteraction::writeStream(std::ostream& stream) +void WriteNNInteraction::writeStream(std::ostream& stream) { int32_t nSpecies=255; //number must fit into 8 bit (uint8_t based lattice) stream<<"## nearest neighbor interactions between types in kT (default 0.0kT)\n"; @@ -129,9 +129,9 @@ void WriteContactInteraction::writeStream(std::ostream& stream) { for(int32_t typeB=1;typeB<=typeA;typeB++) { - if(this->getSource().getContactInteraction(typeA,typeB)!=0.0) + if(this->getSource().getNNInteraction(typeA,typeB)!=0.0) { - stream<<"!contact_interaction "<getSource().getContactInteraction(typeB,typeA)<<"\n"; + stream<<"!nn_interaction "<getSource().getNNInteraction(typeB,typeA)<<"\n"; } } @@ -144,4 +144,4 @@ void WriteContactInteraction::writeStream(std::ostream& stream) -#endif // FEATURE_CONTACT_INTERACTION_READ_WRITE_H +#endif // FEATURE_NN_INTERACTION_READ_WRITE_H diff --git a/include/LeMonADE/feature/FeatureContactInteractionSc.h b/include/LeMonADE/feature/FeatureNNInteractionSc.h similarity index 88% rename from include/LeMonADE/feature/FeatureContactInteractionSc.h rename to include/LeMonADE/feature/FeatureNNInteractionSc.h index 764644d..04d347b 100644 --- a/include/LeMonADE/feature/FeatureContactInteractionSc.h +++ b/include/LeMonADE/feature/FeatureNNInteractionSc.h @@ -26,14 +26,14 @@ along with LeMonADE. If not, see . --------------------------------------------------------------------------------*/ -#ifndef FEATURE_CONTACT_INTERACTION_H -#define FEATURE_CONTACT_INTERACTION_H +#ifndef FEATURE_NN_INTERACTION_H +#define FEATURE_NN_INTERACTION_H /** * @file * @date 2016/06/18 * @author Hauke Rabbel - * @brief Definition and implementation of class template FeatureContactInteractionSc + * @brief Definition and implementation of class template FeatureNNInteractionSc **/ #include @@ -42,10 +42,10 @@ along with LeMonADE. If not, see . #include #include #include -#include +#include /** - * @class FeatureContactInteractionSc + * @class FeatureNNInteractionSc * @brief Provides interaction of monomers on distances d<=sqrt(6) for standard BFM * * @tparam FeatureLatticeType Underlying lattice feature, e.g. FeatureLattice or @@ -64,14 +64,14 @@ along with LeMonADE. If not, see . * - 0 d>sqrt(6) * . * Usage: In the feature list defining Ingredients use this feature as - * FeatureContactInteractionSc (arbitrary lattices), or as - * FeatureContactInteractionSc (2**n lattices) - * The feature adds the bfm-file command !contact_interaction A B E + * FeatureNNInteractionSc (arbitrary lattices), or as + * FeatureNNInteractionSc (2**n lattices) + * The feature adds the bfm-file command !nn_interaction A B E * for monomers of types A B with interaction energy of E in kT. **/ template class FeatureLatticeType> -class FeatureContactInteractionSc:public Feature +class FeatureNNInteractionSc:public Feature { private: @@ -99,14 +99,14 @@ class FeatureContactInteractionSc:public Feature public: - FeatureContactInteractionSc(); - ~FeatureContactInteractionSc(){} + FeatureNNInteractionSc(); + ~FeatureNNInteractionSc(){} //This feature adds interaction energies, so it requires FeatureBoltzmann typedef LOKI_TYPELIST_1(FeatureBoltzmann) required_features_back; - //FeatureExcludedVolumeSc needs to be in front, because FeatureContactInteractionSc + //FeatureExcludedVolumeSc needs to be in front, because FeatureNNInteractionSc //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written. //FeatureAttributes needs to be in front, because when a monomer is added to the system //by a MoveAddScMonomer, its attribute has to be set before it is written to the lattice. @@ -148,16 +148,16 @@ class FeatureContactInteractionSc:public Feature void synchronize(IngredientsType& ingredients); //!adds interaction energy between two types of monomers - void setContactInteraction(int32_t typeA,int32_t typeB,double energy); + void setNNInteraction(int32_t typeA,int32_t typeB,double energy); //!returns the interaction energy between two types of monomers - double getContactInteraction(int32_t typeA,int32_t typeB) const; + double getNNInteraction(int32_t typeA,int32_t typeB) const; - //!export bfm-file read command !contact_interaction + //!export bfm-file read command !nn_interaction template void exportRead(FileImport & fileReader); - //!export bfm-file write command !contact_interaction + //!export bfm-file write command !nn_interaction template void exportWrite(AnalyzerWriteBfmFile & fileWriter) const; @@ -170,7 +170,7 @@ class FeatureContactInteractionSc:public Feature * @brief Constructor **/ template class LatticeClassType> -FeatureContactInteractionSc::FeatureContactInteractionSc() +FeatureNNInteractionSc::FeatureNNInteractionSc() { //initialize the energy and probability lookups with default values for(size_t n=0;n<256;n++) @@ -192,7 +192,7 @@ FeatureContactInteractionSc::FeatureContactInteractionSc() **/ template class LatticeClassType> template -bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, const MoveBase& move) const { return true; @@ -208,7 +208,7 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT **/ template class LatticeClassType> template -bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) const { //add the probability factor coming from this feature, then return true, @@ -230,12 +230,12 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT **/ template class LatticeClassType> template -bool FeatureContactInteractionSc::checkMove(const IngredientsType& ingredients, +bool FeatureNNInteractionSc::checkMove(const IngredientsType& ingredients, const MoveLocalBcc& move) const { //throw exception in case someone accidentaly uses a bcc-BFM move with this feature std::stringstream errormessage; - errormessage<<"FeatureContactInteractionSc::checkMove(...):\n"; + errormessage<<"FeatureNNInteractionSc::checkMove(...):\n"; errormessage<<"attempting to use bcc-BFM move, which is not allowed\n"; throw std::runtime_error(errormessage.str()); @@ -254,7 +254,7 @@ bool FeatureContactInteractionSc::checkMove(const IngredientsT **/ template class LatticeClassType> template -void FeatureContactInteractionSc::applyMove(IngredientsType& ing, +void FeatureNNInteractionSc::applyMove(IngredientsType& ing, const MoveAddScMonomer& move) { //get the position and attribute tag of the monomer to be inserted @@ -269,7 +269,7 @@ void FeatureContactInteractionSc::applyMove(IngredientsType& i if(int32_t(type) != move.getType() || int32_t(type)==0) { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionSc::applyMove(MoveAddScMonomer)\n"; + errormessage<<"FeatureNNInteractionSc::applyMove(MoveAddScMonomer)\n"; errormessage<<"Trying to add monomer with type "<maxType=255\n"; throw std::runtime_error(errormessage.str()); } @@ -296,12 +296,12 @@ void FeatureContactInteractionSc::applyMove(IngredientsType& i **/ template class LatticeClassType> template -void FeatureContactInteractionSc::applyMove(const IngredientsType& ing, +void FeatureNNInteractionSc::applyMove(const IngredientsType& ing, const MoveLocalBcc& move) { //throw exception in case someone accidentaly uses a bcc-BFM move with this feature std::stringstream errormessage; - errormessage<<"FeatureContactInteractionSc::applyMove(...):\n"; + errormessage<<"FeatureNNInteractionSc::applyMove(...):\n"; errormessage<<"attempting to use bcc-BFM move, which is not allowed\n"; throw std::runtime_error(errormessage.str()); @@ -313,7 +313,7 @@ void FeatureContactInteractionSc::applyMove(const IngredientsT **/ template class LatticeClassType> template -void FeatureContactInteractionSc::synchronize(IngredientsType& ingredients) +void FeatureNNInteractionSc::synchronize(IngredientsType& ingredients) { //refill the lattice with attribute tags @@ -332,7 +332,7 @@ void FeatureContactInteractionSc::synchronize(IngredientsType& * @throw std::runtime_error In debug mode, if types are not in range [1,255] **/ template class LatticeClassType> -inline double FeatureContactInteractionSc::getProbabilityFactor(int32_t typeA, +inline double FeatureNNInteractionSc::getProbabilityFactor(int32_t typeA, int32_t typeB) const { #ifdef DEBUG @@ -364,10 +364,10 @@ inline double FeatureContactInteractionSc::getProbabilityFacto **/ template class LatticeClassType> template -void FeatureContactInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) +void FeatureNNInteractionSc::exportRead(FileImport< IngredientsType >& fileReader) { - typedef FeatureContactInteractionSc my_type; - fileReader.registerRead("!contact_interaction",new ReadContactInteraction(*this)); + typedef FeatureNNInteractionSc my_type; + fileReader.registerRead("!nn_interaction",new ReadNNInteraction(*this)); } @@ -383,10 +383,10 @@ void FeatureContactInteractionSc::exportRead(FileImport< Ingre */ template class LatticeClassType> template -void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const +void FeatureNNInteractionSc::exportWrite(AnalyzerWriteBfmFile< IngredientsType >& fileWriter) const { - typedef FeatureContactInteractionSc my_type; - fileWriter.registerWrite("!contact_interaction",new WriteContactInteraction(*this)); + typedef FeatureNNInteractionSc my_type; + fileWriter.registerWrite("!nn_interaction",new WriteNNInteraction(*this)); } /** @@ -400,7 +400,7 @@ void FeatureContactInteractionSc::exportWrite(AnalyzerWriteBfm **/ template class LatticeClassType> template -void FeatureContactInteractionSc::fillLattice(IngredientsType& ingredients) +void FeatureNNInteractionSc::fillLattice(IngredientsType& ingredients) { const typename IngredientsType::molecules_type& molecules=ingredients.getMolecules(); @@ -411,7 +411,7 @@ void FeatureContactInteractionSc::fillLattice(IngredientsType& if(int32_t(attribute)!=molecules[n].getAttributeTag()){ std::stringstream errormessage; - errormessage<<"***FeatureContactInteractionSc::fillLattice()***\n"; + errormessage<<"***FeatureNNInteractionSc::fillLattice()***\n"; errormessage<<"type "<::fillLattice(IngredientsType& **/ template class LatticeClassType> template -double FeatureContactInteractionSc::calculateAcceptanceProbability( +double FeatureNNInteractionSc::calculateAcceptanceProbability( const IngredientsType& ingredients, const MoveLocalSc& move) const { @@ -550,7 +550,7 @@ double FeatureContactInteractionSc::calculateAcceptanceProbabi * @throw std::runtime_error In case typeA or typeB exceed range [1,255] **/ template class LatticeClassType> -void FeatureContactInteractionSc::setContactInteraction(int32_t typeA, +void FeatureNNInteractionSc::setNNInteraction(int32_t typeA, int32_t typeB, double energy) { @@ -566,7 +566,7 @@ void FeatureContactInteractionSc::setContactInteraction(int32_ else { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionSc::setContactInteraction(typeA,typeB,energy).\n"; + errormessage<<"FeatureNNInteractionSc::setNNInteraction(typeA,typeB,energy).\n"; errormessage<<"typeA "<::setContactInteraction(int32_ * @return interaction energy per nearest neighbor contact for typeA,typeB **/ template class LatticeClassType> -double FeatureContactInteractionSc::getContactInteraction(int32_t typeA, +double FeatureNNInteractionSc::getNNInteraction(int32_t typeA, int32_t typeB) const { @@ -588,7 +588,7 @@ double FeatureContactInteractionSc::getContactInteraction(int3 else { std::stringstream errormessage; - errormessage<<"FeatureContactInteractionSc::getContactInteraction(typeA,typeB).\n"; + errormessage<<"FeatureNNInteractionSc::getNNInteraction(typeA,typeB).\n"; errormessage<<"typeA "< #include #include -#include +#include #include #include using namespace std; -class ContactInteractionBccTest: public ::testing::Test{ +class NNInteractionBccTest: public ::testing::Test{ /* suppress cout output for better readability -->un-/comment here:*/ public: //redirect cout output @@ -33,9 +33,9 @@ class ContactInteractionBccTest: public ::testing::Test{ }; -TEST_F(ContactInteractionBccTest,CheckApplyBccMovePowerOfTwoLattice) +TEST_F(NNInteractionBccTest,CheckApplyBccMovePowerOfTwoLattice) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -51,7 +51,7 @@ TEST_F(ContactInteractionBccTest,CheckApplyBccMovePowerOfTwoLattice) myIngredients1.setPeriodicZ(1); //set interaction between types 1,2 - myIngredients1.setContactInteraction(1,2,0.8); + myIngredients1.setNNInteraction(1,2,0.8); double epsilon0=0.8; //add two monomers. the test then proceeds like this: monomer 1 is moved @@ -514,9 +514,9 @@ TEST_F(ContactInteractionBccTest,CheckApplyBccMovePowerOfTwoLattice) //same test but with any lattice -TEST_F(ContactInteractionBccTest,CheckApplyBccMoveAnyLattice) +TEST_F(NNInteractionBccTest,CheckApplyBccMoveAnyLattice) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -532,7 +532,7 @@ TEST_F(ContactInteractionBccTest,CheckApplyBccMoveAnyLattice) myIngredients1.setPeriodicZ(1); //set interaction between types 1,2 - myIngredients1.setContactInteraction(1,2,0.8); + myIngredients1.setNNInteraction(1,2,0.8); double epsilon0=0.8; //add two monomers. the test then proceeds like this: monomer 1 is moved @@ -997,9 +997,9 @@ TEST_F(ContactInteractionBccTest,CheckApplyBccMoveAnyLattice) -TEST_F(ContactInteractionBccTest,getSetInteraction) +TEST_F(NNInteractionBccTest,getSetInteraction) { - typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients; @@ -1008,31 +1008,31 @@ TEST_F(ContactInteractionBccTest,getSetInteraction) { for(int32_t j=1;j<=255;j++) { - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),0.0); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(i,j),0.0); } } - EXPECT_THROW(myIngredients.getContactInteraction(-1,5),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(1,-5),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(0,1),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(1,0),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(0,256),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(256,0),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(-1,5),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(1,-5),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(0,1),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(1,0),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(0,256),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(256,0),std::runtime_error); //set interaction between types 1,2 - myIngredients.setContactInteraction(1,2,0.8); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.8); + myIngredients.setNNInteraction(1,2,0.8); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),0.8); - myIngredients.setContactInteraction(1,2,-0.8); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),-0.8); + myIngredients.setNNInteraction(1,2,-0.8); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),-0.8); - myIngredients.setContactInteraction(1,2,0.0); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.0); + myIngredients.setNNInteraction(1,2,0.0); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),0.0); } -TEST_F(ContactInteractionBccTest,Synchronize) +TEST_F(NNInteractionBccTest,Synchronize) { - typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -1083,19 +1083,19 @@ TEST_F(ContactInteractionBccTest,Synchronize) } -TEST_F(ContactInteractionBccTest,ReadWrite) +TEST_F(NNInteractionBccTest,ReadWrite) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients; //set interaction between types 1,2 - myIngredients.setContactInteraction(1,2,0.8); - myIngredients.setContactInteraction(1,3,-0.8); - myIngredients.setContactInteraction(2,3,0.0); - myIngredients.setContactInteraction(9,4,10.0); + myIngredients.setNNInteraction(1,2,0.8); + myIngredients.setNNInteraction(1,3,-0.8); + myIngredients.setNNInteraction(2,3,0.0); + myIngredients.setNNInteraction(9,4,10.0); //prepare myIngredients myIngredients.setBoxX(32); @@ -1126,7 +1126,7 @@ TEST_F(ContactInteractionBccTest,ReadWrite) { for(int32_t j=1;j<=255;j++) { - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),myIngredients2.getContactInteraction(i,j)); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(i,j),myIngredients2.getNNInteraction(i,j)); } } @@ -1139,9 +1139,9 @@ TEST_F(ContactInteractionBccTest,ReadWrite) } -TEST_F(ContactInteractionBccTest,ApplyMoveAddBccMonomer) +TEST_F(NNInteractionBccTest,ApplyMoveAddBccMonomer) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionBcc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionBcc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; diff --git a/tests/feature/TestFeatureContactInteractionSc.cpp b/tests/feature/TestFeatureNNInteractionSc.cpp similarity index 97% rename from tests/feature/TestFeatureContactInteractionSc.cpp rename to tests/feature/TestFeatureNNInteractionSc.cpp index 7fe7fba..ca7f7ed 100644 --- a/tests/feature/TestFeatureContactInteractionSc.cpp +++ b/tests/feature/TestFeatureNNInteractionSc.cpp @@ -8,13 +8,13 @@ #include #include #include -#include +#include #include #include using namespace std; -class ContactInteractionScTest: public ::testing::Test{ +class NNInteractionScTest: public ::testing::Test{ /* suppress cout output for better readability -->un-/comment here:*/ public: //redirect cout output @@ -33,9 +33,9 @@ class ContactInteractionScTest: public ::testing::Test{ }; -TEST_F(ContactInteractionScTest,CheckApplyScMovePowerOfTwoLattice) +TEST_F(NNInteractionScTest,CheckApplyScMovePowerOfTwoLattice) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -51,7 +51,7 @@ TEST_F(ContactInteractionScTest,CheckApplyScMovePowerOfTwoLattice) myIngredients1.setPeriodicZ(1); //set interaction between types 1,2 - myIngredients1.setContactInteraction(1,2,0.8); + myIngredients1.setNNInteraction(1,2,0.8); double epsilon0=0.8; //add two monomers. the test then proceeds like this: monomer 1 is moved @@ -1083,9 +1083,9 @@ TEST_F(ContactInteractionScTest,CheckApplyScMovePowerOfTwoLattice) //same test again with no power of two lattice -TEST_F(ContactInteractionScTest,CheckApplyScMoveAnyLattice) +TEST_F(NNInteractionScTest,CheckApplyScMoveAnyLattice) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -1101,7 +1101,7 @@ TEST_F(ContactInteractionScTest,CheckApplyScMoveAnyLattice) myIngredients1.setPeriodicZ(1); //set interaction between types 1,2 - myIngredients1.setContactInteraction(1,2,0.8); + myIngredients1.setNNInteraction(1,2,0.8); double epsilon0=0.8; //add two monomers. the test then proceeds like this: monomer 1 is moved @@ -2132,9 +2132,9 @@ TEST_F(ContactInteractionScTest,CheckApplyScMoveAnyLattice) -TEST_F(ContactInteractionScTest,getSetInteraction) +TEST_F(NNInteractionScTest,getSetInteraction) { - typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients; @@ -2143,31 +2143,31 @@ TEST_F(ContactInteractionScTest,getSetInteraction) { for(int32_t j=1;j<=255;j++) { - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),0.0); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(i,j),0.0); } } - EXPECT_THROW(myIngredients.getContactInteraction(-1,5),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(1,-5),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(0,1),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(1,0),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(0,256),std::runtime_error); - EXPECT_THROW(myIngredients.getContactInteraction(256,0),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(-1,5),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(1,-5),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(0,1),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(1,0),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(0,256),std::runtime_error); + EXPECT_THROW(myIngredients.getNNInteraction(256,0),std::runtime_error); //set interaction between types 1,2 - myIngredients.setContactInteraction(1,2,0.8); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.8); + myIngredients.setNNInteraction(1,2,0.8); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),0.8); - myIngredients.setContactInteraction(1,2,-0.8); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),-0.8); + myIngredients.setNNInteraction(1,2,-0.8); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),-0.8); - myIngredients.setContactInteraction(1,2,0.0); - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(1,2),0.0); + myIngredients.setNNInteraction(1,2,0.0); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(1,2),0.0); } -TEST_F(ContactInteractionScTest,Synchronize) +TEST_F(NNInteractionScTest,Synchronize) { - typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_2(FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; @@ -2246,19 +2246,19 @@ TEST_F(ContactInteractionScTest,Synchronize) } -TEST_F(ContactInteractionScTest,ReadWrite) +TEST_F(NNInteractionScTest,ReadWrite) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients; //set interaction between types 1,2 - myIngredients.setContactInteraction(1,2,0.8); - myIngredients.setContactInteraction(1,3,-0.8); - myIngredients.setContactInteraction(2,3,0.0); - myIngredients.setContactInteraction(9,4,10.0); + myIngredients.setNNInteraction(1,2,0.8); + myIngredients.setNNInteraction(1,3,-0.8); + myIngredients.setNNInteraction(2,3,0.0); + myIngredients.setNNInteraction(9,4,10.0); //prepare myIngredients myIngredients.setBoxX(32); @@ -2289,7 +2289,7 @@ TEST_F(ContactInteractionScTest,ReadWrite) { for(int32_t j=1;j<=255;j++) { - EXPECT_DOUBLE_EQ(myIngredients.getContactInteraction(i,j),myIngredients2.getContactInteraction(i,j)); + EXPECT_DOUBLE_EQ(myIngredients.getNNInteraction(i,j),myIngredients2.getNNInteraction(i,j)); } } @@ -2302,9 +2302,9 @@ TEST_F(ContactInteractionScTest,ReadWrite) } -TEST_F(ContactInteractionScTest,ApplyMoveAddScMonomer) +TEST_F(NNInteractionScTest,ApplyMoveAddScMonomer) { - typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureContactInteractionSc) Features1; + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureBondset<>,FeatureNNInteractionSc) Features1; typedef ConfigureSystem Config1; typedef Ingredients Ing1; Ing1 myIngredients1; From 9d57d776dd45446fd01cfa9d3f3904e83ea4abed Mon Sep 17 00:00:00 2001 From: Hauke Rabbel Date: Mon, 10 Oct 2016 18:45:09 +0200 Subject: [PATCH 12/16] deleted testproject folder --- projects/CMakeLists.txt | 1 - projects/testproject/CMakeLists.txt | 4 - .../ChainSimulatorINT/CMakeLists.txt | 14 ---- .../testproject/ChainSimulatorINT/main.cpp | 78 ------------------- 4 files changed, 97 deletions(-) delete mode 100644 projects/testproject/CMakeLists.txt delete mode 100644 projects/testproject/ChainSimulatorINT/CMakeLists.txt delete mode 100644 projects/testproject/ChainSimulatorINT/main.cpp diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index f64ce04..2d2387d 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -2,4 +2,3 @@ add_subdirectory(SimpleSimulator) add_subdirectory(Examples) -add_subdirectory(testproject) diff --git a/projects/testproject/CMakeLists.txt b/projects/testproject/CMakeLists.txt deleted file mode 100644 index 4895d4b..0000000 --- a/projects/testproject/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -ADD_SUBDIRECTORY(ChainSimulatorINT) - - - diff --git a/projects/testproject/ChainSimulatorINT/CMakeLists.txt b/projects/testproject/ChainSimulatorINT/CMakeLists.txt deleted file mode 100644 index 7d4e48a..0000000 --- a/projects/testproject/ChainSimulatorINT/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -if (NOT DEFINED LEMONADE_INCLUDE_DIR) -message("LEMONADE_INCLUDE_DIR is not provided. If build fails, use -DLEMONADE_INCLUDE_DIR=/path/to/LeMonADE/headers/ or install to default location") -endif() - -if (NOT DEFINED LEMONADE_LIBRARY_DIR) -message("LEMONADE_LIBRARY_DIR is not provided. If build fails, use -DLEMONADE_LIBRARY_DIR=/path/to/LeMonADE/lib/ or install to default location") -endif() - -include_directories (${LEMONADE_INCLUDE_DIR}) -link_directories (${LEMONADE_LIBRARY_DIR}) -ADD_EXECUTABLE(ChainSimulatorINT main.cpp) -TARGET_LINK_LIBRARIES(ChainSimulatorINT LeMonADE) diff --git a/projects/testproject/ChainSimulatorINT/main.cpp b/projects/testproject/ChainSimulatorINT/main.cpp deleted file mode 100644 index 5994547..0000000 --- a/projects/testproject/ChainSimulatorINT/main.cpp +++ /dev/null @@ -1,78 +0,0 @@ - - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char* argv[]) -{ - try{ - std::string infile; - std::string outfile; - uint32_t max_mcs=0; - uint32_t save_interval=0; - - outfile="outfile.bfm"; - - if(!(argc==4 || argc==5 )|| (argc==2 && strcmp(argv[1],"--help")==0 )) - { - std::string errormessage; - errormessage="usage: ./SimpleSimulator input_file max_mcs save_interval(mcs) [output_file]\n"; - errormessage+="\nSimple Simulator for the ScBFM with Ex.Vol and BondCheck\n"; - errormessage+="maximum number of connections per monomer is 6\n"; - errormessage+="If output_filename specified, the results are written to the new file\n"; - errormessage+="otherwise the results are appended to the old input file\n"; - errormessage+="Updaters used: ReadFullBFMFile, SimpleSimulator\n"; - errormessage+="Analyzers used: WriteBfmFile\n"; - throw std::runtime_error(errormessage); - - } - else - { - infile=argv[1]; - max_mcs=atoi(argv[2]); - save_interval=atoi(argv[3]); - - if(argc==5) outfile=argv[4]; - else outfile=argv[1]; - } - - //seed the globally available random number generators - RandomNumberGenerators rng; - rng.seedAll(); - - // FeatureExcludedVolume<> is equivalent to FeatureExcludedVolume > - typedef LOKI_TYPELIST_2(FeatureMoleculesIO,FeatureContactInteractionSc) Features; - - typedef ConfigureSystem Config; - typedef Ingredients Ing; - Ing myIngredients; - - TaskManager taskmanager; - taskmanager.addUpdater(new UpdaterReadBfmFile(infile,myIngredients,UpdaterReadBfmFile::READ_LAST_CONFIG_SAVE),0); - taskmanager.addUpdater(new UpdaterSimpleSimulator(myIngredients,save_interval)); - - taskmanager.addAnalyzer(new AnalyzerWriteBfmFile(outfile,myIngredients)); - //taskmanager.addAnalyzer(new LatticeOccupationAnalyzer(myIngredients)); - - taskmanager.initialize(); - taskmanager.run(max_mcs/save_interval); - taskmanager.cleanup(); - - } - catch(std::exception& err){std::cerr< Date: Mon, 10 Oct 2016 18:52:18 +0200 Subject: [PATCH 13/16] deleted files left over from code experiments --- .../analyzer/AnalyzerLatticeOccupation.h | 68 ----- include/LeMonADE/utility/PairPotentials.h | 237 ------------------ projects/CMakeLists.txt | 1 - 3 files changed, 306 deletions(-) delete mode 100644 include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h delete mode 100644 include/LeMonADE/utility/PairPotentials.h diff --git a/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h b/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h deleted file mode 100644 index 165c35e..0000000 --- a/include/LeMonADE/analyzer/AnalyzerLatticeOccupation.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef LATTICE_OCCUPATION_ANALYZER_H -#define LATTICE_OCCUPATION_ANALYZER_H - -#include -#include - -template -class LatticeOccupationAnalyzer:public IngredientsAnalyzer -{ -public: - LatticeOccupationAnalyzer(const IngredientsType& ing) - :IngredientsAnalyzer(ing) - {} - - virtual ~LatticeOccupationAnalyzer(){} - - - virtual bool execute(); - virtual void initialize(); - virtual void cleanup(){} -}; - - -/************ implementation ******************/ - -template -bool LatticeOccupationAnalyzer::execute() -{ - int32_t boxX=this->getIngredients().getBoxX(); - int32_t boxY=this->getIngredients().getBoxY(); - int32_t boxZ=this->getIngredients().getBoxZ(); - VectorInt3 pos; - int32_t latticeOccupation=0; - for(int32_t x=0;xgetIngredients().getLatticeEntry(pos)>0) - latticeOccupation++; - } - } - } - - std::cout<<"********LatticeOccupationAnalyzer *******************\n"; - std::cout<<"lattice occupation "<getIngredients().getMolecules().size(); - - if(8*this->getIngredients().getMolecules().size()==latticeOccupation) - std::cout<<"...ok"< -void LatticeOccupationAnalyzer::initialize() -{ - std::cout<<"LatticeOccupationAnalyzer:checking initial lattice occupation......"; - execute(); -} - -#endif diff --git a/include/LeMonADE/utility/PairPotentials.h b/include/LeMonADE/utility/PairPotentials.h deleted file mode 100644 index 2ff1895..0000000 --- a/include/LeMonADE/utility/PairPotentials.h +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef PAIR_POTENTIALS_H -#define PAIR_POTENTIALS_H - -#include - -#include - -class PairPotentialSquare{ -public: - PairPotentialSquare():rangeSquared(0) - { - energy.resize(10,std::vector(10,0.0)); - probability.resize(10,std::vector(10,1.0)); - - } - - void setInteraction(int32_t typeA,int32_t typeB,double nrg) - { - energy.at(typeA-1).at(typeB-1)=nrg; - energy.at(typeB-1).at(typeA-1)=nrg; - } - - double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} - - void setRange(double r){rangeSquared=int32_t(r*r);} - double getRange() const {return std::sqrt(rangeSquared);} - - template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - - if(distVector*distVector<=rangeSquared){ - return energy.at(typeA-1).at(typeB-1); - } - - else return 0.0; - } - - template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - - if(distVector*distVector<=rangeSquared){ - return probability.at(typeA-1).at(typeB-1); - } - - else return 1.0; - - } - - template void synchronize(const IngredientsType& ing) - { - std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; - std::vector > probability; - - int32_t rangeSquared; - - -}; - -class PairPotentialSquareEV{ -public: - PairPotentialSquareEV():rangeSquared(0) - { - energy.resize(10,std::vector(10,0.0)); - probability.resize(10,std::vector(10,1.0)); - - } - - void setInteraction(int32_t typeA,int32_t typeB,double nrg) - { - energy.at(typeA-1).at(typeB-1)=nrg; - energy.at(typeB-1).at(typeA-1)=nrg; - } - - double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} - - void setRange(double r){rangeSquared=int32_t(r*r);} - double getRange() const {return std::sqrt(rangeSquared);} - - template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - int32_t dist2=distVector*distVector; - - if(dist2<4){ - return std::numeric_limits< double >::infinity(); - } - else if(dist2<=rangeSquared){ - return energy.at(typeA-1).at(typeB-1); - } - - else return 0.0; - } - - template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - int32_t dist2=distVector*distVector; - - if(dist2<4){ - return 0.0; - } - else if(dist2<=rangeSquared){ - return probability.at(typeA-1).at(typeB-1); - } - - else return 1.0; - - } - - template void synchronize(const IngredientsType& ing) - { - std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; - std::vector > probability; - - int32_t rangeSquared; - - -}; - -class PairPotentialSquareNNI{ -public: - PairPotentialSquareNNI() - :rangeSquared(0),nnEnergy(0.0) - ,expNNEnergy(1.0),exp2NNEnergy(1.0),exp4NNEnergy(1.0) - { - energy.resize(10,std::vector(10,0.0)); - probability.resize(10,std::vector(10,1.0)); - - } - - void setInteraction(int32_t typeA,int32_t typeB,double nrg) - { - energy.at(typeA-1).at(typeB-1)=nrg; - energy.at(typeB-1).at(typeA-1)=nrg; - } - - double getInteraction(int32_t typeA,int32_t typeB) const {return energy.at(typeA-1).at(typeB-1);} - - void setRange(double r){rangeSquared=int32_t(r*r);} - double getRange() const {return std::sqrt(rangeSquared);} - - void setNNRepulsion(double nrg){nnEnergy=nrg;} - double getNNRepultion()const{return nnEnergy;} - - template double getEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - int32_t dist2=distVector*distVector; - - if(dist2<4){ - return std::numeric_limits< double >::infinity(); - } - else if(dist2==4){ - return 4*nnEnergy; - } - else if(dist2==5){ - return 2*nnEnergy; - } - else if(dist2==6){ - return nnEnergy; - } - else if(dist2<=rangeSquared){ - return energy.at(typeA-1).at(typeB-1); - } - - else return 0.0; - } - - template double getExpEnergy(VectorInt3 posA,VectorInt3 posB, int32_t typeA, int32_t typeB, const IngredientsType& ing) const - { - VectorInt3 distVector=Lemonade::calcDistanceVector3D(posA,posB,ing); - int32_t dist2=distVector*distVector; - - if(dist2<4){ - return 0.0; - } - else if(dist2==4){ - return exp4NNEnergy; - } - else if(dist2==5){ - return exp2NNEnergy; - } - else if(dist2==6){ - return expNNEnergy; - } - else if(dist2<=rangeSquared){ - return probability.at(typeA-1).at(typeB-1); - } - - else return 1.0; - - } - - template void synchronize(const IngredientsType& ing) - { - std::cout<<"PairPotentialSquareNNI range set to sqrt("< > energy; - std::vector > probability; - - int32_t rangeSquared; - double nnEnergy; - double expNNEnergy; - double exp2NNEnergy; - double exp4NNEnergy; -}; -#endif /*PAIR_POTENTIALS_H*/ \ No newline at end of file diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 2d2387d..ac955d9 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -1,4 +1,3 @@ add_subdirectory(SimpleSimulator) add_subdirectory(Examples) - From 151005a897612023c5b875884dfe2d35bffd74d3 Mon Sep 17 00:00:00 2001 From: MartinWenge Date: Tue, 10 Jan 2017 11:05:14 +0100 Subject: [PATCH 14/16] added documentation to the code, fixed the normal vector choise, adjusted file and class names and updated contributors list --- AUTHORS | 4 + include/LeMonADE/feature/FeatureWall.h | 182 ++++++++++++++++--------- tests/feature/TestFeatureWall.cpp | 15 +- 3 files changed, 132 insertions(+), 69 deletions(-) diff --git a/AUTHORS b/AUTHORS index c7bc327..bb770ec 100644 --- a/AUTHORS +++ b/AUTHORS @@ -12,6 +12,10 @@ Hauke Rabbel, Germany Martin Wengenmayr, Germany Marco Werner, Germany +Other contributors: +-------------------- +Cornelia StrĂ¼big, Germany: FeatureWall + These authors keep copyright of their contributions. They just grant a license to everyone to use it as detailed in LICENSE.txt. diff --git a/include/LeMonADE/feature/FeatureWall.h b/include/LeMonADE/feature/FeatureWall.h index 325f055..2096ea4 100644 --- a/include/LeMonADE/feature/FeatureWall.h +++ b/include/LeMonADE/feature/FeatureWall.h @@ -36,97 +36,138 @@ along with LeMonADE. If not, see . #include #include #include -#include -//#include #include #include - - - +#include + + +/** + * @file + * @brief Enable arbitrary walls in the simulation box by the FeatureWall + * @details For the \b sc-BFM this feature can hold an arbitrary + * number of walls with normal vectors (1,0,0), (0,1,0) and (0,0,1) being the + * unit vectors along the principal lattice directions. + * + * @todo Enable this feature for the \b bcc-BFM. + * */ + +/** + * @class Wall + * @brief class providing a single wall with definitions, setter and getter functions + * */ class Wall { public: - + //! standard constructor creating an empty wall Wall(): base(), normal() {} + //! getter function for the base vector of the wall const VectorInt3 getBase() const { return base; } - VectorInt3 setBase(uint32_t basX_, uint32_t basY_, uint32_t basZ_) { - base.setAllCoordinates(basX_,basY_,basZ_); + //! setter function for the base vector of the wall + VectorInt3 setBase(uint32_t baseX_, uint32_t baseY_, uint32_t baseZ_) { + base.setAllCoordinates(baseX_,baseY_,baseZ_); } + //! getter function for the normal vector of the wall const VectorInt3 getNormal() const { return normal; } + //! setter function for the normal vector of the wall VectorInt3 setNormal(uint32_t norX_, uint32_t norY_, uint32_t norZ_) { + VectorInt3 test(norX_, norY_, norZ_); + if(test==VectorInt3(1,0,0) || test==VectorInt3(0,1,0) || test==VectorInt3(0,0,1) ){ normal.setAllCoordinates(norX_,norY_,norZ_); + }else{ + throw std::runtime_error("normal vector should be P(1,0,0)"); + } } private: + //! base vector of the wall: arbitrary position somewhere on the wall to provide a well defined wall VectorInt3 base; + //! normal vector of the wall: vector perpendiculat to the walls surface VectorInt3 normal; }; - +/** + * @class FeatureWall + * @brief Feature holding a vector of walls. + * */ class FeatureWall: public Feature { public: - //constructor + //! standard constructor FeatureWall() {} - //destructor + //! standard destructor virtual ~FeatureWall(){} - //read and write wall in/from bfm-file + //! read walls from bfm file template void exportRead(FileImport& fileReader); + //! write walls to bfm file template void exportWrite(AnalyzerWriteBfmFile& fileWriter) const; - //checks if move is allowed by the Metropolis-criterion. - template - bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move); + //! check move function for local sc move + template + bool checkMove(const IngredientsType& ingredients,MoveLocalSc& move); + //! check move function for add sc move template - bool checkMove(const IngredientsType& ingredients,MoveAddScMonomer& addmove); + bool checkMove(const IngredientsType& ingredients,MoveAddMonomerSc& addmove); + //! implemantation of synchronize template void synchronize(const IngredientsType& ingredients); - std::vector getWalls() const - { + //! getter function for the walls container + std::vector getWalls() const{ return walls; } - void addWall(Wall wall) - { + /** + * @brief add function to add a wall to the walls container + * @throw monomer occupies a position on the walls + **/ + void addWall(Wall wall){ + if(wall.getNormal().getLength()!=0.0) walls.push_back(wall); + else + throw std::runtime_error("wall is not well defined: normal vector has length 0"); } - void clearAllWalls() - { + //! empty walls container + void clearAllWalls(){ walls.clear(); } private: - + //! walls container std::vector walls; }; - +/*****************************************************************/ +/** + * @class WriteWall + * + * @brief Handles BFM-File-Write \b #!wall + * @tparam [in] IngredientsType Ingredients class storing all system information. + **/ template class WriteWall: public AbstractWrite { @@ -134,8 +175,7 @@ class WriteWall: public AbstractWrite WriteWall(const IngredientsType& src):AbstractWrite(src){this->setHeaderOnly(true);} - void writeStream(std::ostream& strm) - { + void writeStream(std::ostream& strm){ const IngredientsType& ingredients=(this->getSource()); for (size_t i=0; i }; - +/*****************************************************************/ +/** + * @class ReadWall + * + * @brief Handles BFM-File-Read \b #!wall + * @tparam [in] IngredientsType Ingredients class storing all system information. + **/ template < class IngredientsType > class ReadWall : public ReadToDestination < IngredientsType > { @@ -158,13 +204,12 @@ class ReadWall : public ReadToDestination < IngredientsType > }; - - - - - -/* checkMove */ - +/** + * @details checking if move is going to touch one of the walls + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] move local sc move + */ template bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveLocalSc& move) { @@ -191,12 +236,14 @@ bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveLocalSc& mov return false; } - - -/* checkMove for addmove */ - +/** + * @details checking if added monomer is going to touch one of the walls + * + * @param [in] ingredients A reference to the IngredientsType - mainly the system + * @param [in] addmove move to add sc monomer + */ template -bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveAddScMonomer& addmove) +bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveAddMonomerSc& addmove) { uint32_t counter(0); @@ -221,12 +268,14 @@ bool FeatureWall::checkMove(const IngredientsType& ingredients, MoveAddScMonomer return false; } - - - - -/* synchronize */ - +/** + * @brief Synchronize this feature with the system given as argument + * + * @details checking all monomer positions to be not in conflict with one of the walls + * + * @throw monomer occupies a position on the walls + * @param [in] ingredients a reference to the IngredientsType - mainly the system + **/ template void FeatureWall::synchronize(const IngredientsType& ingredients) { @@ -252,14 +301,12 @@ void FeatureWall::synchronize(const IngredientsType& ingredients) } } - - - - - - -/* ReadWall execute() */ - +/** + * @brief Executes the reading routine to extract \b #!wall. + * + * @throw walls could not be read. + * @tparam IngredientsType Features used in the system. See Ingredients. + **/ template < class IngredientsType > void ReadWall::execute() { @@ -284,9 +331,16 @@ void ReadWall::execute() } - -/* exportRead wall */ - +/** + * @details The function is called by the Ingredients class when an object of type Ingredients + * is associated with an object of type FileImport. The export of the Reads is thus + * taken care automatically when it becomes necessary.\n + * Registered Read-In Commands: + * * #!wall: bx by bz nx ny nz + * + * @param fileReader File importer for the bfm-file + * @tparam IngredientsType Features used in the system. See Ingredients. + **/ template < class IngredientsType > void FeatureWall::exportRead(FileImport& fileReader) { @@ -294,10 +348,16 @@ void FeatureWall::exportRead(FileImport& fileReader) fileReader.registerRead("#!wall:", new ReadWall< IngredientsType > (destination)); } - - -/* exportWrite wall */ - +/** + * The function is called by the Ingredients class when an object of type Ingredients + * is associated with an object of type AnalyzerWriteBfmFile. The export of the Writes is thus + * taken care automatically when it becomes necessary.\n + * Registered Write-Out Commands: + * * #!wall: bx by bz nx ny nz + * + * @param fileWriter File writer for the bfm-file. + * @tparam IngredientsType Features used in the system. See Ingredients. + */ template < class IngredientsType > void FeatureWall::exportWrite(AnalyzerWriteBfmFile& fileWriter) const { @@ -305,6 +365,4 @@ void FeatureWall::exportWrite(AnalyzerWriteBfmFile& fileWriter) fileWriter.registerWrite("#!wall:", new WriteWall (source)); } - - #endif //LEMONADE_FEATURE_WALL_H diff --git a/tests/feature/TestFeatureWall.cpp b/tests/feature/TestFeatureWall.cpp index a7f37ce..933d676 100644 --- a/tests/feature/TestFeatureWall.cpp +++ b/tests/feature/TestFeatureWall.cpp @@ -39,10 +39,7 @@ along with LeMonADE. If not, see . #include #include #include -#include -//#include -//#include - +#include class TestFeatureWall: public ::testing::Test{ @@ -85,7 +82,7 @@ TEST(TestFeatureWall,Moves) //one move of every type MoveLocalSc scmove; - MoveAddScMonomer addmove; + MoveAddMonomerSc addmove; ingredients.modifyMolecules().resize(3); ingredients.modifyMolecules()[0].setAllCoordinates(0,0,0); @@ -95,11 +92,17 @@ TEST(TestFeatureWall,Moves) EXPECT_NO_THROW(ingredients.synchronize(ingredients)); + //************ scmove *************** //build wall in y-z-plane at x=2 -> x=1 should be forbidden Wall wall1; wall1.setBase(2,0,0); + // check forbidden nomal vector: must be a unit vector! P(1,0,0) + EXPECT_ANY_THROW(wall1.setNormal(2,0,0)); + EXPECT_ANY_THROW(wall1.setNormal(0,1,1)); + + //add correct normal vector wall1.setNormal(1,0,0); ingredients.addWall(wall1); /* @@ -130,8 +133,6 @@ TEST(TestFeatureWall,Moves) while((scmove.getDir().getX()==-1) || (scmove.getIndex()!=2)) scmove.init(ingredients); EXPECT_TRUE(ingredients.checkMove(ingredients,scmove)); - - //build additional wall in x-z-plane at y=2 -> x=1 and y=1 should be forbidden now Wall wall2; wall2.setBase(0,2,0); From b02789b17d92d533e1c757c3884d631fccc060fb Mon Sep 17 00:00:00 2001 From: MartinWenge Date: Tue, 10 Jan 2017 15:27:07 +0100 Subject: [PATCH 15/16] added Updater to setup a system containing a monodisperse solution of linear chains. Fix name conflict in Feature NNInteraction and tests --- .../feature/FeatureNNInteractionBcc.h | 16 +- .../LeMonADE/feature/FeatureNNInteractionSc.h | 14 +- .../LeMonADE/updater/UpdaterAddLinearChains.h | 173 ++++++++++++++++++ tests/feature/TestFeatureNNInteractionBcc.cpp | 22 +-- tests/feature/TestFeatureNNInteractionSc.cpp | 16 +- .../updater/TestUpdaterSetupLinearChains.cpp | 130 +++++++++++++ 6 files changed, 337 insertions(+), 34 deletions(-) create mode 100644 include/LeMonADE/updater/UpdaterAddLinearChains.h create mode 100644 tests/updater/TestUpdaterSetupLinearChains.cpp diff --git a/include/LeMonADE/feature/FeatureNNInteractionBcc.h b/include/LeMonADE/feature/FeatureNNInteractionBcc.h index d541b0d..3c5b118 100644 --- a/include/LeMonADE/feature/FeatureNNInteractionBcc.h +++ b/include/LeMonADE/feature/FeatureNNInteractionBcc.h @@ -35,13 +35,13 @@ along with LeMonADE. If not, see . * @author Hauke Rabbel * @brief Definition and implementation of class template FeatureNNInteractionBcc * - * @todo MoveAddBccMonomer is used here, which might be obsolete. + * @todo MoveAddMonomerBcc is used here, which might be obsolete. **/ #include #include #include -#include +#include #include #include #include @@ -139,7 +139,7 @@ class FeatureNNInteractionBcc:public Feature //! apply function for adding a monomer in bcc-BFM template - void applyMove(IngredientsType& ing, const MoveAddBccMonomer& move); + void applyMove(IngredientsType& ing, const MoveAddMonomerBcc& move); //note: apply function for bcc-BFM local move is not necessary, because //job of moving lattice entries is done by the underlying FeatureLatticeType @@ -250,24 +250,24 @@ bool FeatureNNInteractionBcc::checkMove(const IngredientsType& * of this. * * @param [in] ingredients A reference to the IngredientsType - mainly the system - * @param [in] move Monte Carlo move of type MoveAddBccMonomer + * @param [in] move Monte Carlo move of type MoveAddMonomerBcc * @throw std::runtime_error if attribute tag is not in range [1,255] **/ template class LatticeClassType> template void FeatureNNInteractionBcc::applyMove(IngredientsType& ing, - const MoveAddBccMonomer& move) + const MoveAddMonomerBcc& move) { //get the position and attribute tag of the monomer to be inserted VectorInt3 pos=move.getPosition(); - lattice_value_type type=lattice_value_type(move.getType()); + lattice_value_type type=lattice_value_type(move.getTag()); //the feature is based on a uint8_t lattice, thus the max type must not //exceed the max value of uint8_t (255) - if(int32_t(type) != move.getType() || int32_t(type)==0) + if(int32_t(type) != move.getTag() || int32_t(type)==0) { std::stringstream errormessage; - errormessage<<"FeatureNNInteractionBcc::applyMove(MoveAddBccMonomer)\n"; + errormessage<<"FeatureNNInteractionBcc::applyMove(MoveAddMonomerBcc)\n"; errormessage<<"Trying to add monomer with type "<maxType=255\n"; throw std::runtime_error(errormessage.str()); } diff --git a/include/LeMonADE/feature/FeatureNNInteractionSc.h b/include/LeMonADE/feature/FeatureNNInteractionSc.h index 04d347b..2bfcecc 100644 --- a/include/LeMonADE/feature/FeatureNNInteractionSc.h +++ b/include/LeMonADE/feature/FeatureNNInteractionSc.h @@ -109,7 +109,7 @@ class FeatureNNInteractionSc:public Feature //FeatureExcludedVolumeSc needs to be in front, because FeatureNNInteractionSc //re-initializes the lattice and overwrites what FeatureExcludedVolumeSc has written. //FeatureAttributes needs to be in front, because when a monomer is added to the system - //by a MoveAddScMonomer, its attribute has to be set before it is written to the lattice. + //by a MoveAddMonomerSc, its attribute has to be set before it is written to the lattice. typedef LOKI_TYPELIST_2( FeatureAttributes, FeatureExcludedVolumeSc >) @@ -138,7 +138,7 @@ class FeatureNNInteractionSc:public Feature //! apply function for adding a monomer in sc-BFM template - void applyMove(IngredientsType& ing, const MoveAddScMonomer& move); + void applyMove(IngredientsType& ing, const MoveAddMonomerSc& move); //note: apply function for sc-BFM local move is not necessary, because //job of moving lattice entries is done by the underlying FeatureLatticeType @@ -249,27 +249,27 @@ bool FeatureNNInteractionSc::checkMove(const IngredientsType& * of this. * * @param [in] ingredients A reference to the IngredientsType - mainly the system - * @param [in] move Monte Carlo move of type MoveAddScMonomer + * @param [in] move Monte Carlo move of type MoveAddMonomerSc * @throw std::runtime_error if attribute tag is not in range [1,255] **/ template class LatticeClassType> template void FeatureNNInteractionSc::applyMove(IngredientsType& ing, - const MoveAddScMonomer& move) + const MoveAddMonomerSc& move) { //get the position and attribute tag of the monomer to be inserted VectorInt3 pos=move.getPosition(); VectorInt3 dx(1,0,0); VectorInt3 dy(0,1,0); VectorInt3 dz(0,0,1); - lattice_value_type type=lattice_value_type(move.getType()); + lattice_value_type type=lattice_value_type(move.getTag()); //the feature is based on a uint8_t lattice, thus the max type must not //exceed the max value of uint8_t (255) - if(int32_t(type) != move.getType() || int32_t(type)==0) + if(int32_t(type) != move.getTag() || int32_t(type)==0) { std::stringstream errormessage; - errormessage<<"FeatureNNInteractionSc::applyMove(MoveAddScMonomer)\n"; + errormessage<<"FeatureNNInteractionSc::applyMove(MoveAddMonomerSc)\n"; errormessage<<"Trying to add monomer with type "<maxType=255\n"; throw std::runtime_error(errormessage.str()); } diff --git a/include/LeMonADE/updater/UpdaterAddLinearChains.h b/include/LeMonADE/updater/UpdaterAddLinearChains.h new file mode 100644 index 0000000..38bd7f2 --- /dev/null +++ b/include/LeMonADE/updater/UpdaterAddLinearChains.h @@ -0,0 +1,173 @@ +/*-------------------------------------------------------------------------------- + ooo L attice-based | + o\.|./o e xtensible | LeMonADE: An Open Source Implementation of the + o\.\|/./o Mon te-Carlo | Bond-Fluctuation-Model for Polymers +oo---0---oo A lgorithm and | + o/./|\.\o D evelopment | Copyright (C) 2013-2015 by + o/.|.\o E nvironment | LeMonADE Principal Developers + ooo | +---------------------------------------------------------------------------------- + +This file is part of LeMonADE. + +LeMonADE is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LeMonADE is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LeMonADE. If not, see . + +--------------------------------------------------------------------------------*/ + +#ifndef LEMONADE_UPDATER_SETUP_LINEAR_CHAINS +#define LEMONADE_UPDATER_SETUP_LINEAR_CHAINS +/** + * @file + * + * @class UpdaterAddLinearChains + * + * @brief Updater to create a solution of monomdisperse linear chains. + * + * @details This is a simple implementation of a system setup starting from an empty ingredients + * or a system with some monomers inside. This updater requires FeatureAttributes. + * Two tags are added to the monomers in alternating manner, usually needed for GPU computing. + * + * @tparam IngredientsType + * + * @param ingredients_ The system, holding eigther an empty simulation box for system setup + * or a prefilled ingredients where the linear chains shall be added + * @param NChain_ number of chains that are added to ingredients + * @param NMonoPerChain_ number of monomer is each chain + * @param type1_ attribute tag of "even" monomers + * @param type2_ attribute tag of "odd" monomers + **/ + +#include +#include + +template +class UpdaterAddLinearChains: public UpdaterAbstractCreate +{ + typedef UpdaterAbstractCreate BaseClass; + +public: + UpdaterAddLinearChains(IngredientsType& ingredients_, uint32_t NChain_, uint32_t NMonoPerChain_, int32_t type1_=1, int32_t type2_=2); + + virtual void initialize(); + virtual bool execute(); + virtual void cleanup(); + +private: + // provide access to functions of UpdaterAbstractCreate used in this updater + using BaseClass::ingredients; + using BaseClass::addMonomerToParent; + using BaseClass::addSingleMonomer; + using BaseClass::linearizeSystem; + + //! number of monomers in a chain + uint32_t NMonoPerChain; + + //!number of linear chains in the box + uint32_t NChain; + + //! lattice occupation density + double density; + + //! bool for execution + bool wasExecuted; + + //! attribute tag of even monomers + int32_t type1; + + //!getAttributeTag of odd monomers + int32_t type2; + +}; + +/** +* @brief Constructor handling the new systems paramters +* +* @param ingredients_ a reference to the IngredientsType - mainly the system +* @param NChain_ number of chains to be added in the system instead of solvent +* @param NMonoPerChain_ number of monomers in one chain +*/ +template < class IngredientsType > +UpdaterAddLinearChains::UpdaterAddLinearChains(IngredientsType& ingredients_, uint32_t NChain_, uint32_t NMonoPerChain_, int32_t type1_, int32_t type2_): +BaseClass(ingredients_), NChain(NChain_), NMonoPerChain(NMonoPerChain_), density(0), wasExecuted(false), +type1(type1_), type2(type2_) +{} + +/** +* @brief initialise function, calculate the target density to compare with at the end. +* +* @tparam IngredientsType Features used in the system. See Ingredients. +*/ +template < class IngredientsType > +void UpdaterAddLinearChains::initialize(){ + std::cout << "initialize UpdaterAddLinearChains" << std::endl; + + // get the target density from the sum of existing monomers and the new added chains + density=(double)( ingredients.getMolecules().size() + NMonoPerChain*NChain ) * 8 /(double)( ingredients.getBoxX()*ingredients.getBoxY()*ingredients.getBoxZ() ); + + std::cout << "add "< +bool UpdaterAddLinearChains::execute(){ + if(wasExecuted) + return true; + + std::cout << "execute UpdaterAddLinearChains" << std::endl; + + //loop over chains and chain monomers and build it up + for(uint32_t i=0;i<(NChain);i++){ + for(uint32_t j=0;j<(NMonoPerChain);j++){ + if(j==0) + addSingleMonomer(type1); + else{ + if(ingredients.getMolecules()[ingredients.getMolecules().size()-1].getAttributeTag() == type1) + addMonomerToParent(ingredients.getMolecules().size()-1,type2); + else + addMonomerToParent(ingredients.getMolecules().size()-1,type1); + } + } + } + + ingredients.synchronize(); + double lattice_volume(ingredients.getBoxX()*ingredients.getBoxY()*ingredients.getBoxZ()); + if(density =! ( (double)(ingredients.getMolecules().size()*8) / lattice_volume ) ){ + std::cout << density << " " <<( (ingredients.getMolecules().size()*8) / lattice_volume)< +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; + + + + +/************************************************************************/ +//define test fixtures for the different tests their purpose is to set up +//the tests to suppress cout's output such that is does not display on the +//standard output during the tests. this makes google test's output more readeable +/************************************************************************/ + +class TestUpdaterAddLinearChains: public ::testing::Test{ +public: + + //redirect cout output + virtual void SetUp(){ + originalBuffer=cout.rdbuf(); + cout.rdbuf(tempStream.rdbuf()); + }; + + //restore original output + virtual void TearDown(){ + cout.rdbuf(originalBuffer); + }; + +private: + std::streambuf* originalBuffer; + std::ostringstream tempStream; + +}; + +TEST_F(TestUpdaterAddLinearChains, Constructor) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureExcludedVolumeSc< FeatureLatticePowerOfTwo >,FeatureAttributes) Features; + typedef ConfigureSystem Config; + typedef Ingredients IngredientsType; + + IngredientsType ingredients; + + //Constructor call + EXPECT_NO_THROW(UpdaterAddLinearChains Timmy(ingredients,1,2)); +} + +TEST_F(TestUpdaterAddLinearChains, TestUpdater) +{ + typedef LOKI_TYPELIST_3(FeatureMoleculesIO, FeatureExcludedVolumeSc< FeatureLatticePowerOfTwo >,FeatureAttributes) Features; + typedef ConfigureSystem Config; + typedef Ingredients IngredientsType; + + IngredientsType ingredients; + ingredients.setBoxX(16); + ingredients.setBoxY(16); + ingredients.setBoxZ(16); + ingredients.setPeriodicX(true); + ingredients.setPeriodicY(true); + ingredients.setPeriodicZ(true); + ingredients.modifyBondset().addBFMclassicBondset(); + EXPECT_NO_THROW(ingredients.synchronize()); + + UpdaterAddLinearChains Tommy(ingredients, 4, 16); + + // first execution + EXPECT_TRUE(Tommy.execute()); + EXPECT_NO_THROW(ingredients.synchronize()); + EXPECT_EQ((4*16),ingredients.getMolecules().size()); + // check (default) monomer taggs + EXPECT_EQ(1,ingredients.getMolecules()[0].getAttributeTag()); + EXPECT_EQ(2,ingredients.getMolecules()[1].getAttributeTag()); + EXPECT_EQ(1,ingredients.getMolecules()[2].getAttributeTag()); + EXPECT_EQ(2,ingredients.getMolecules()[15].getAttributeTag()); + + // check connectivity + EXPECT_EQ(1, ingredients.getMolecules().getNumLinks(0)); + EXPECT_EQ(2, ingredients.getMolecules().getNumLinks(1)); + EXPECT_EQ(2, ingredients.getMolecules().getNumLinks(14)); + EXPECT_EQ(1, ingredients.getMolecules().getNumLinks(15)); + + EXPECT_EQ(1, ingredients.getMolecules().getNumLinks(16)); + EXPECT_EQ(2, ingredients.getMolecules().getNumLinks(17)); + EXPECT_EQ(2, ingredients.getMolecules().getNumLinks(30)); + EXPECT_EQ(1, ingredients.getMolecules().getNumLinks(31)); + +} + From 72b1056c8cccbbea75cfcdbb31011b8c6d5860b9 Mon Sep 17 00:00:00 2001 From: Ron Dockhorn Date: Tue, 10 Jan 2017 17:04:29 +0100 Subject: [PATCH 16/16] Update CMakeLists.txt change version number for Release 2.0.0 --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b5fecb..11c092e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,9 @@ PROJECT (LeMonADE) SET (APPLICATION_NAME "LeMonADE") SET (APPLICATION_CODENAME "${PROJECT_NAME}") SET (APPLICATION_COPYRIGHT_YEARS "2015") -SET (APPLICATION_VERSION_MAJOR 1) -SET (APPLICATION_VERSION_MINOR 1) -SET (APPLICATION_VERSION_PATCH 3) +SET (APPLICATION_VERSION_MAJOR 2) +SET (APPLICATION_VERSION_MINOR 0) +SET (APPLICATION_VERSION_PATCH 0) SET (APPLICATION_VERSION_TYPE SNAPSHOT) SET (APPLICATION_VERSION_STRING "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}-${APPLICATION_VERSION_TYPE}") SET (APPLICATION_ID "${APPLICATION_VENDOR_ID}.${PROJECT_NAME}")