Skip to content

Commit 70e84bd

Browse files
authored
Merge pull request #109 from lcpp-org/new_surface_refraction
New surface refraction
2 parents 7798a64 + e10416a commit 70e84bd

File tree

4 files changed

+46
-18
lines changed

4 files changed

+46
-18
lines changed

src/material.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -326,16 +326,13 @@ pub fn surface_binding_energy<T: Geometry>(particle_1: &mut particle::Particle,
326326
let dy = y2 - y;
327327
let dz = z2 - z;
328328
let mag = (dx*dx + dy*dy + dz*dz).sqrt();
329-
330329
let costheta = dx*cosx/mag + dy*cosy/mag + dz*cosz/mag;
331-
particle_1.E += Es;
332330

333331
match material.surface_binding_model {
334332
SurfaceBindingModel::PLANAR{..} => {
335-
let delta_theta = particle::refraction_angle(costheta, E, E + Es);
336-
particle::rotate_particle(particle_1, delta_theta, 0.);
333+
particle::surface_refraction(particle_1, Vector::new(dx/mag, dy/mag, dz/mag), Es);
337334
}
338-
_ => ()
335+
_ => particle_1.E += Es,
339336
}
340337
}
341338
}
@@ -348,19 +345,20 @@ pub fn surface_binding_energy<T: Geometry>(particle_1: &mut particle::Particle,
348345
let dz = z2 - z;
349346
let mag = (dx*dx + dy*dy + dz*dz).sqrt();
350347
let costheta = dx*cosx/mag + dy*cosy/mag + dz*cosz/mag;
351-
let leaving_energy = E*costheta*costheta;
348+
349+
let leaving_energy = match material.surface_binding_model {
350+
SurfaceBindingModel::ISOTROPIC{..} => E,
351+
SurfaceBindingModel::PLANAR{..} => E*costheta*costheta,
352+
};
352353

353354
if costheta < 0. {
354355
if leaving_energy > Es {
355356

356-
particle_1.E += -Es;
357-
358357
match material.surface_binding_model {
359358
SurfaceBindingModel::PLANAR{..} => {
360-
let delta_theta = particle::refraction_angle(costheta, E, E + Es);
361-
particle::rotate_particle(particle_1, delta_theta, 0.);
359+
particle::surface_refraction(particle_1, Vector::new(-dx/mag, -dy/mag, -dz/mag), -Es);
362360
}
363-
_ => ()
361+
_ => particle_1.E += -Es,
364362
}
365363

366364
} else {

src/particle.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,24 @@ pub fn particle_advance(particle_1: &mut particle::Particle, mfp: f64, asymptoti
208208
return distance_traveled;
209209
}
210210

211+
pub fn surface_refraction(particle: &mut Particle, normal: Vector, Es: f64) {
212+
let E = particle.E;
213+
214+
let costheta = particle.dir.dot(&normal);
215+
216+
let a = (E/(E + Es)).sqrt();
217+
let b = -(E).sqrt()*costheta;
218+
let c = (E*costheta.powi(2) + Es).sqrt();
219+
220+
let u1x = (E/(E + Es)).sqrt()*particle.dir.x + ((-(E).sqrt()*costheta + (E*costheta.powi(2) + Es).sqrt())/(E + Es).sqrt())*normal.x;
221+
let u1y = (E/(E + Es)).sqrt()*particle.dir.y + ((-(E).sqrt()*costheta + (E*costheta.powi(2) + Es).sqrt())/(E + Es).sqrt())*normal.y;
222+
let u1z = (E/(E + Es)).sqrt()*particle.dir.z + ((-(E).sqrt()*costheta + (E*costheta.powi(2) + Es).sqrt())/(E + Es).sqrt())*normal.z;
223+
particle.dir.x = u1x;
224+
particle.dir.y = u1y;
225+
particle.dir.z = u1z;
226+
particle.E += Es;
227+
}
228+
211229
/// Calcualte the refraction angle based on the surface binding energy of the material.
212230
pub fn refraction_angle(costheta: f64, energy_old: f64, energy_new: f64) -> f64 {
213231
let costheta = if costheta.abs() > 1. {costheta.signum()} else {costheta};

src/structs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ impl Vector {
3838
pub fn add(&self, other: &Vector) -> Vector {
3939
Vector::new(self.x + other.x, self.y + other.y, self.z + other.z)
4040
}
41+
42+
pub fn dot(&self, other: &Vector) -> f64 {
43+
self.x*other.x + self.y*other.y + self.z*other.z
44+
}
4145
}
4246

4347
/// Vector4 is a trajectory-tracking object that includes x, y, z, and the current energy.

src/tests.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,11 @@ fn test_surface_refraction() {
475475
let cosy_new = cosy_new/dir_mag;
476476
let cosz_new = cosz_new/dir_mag;
477477

478-
let delta_theta = particle::refraction_angle(cosx, E, E + Es);
479-
particle::rotate_particle(&mut particle_1, delta_theta, 0.);
478+
//let delta_theta = particle::refraction_angle(cosx, E, E + Es);
479+
//particle::rotate_particle(&mut particle_1, delta_theta, 0.);
480+
481+
let normal = Vector::new(1.0, 0.0, 0.0);
482+
particle::surface_refraction(&mut particle_1, normal, Es);
480483

481484
if print_output {
482485
println!("dir_mag: {}", dir_mag);
@@ -502,17 +505,22 @@ fn test_surface_refraction() {
502505
println!("{} {} {}", particle_1.dir.x, particle_1.dir.y, particle_1.dir.z);
503506
}
504507

505-
let delta_theta = particle::refraction_angle(particle_1.dir.x, particle_1.E, particle_1.E - Es);
506-
particle::rotate_particle(&mut particle_1, delta_theta, 0.);
508+
//let delta_theta = particle::refraction_angle(particle_1.dir.x, particle_1.E, particle_1.E - Es);
509+
//particle::rotate_particle(&mut particle_1, delta_theta, 0.);
510+
511+
let normal = Vector::new(1.0, 0.0, 0.0);
512+
particle::surface_refraction(&mut particle_1, normal, -Es);
513+
507514

508515
if print_output {
509516
println!("{} {} {}", cosx_new, cosy_new, cosz_new);
510517
println!("{} {} {}", particle_1.dir.x, particle_1.dir.y, particle_1.dir.z);
511518
}
512519

513-
assert!(approx_eq!(f64, particle_1.dir.x, cosx_new, epsilon=1E-12));
514-
assert!(approx_eq!(f64, particle_1.dir.y, cosy_new, epsilon=1E-12));
515-
assert!(approx_eq!(f64, particle_1.dir.z, cosz_new, epsilon=1E-12));
520+
assert!(approx_eq!(f64, particle_1.dir.x, cosx_new, epsilon=1E-9));
521+
assert!(approx_eq!(f64, particle_1.dir.y, cosy_new, epsilon=1E-9));
522+
assert!(approx_eq!(f64, particle_1.dir.z, cosz_new, epsilon=1E-9));
523+
516524
}
517525

518526
#[test]

0 commit comments

Comments
 (0)