mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
mc.cpp
00001 #include "mcpele/mc.h"
00002 #include "mcpele/progress.h"
00003 
00004 using pele::Array;
00005 
00006 namespace mcpele{
00007 
00008 MC::MC(std::shared_ptr<pele::BasePotential> potential, Array<double>& coords, const double temperature)
00009     : m_potential(potential),
00010       m_coords(coords.copy()),
00011       m_trial_coords(m_coords.copy()),
00012       m_take_step(NULL),
00013       m_nitercount(0),
00014       m_accept_count(0),
00015       m_E_reject_count(0),
00016       m_conf_reject_count(0),
00017       m_success(true),
00018       m_print_progress(false),
00019       m_niter(0),
00020       m_neval(0),
00021       m_temperature(temperature),
00022       m_report_steps(0)
00023 {
00024     m_energy = compute_energy(m_coords);
00025     m_trial_energy = m_energy;
00026     /*std::cout<<"mcrunner Energy is "<<_energy<< "\n";
00027     std::cout<<"mcrunner potential ptr is "<<_potential<< "\n";*/
00028 }
00029 
00033 bool MC::do_conf_tests(Array<double> x)
00034 {
00035     bool result;
00036     for (auto & test : m_conf_tests) {
00037         result = test->conf_test(x, this);
00038         if (not result) {
00039             ++m_conf_reject_count;
00040             return false;
00041         }
00042     }
00043     return true;
00044 }
00045 
00049 bool MC::do_accept_tests(Array<double> xtrial, double etrial, Array<double> xold, double eold)
00050 {
00051     bool result;
00052     for (auto & test : m_accept_tests) {
00053         result = test->test(xtrial, etrial, xold, eold, m_temperature, this);
00054         if (not result) {
00055             ++m_E_reject_count;
00056             return false;
00057         }
00058     }
00059     return true;
00060 }
00061 
00065 bool MC::do_late_conf_tests(Array<double> x)
00066 {
00067     bool result;
00068     for (auto & test : m_late_conf_tests) {
00069         result = test->conf_test(x, this);
00070         if (not result) {
00071             ++m_conf_reject_count;
00072             return false;
00073         }
00074     }
00075     return true;
00076 }
00077 
00078 void MC::do_actions(Array<double> x, double energy, bool success)
00079 {
00080     for (auto & action : m_actions){
00081         action->action(x, energy, success, this);
00082     }
00083 }
00084 
00085 void MC::take_steps()
00086 {
00087     m_take_step->displace(m_trial_coords, this);
00088 }
00089 
00090 
00091 void MC::one_iteration()
00092 {
00093     m_success = true;
00094     ++m_niter;
00095     ++m_nitercount;
00096 
00097     m_trial_coords.assign(m_coords);
00098 
00099     // take a step with the trial coords
00100     //_takestep->takestep(_trial_coords, _stepsize, this);
00101     take_steps();
00102 
00103     // perform the initial configuration tests
00104     m_success = do_conf_tests(m_trial_coords);
00105 
00106     // if the trial configuration is OK, compute the energy, and run the acceptance tests
00107     if (m_success) {
00108         // compute the energy
00109         m_trial_energy = compute_energy(m_trial_coords);
00110 
00111         // perform the acceptance tests.  Stop as soon as one of them fails
00112         m_success = do_accept_tests(m_trial_coords, m_trial_energy, m_coords, m_energy);
00113     }
00114 
00115     // Do some final checks to ensure the configuration is OK.
00116     // These come last because they might be computationally demanding.
00117     if (m_success) {
00118         m_success = do_late_conf_tests(m_trial_coords);
00119     }
00120 
00121     // adapt stepsize etc.
00122     if (get_iterations_count() <= m_report_steps) {
00123         m_take_step->report(m_coords, m_energy, m_trial_coords, m_trial_energy, m_success, this);
00124     }
00125 
00126     // if the step is accepted, copy the coordinates and energy
00127     if (m_success) {
00128         m_coords.assign(m_trial_coords);
00129         m_energy = m_trial_energy;
00130         ++m_accept_count;
00131     }
00132 
00133     // perform the actions on the new configuration
00134     do_actions(m_coords, m_energy, m_success);
00135 }
00136 
00137 void MC::check_input(){
00138     //std::cout << "_conf_tests.size(): " << _conf_tests.size() <<  "\n"; //debug
00139     //std::cout << "_late_conf_tests.size(): " << _late_conf_tests.size() <<  "\n"; //debug
00140     //std::cout << "_actions.size(): " << _actions.size() <<  "\n"; //debug
00141     //std::cout << "_accept_tests.size(): " << _accept_tests.size() <<  "\n"; //debug
00142     if (!take_step_specified()) throw std::runtime_error("MC::check_input: takestep not set");
00143     if (m_conf_tests.size()==0 && m_late_conf_tests.size()==0) std::cout << "warning: no conf tests set" <<"\n";
00144     if (m_actions.size()==0) std::cout << "warning: no actions set" <<  "\n";
00145     if (m_accept_tests.size()==0) std::cout << "warning: no accept tests set" <<  "\n";
00146 }
00147 
00148 void MC::set_coordinates(pele::Array<double>& coords, double energy)
00149 {
00150     m_coords = coords.copy();
00151     m_energy = energy;
00152 }
00153 
00154 //this function is necessary if for example some potential parameter has been varied
00155 void MC::reset_energy()
00156 {
00157     if(m_niter > 0){
00158         throw std::runtime_error("MC::reset_energy after first iteration is forbidden");
00159     }
00160     m_energy = compute_energy(m_coords);
00161 }
00162 
00163 void MC::run(size_t max_iter)
00164 {
00165     check_input();
00166     progress stat(max_iter);
00167     while(m_niter < max_iter) {
00168         //std::cout << "done: " << double(m_niter) / double(max_iter) <<  "\n";
00169         //std::cout << "m_niter: " << m_niter <<  "\n";
00170         //std::cout << "max_iter: " << max_iter <<  "\n";
00171         this->one_iteration();
00172         if (m_print_progress) {
00173             stat.next(m_niter);
00174         }
00175     }
00176     m_niter = 0;
00177 }
00178 
00179 }//namespace mcpele
 All Classes Namespaces Functions Variables Typedefs