10 #include "BennettsMethod.h" 11 #include <mcMd/perturb/Perturbation.h> 12 #include <mcMd/perturb/LinearPerturbation.h> 13 #include <mcMd/simulation/Simulation.h> 14 #include <mcMd/simulation/System.h> 16 #include <util/format/Dbl.h> 18 #include <util/containers/DArray.h> 29 const int BennettsMethod::TagDerivative[2] = {1, 2};
30 const int BennettsMethod::TagFermi[2] = {8, 9};
62 myId_ = communicatorPtr_->Get_rank();
63 nProcs_ = communicatorPtr_->Get_size();
69 if (myId_ != nProcs_-1) {
88 read<int>(in,
"nSamplePerBlock", nSamplePerBlock_);
93 shifts_[nProcs_-1]=0.0;
94 readDArray<double>(in,
"shifts", shifts_, nProcs_-1);
97 read<double>(in,
"shift",
shift_);
100 read<double>(in,
"shift",
shift_);
111 isInitialized_ =
true;
121 loadParameter<int>(ar,
"nSamplePerBlock", nSamplePerBlock_);
126 shifts_[nProcs_-1] = 0.0;
127 loadDArray<double>(ar,
"shifts", shifts_, nProcs_-1);
130 loadParameter<double>(ar,
"shift",
shift_);
133 loadParameter<double>(ar,
"shift",
shift_);
137 ar & upperAccumulator_;
156 if (myAccumulator_.nSamplePerBlock()) {
160 isInitialized_ =
true;
171 if (!isInitialized_) {
175 communicatorPtr_->Bcast((
void*)&shifts_[0], nProcs_, MPI::DOUBLE, 0);
180 myAccumulator_.
clear();
181 upperAccumulator_.
clear();
188 int myPort, upperPort;
189 MPI::Request requestFermi[2];
193 if (myId_ != 0 && myId_ != nProcs_ - 1) {
196 upperPort = upperId_%2;
198 for (
int i = 0; i < nParameter_; ++i) {
210 myFermi_ = 1/(1 + exp(myArg_));
211 lowerFermi_ = 1/(1 + exp(lowerArg_));
213 requestFermi[0] = communicatorPtr_->Irecv(&upperFermi_, 1, MPI::DOUBLE, upperId_,
214 TagFermi[upperPort]);
216 requestFermi[1] = communicatorPtr_->Isend(&lowerFermi_, 1, MPI::DOUBLE, lowerId_,
220 requestFermi[0].Wait();
221 requestFermi[1].Wait();
223 upperAccumulator_.
sample(upperFermi_);
224 myAccumulator_.
sample(myFermi_);
226 outputFile_ <<
Dbl(myFermi_) <<
" " <<
Dbl(upperFermi_) <<
" ";
227 outputFile_ << std::endl;
229 }
else if (myId_ == 0) {
232 upperPort = upperId_%2;
234 for (
int i = 0; i < nParameter_; ++i) {
242 myFermi_ = 1/(1 + exp(myArg_));
244 requestFermi[0] = communicatorPtr_->Irecv(&upperFermi_, 1, MPI::DOUBLE, upperId_,
245 TagFermi[upperPort]);
248 requestFermi[0].Wait();
250 upperAccumulator_.
sample(upperFermi_);
251 myAccumulator_.
sample(myFermi_);
253 outputFile_ <<
Dbl(myFermi_) <<
" " <<
Dbl(upperFermi_) <<
" ";
254 outputFile_ << std::endl;
256 }
else if (myId_ == nProcs_ - 1) {
260 for (
int i = 0; i < nParameter_; ++i) {
268 lowerFermi_ = 1/(1 + exp(lowerArg_));
270 requestFermi[1] = communicatorPtr_->Isend(&lowerFermi_, 1, MPI::DOUBLE, lowerId_,
274 requestFermi[1].Wait();
278 void BennettsMethod::analyze()
280 double EnergyDiff, ratio, improvedShift;
281 if (myId_ != nProcs_ - 1) {
285 EnergyDiff = log(ratio)+
shift_;
287 improvedShift = EnergyDiff;
289 shifts_[myId_] = improvedShift;
304 if (myId_ != nProcs_ - 1) {
305 myAccumulator_.
output(outputFile_);
306 outputFile_ << std::endl;
307 outputFile_ << std::endl;
308 upperAccumulator_.
output(outputFile_);
309 outputFile_ << std::endl;
310 outputFile_ << std::endl;
316 communicatorPtr_->Gather((
const void *) &
shift_, 1, MPI::DOUBLE, (
void *) &shifts_[0], 1, MPI::DOUBLE, 0);
320 for (i = 0; i < nProcs_-1; ++i) {
321 outputFile_ <<
Dbl(shifts_[i]);
322 outputFile_ << std::endl;
329 #endif // ifdef UTIL_MPI 330 #endif // ifdef MCMD_PERTURB void clear()
Clear all accumulators, set to empty initial state.
double average() const
Return the average of all sampled values.
void openOutputFile(const std::string &filename, std::ofstream &out, std::ios_base::openmode mode=std::ios_base::out) const
Open an output file.
virtual void loadParameters(Serializable::IArchive &ar)
Load parameters from archive.
double shift_
Value of shift constant for associated system.
A set of interacting Molecules enclosed by a Boundary.
System & system()
Return reference to parent system.
Wrapper for a double precision number, for formatted ostream output.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Saving / output archive for binary ostream.
double parameter(int i, int id)
Get parameter i of system id.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
double lowerShift_
Value of shift constant for lower replica system.
Simulation & simulation() const
Get the parent Simulation by reference.
virtual void sample(long iStep)
Calculate, analyze and/or output a physical quantity.
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
int getNParameters() const
Gets the number of parameters per system.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
MPI::Intracomm & communicator()
Get the MPI communicator by reference.
virtual double difference(DArray< double > iPartnerParameter) const =0
Returns the difference W(X, p') - W(X, p).
virtual void setup()
Clear accumulators.
Template for Analyzer associated with one System.
void output(std::ostream &out) const
Output final statistical properties to file.
void setNSamplePerBlock(int nSamplePerBlock)
Set nSamplePerBlock.
bool hasIoCommunicator() const
Does this object have an associated MPI communicator?
Saving archive for binary istream.
Perturbation & perturbation() const
Get the associated Perturbation by reference.
void sample(double value)
Add a sampled value to the ensemble.
virtual void output()
Output results at end of simulation.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSamplePerBlock() const
Get number of samples per block average.
This file contains templates for global functions send<T>, recv<T> and bcast<T>.
void setClassName(const char *className)
Set class name string.
FileMaster & fileMaster()
Get the FileMaster by reference.
bool isAtInterval(long counter) const
Return true iff counter is a multiple of the interval.
const std::string & outputFileName() const
Return outputFileName string.
void allocate(int capacity)
Allocate the underlying C array.
BennettsMethod(System &system)
Constructor.
virtual void readParameters(std::istream &in)
Read parameters from file.