///|
pub(all) struct Field1D {
grid : Grid1D
charge_density : Array[Double]
electric : Array[Double]
potential : Array[Double]
} derive(Debug, ToJson)
///|
pub fn Field1D::new(grid : Grid1D) -> Field1D {
{
grid,
charge_density: zeros(grid.cells),
electric: zeros(grid.cells),
potential: zeros(grid.cells),
}
}
///|
pub fn Field1D::electric_energy(field : Field1D) -> Double {
field_energy(field)
}
///|
pub fn Field1D::charge_neutrality_error(field : Field1D) -> Double {
mean(field.charge_density).abs()
}
///|
pub fn Field1D::potential_range(field : Field1D) -> (Double, Double) {
(min_value(field.potential), max_value(field.potential))
}
///|
pub fn Field1D::electric_range(field : Field1D) -> (Double, Double) {
(min_value(field.electric), max_value(field.electric))
}
///|
pub fn solve_periodic_field(
grid : Grid1D,
charge_density : ArrayView[Double],
) -> Field1D {
let rho_mean = mean(charge_density)
let electric = zeros(grid.cells)
for i in 1.. Double {
let y = grid.wrap(x)
let scaled = y / grid.dx - 0.5
let i0 = @math.floor(scaled).to_int()
let frac = scaled - i0.to_double()
let left = if i0 < 0 { grid.cells - 1 } else { i0 % grid.cells }
let right = (left + 1) % grid.cells
values[left] * (1.0 - frac) + values[right] * frac
}