some fixes and updates

This commit is contained in:
danijoo
2017-01-30 09:40:35 +01:00
parent aa507b6278
commit 8b7d2ec1a2
6 changed files with 198 additions and 26 deletions

View File

@@ -13,33 +13,59 @@ static MKSA_PLANCKS_CONSTANT_H : f64 = 1.0;
static MASS : f64 = 1.0;
const INSERTIONS_PER_STEP : usize = 1000;
const RUN_AVG_SIZE : usize = 10;
const RUN_AVG_SIZE : usize = 100;
const SHIFT : bool = true;
fn main() {
// open file
// parse args
let args: Vec<String> = env::args().collect();
let mut trj_reader = TrjReader::new(&args[1]);
let mut filename = "montecarlo.xyz".to_string();
let mut skip: usize = 0;
// liquid phase boundaries
let mut liquid_start = 0.0;
let mut liquid_end = 0.0;
for i in 0..args.len() {
if args[i] == "-f" {
filename = args[i + 1].clone();
} else if args[i] == "-s" {
skip = args[i + 1].parse::<usize>().unwrap();
} else if args[i] == "-ls" {
liquid_start = args[i + 1].parse::<f64>().unwrap();
} else if args[i] == "-le" {
liquid_end = args[i + 1].parse::<f64>().unwrap();
}
}
// open file and skip to requiested position
let mut trj_reader = TrjReader::new(&filename);
if skip > 0 { trj_reader.skip(skip) };
let mut frame = trj_reader.next_frame();
println!("{:?}", frame);
// get some non changing values
let volume = frame.box_x * frame.box_y * frame.box_z;
let beta = 1.0/frame.temperature;
let cutoff_sqr = frame.lj_cutoff * frame.lj_cutoff;
// account for gas phase slab
let gas_slab = args[2].parse::<f64>().unwrap();
let liquid_height = frame.box_z / (gas_slab + 1.0);
let liquid_volume = volume / (gas_slab + 1.0);
// rnd number generator for particle insertion
let mut rng = rand::thread_rng();
// calculate liquid and gas volume
let liquid_height : f64 = liquid_end - liquid_start;
let liquid_volume = liquid_height * frame.box_x * frame.box_y;
let gas_volume = volume - liquid_volume;
let wave = MKSA_PLANCKS_CONSTANT_H / (2.0 * std::f64::consts::PI * MASS * frame.temperature / frame.lj_eps).sqrt();
// lambda = h/sqrt(2*pi*m*kb*T) = (2*pi*m*kb*T/h^2)^3/2
// this is lambda^3
let wave3 = ((2.0 * std::f64::consts::PI * MASS * frame.temperature / frame.lj_eps)/MKSA_PLANCKS_CONSTANT_H.powi(2)).powf(3.0/2.0);
let e_shift = if SHIFT { 4.0 * LJ_EPS * ( (LJ_SIG/frame.lj_cutoff).powi(12) - (LJ_SIG/frame.lj_cutoff).powi(6) ) } else { 0.0 };
let mut rng = rand::thread_rng();
// average counters
let mut frame_count = 0;
@@ -47,8 +73,6 @@ fn main() {
let mut ideal_sum_gas = 0.0;
let mut widom_sum_liquid = 0.0;
let mut ideal_sum_liquid = 0.0;
// loop over frames
let mut avg_count = 0;
loop {
frame_count += 1;
@@ -57,32 +81,40 @@ fn main() {
let mut liquid_count = 0.0;
let mut gas_count = 0.0;
for i in 0..frame.num_particles {
if frame.rz[i] < liquid_height { liquid_count += 1.0; }
if frame.rz[i] > liquid_start && frame.rz[i] < liquid_end { liquid_count += 1.0; }
else { gas_count += 1.0; }
}
// test particle insertion multiple times
for i in 0..INSERTIONS_PER_STEP {
avg_count += 1;
// liquid test partciles
// liquid test partcile
let lx = frame.box_x * rng.gen::<f64>();
let ly = frame.box_y * rng.gen::<f64>();
let lz = liquid_height * rng.gen::<f64>();
let lz = liquid_start + (liquid_height * rng.gen::<f64>());
let widom_e_liquid = get_particle_insertion_energy(&frame.rx, &frame.ry, &frame.rz, frame.num_particles, lx, ly, lz, frame.box_x, frame.box_y, frame.box_z, cutoff_sqr, e_shift);
widom_sum_liquid += (-beta*widom_e_liquid).exp();
// widom_sum_liquid += widom_e_liquid;
// test particle gas energy
// gas test particle
let upper_or_lower = rng.gen::<bool>();
let gx = frame.box_x * rng.gen::<f64>();
let gy = frame.box_y * rng.gen::<f64>();
let gz = ((frame.box_z - liquid_height) * rng.gen::<f64>()) + liquid_height;
let gz;
if upper_or_lower {
gz = rng.gen::<f64>() * liquid_start;
} else {
gz = rng.gen::<f64>() * (frame.box_z - liquid_end) + liquid_end;
}
let widom_e_gas = get_particle_insertion_energy(&frame.rx, &frame.ry, &frame.rz, frame.num_particles, gx, gy, gz, frame.box_x, frame.box_y, frame.box_z, cutoff_sqr, e_shift);
widom_sum_gas += (-beta*widom_e_gas).exp();
// widom_sum_gas += widom_e_gas;
// calculate ideal gas potential for both phases
ideal_sum_gas += frame.temperature / frame.lj_eps * (gas_volume/(wave.powi(3)* gas_count)).ln();
ideal_sum_liquid += frame.temperature / frame.lj_eps * (liquid_volume/(wave.powi(3)* liquid_count)).ln();
// calculate ideal gas potential
ideal_sum_gas += -frame.temperature / frame.lj_eps * ((gas_volume/gas_count) * wave3).ln();
ideal_sum_liquid += frame.temperature / frame.lj_eps * ((liquid_volume/liquid_count) * wave3).ln();
}
@@ -90,9 +122,14 @@ fn main() {
if avg_count / INSERTIONS_PER_STEP > RUN_AVG_SIZE {
let ideal_gas = ideal_sum_gas / avg_count as f64;
let ideal_liquid = ideal_sum_liquid / avg_count as f64;
// let excess_gas = - (widom_sum_gas/avg_count as f64).ln()/beta;
// let excess_liquid = - (widom_sum_liquid/avg_count as f64).ln()/beta;
let excess_gas = -(widom_sum_gas/avg_count as f64).ln()/beta;
let excess_liquid = -(widom_sum_liquid/avg_count as f64).ln()/beta;
println!("Frame {}\tgas {}\tliquid {}\t particles gas/liquid:{}/{}", frame_count, ideal_gas + excess_gas, ideal_liquid + excess_liquid, gas_count, liquid_count);
let gas_total = ideal_gas + excess_gas;
let liquid_total = ideal_liquid + excess_liquid;
println!("Frame {}\tg_ex: {:5}\tl_ex: {:5}\tg_tot: {:5}\tl_tot: {:5}\t\tnparticles: {}/{}", frame_count, excess_gas, excess_liquid, gas_total, liquid_total, gas_count, liquid_count);
// println!("Frame {}\tgas {}\tliquid {}\t particles gas/liquid:{}/{}", frame_count, ideal_gas + excess_gas, ideal_liquid + excess_liquid, gas_count, liquid_count);
// reset averages for next round
avg_count = 0;