///|
pub fn divergence_periodic(
  grid : Grid1D,
  values : ArrayView[Double],
) -> Array[Double] {
  periodic_gradient(grid, values)
}

///|
pub fn curl_1d(grid : Grid1D, values : ArrayView[Double]) -> Array[Double] {
  periodic_gradient(grid, values)
}

///|
pub fn gradient_periodic(
  grid : Grid1D,
  values : ArrayView[Double],
) -> Array[Double] {
  periodic_gradient(grid, values)
}

///|
pub fn laplacian_periodic(
  grid : Grid1D,
  values : ArrayView[Double],
) -> Array[Double] {
  periodic_laplacian(grid, values)
}

///|
pub fn field_residual(
  grid : Grid1D,
  electric : ArrayView[Double],
  charge_density : ArrayView[Double],
) -> Array[Double] {
  let gradient = periodic_gradient(grid, electric)
  let output = zeros(grid.cells)
  for i in 0.. Double {
  l2_norm(field_residual(grid, electric, charge_density))
}

///|
pub fn electrostatic_energy_density(
  electric : ArrayView[Double],
) -> Array[Double] {
  electric.map(fn(value) { 0.5 * vacuum_permittivity * value * value })
}

///|
pub fn electrostatic_energy(
  grid : Grid1D,
  electric : ArrayView[Double],
) -> Double {
  sum_values(electrostatic_energy_density(electric)) * grid.dx
}

///|
pub fn potential_from_electric(
  grid : Grid1D,
  electric : ArrayView[Double],
) -> Array[Double] {
  let potential = zeros(grid.cells)
  for i in 1.. Array[Double] {
  poisson_electric_field(grid, potential)
}

///|
pub fn project_zero_mean(values : ArrayView[Double]) -> Array[Double] {
  poisson_mean_free(values)
}

///|
pub fn field_scale(
  values : ArrayView[Double],
  factor : Double,
) -> Array[Double] {
  values.map(fn(value) { value * factor })
}

///|
pub fn field_add(
  first : ArrayView[Double],
  second : ArrayView[Double],
) -> Array[Double] {
  add_profile(first, second)
}

///|
pub fn field_difference(
  first : ArrayView[Double],
  second : ArrayView[Double],
) -> Array[Double] {
  let output = zeros(first.length())
  for i in 0.. Double {
  l2_norm(field_difference(first, second))
}

///|
pub fn field_maximum(values : ArrayView[Double]) -> Double {
  max_abs_value(values)
}

///|
pub fn field_mean_abs(values : ArrayView[Double]) -> Double {
  mean(values.map(fn(value) { value.abs() }))
}