Untested ferromagnetic model

It's pretty basic.
This commit is contained in:
2020-08-22 21:55:27 -07:00
parent 3830cf2ef8
commit f4d8ffdf34
3 changed files with 44 additions and 3 deletions

View File

@@ -22,8 +22,6 @@ fn main() {
// NB: different sources give pretty different values for this
// NB: Simulation misbehaves for values > 10... Proably this model isn't so great.
// Maybe use \eps or \xi instead of conductivity.
// No, I don't think that gives us what's needed. Rather, the calculation of static_ex
// is wrong (it's computed for the wrong value of time)
state.get_mut(x, y).mat_mut().conductivity = (2.17).into();
}
}

View File

@@ -287,11 +287,53 @@ pub trait Material {
#[derive(Clone, Default)]
pub struct GenericMaterial {
// Electrical parameters:
pub conductivity: f64,
// Magnetic state:
/// Instantaneous magnetization in the z direction.
pub mz: f64,
// Ferromagnetic parameters:
/// Magnetic saturation (symmetric, so saturates to either +Ms or -Ms).
pub ms: f64,
/// Rate at which M changes w.r.t. H.
pub xi: f64,
}
impl Material for GenericMaterial {
fn conductivity(&self) -> f64 {
self.conductivity
}
fn mz(&self) -> f64 {
self.mz
}
fn step_h(&mut self, context: &CellState, delta_bz: f64) -> f64 {
// COMSOL ferromagnetic model: https://www.comsol.com/blogs/accessing-external-material-models-for-magnetic-simulations/
// delta(M) = xi * delta*(H) # delta(M) = M(t+1) - M(t)
// new_M = clamp(M+delta(M), -Ms, Ms)) # i.e. clamp to saturation
// Where delta*(H) is H(t+1) - H(t), but clamping H(t) to <= 0 if positively saturated
// and clamping H(t) to >= 0 if negatively saturated
let expected_delta_h = delta_bz / consts::MU0;
let expected_new_h = context.hz() + expected_delta_h;
// let unsaturated_new_m = self.mz + self.xi * unsaturated_delta_h;
let unsaturated_new_m = if self.mz == self.ms {
// positively saturated
let delta_h = expected_new_h.max(0.0) - context.hz().max(0.0);
self.mz + self.xi * delta_h
} else if self.mz == -self.ms {
// negatively saturated
let delta_h = expected_new_h.min(0.0) - context.hz().min(0.0);
self.mz + self.xi * delta_h
} else {
// not saturated
self.mz + self.xi * expected_delta_h
};
let new_m = unsaturated_new_m.min(self.ms).max(-self.ms);
let delta_m = new_m - self.mz;
self.mz = new_m;
// B = mu0*(H + M)
// \Delta B = mu0*(\Delta H + \Delta M)
let delta_h = delta_bz / consts::MU0 - delta_m;
context.hz() + delta_h
}
}

View File

@@ -50,7 +50,8 @@ impl ColorTermRenderer {
for x in 0..state.width() {
let cell = state.get(x, y);
//let r = norm_color(cell.bz() * consts::C);
let r = 0;
//let r = 0;
let r = norm_color(cell.mat.mz*50.0);
let b = (55.0*cell.mat().conductivity).min(255.0) as u8;
//let b = 0;
//let g = norm_color(cell.ex());