Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-2017 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 : #include "core/ActionWithValue.h" 23 : #include "core/ActionWithArguments.h" 24 : #include "core/ActionRegister.h" 25 : #include "tools/Communicator.h" 26 : 27 : //+PLUMEDOC ANALYSIS GATHER_REPLICAS 28 : /* 29 : Create a vector that contains the copies of the input quantities from all replicas 30 : 31 : \par Examples 32 : 33 : 34 : */ 35 : //+ENDPLUMEDOC 36 : 37 : namespace PLMD { 38 : namespace generic { 39 : 40 : class GatherReplicas : 41 : public ActionWithValue, 42 : public ActionWithArguments { 43 : private: 44 : unsigned nreplicas; 45 : public: 46 : static void registerKeywords( Keywords& keys ); 47 : explicit GatherReplicas( const ActionOptions& ); 48 : unsigned getNumberOfDerivatives(); 49 : void calculate(); 50 : void apply(); 51 : }; 52 : 53 : PLUMED_REGISTER_ACTION(GatherReplicas,"GATHER_REPLICAS") 54 : 55 29 : void GatherReplicas::registerKeywords( Keywords& keys ) { 56 29 : Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); 57 58 : keys.addInputKeyword("compulsory","ARG","scalar/vector/matrix/grid","the argument from the various replicas that you would like to gather"); 58 58 : keys.addOutputComponent("rep","default","scalar/vector/matrix/grid","the input arguments for each of the replicas"); 59 29 : } 60 : 61 13 : GatherReplicas::GatherReplicas( const ActionOptions& ao ): 62 : Action(ao), 63 : ActionWithValue(ao), 64 13 : ActionWithArguments(ao) 65 : { 66 13 : if( getNumberOfArguments()!=1 ) error("you can only gather one argument at a time with GatherReplicas"); 67 : 68 13 : std::vector<unsigned> shape( getPntrToArgument(0)->getShape() ); 69 13 : std::string min, max; nreplicas=multi_sim_comm.Get_size(); bool periodic=false; 70 13 : if( getPntrToArgument(0)->isPeriodic() ) { periodic=true; getPntrToArgument(0)->getDomain( min, max ); } 71 : 72 86 : for(unsigned i=0; i<nreplicas; ++i) { 73 73 : std::string num; Tools::convert( i+1, num); 74 146 : if( getPntrToArgument(0)->hasDerivatives() ) addComponentWithDerivatives( "rep-" + num, shape ); 75 0 : else addComponent( "rep-" + num, shape ); 76 73 : if( periodic ) componentIsPeriodic( "rep-" + num, min, max ); 77 146 : else componentIsNotPeriodic( "rep-" + num ); 78 : } 79 13 : } 80 : 81 0 : unsigned GatherReplicas::getNumberOfDerivatives() { 82 0 : return getPntrToArgument(0)->getNumberOfDerivatives(); 83 : } 84 : 85 4224 : void GatherReplicas::calculate() { 86 : Value* myarg = getPntrToArgument(0); 87 4224 : unsigned nvals = myarg->getNumberOfValues(), nder = myarg->getNumberOfDerivatives(); 88 4224 : std::vector<double> dval( nvals*(1+nder) ), datap(nreplicas*nvals*(1+nder) ); 89 8448 : for(unsigned i=0; i<nvals; ++i) { 90 4224 : dval[i*(1+nder)] = myarg->get(i); 91 8448 : if( myarg->getRank()==0 ) { for(unsigned j=0; j<nder; ++j) dval[i*(1+nder)+1+j] = myarg->getDerivative(j); } 92 0 : else if( myarg->hasDerivatives() ) { for(unsigned j=0; j<nder; ++j) dval[i*(1+nder)+1+j] = myarg->getGridDerivative( i, j ); } 93 : } 94 4224 : if(comm.Get_rank()==0) multi_sim_comm.Allgather(dval,datap); 95 : 96 29568 : for(unsigned k=0; k<nreplicas; k++) { 97 25344 : Value* myout = getPntrToComponent(k); 98 25344 : if( myout->getNumberOfDerivatives()!=myarg->getNumberOfDerivatives() ) myout->resizeDerivatives( myarg->getNumberOfDerivatives() ); 99 25344 : unsigned sstart=k*nvals*(1+nder); 100 50688 : for(unsigned i=0; i<nvals; ++i) { 101 25344 : myout->set( i, datap[sstart+i*(1+nder)] ); 102 50688 : if( myarg->getRank()==0 ) { for(unsigned j=0; j<nder; ++j) myout->setDerivative( j, dval[i*(1+nder)+1+j] ); } 103 0 : else if( myarg->hasDerivatives() ) { for(unsigned j=0; j<nder; ++j) myout->addGridDerivatives( i, j, dval[i*(1+nder)+1+j] ); } 104 : } 105 : } 106 4224 : } 107 : 108 4224 : void GatherReplicas::apply() { 109 4224 : if( doNotCalculateDerivatives() ) return; 110 0 : error("apply has not been implemented for GatherReplicas"); 111 : } 112 : 113 : } 114 : }