Program Listing for File montercarlo_vertex.cpp#
↰ Return to documentation for file (pymembrane/cppmodule/src/integrators/montercarlo_vertex.cpp)
#include "montercarlo_vertex.hpp"
int MonteCarloIntegratorVertex::integrate(void)
{
int accepted_moves = 0;
for(int vertex_index = 0; vertex_index<_system.Numvertices; vertex_index++)
{
// The following IF makes sure that we only move either particle-free vertices or the central vertex of a particle:
if ((_system.vertices[vertex_index].type==-1) || (_system.vertices[vertex_index].type==vertex_index)) {
//attempt to move the vertex
double dx, dy, dz;
double orig_pos[_system.Numvertices][3];
if (m_spherical_move)
{
double x = _system.vertices[vertex_index].r.x, y =_system.vertices[vertex_index].r.y, z= _system.vertices[vertex_index].r.z;
double r = sqrt(x * x + y * y + z * z);
double sigma = sqrt(m_dx * m_dx + m_dy * m_dy + m_dz * m_dz);
dx = m_rng->gauss_rng(sigma);
dy = m_rng->gauss_rng(sigma);
dz = m_rng->gauss_rng(sigma);
double x_new = x + dx, y_new = y + dy, z_new = z + dz;
double r_new = sqrt(x_new * x_new + y_new * y_new + z_new * z_new);
double scale = r / r_new;
dx = scale * x_new - x;
dy = scale * y_new - y;
dz = scale * z_new - z;
}
else
{
dx = m_dx * (m_rng->drnd() - 0.5);
dy = m_dy * (m_rng->drnd() - 0.5);
dz = m_dz * (m_rng->drnd() - 0.5);
}
double energy_i = this->ComputeEnergyFromVertex(vertex_index);
if (_system.vertices[vertex_index].type==-1) { //Particle-free vertices move as usual.
_system.vertices[vertex_index].r.x+= dx;
_system.vertices[vertex_index].r.y+= dy;
_system.vertices[vertex_index].r.z+= dz;
} else if (_system.vertices[vertex_index].type==vertex_index) { //Vertices located "inside a particle" move together with the particle center, as a solid body.
for(int vertex_index_ii = 0; vertex_index_ii<_system.Numvertices; vertex_index_ii++) {
if (_system.vertices[vertex_index_ii].type==vertex_index) {
//Keep the original positions, to be able to step back, if MC step is declined.
double x=_system.vertices[vertex_index_ii].r.x;
double y=_system.vertices[vertex_index_ii].r.y;
double z=_system.vertices[vertex_index_ii].r.z;
orig_pos[vertex_index_ii][0]=x;
orig_pos[vertex_index_ii][1]=y;
orig_pos[vertex_index_ii][2]=z;
double x_new=x + dx;
double y_new=y + dy;
double z_new=z + dz;
double dx1 = dx;
double dy1 = dy;
double dz1 = dz;
if (m_spherical_move) {
double r = sqrt(x * x + y * y + z * z);
double r_new = sqrt(x_new * x_new + y_new * y_new + z_new * z_new);
double scale = r / r_new;
double dx1 = scale * x_new - x;
double dy1 = scale * y_new - y;
double dz1 = scale * z_new - z;
}
_system.vertices[vertex_index_ii].r.x+=dx1;
_system.vertices[vertex_index_ii].r.y+=dy1;
_system.vertices[vertex_index_ii].r.z+=dz1;
}
}
}
double energy_f = this->ComputeEnergyFromVertex(vertex_index);
double delE = energy_f - energy_i;
accepted_moves++;
if (!(delE<0.0))
{
if (!(m_rng->drnd() < exp(-delE/get_temperature())))
{
if (_system.vertices[vertex_index].type==-1) {
_system.vertices[vertex_index].r.x-= dx;
_system.vertices[vertex_index].r.y-= dy;
_system.vertices[vertex_index].r.z-= dz;
} else if (_system.vertices[vertex_index].type==vertex_index) { //Vertices located "inside a particle" move together with the particle center, as a solid body.
for(int vertex_index_ii = 0; vertex_index_ii<_system.Numvertices; vertex_index_ii++) {
if (_system.vertices[vertex_index_ii].type==vertex_index) {
_system.vertices[vertex_index_ii].r.x=orig_pos[vertex_index_ii][0];
_system.vertices[vertex_index_ii].r.y=orig_pos[vertex_index_ii][1];
_system.vertices[vertex_index_ii].r.z=orig_pos[vertex_index_ii][2];
}
}
}
accepted_moves--;
}
}
}
}
double totE=0;
for(int vertex_index = 0; vertex_index<_system.Numvertices; vertex_index++)
{
totE+=this->ComputeEnergyFromVertex(vertex_index);
}
return(accepted_moves);
}