Skip to main content

Conductor

Struct Conductor 

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

A block of conducting material with two electrodes, solved for its potential.

Cells are cubes. The electrodes are the whole x = 0 and x = L faces, held at fixed potentials; every other surface is insulating, so no current leaves through it. That is the four-terminal arrangement a resistance is defined by, and it is what makes ρL/A the exact answer for a uniform block rather than an approximation to it.

Implementations§

Source§

impl Conductor

Source

pub fn new( name: impl Into<String>, counts: (usize, usize, usize), dx: Length, material: Resistivity, drive: Voltage, ) -> Conductor

A uniform block of counts cubic cells of side dx, driven by a potential difference across its x faces.

Source

pub fn with_solver(self, tolerance: f64, max_iterations: usize) -> Conductor

What Domain::step asks of the solver, and what it refuses below.

Exposed because a caller with a hard time budget may prefer a bounded solve to an unbounded one — and because the refusal path needs to be reachable from a test. A domain whose only failure mode cannot be provoked is a domain whose failure mode is untested.

Source

pub fn counts(&self) -> (usize, usize, usize)

Cell counts along x, y and z.

Source

pub fn spacing(&self) -> Length

The cell side.

Source

pub fn size(&self) -> LengthVec

The block’s extent — cells times spacing.

Source

pub fn section(&self) -> Area

The cross-section the current passes through.

Source

pub fn drive(&self) -> Voltage

The potential difference across the electrodes.

Source

pub fn set_resistivity( &mut self, i: usize, j: usize, k: usize, material: Resistivity, )

Give one cell a different material.

The point of the whole domain: a block that is not one material has no ρL/A, and this is how it stops being one. Out of range is ignored.

Source

pub fn set_region( &mut self, which: impl FnMut(usize, usize, usize) -> bool, material: Resistivity, )

Give a whole slab of cells one material, by a predicate on cell indices.

The readable way to build a series or parallel arrangement, and the way the closed-form tests do it.

Source

pub fn index(&self, i: usize, j: usize, k: usize) -> Option<usize>

The flat index of a cell, or None out of range.

Source

pub fn potential_at(&self, i: usize, j: usize, k: usize) -> Voltage

The potential at one cell centre.

Source

pub fn current_density_at(&self, i: usize, j: usize, k: usize) -> DVec3

The current density at one cell, by central differences on the potential.

J = −σ∇φ. At a cell against an insulating face the normal component is zero by construction, because there is no neighbour to differ from.

Source

pub fn current(&self) -> Current

The total current through the block, measured at the driven electrode.

Measured rather than derived: the current is the sum of what actually crosses the electrode faces in the solved field. A solve that had not converged would report a current that disagreed with the one measured at the other electrode, which is exactly the check Conductor::current_balance makes.

Source

pub fn current_balance(&self) -> f64

How much the current in disagrees with the current out, relative to the current itself.

Zero for a converged solve, because charge does not accumulate. This is the number that says whether the answer is an answer — and it is measured from the two electrodes independently rather than being a residual the solver reports about itself.

Source

pub fn resistance(&self) -> Resistance

The resistance the geometry has, V/I.

Not stated anywhere. For a uniform block this comes out as ρL/A to machine precision; for anything else it comes out as whatever the shape gives, which is the reason the domain exists.

Source

pub fn dissipation(&self) -> Power

The power dissipated, ∫σ|∇φ|²dV, summed over the faces where the gradient actually is.

Computed from the field rather than as V·I, so that the two agreeing is a check and not a tautology. They agree to machine precision for a converged solve — that is Tellegen’s theorem, and it is the sharpest single statement about whether the discretisation is self-consistent.

Source

pub fn dissipated_energy(&self) -> Energy

Energy dissipated over the run.

Source

pub fn converged(&self) -> bool

Whether the last solve met its tolerance.

Source

pub fn residual(&self) -> f64

The relative residual the last solve reached.

Source

pub fn solve(&mut self, tolerance: f64) -> bool

Solve for the potential, to a relative residual of tolerance.

Conjugate gradients, which is exact for this system in n steps in exact arithmetic and is symmetric positive definite because the conductances are positive and the coupling is symmetric. Deterministic: fixed order, fixed start, no threads.

Returns whether it converged. A caller that ignores the answer gets a field that looks like a field, which is why Domain::step refuses instead.

Source

pub fn solve_within(&mut self, tolerance: f64, max_iterations: usize) -> bool

Solve, spending at most max_iterations.

Returns whether the tolerance was met. A false here is the whole reason the method returns anything: the potential field left behind is smooth, bounded and shaped exactly like an answer, and nothing downstream can tell it from one.

