Skip to main content

Exchange

Struct Exchange 

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

The channel between domains: named quantities, in SI base units.

A domain publishes what it produced and consumes what it needs. Nothing else crosses between domains, which means every transfer is in one place and can be checked in one place.

Implementations§

Source§

impl Exchange

Source

pub fn new() -> Exchange

An empty bus.

Source

pub fn publish(&mut self, channel: &'static str, si_amount: f64)

Offer an amount on a channel. Repeated publishes accumulate, so several surfaces can each contribute to one heat load.

Source

pub fn take(&mut self, channel: &'static str) -> f64

Take everything on a channel, recording that it was taken. The channel is left empty: an amount consumed twice would be an amount doubled.

Source

pub fn peek(&self, channel: &'static str) -> f64

Look without taking.

Source

pub fn take_share(&mut self, channel: &'static str, dt: Time) -> f64

Take the share of a channel that belongs to a substep of length dt.

For a domain that subcycles. Exchange::take empties the channel, which is right for a domain stepping once per interval and wrong for one stepping many times: a publisher offers a whole outer step’s worth at once, so the first substep would take all of it and the rest would find the channel dark. Every joule of the interval then lands at its beginning, and refining the substep stops improving the answer — see Schedule::Multirate, where the measured error is 26% at a 300 s outer step whatever the substep count.

The share is taken against the time remaining, not against the whole interval. That is what makes it exact: after handing out A·dt/T and reducing both, A/T is unchanged, so the last substep — which asks for at least what is left — receives the remainder and the channel ends empty to the last bit. Apportioning against the whole interval instead leaves O(n·ε·A) stranded, and Exchange::audit_transfers uses an absolute tolerance that would eventually refuse it.

Falls back to Exchange::take when the interval is unknown, so a domain written against this works unchanged under a bare Exchange and under Schedule::Staggered, where it steps once and the share is the whole.

Source

pub fn covering(&mut self, dt: Time)

Tell the bus what interval the current sweep covers, so Exchange::take_share can apportion. Called by Simulation::advance; a standalone Exchange need not.

Source

pub fn publish_on( &mut self, interface: &Interface, channel: &'static str, flux: &Flux, ) -> Result<(), Violation>

Offer an amount that knows where on a boundary it landed.

The spatial counterpart of publish, and the reason scene exists: a coating absorbs where the beam is, and a lumped number cannot say that. Repeated publishes accumulate face by face, so two mechanisms heating the same surface add up in place.

Refuses a Flux whose face count does not match the interface. Silently padding or truncating would put energy on the wrong part of the boundary, which is worse than losing it — losing it the audit would catch.

Source

pub fn take_on( &mut self, interface: &Interface, channel: &'static str, ) -> Result<Flux, Violation>

Take everything offered on an interface’s channel, leaving it empty.

Returns zeros rather than an error when nothing was published, because a consumer stepping a boundary that happens to be dark this step is not a fault. A face-count disagreement is, and is reported: the two sides do not share a discretisation, and the fix is Flux::resample at whichever side owns the decision.

Source

pub fn peek_on( &self, interface: &Interface, channel: &'static str, ) -> Option<&Flux>

Look at a spatial channel without taking it.

Source

pub fn unclaimed(&self) -> impl Iterator<Item = (String, f64)> + '_

Channels that were published to but never taken from, with what is left on them. Energy sitting here at the end of a step is energy that left one domain and arrived nowhere.

Spatial channels appear as "interface/channel", with the total left on them.

Source

pub fn audit_transfers(&self, site: &str, abs_tol: f64) -> Result<(), Violation>

Fail if anything published was not consumed.

This is the check that catches a coupling whose two sides disagree — a surface that absorbed 3.7 mW handing it to a mesh that received 3.4 mW because the interpolation between their discretisations lost the rest.

The original design said that, and then could not check it: with one number per channel there was no discretisation to disagree about. Spatial channels close that gap, and they are audited face by face rather than on their total — a redistribution that moves heat from one side of a mirror to the other keeps the sum exactly right, so a total-only check would pass the one bug the spatial coupling exists to prevent. The failure names the face.

Source

pub fn total_consumed(&self, channel: &str) -> f64

Total taken from a channel over the run, for reporting.

Source

pub fn total_consumed_on( &self, interface: &Interface, channel: &'static str, ) -> f64

Total taken from a spatial channel over the run, summed over its faces.

Source

pub fn clear_offers(&mut self)

Empty the offers, keeping the running consumption totals.

Trait Implementations§

Source§

impl Clone for Exchange

Source§

fn clone(&self) -> Exchange

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 Exchange

Source§

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

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

impl Default for Exchange

Source§

fn default() -> Exchange

Returns the “default value” for a type. 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
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.