Skip to main content

DiimfpGrid

Struct DiimfpGrid 

Source
pub struct DiimfpGrid { /* private fields */ }
Expand description

The full Penn DIIMFP of one table build, tabulated so that each row of the table costs interpolations instead of nested integrals (issue #256).

The DIIMFP is p(T, ω) = (1/(π T')) ∫_{q-}^{q+} Im[-1/ε(q, ω)] dq/q (S2017 eq. (2)), and only the window [q-, q+] depends on T. So for a set of loss nodes ω_i the grid stores the integrand Im[-1/ε(q, ω_i)] as a function of u = ln q, once, over every window it can be asked for (from a quarter of q- at the highest table energy to 2k there): the accepted panels of an adaptive Gauss-Legendre integration (quadrature::integrate_panels) from segments 0.125 wide in u, at a tenth of the model tolerance and with every segment held to that tolerance relative to its own integral (down to 1e-4 of the mean segment), so that a narrow window is as accurate as a wide one. The integral to any u comes from the polynomial through the node values of its panel (quadrature::Panels), so the integral over the window of any (T, ω_i) costs no new evaluation. (With 0.5-wide starting segments and the mean-segment floor of FullPenn::diimfp_per_m_ev, the bisection was seen to stop early, by coincidence, at a few isolated ω near the Al plasmon, with window errors up to 1.5e-3; the finer segments removed these.)

Between two loss nodes the window integrals of the two neighbouring profiles, each over the window of the requested (T, ω), are interpolated linearly in ln p against ln ω (exact for a power law, the shape of the DIIMFP’s tails; linear in p where one of them is zero). The nodes are the two ends ω = ω_min (FULL_LOWEST_LOSS_FRACTION of the lowest table energy, or the lowest ELF energy if lower; #361) and ω = T_max, the lowest ELF energy, every ELF knot in between (where Im[-1/ε] has kinks at small q, and where a feature narrower than the knot spacing sits) and a subdivision to cells no wider than 0.25 in ln ω. A cell is then halved, level by level, while at its midpoint ω_m, for any row energy T > ω_m of the table, |ω_m (p_exact - p_interp)| > tol · max(ω_m p_exact, ḡ_T), with tol the model tolerance and ḡ_T the mean of ω p(T, ω) over ln ω on the current nodes (the row’s average loss density in ln ω, the scale of the table’s own density tolerance). The interpolation error is therefore held to the model tolerance (relative, or relative to the row’s average density where the DIIMFP is below it) at the midpoints checked, with the row energies of the table as the test set. Every computed midpoint is kept as a node. Cells are not halved below 1e-4 in ln ω, nor beyond 20000 nodes; a cell that still fails there is counted in Self::unresolved_cells and kept, and Self::diimfp_per_m_ev does not answer inside it (the caller uses the direct model there), so no unchecked interpolation enters a table.

Implementations§

Source§

impl DiimfpGrid

Source

pub fn len(&self) -> usize

Number of loss nodes.

Source

pub fn is_empty(&self) -> bool

Whether the grid has no nodes (no table energy).

Source

pub fn panel_count(&self) -> usize

Total number of momentum panels over all profiles.

Source

pub fn unconverged_profile_panels(&self) -> u64

Number of cells of the momentum integrations of the profiles that were accepted without meeting their tolerance (budget of the bisection spent, maximum depth, or a midpoint that is not representable; #298). Zero when every profile converged.

Source

pub fn unconverged_profile_loss_evaluations(&self) -> u64

Number of evaluations of the loss function inside the profiles whose own ω_p integral did not converge (see FullPenn::loss_function_evaluation). Zero when every evaluation converged.

Source

pub fn largest_unconverged_profile_error(&self) -> f64

The largest error estimate of the cells counted in Self::unconverged_profile_panels within one profile, relative to that profile’s integral over its whole momentum range (zero when every profile converged).

Source

pub fn unresolved_cells(&self) -> usize

Number of cells that failed the interpolation check but were not halved, at the narrowest cell width or the node cap (zero when the refinement converged).

Source

pub fn loss_is_unresolved_ev(&self, loss_ev: f64) -> bool

Whether loss loss_ev (eV) lies in an unresolved cell, where Self::diimfp_per_m_ev gives no answer.

Source

pub fn unresolved_loss_range_ev(&self) -> Option<(f64, f64)>

The loss range, eV, from the lowest to the highest edge of the cells counted in Self::unresolved_cells; None when there are none. The grid answers in none of these cells.

Source

pub fn tolerance(&self) -> f64

The tolerance the grid was refined to (the model tolerance).

Source

pub fn diimfp_per_m_ev(&self, energy_ev: f64, loss_ev: f64) -> Option<f64>

The DIIMFP at kinetic energy energy_ev (above the Fermi level) and loss loss_ev, m⁻¹ eV⁻¹, from the grid; None where the grid does not cover it (a loss below the lowest node, FULL_LOWEST_LOSS_FRACTION of the lowest table energy, an energy above the highest table energy, or a loss in an unresolved cell, see Self::unresolved_cells), where the caller uses FullPenn::diimfp_per_m_ev. Zero for ω <= 0 or ω > T, as there.

Any T up to the highest table energy is answered, but the refinement of the loss nodes checks the interpolation only at the energies passed to FullPenn::diimfp_grid. The accuracy is controlled at those energies; between them it is not checked.

Trait Implementations§

Source§

impl Clone for DiimfpGrid

Source§

fn clone(&self) -> DiimfpGrid

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DiimfpGrid

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V