Impl Harmonic Angle Force Test, Harmonic Bond Force Test #10
@@ -10,11 +10,11 @@ pub struct Context {
|
||||
pub platform: Box<dyn Platform>,
|
||||
}
|
||||
impl Context {
|
||||
pub fn set_positions(&mut self, positions: Vec<Vector3<f32>>) {
|
||||
pub fn set_positions(&mut self, _positions: Vec<Vector3<f32>>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_state(&self, state_type: StateType) -> State {
|
||||
pub fn get_state(&self, _state_type: StateType) -> State {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,177 @@ use crate::force::Force;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct HarmonicAngleForce {}
|
||||
impl Force for HarmonicAngleForce {
|
||||
fn add_bond(&mut self, particle1: usize, particle2: usize, length: f64, k: f64) {
|
||||
impl HarmonicAngleForce {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_angle(
|
||||
&mut self,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_particle3: usize,
|
||||
_angle: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_bond_parameters(&mut self, particle1: usize, particle2: usize, length: f64, k: f64) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn update_parameters_in_context(&mut self, context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_uses_periodic_boundary_conditions(&mut self, status: bool) {
|
||||
pub fn set_angle_parameters(
|
||||
&mut self,
|
||||
_angle_id: usize,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_particle3: usize,
|
||||
_angle: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Force for HarmonicAngleForce {
|
||||
fn update_parameters_in_context(&mut self, _context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_periodic_boundary_conditions(&mut self, _status: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HarmonicAngleForce {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HarmonicAngleForce;
|
||||
use crate::context::Context;
|
||||
use crate::force::Force;
|
||||
use crate::integrator::VerletIntegrator;
|
||||
use crate::platform::CPU;
|
||||
use crate::state::StateType;
|
||||
use crate::system::System;
|
||||
use approx::assert_relative_eq;
|
||||
use nalgebra::Vector3;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force() {
|
||||
let mut system = System::new();
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
|
||||
let mut forcefield = HarmonicAngleForce::new();
|
||||
forcefield.add_angle(0, 1, 2, PI / 3.0, 1.1);
|
||||
forcefield.add_angle(1, 2, 3, PI / 2.0, 1.2);
|
||||
|
||||
system.add_force(Box::new(forcefield.clone()));
|
||||
assert_eq!(forcefield.use_periodic_boundary_conditions(), false);
|
||||
assert_eq!(system.use_periodic_boundary_conditions(), false);
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
|
||||
let mut positions = vec![Vector3::zeros(); 4];
|
||||
positions[0] = Vector3::new(0.0, 2.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
positions[3] = Vector3::new(2.0, 1.0, 0.0);
|
||||
|
||||
context.set_positions(positions);
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
let torque1 = 1.1 * PI / 6.0;
|
||||
let torque2 = 1.2 * PI / 4.0;
|
||||
assert_relative_eq!(forces[0], Vector3::new(torque1, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[3], Vector3::new(-0.5 * torque2, 0.5 * torque2, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
assert_relative_eq!(
|
||||
state.get_potential_energy(),
|
||||
0.5 * 1.1 * PI / 6.0 * PI / 6.0 + 0.5 * 1.2 * PI / 4.0 * PI / 4.0
|
||||
);
|
||||
|
||||
forcefield.set_angle_parameters(0, 0, 1, 2, PI / 3.1, 1.3);
|
||||
forcefield.set_angle_parameters(1, 1, 2, 3, PI / 2.1, 1.4);
|
||||
forcefield.update_parameters_in_context(&mut context);
|
||||
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
let dtheta1 = (PI / 2.0) - (PI / 3.1);
|
||||
let dtheta2 = (3.0 * PI / 4.0) - (PI / 2.1);
|
||||
let torque1 = 1.3 * dtheta1;
|
||||
let torque2 = 1.4 * dtheta2;
|
||||
assert_relative_eq!(forces[0], Vector3::new(torque1, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[3], Vector3::new(-0.5 * torque2, 0.5 * torque2, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
assert_relative_eq!(
|
||||
state.get_potential_energy(),
|
||||
0.5 * 1.3 * dtheta1 * dtheta1 + 0.5 * 1.4 * dtheta2 * dtheta2
|
||||
);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force_with_periodic_boundary_conditions() {
|
||||
let mut system = System {};
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.set_default_periodic_box_vectors(
|
||||
Vector3::new(3.0, 0.0, 0.0),
|
||||
Vector3::new(0.0, 1.5, 0.0),
|
||||
Vector3::new(0.0, 0.0, 3.0),
|
||||
);
|
||||
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
let mut forcefield = HarmonicAngleForce {};
|
||||
forcefield.add_angle(0, 1, 2, PI / 3.0, 1.1);
|
||||
forcefield.set_periodic_boundary_conditions(true);
|
||||
|
||||
system.add_force(Box::new(forcefield));
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
|
||||
let mut positions = vec![Vector3::zeros(); 3];
|
||||
positions[0] = Vector3::new(0.0, 1.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
context.set_positions(positions);
|
||||
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
|
||||
let torque = 1.1 * PI / 6.0;
|
||||
assert_relative_eq!(forces[0], Vector3::new(2.0 * torque, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[2], Vector3::new(0.0, -torque, 0.0));
|
||||
|
||||
let energy = state.get_potential_energy();
|
||||
assert_relative_eq!(energy, 0.5 * 1.1 * (PI / 6.0) * (PI / 6.0));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force_parallel_computation() {
|
||||
// TODO: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,42 @@ use crate::force::Force;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct HarmonicBondForce {}
|
||||
impl HarmonicBondForce {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_bond(&mut self, _particle1: usize, _particle2: usize, _length: f64, _k: f64) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_bond_parameters(
|
||||
&mut self,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_length: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
impl Force for HarmonicBondForce {
|
||||
fn add_bond(&mut self, particle1: usize, particle2: usize, length: f64, k: f64) {
|
||||
fn update_parameters_in_context(&mut self, _context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_bond_parameters(&mut self, particle1: usize, particle2: usize, length: f64, k: f64) {
|
||||
fn set_periodic_boundary_conditions(&mut self, _status: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn update_parameters_in_context(&mut self, context: &mut Context) {
|
||||
fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
fn set_uses_periodic_boundary_conditions(&mut self, status: bool) {
|
||||
unimplemented!()
|
||||
impl Default for HarmonicBondForce {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +49,12 @@ mod test {
|
||||
use crate::force::Force;
|
||||
use crate::integrator::VerletIntegrator;
|
||||
use crate::platform::CPU;
|
||||
use crate::state::{State, StateType};
|
||||
use crate::state::StateType;
|
||||
use crate::system::System;
|
||||
use approx::assert_relative_eq;
|
||||
use nalgebra::Vector3;
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force() {
|
||||
let mut system = System {};
|
||||
@@ -58,7 +80,7 @@ mod test {
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
context.set_positions(positions);
|
||||
|
||||
let state = context.get_state(StateType::Both);
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
assert_relative_eq!(forces[0], Vector3::new(0.0, -0.8 * 0.5, 0.0));
|
||||
assert_relative_eq!(forces[2], Vector3::new(0.7 * 0.2, 0.0, 0.0));
|
||||
@@ -81,6 +103,7 @@ mod test {
|
||||
assert_relative_eq!(energy, 0.5 * 0.9 * 0.4 * 0.4 + 0.5 * 0.8 * 0.3 * 0.3);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force_with_periodic_boundary_conditions() {
|
||||
let mut system = System {};
|
||||
@@ -95,7 +118,7 @@ mod test {
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
let mut forcefield = HarmonicBondForce {};
|
||||
forcefield.add_bond(0, 1, 1.2, 0.8);
|
||||
forcefield.set_uses_periodic_boundary_conditions(true);
|
||||
forcefield.set_periodic_boundary_conditions(true);
|
||||
|
||||
system.add_force(Box::new(forcefield));
|
||||
|
||||
@@ -119,6 +142,7 @@ mod test {
|
||||
assert_relative_eq!(energy, 0.5 * 0.8 * 0.2 * 0.2);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force_parallel_computation() {
|
||||
// TODO: Rust-OpenMM
|
||||
|
||||
@@ -3,10 +3,9 @@ use std::fmt::Debug;
|
||||
use crate::context::Context;
|
||||
|
||||
pub trait Force: Debug {
|
||||
fn add_bond(&mut self, particle1: usize, particle2: usize, length: f64, k: f64);
|
||||
fn set_bond_parameters(&mut self, particle1: usize, particle2: usize, length: f64, k: f64);
|
||||
fn update_parameters_in_context(&mut self, context: &mut Context);
|
||||
fn set_uses_periodic_boundary_conditions(&mut self, status: bool);
|
||||
fn set_periodic_boundary_conditions(&mut self, status: bool);
|
||||
fn use_periodic_boundary_conditions(&self) -> bool;
|
||||
}
|
||||
|
||||
pub mod harmonic_angle_force;
|
||||
|
||||
@@ -2,22 +2,23 @@ use nalgebra::Vector3;
|
||||
|
||||
pub enum StateType {
|
||||
Both,
|
||||
Either,
|
||||
Forces,
|
||||
Energy,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub state_type: StateType,
|
||||
pub forces: Vec<Vector3<f32>>,
|
||||
pub energy: f32,
|
||||
pub forces: Vec<Vector3<f64>>,
|
||||
pub energy: f64,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn get_forces(&self) -> &Vec<Vector3<f32>> {
|
||||
pub fn get_forces(&self) -> &Vec<Vector3<f64>> {
|
||||
&self.forces
|
||||
}
|
||||
|
||||
pub fn get_potential_energy(&self) -> f32 {
|
||||
pub fn get_potential_energy(&self) -> f64 {
|
||||
self.energy
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ use crate::virtual_site::VirtualSite;
|
||||
use nalgebra::Vector3;
|
||||
pub struct System {}
|
||||
impl System {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_particle(&mut self, _mass: f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
@@ -92,7 +96,19 @@ impl System {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for System {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::force::{HarmonicAngleForce, HarmonicBondForce};
|
||||
|
||||
Reference in New Issue
Block a user