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 : }
|