Source§

impl Conductor

The current density as a vector, for a caller that wants J rather than φ.

Source

pub fn current_density_magnitude( &self, i: usize, j: usize, k: usize, ) -> CurrentDensity

|J| at a cell, which is what a picture of current crowding wants.

Source

pub fn conductivity_at(&self, i: usize, j: usize, k: usize) -> Conductivity

The conductivity of one cell.

Trait Implementations§

Source§

impl Clone for Conductor

Source§

fn clone(&self) -> Conductor

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 Conductor

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Domain for Conductor

Source§

fn kind(&self) -> Kind

Quasi-static: charge relaxes in ε/σ, which for copper is 1.5×10⁻¹⁹ s. On any timescale a simulation cares about, the current distribution is a solution and not a state.

Source§

fn ledger(&self) -> Ledger

What it has left to give, which for a source held at a fixed voltage is a negative number that keeps getting more negative.

The same bookkeeping Winding uses: a domain paying joules out has to say so, or the audit sees energy appear from nowhere. It is not a reserve — an ideal voltage source has none — so what is reported is the debt.

Source§

fn readings(&self) -> Vec<Reading>

The resistance, the current, the dissipation and how well the solve converged.

The residual is a reading, not merely an internal number, and that is the point of having it here: an iterative solve that quietly stopped early produces a field shaped like an answer, and the only thing that would ever say otherwise is a column somebody can look at.

Source§

fn as_field(&self) -> Option<&dyn ScalarField>

The potential, in volts, as a field.

Not the current density, which is a vector and has no ScalarField. A view wanting to see where the current crowds should take |J| from current_density_at; the potential is what the solve produces and what a contour plot of an electrical problem conventionally shows.

Source§

fn books_balance(&self) -> bool

Whether this domain’s books are exact: its ledger changes by precisely what it takes from the bus minus what it publishes, every step. Read more
Source§

fn name(&self) -> &str

What this domain is called. Used to look it up and to name it in a violation. Read more
Source§

fn step( &mut self, _t: Time, dt: Time, bus: &mut Exchange, ) -> Result<(), Violation>

Advance by dt from t, reading inputs from bus and publishing outputs to it. A quasi-static domain ignores dt. Read more
Source§

fn as_any(&self) -> Option<&dyn Any>

This domain as Any, so a caller can get the concrete type back out of a Simulation — see Simulation::domain_as. Read more
Source§

fn as_any_mut(&mut self) -> Option<&mut dyn Any>

The same, mutably, so a caller can write to a domain between steps. Read more
Source§

fn max_stable_dt( &self, now: Qty<0, 0, 1, 0, 0, 0, 0>, ) -> Qty<0, 0, 1, 0, 0, 0, 0>

The largest step this domain can take from now and stay stable — a CFL condition, a diffusion limit, a contact penetration budget. Read more
Source§

fn residual(&self) -> f64

How far this domain still is from agreeing with its neighbours, for Schedule::Iterative. Zero means converged.
Source§

fn checkpoint(&mut self)

Save state so an iterative sweep can be re-run from the same starting point. A domain that does not implement this cannot take part in Schedule::Iterative, and Simulation::advance says so rather than silently iterating from the wrong state.
Source§

fn restore(&mut self)

Restore the last Domain::checkpoint.
Source§

fn supports_restore(&self) -> bool

Whether Domain::checkpoint and Domain::restore actually do something. Read more
Source§

fn as_bodies(&self) -> Option<&dyn Bodies>

This domain as a countable set of bodies, if that is what it is. Read more
Source§

impl ScalarField for Conductor

Source§

fn at(&self, p: LengthVec, _t: Time) -> f64

Trilinear between cell centres, clamped at the faces.

Source§

fn gradient(&self, p: LengthVec, t: Time, h: Length) -> DVec3

∇φ, whose negative times σ is the current density.

Source§

fn rate(&self, _p: LengthVec, _t: Time, _dt: Time) -> f64

Zero. A quasi-static potential does not evolve; it is re-solved when something changes.

Source§

fn unit(&self) -> &'static str

What this field is measured in — "Pa", "C", "V". Read more
Source§

fn laplacian( &self, p: QVec3<1, 0, 0, 0, 0, 0, 0>, t: Qty<0, 0, 1, 0, 0, 0, 0>, h: Qty<1, 0, 0, 0, 0, 0, 0>, ) -> f64

∇²f — the operator that makes diffusion diffuse. A point hotter than the average of its neighbours has a negative Laplacian and cools; that is the whole content of the heat equation.

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
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> 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.