///|
pub(all) struct MagneticField3D {
origin : Vector3
uniform : Vector3
gradient : Vector3
} derive(Debug, ToJson)
///|
pub fn uniform_magnetic_field(field : Vector3) -> MagneticField3D {
{ origin: Vector3::zero(), uniform: field, gradient: Vector3::zero() }
}
///|
pub fn linear_magnetic_field(
origin : Vector3,
uniform : Vector3,
gradient : Vector3,
) -> MagneticField3D {
{ origin, uniform, gradient }
}
///|
pub fn MagneticField3D::sample(
field : MagneticField3D,
position : Vector3,
) -> Vector3 {
let offset = position.sub(field.origin)
{
x: field.uniform.x + field.gradient.x * offset.x,
y: field.uniform.y + field.gradient.y * offset.y,
z: field.uniform.z + field.gradient.z * offset.z,
}
}
///|
pub fn MagneticField3D::magnitude(
field : MagneticField3D,
position : Vector3,
) -> Double {
field.sample(position).norm()
}
///|
pub fn MagneticField3D::flux_through_area(
field : MagneticField3D,
position : Vector3,
normal : Vector3,
area : Double,
) -> Double {
field.sample(position).dot(normal.normalized()) * area
}
///|
pub fn dipole_magnetic_field(
moment : Vector3,
position : Vector3,
coefficient : Double,
) -> Vector3 {
let radius = position.norm()
if radius == 0.0 {
Vector3::zero()
} else {
let unit = position.scale(1.0 / radius)
let dot = moment.dot(unit)
let factor = coefficient / (radius * radius * radius)
unit.scale(3.0 * dot * factor).sub(moment.scale(factor))
}
}
///|
pub fn magnetic_force(
charge : Double,
velocity : Vector3,
magnetic : Vector3,
) -> Vector3 {
velocity.cross(magnetic).scale(charge)
}
///|
pub fn electric_force(charge : Double, electric : Vector3) -> Vector3 {
electric.scale(charge)
}
///|
pub fn lorentz_force(
charge : Double,
velocity : Vector3,
electric : Vector3,
magnetic : Vector3,
) -> Vector3 {
electric_force(charge, electric).add(
magnetic_force(charge, velocity, magnetic),
)
}
///|
pub fn field_line_step(
position : Vector3,
field : MagneticField3D,
step : Double,
) -> Vector3 {
position.add(field.sample(position).normalized().scale(step))
}
///|
pub fn trace_field_line(
position : Vector3,
field : MagneticField3D,
step : Double,
count : Int,
) -> Array[Vector3] {
let output : Array[Vector3] = []
let mut current = position
for _ in 0.. Double {
0.5 * field.dot(field) / vacuum_permittivity
}
///|
pub fn magnetic_pressure(field : Vector3) -> Double {
magnetic_energy_density(field)
}
///|
pub fn gyroradius(
mass : Double,
speed : Double,
charge : Double,
magnetic : Double,
) -> Double {
let denominator = charge.abs() * magnetic.abs()
if denominator == 0.0 {
0.0
} else {
mass * speed / denominator
}
}