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);
}
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;
}
示例#3
0
void colvar::distance_pairs::calc_value()
{
  x.vector1d_value.resize(group1->size() * group2->size());

  if (!is_enabled(f_cvc_pbc_minimum_image)) {
    size_t i1, i2;
    for (i1 = 0; i1 < group1->size(); i1++) {
      for (i2 = 0; i2 < group2->size(); i2++) {
        cvm::rvector const dv = (*group2)[i2].pos - (*group1)[i1].pos;
        cvm::real const d = dv.norm();
        x.vector1d_value[i1*group2->size() + i2] = d;
        (*group1)[i1].grad = -1.0 * dv.unit();
        (*group2)[i2].grad =  dv.unit();
      }
    }
  } else {
    size_t i1, i2;
    for (i1 = 0; i1 < group1->size(); i1++) {
      for (i2 = 0; i2 < group2->size(); i2++) {
        cvm::rvector const dv = cvm::position_distance((*group1)[i1].pos,
                                                       (*group2)[i2].pos);
        cvm::real const d = dv.norm();
        x.vector1d_value[i1*group2->size() + i2] = d;
        (*group1)[i1].grad = -1.0 * dv.unit();
        (*group2)[i2].grad =  dv.unit();
      }
    }
  }
}
void colvar::distance_pairs::calc_value()
{
  x.vector1d_value.resize(group1.size() * group2.size());

  if (b_no_PBC) {
    size_t i1, i2;
    for (i1 = 0; i1 < group1.size(); i1++) {
      for (i2 = 0; i2 < group2.size(); i2++) {
        cvm::rvector const dv = group2[i2].pos - group1[i1].pos;
        cvm::real const d = dv.norm();
        x.vector1d_value[i1*group2.size() + i2] = d;
        group1[i1].grad = -1.0 * dv.unit();
        group2[i2].grad =  dv.unit();
      }
    }
  } else {
    size_t i1, i2;
    for (i1 = 0; i1 < group1.size(); i1++) {
      for (i2 = 0; i2 < group2.size(); i2++) {
        cvm::rvector const dv = cvm::position_distance(group1[i1].pos, group2[i2].pos);
        cvm::real const d = dv.norm();
        x.vector1d_value[i1*group2.size() + i2] = d;
        group1[i1].grad = -1.0 * dv.unit();
        group2[i2].grad =  dv.unit();
      }
    }
  }
}
示例#5
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)));
}
示例#6
0
void colvar::distance_pairs::apply_force(colvarvalue const &force)
{
  if (b_no_PBC) {
    size_t i1, i2;
    for (i1 = 0; i1 < group1->size(); i1++) {
      for (i2 = 0; i2 < group2->size(); i2++) {
        cvm::rvector const dv = (*group2)[i2].pos - (*group1)[i1].pos;
        (*group1)[i1].apply_force(force[i1*group2->size() + i2] * (-1.0) * dv.unit());
        (*group2)[i2].apply_force(force[i1*group2->size() + i2] * dv.unit());
      }
    }
  } else {
    size_t i1, i2;
    for (i1 = 0; i1 < group1->size(); i1++) {
      for (i2 = 0; i2 < group2->size(); i2++) {
        cvm::rvector const dv = cvm::position_distance((*group1)[i1].pos, (*group2)[i2].pos);
        (*group1)[i1].apply_force(force[i1*group2->size() + i2] * (-1.0) * dv.unit());
        (*group2)[i2].apply_force(force[i1*group2->size() + i2] * dv.unit());
      }
    }
  }
}