void colvar::distance6::calc_value()
{
  group1.reset_atoms_data();
  group2.reset_atoms_data();

  group1.read_positions();
  group2.read_positions();

  x.real_value = 0.0;
  if (b_no_PBC) {
    for (cvm::atom_iter ai1 = group1.begin(); ai1 != group1.end(); ai1++) {
      for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) {
        cvm::rvector const dv = ai2->pos - ai1->pos;
        cvm::real const d2 = dv.norm2();
        x.real_value += 1.0/(d2*d2*d2);
        cvm::rvector const dsumddv = -6.0/(d2*d2*d2*d2) * dv;
        ai1->grad += -1.0 * dsumddv;
        ai2->grad +=        dsumddv;
      }
    }
  } else {
    for (cvm::atom_iter ai1 = group1.begin(); ai1 != group1.end(); ai1++) {
      for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) {
        cvm::rvector const dv = cvm::position_distance (ai1->pos, ai2->pos);
        cvm::real const d2 = dv.norm2();
        x.real_value += 1.0/(d2*d2*d2);
        cvm::rvector const dsumddv = -6.0/(d2*d2*d2*d2) * dv;
        ai1->grad += -1.0 * dsumddv;
        ai2->grad +=        dsumddv;
      }
    }
  }

  x.real_value = std::pow (x.real_value, -1.0/6.0);
}
Ejemplo n.º 2
0
cvm::real colvar::coordnum::switching_function(cvm::rvector const &r0_vec,
                                                int const &en,
                                                int const &ed,
                                                cvm::atom &A1,
                                                cvm::atom &A2)
{
  cvm::rvector const diff = cvm::position_distance(A1.pos, A2.pos);
  cvm::rvector const scal_diff(diff.x/r0_vec.x, diff.y/r0_vec.y, diff.z/r0_vec.z);
  cvm::real const l2 = scal_diff.norm2();

  // Assume en and ed are even integers, and avoid sqrt in the following
  int const en2 = en/2;
  int const ed2 = ed/2;

  cvm::real const xn = std::pow(l2, en2);
  cvm::real const xd = std::pow(l2, ed2);
  cvm::real const func = (1.0-xn)/(1.0-xd);

  if (calculate_gradients) {
    cvm::real const dFdl2 = (1.0/(1.0-xd))*(en2*(xn/l2) - func*ed2*(xd/l2))*(-1.0);
    cvm::rvector const dl2dx((2.0/(r0_vec.x*r0_vec.x))*diff.x,
                             (2.0/(r0_vec.y*r0_vec.y))*diff.y,
                             (2.0/(r0_vec.z*r0_vec.z))*diff.z);
    A1.grad += (-1.0)*dFdl2*dl2dx;
    A2.grad +=        dFdl2*dl2dx;
  }
  return func;
}
Ejemplo n.º 3
0
void colvar::distance_inv::calc_value()
{
  x.real_value = 0.0;
  if (!is_enabled(f_cvc_pbc_minimum_image)) {
    for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) {
      for (cvm::atom_iter ai2 = group2->begin(); ai2 != group2->end(); ai2++) {
        cvm::rvector const dv = ai2->pos - ai1->pos;
        cvm::real const d2 = dv.norm2();
        cvm::real dinv = 1.0;
        for (int ne = 0; ne < exponent/2; ne++)
          dinv *= 1.0/d2;
        x.real_value += dinv;
        cvm::rvector const dsumddv = -(cvm::real(exponent)) * dinv/d2 * dv;
        ai1->grad += -1.0 * dsumddv;
        ai2->grad +=        dsumddv;
      }
    }
  } else {
    for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) {
      for (cvm::atom_iter ai2 = group2->begin(); ai2 != group2->end(); ai2++) {
        cvm::rvector const dv = cvm::position_distance(ai1->pos, ai2->pos);
        cvm::real const d2 = dv.norm2();
        cvm::real dinv = 1.0;
        for (int ne = 0; ne < exponent/2; ne++)
          dinv *= 1.0/d2;
        x.real_value += dinv;
        cvm::rvector const dsumddv = -(cvm::real(exponent)) * dinv/d2 * dv;
        ai1->grad += -1.0 * dsumddv;
        ai2->grad +=        dsumddv;
      }
    }
  }

  x.real_value *= 1.0 / cvm::real(group1->size() * group2->size());
  x.real_value = std::pow(x.real_value, -1.0/(cvm::real(exponent)));
}