Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2017-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #ifndef __PLUMED_core_DomainDecomposition_h 23 : #define __PLUMED_core_DomainDecomposition_h 24 : 25 : #include "ActionForInterface.h" 26 : #include "tools/Communicator.h" 27 : 28 : namespace PLMD { 29 : 30 : class ActionToPutData; 31 : class ActionAtomistic; 32 : 33 : class DomainDecomposition : public ActionForInterface { 34 : private: 35 : class DomainComms : public Communicator { 36 : public: 37 : bool on; 38 : bool async; 39 : 40 : std::vector<Communicator::Request> mpi_request_positions; 41 : std::vector<Communicator::Request> mpi_request_index; 42 : 43 : std::vector<double> positionsToBeSent; 44 : std::vector<double> positionsToBeReceived; 45 : std::vector<int> indexToBeSent; 46 : std::vector<int> indexToBeReceived; 47 : operator bool() const { 48 695412 : return on; 49 : } 50 2176 : DomainComms(): on(false), async(false) {} 51 : void enable(Communicator& c); 52 : }; 53 : DomainComms dd; 54 : long int ddStep; 55 : 56 : std::vector<int> gatindex; 57 : /// Map global indexes to local indexes 58 : /// E.g. g2l[i] is the position of atom i in the array passed from the MD engine. 59 : /// Called "global to local" since originally it was used to map global indexes to local 60 : /// ones used in domain decomposition. However, it is now also used for the NAMD-like 61 : /// interface, where only a small number of atoms is passed to plumed. 62 : std::vector<int> g2l; 63 : 64 : unsigned shuffledAtoms; 65 : 66 : bool asyncSent; 67 : bool unique_serial; // use unique in serial mode 68 : /// Are g2l and shuffledAtoms consistent with gatindex 69 : bool g2lIsValid; 70 : /// Are unique, forced_unique and the corresponding indexes up to date with the atoms requested by the actions 71 : bool uniqueListsValid; 72 : /// Is allActiveUnique up to date 73 : bool allActiveValid; 74 : /// Is any active action using atoms (the same on all ranks) 75 : bool atomsNeeded; 76 : /// This holds the list of unique atoms that are local to this rank 77 : std::vector<AtomNumber> unique; 78 : /// The position of the atoms in unique in the arrays passed from the MD code 79 : std::vector<unsigned> uniq_index; 80 : /// This holds the list of atoms that have a force on 81 : std::vector<AtomNumber> forced_unique; 82 : /// The position of the atoms in forced_unique in the arrays passed from the MD code 83 : std::vector<unsigned> forced_uniq_index; 84 : /// The atoms requested by all the active actions, including those that are not local (used with domain decomposition) 85 : std::vector<AtomNumber> allActiveUnique; 86 : /// A buffer used when the list of active atoms has to be rebuilt 87 : std::vector<AtomNumber> activeAtomsBuffer; 88 : /// The state of each action when the lists were built: 0 inactive or without atoms, 1 active, 2 active and applying forces 89 : std::vector<unsigned char> actionState; 90 : /// The values that are exchanged between the domains in share and received in wait 91 : std::vector<Value*> values_to_get; 92 : /// This holds the list of actions that are set from this action 93 : std::vector<ActionToPutData*> inputs; 94 : /// This holds all the actions that read atoms 95 : std::vector<ActionAtomistic*> actions; 96 : /// The list that holds all the atom indexes we need 97 : std::vector<int> fullList; 98 : /// Are all the atoms local and in the order of their index 99 : bool allAtomsAreLocal() const ; 100 : /// The lists of atoms must be rebuilt at the next share 101 : void invalidateUniqueLists(); 102 : /// Compute uniq_index and forced_uniq_index 103 : void setIndexesInMDArrays(); 104 : /// Rebuild the lists of atoms if the active actions or their atoms changed, returns true if they were rebuilt 105 : bool updateUniqueLists(); 106 : /// Did an active action request different atoms after the lists were built 107 : bool activeAtomsChangedSinceShare() const ; 108 : /// This actually does the sharing of the data across the domains, either all the atoms or those in unique 109 : void shareValues( const bool& allAtoms ); 110 : /// Get all the atoms in the input that are active at this time 111 : void getAllActiveAtoms( std::vector<AtomNumber>& u ); 112 : public: 113 : static void registerKeywords(Keywords& keys); 114 : explicit DomainDecomposition(const ActionOptions&ao); 115 : void setStart( const std::string& name, const unsigned& sss) override ; 116 : void setStride( const std::string& name, const unsigned& sss) override ; 117 : void resetForStepStart() override ; 118 : bool setValuePointer( const std::string& name, const TypesafePtr & ) override ; 119 : bool setForcePointer( const std::string& name, const TypesafePtr & ) override ; 120 : unsigned getNumberOfForcesToRescale() const override ; 121 : void share() override ; 122 : void shareAll() override ; 123 : void wait() override ; 124 : void reset() override ; 125 : void writeBinary(std::ostream&o) override ; 126 : void readBinary(std::istream&i) override ; 127 : void apply() override ; 128 : void setAtomsNlocal(int n); 129 : void setAtomsGatindex(const TypesafePtr & g,bool fortran); 130 : void setAtomsContiguous(int start); 131 : void Set_comm(Communicator& comm) override ; 132 : void broadcastToDomains( Value* val ); 133 : void sumOverDomains( Value* val ); 134 : const long int& getDdStep() const ; 135 : const std::vector<int>& getGatindex() const ; 136 : void createFullList(const TypesafePtr & x); 137 : void getFullList(const TypesafePtr & x); 138 : void clearFullList(); 139 1858 : bool onStep() const override { 140 1858 : return getNumberOfAtoms()>0; 141 : } 142 : unsigned getNumberOfAtoms() const; 143 5468 : DomainDecomposition* castToDomainDecomposition() noexcept final { 144 5468 : return this; 145 : } 146 : }; 147 : 148 : } 149 : #endif