LCOV - code coverage report
Current view: top level - core - GREX.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 104 136 76.5 %
Date: 2018-12-19 07:49:13 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2018 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 "GREX.h"
      23             : #include "PlumedMain.h"
      24             : #include "Atoms.h"
      25             : #include "tools/Tools.h"
      26             : #include "tools/Communicator.h"
      27             : #include <sstream>
      28             : 
      29             : #include "GREXEnum.inc"
      30             : 
      31             : using namespace std;
      32             : namespace PLMD {
      33             : 
      34         986 : std::map<std::string, int> & GREXWordMap() {
      35         986 :   static std::map<std::string, int> word_map;
      36             :   static bool init=false;
      37         986 :   if(!init) {
      38             : #include "GREXMap.inc"
      39             :   }
      40         986 :   init=true;
      41         986 :   return word_map;
      42             : }
      43             : 
      44          63 : GREX::GREX(PlumedMain&p):
      45             :   initialized(false),
      46          63 :   intracomm(*new Communicator),
      47          63 :   intercomm(*new Communicator),
      48             :   plumedMain(p),
      49          63 :   atoms(p.getAtoms()),
      50             :   partner(-1), // = unset
      51             :   localDeltaBias(0),
      52             :   foreignDeltaBias(0),
      53             :   localUNow(0),
      54             :   localUSwap(0),
      55         252 :   myreplica(-1) // = unset
      56             : {
      57          63 :   p.setSuffix(".NA");
      58          63 : }
      59             : 
      60         189 : GREX::~GREX() {
      61          63 :   delete &intercomm;
      62          63 :   delete &intracomm;
      63         126 : }
      64             : 
      65             : #define CHECK_INIT(ini,word) plumed_massert(ini,"cmd(\"" + word +"\") should be only used after GREX initialization")
      66             : #define CHECK_NOTINIT(ini,word) plumed_massert(!(ini),"cmd(\"" + word +"\") should be only used before GREX initialization")
      67             : #define CHECK_NOTNULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"GREX " + word + "\")");
      68             : 
      69         493 : void GREX::cmd(const string&key,void*val) {
      70         493 :   std::vector<std::string> words=Tools::getWords(key);
      71         493 :   unsigned nw=words.size();
      72         493 :   if(nw==0) {
      73             :     // do nothing
      74             :   } else {
      75         493 :     int iword=-1;
      76         493 :     std::map<std::string, int>::const_iterator it=GREXWordMap().find(words[0]);
      77         493 :     if(it!=GREXWordMap().end()) iword=it->second;
      78         493 :     switch(iword) {
      79             :     case cmd_initialized:
      80           0 :       CHECK_NOTNULL(val,key);
      81           0 :       *static_cast<int*>(val)=initialized;
      82           0 :       break;
      83             :     case cmd_setMPIIntracomm:
      84          63 :       CHECK_NOTINIT(initialized,key);
      85          63 :       intracomm.Set_comm(val);
      86          63 :       break;
      87             :     case cmd_setMPIIntercomm:
      88          43 :       CHECK_NOTINIT(initialized,key);
      89          43 :       intercomm.Set_comm(val);
      90          43 :       plumedMain.multi_sim_comm.Set_comm(val);
      91          43 :       break;
      92             :     case cmd_setMPIFIntracomm:
      93           0 :       CHECK_NOTINIT(initialized,key);
      94           0 :       intracomm.Set_fcomm(val);
      95           0 :       break;
      96             :     case cmd_setMPIFIntercomm:
      97           0 :       CHECK_NOTINIT(initialized,key);
      98           0 :       intercomm.Set_fcomm(val);
      99           0 :       plumedMain.multi_sim_comm.Set_fcomm(val);
     100           0 :       break;
     101             :     case cmd_init:
     102          63 :       CHECK_NOTINIT(initialized,key);
     103          63 :       initialized=true;
     104             : // note that for PEs!=root this is automatically 0 (comm defaults to MPI_COMM_SELF)
     105          63 :       myreplica=intercomm.Get_rank();
     106          63 :       intracomm.Sum(myreplica);
     107             :       {
     108          63 :         std::string s;
     109          63 :         Tools::convert(myreplica,s);
     110          63 :         plumedMain.setSuffix("."+s);
     111             :       }
     112          63 :       break;
     113             :     case cmd_prepare:
     114          36 :       CHECK_INIT(initialized,key);
     115          36 :       if(intracomm.Get_rank()==0) return;
     116          36 :       intracomm.Bcast(partner,0);
     117          36 :       calculate();
     118          36 :       break;
     119             :     case cmd_setPartner:
     120          36 :       CHECK_INIT(initialized,key);
     121          36 :       partner=*static_cast<int*>(val);
     122          36 :       break;
     123             :     case cmd_savePositions:
     124          72 :       CHECK_INIT(initialized,key);
     125          72 :       savePositions();
     126          72 :       break;
     127             :     case cmd_calculate:
     128          36 :       CHECK_INIT(initialized,key);
     129          36 :       if(intracomm.Get_rank()!=0) return;
     130          36 :       intracomm.Bcast(partner,0);
     131          36 :       calculate();
     132          36 :       break;
     133             :     case cmd_getLocalDeltaBias:
     134           0 :       CHECK_INIT(initialized,key);
     135           0 :       CHECK_NOTNULL(val,key);
     136           0 :       atoms.double2MD(localDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
     137           0 :       break;
     138             :     case cmd_cacheLocalUNow:
     139           0 :       CHECK_INIT(initialized,key);
     140           0 :       CHECK_NOTNULL(val,key);
     141             :       {
     142             :         double x;
     143           0 :         atoms.MD2double(val,x);
     144           0 :         localUNow=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
     145           0 :         intracomm.Sum(localUNow);
     146             :       }
     147           0 :       break;
     148             :     case cmd_cacheLocalUSwap:
     149           0 :       CHECK_INIT(initialized,key);
     150           0 :       CHECK_NOTNULL(val,key);
     151             :       {
     152             :         double x;
     153           0 :         atoms.MD2double(val,x);
     154           0 :         localUSwap=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
     155           0 :         intracomm.Sum(localUSwap);
     156             :       }
     157           0 :       break;
     158             :     case cmd_getForeignDeltaBias:
     159           0 :       CHECK_INIT(initialized,key);
     160           0 :       CHECK_NOTNULL(val,key);
     161           0 :       atoms.double2MD(foreignDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
     162           0 :       break;
     163             :     case cmd_shareAllDeltaBias:
     164          36 :       CHECK_INIT(initialized,key);
     165          36 :       if(intracomm.Get_rank()!=0) return;
     166          36 :       allDeltaBias.assign(intercomm.Get_size(),0.0);
     167          36 :       allDeltaBias[intercomm.Get_rank()]=localDeltaBias;
     168          36 :       intercomm.Sum(allDeltaBias);
     169          36 :       break;
     170             :     case cmd_getDeltaBias:
     171         108 :       CHECK_INIT(initialized,key);
     172         108 :       CHECK_NOTNULL(val,key);
     173         108 :       plumed_assert(nw==2);
     174         108 :       plumed_massert(allDeltaBias.size()==static_cast<unsigned>(intercomm.Get_size()),
     175           0 :                      "to retrieve bias with cmd(\"GREX getDeltaBias\"), first share it with cmd(\"GREX shareAllDeltaBias\")");
     176             :       {
     177             :         unsigned rep;
     178         108 :         Tools::convert(words[1],rep);
     179         108 :         plumed_massert(rep<allDeltaBias.size(),"replica index passed to cmd(\"GREX getDeltaBias\") is out of range");
     180         108 :         double d=allDeltaBias[rep]/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
     181         108 :         atoms.double2MD(d,val);
     182             :       }
     183         108 :       break;
     184             :     default:
     185           0 :       plumed_merror("cannot interpret cmd(\" GREX" + key + "\"). check plumed developers manual to see the available commands.");
     186             :       break;
     187             :     }
     188         493 :   }
     189             : }
     190             : 
     191          72 : void GREX::savePositions() {
     192          72 :   plumedMain.prepareDependencies();
     193          72 :   plumedMain.resetActive(true);
     194          72 :   atoms.shareAll();
     195          72 :   plumedMain.waitData();
     196          72 :   ostringstream o;
     197          72 :   atoms.writeBinary(o);
     198          72 :   buffer=o.str();
     199          72 : }
     200             : 
     201          72 : void GREX::calculate() {
     202             : //fprintf(stderr,"CALCULATE %d %d\n",intercomm.Get_rank(),partner);
     203          72 :   unsigned nn=buffer.size();
     204          72 :   vector<char> rbuf(nn);
     205          72 :   localDeltaBias=-plumedMain.getBias();
     206          72 :   if(intracomm.Get_rank()==0) {
     207          36 :     Communicator::Request req=intercomm.Isend(buffer,partner,1066);
     208          36 :     intercomm.Recv(rbuf,partner,1066);
     209          36 :     req.wait();
     210             :   }
     211          72 :   intracomm.Bcast(rbuf,0);
     212         144 :   istringstream i(string(&rbuf[0],rbuf.size()));
     213          72 :   atoms.readBinary(i);
     214          72 :   plumedMain.setExchangeStep(true);
     215          72 :   plumedMain.prepareDependencies();
     216          72 :   plumedMain.justCalculate();
     217          72 :   plumedMain.setExchangeStep(false);
     218          72 :   localDeltaBias+=plumedMain.getBias();
     219          72 :   localDeltaBias+=localUSwap-localUNow;
     220          72 :   if(intracomm.Get_rank()==0) {
     221          36 :     Communicator::Request req=intercomm.Isend(localDeltaBias,partner,1067);
     222          36 :     intercomm.Recv(foreignDeltaBias,partner,1067);
     223          36 :     req.wait();
     224             : //fprintf(stderr,">>> %d %d %20.12f %20.12f %20.12f %20.12f\n",intercomm.Get_rank(),partner,localDeltaBias,foreignDeltaBias,localUSwap,localUNow);
     225             :   }
     226         144 :   intracomm.Bcast(foreignDeltaBias,0);
     227          72 : }
     228             : 
     229        2523 : }

Generated by: LCOV version 1.13