Update Colvars to version 2021-08-03
This commit is contained in:
@ -442,3 +442,335 @@ void colvar::spin_angle::wrap(colvarvalue &x_unwrapped) const
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_phi::euler_phi(std::string const &conf)
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_phi";
|
||||
period = 360.0;
|
||||
enable(f_cvc_periodic);
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
init(conf);
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_phi::euler_phi()
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_phi";
|
||||
period = 360.0;
|
||||
enable(f_cvc_periodic);
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
}
|
||||
|
||||
|
||||
int colvar::euler_phi::init(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= orientation::init(conf);
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_phi::calc_value()
|
||||
{
|
||||
atoms_cog = atoms->center_of_geometry();
|
||||
|
||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
||||
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
const cvm::real tmp_y = 2 * (q0 * q1 + q2 * q3);
|
||||
const cvm::real tmp_x = 1 - 2 * (q1 * q1 + q2 * q2);
|
||||
x.real_value = cvm::atan2(tmp_y, tmp_x) * (180.0/PI);
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_phi::calc_gradients()
|
||||
{
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
const cvm::real denominator = (2 * q0 * q1 + 2 * q2 * q3) * (2 * q0 * q1 + 2 * q2 * q3) + (-2 * q1 * q1 - 2 * q2 * q2 + 1) * (-2 * q1 * q1 - 2 * q2 * q2 + 1);
|
||||
const cvm::real dxdq0 = (180.0/PI) * 2 * q1 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) / denominator;
|
||||
const cvm::real dxdq1 = (180.0/PI) * (2 * q0 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) - 4 * q1 * (-2 * q0 * q1 - 2 * q2 * q3)) / denominator;
|
||||
const cvm::real dxdq2 = (180.0/PI) * (-4 * q2 * (-2 * q0 * q1 - 2 * q2 * q3) + 2 * q3 * (-2 * q1 * q1 - 2 * q2 * q2 + 1)) / denominator;
|
||||
const cvm::real dxdq3 = (180.0/PI) * 2 * q2 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) / denominator;
|
||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_phi::apply_force(colvarvalue const &force)
|
||||
{
|
||||
cvm::real const &fw = force.real_value;
|
||||
if (!atoms->noforce) {
|
||||
atoms->apply_colvar_force(fw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cvm::real colvar::euler_phi::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return diff * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_phi::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return 2.0 * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_phi::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return (-2.0) * diff;
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_phi::wrap(colvarvalue &x_unwrapped) const
|
||||
{
|
||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
||||
x_unwrapped.real_value -= 360.0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
||||
x_unwrapped.real_value += 360.0;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_psi::euler_psi(std::string const &conf)
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_psi";
|
||||
period = 360.0;
|
||||
enable(f_cvc_periodic);
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
init(conf);
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_psi::euler_psi()
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_psi";
|
||||
period = 360.0;
|
||||
enable(f_cvc_periodic);
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
}
|
||||
|
||||
|
||||
int colvar::euler_psi::init(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= orientation::init(conf);
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_psi::calc_value()
|
||||
{
|
||||
atoms_cog = atoms->center_of_geometry();
|
||||
|
||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
||||
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
const cvm::real tmp_y = 2 * (q0 * q3 + q1 * q2);
|
||||
const cvm::real tmp_x = 1 - 2 * (q2 * q2 + q3 * q3);
|
||||
x.real_value = cvm::atan2(tmp_y, tmp_x) * (180.0/PI);
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_psi::calc_gradients()
|
||||
{
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
const cvm::real denominator = (2 * q0 * q3 + 2 * q1 * q2) * (2 * q0 * q3 + 2 * q1 * q2) + (-2 * q2 * q2 - 2 * q3 * q3 + 1) * (-2 * q2 * q2 - 2 * q3 * q3 + 1);
|
||||
const cvm::real dxdq0 = (180.0/PI) * 2 * q3 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) / denominator;
|
||||
const cvm::real dxdq1 = (180.0/PI) * 2 * q2 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) / denominator;
|
||||
const cvm::real dxdq2 = (180.0/PI) * (2 * q1 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q2 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
||||
const cvm::real dxdq3 = (180.0/PI) * (2 * q0 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q3 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_psi::apply_force(colvarvalue const &force)
|
||||
{
|
||||
cvm::real const &fw = force.real_value;
|
||||
if (!atoms->noforce) {
|
||||
atoms->apply_colvar_force(fw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cvm::real colvar::euler_psi::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return diff * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_psi::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return 2.0 * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_psi::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
||||
return (-2.0) * diff;
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_psi::wrap(colvarvalue &x_unwrapped) const
|
||||
{
|
||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
||||
x_unwrapped.real_value -= 360.0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
||||
x_unwrapped.real_value += 360.0;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_theta::euler_theta(std::string const &conf)
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_theta";
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
init(conf);
|
||||
}
|
||||
|
||||
|
||||
colvar::euler_theta::euler_theta()
|
||||
: orientation()
|
||||
{
|
||||
function_type = "euler_theta";
|
||||
enable(f_cvc_explicit_gradient);
|
||||
x.type(colvarvalue::type_scalar);
|
||||
}
|
||||
|
||||
|
||||
int colvar::euler_theta::init(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= orientation::init(conf);
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_theta::calc_value()
|
||||
{
|
||||
atoms_cog = atoms->center_of_geometry();
|
||||
|
||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
||||
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
x.real_value = cvm::asin(2 * (q0 * q2 - q3 * q1)) * (180.0/PI);
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_theta::calc_gradients()
|
||||
{
|
||||
const cvm::real& q0 = rot.q.q0;
|
||||
const cvm::real& q1 = rot.q.q1;
|
||||
const cvm::real& q2 = rot.q.q2;
|
||||
const cvm::real& q3 = rot.q.q3;
|
||||
const cvm::real denominator = cvm::sqrt(1 - (2 * q0 * q2 - 2 * q1 * q3) * (2 * q0 * q2 - 2 * q1 * q3));
|
||||
const cvm::real dxdq0 = (180.0/PI) * 2 * q2 / denominator;
|
||||
const cvm::real dxdq1 = (180.0/PI) * -2 * q3 / denominator;
|
||||
const cvm::real dxdq2 = (180.0/PI) * 2 * q0 / denominator;
|
||||
const cvm::real dxdq3 = (180.0/PI) * -2 * q1 / denominator;
|
||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvar::euler_theta::apply_force(colvarvalue const &force)
|
||||
{
|
||||
cvm::real const &fw = force.real_value;
|
||||
if (!atoms->noforce) {
|
||||
atoms->apply_colvar_force(fw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cvm::real colvar::euler_theta::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
// theta angle is not periodic
|
||||
return cvc::dist2(x1, x2);
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_theta::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
// theta angle is not periodic
|
||||
return cvc::dist2_lgrad(x1, x2);
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::euler_theta::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
// theta angle is not periodic
|
||||
return cvc::dist2_rgrad(x1, x2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user