mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
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