pub struct IterativeSphereCluster {
k0: f64,
radii: Vec<f64>,
positions: Vec<[f64; 3]>,
degrees: Vec<Vec<MieResidual>>,
mode_degrees: Vec<usize>,
plan: TranslationPlan,
dimension: usize,
}Expand description
The matrix-free counterpart of sphere_cluster: the same
spheres, solved with GMRES for the requested incident columns only.
It keeps the geometry and the local Mie coefficients, never a particle-pair matrix.
treams-rs extension; treams has no matrix-free cluster solver.
Fields§
§k0: f64§radii: Vec<f64>§positions: Vec<[f64; 3]>§degrees: Vec<Vec<MieResidual>>§mode_degrees: Vec<usize>§plan: TranslationPlan§dimension: usizeImplementations§
Source§impl IterativeSphereCluster
impl IterativeSphereCluster
Sourcepub fn new(
lmax: u32,
k0: f64,
radii: &[f64],
epsilon: &[Complex],
positions: &[[f64; 3]],
) -> Result<Self>
pub fn new( lmax: u32, k0: f64, radii: &[f64], epsilon: &[Complex], positions: &[[f64; 3]], ) -> Result<Self>
Homogeneous nonmagnetic spheres in vacuum, with the arguments of
sphere_cluster. Each particle’s modes follow
sw::modes in helicity convention.
Sourcefn local(&self, input: &[Complex], adjoint: bool) -> Vec<Complex> ⓘ
fn local(&self, input: &[Complex], adjoint: bool) -> Vec<Complex> ⓘ
T input, or Tᴴ input if adjoint, from the 2 x 2 Mie block of each degree
and order, for one or more column-major vectors.
sphere places the same blocks in a dense T-matrix
for sphere_cluster; this applies them in place.
Sourcefn apply_local(
&self,
input: &[Complex],
adjoint: bool,
matrix_at: impl Fn(usize, usize) -> Matrix2,
) -> Vec<Complex> ⓘ
fn apply_local( &self, input: &[Complex], adjoint: bool, matrix_at: impl Fn(usize, usize) -> Matrix2, ) -> Vec<Complex> ⓘ
Apply value or tangent Mie blocks without forming a local T-matrix.
Sourceconst fn modes_per_particle(&self) -> usize
const fn modes_per_particle(&self) -> usize
Multipoles per particle.
Sourcefn coupling(
&self,
input: &[Complex],
columns: usize,
adjoint: bool,
) -> Result<Vec<Complex>>
fn coupling( &self, input: &[Complex], columns: usize, adjoint: bool, ) -> Result<Vec<Complex>>
The particle-pair coupling C, or Cᴴ, applied to columns column-major
vectors. Each translation block is evaluated once for all columns.
Sourcefn coupling_tangent(
&self,
input: &[Complex],
columns: usize,
k0: f64,
positions: &[[f64; 3]],
) -> Result<Vec<Complex>>
fn coupling_tangent( &self, input: &[Complex], columns: usize, k0: f64, positions: &[[f64; 3]], ) -> Result<Vec<Complex>>
Directional coupling action, with the same streaming storage as C itself.
Sourcefn coupling_action(
&self,
input: &[Complex],
columns: usize,
apply: impl Fn(usize, usize, MatRef<'_, Complex>, MatMut<'_, Complex>) -> Result<()> + Sync,
) -> Result<Vec<Complex>>
fn coupling_action( &self, input: &[Complex], columns: usize, apply: impl Fn(usize, usize, MatRef<'_, Complex>, MatMut<'_, Complex>) -> Result<()> + Sync, ) -> Result<Vec<Complex>>
Apply either the coupling or its parameter tangent, sharing each pair’s harmonic table across the incident columns without a dense pair block.
Sourcefn apply(
&self,
input: &[Complex],
columns: usize,
adjoint: bool,
) -> Result<Vec<Complex>>
fn apply( &self, input: &[Complex], columns: usize, adjoint: bool, ) -> Result<Vec<Complex>>
(I - T C) input, or (I - T C)ᴴ input = (I - Cᴴ Tᴴ) input if adjoint: the
operator that GMRES inverts.
Sourcefn solve_rhs(
&self,
rhs: &DMatrix<Complex>,
options: GmresOptions,
adjoint: bool,
) -> Result<IterativeSolution>
fn solve_rhs( &self, rhs: &DMatrix<Complex>, options: GmresOptions, adjoint: bool, ) -> Result<IterativeSolution>
Solve (I - T C) X = rhs, or (I - T C)ᴴ X = rhs if adjoint, one column of
rhs independently, sharing pair translations across bounded column batches.
Sourcepub fn solve(
&self,
incident: &DMatrix<Complex>,
options: GmresOptions,
) -> Result<IterativeSolution>
pub fn solve( &self, incident: &DMatrix<Complex>, options: GmresOptions, ) -> Result<IterativeSolution>
Solve (I - T C) X = T B for only the columns B supplied in incident.
An unconverged solve returns an error containing the measured residual.
Sourcepub fn record(
self: &Arc<Self>,
incident: DMatrix<Complex>,
options: GmresOptions,
) -> Result<IterativeResidual>
pub fn record( self: &Arc<Self>, incident: DMatrix<Complex>, options: GmresOptions, ) -> Result<IterativeResidual>
Source§impl IterativeSphereCluster
impl IterativeSphereCluster
Sourcefn pair_gradients(
&self,
local_adjoint: &DMatrix<Complex>,
value: &DMatrix<Complex>,
) -> Result<(Vec<[f64; 3]>, f64)>
fn pair_gradients( &self, local_adjoint: &DMatrix<Complex>, value: &DMatrix<Complex>, ) -> Result<(Vec<[f64; 3]>, f64)>
Position and wavenumber gradients through the coupling C, whose cotangent is
(Tᴴ Y) Xᴴ for local_adjoint = Tᴴ Y and the solution value = X, summed one
particle-pair block at a time.
Chunks of consecutive particles i, fixed by the particle count, add their
pairs (i, j) in order into one partial sum each, and the partial sums add in
chunk order (numerics::parallel::try_fold_ordered), so the thread count does
not change the result.
Sourcefn local_gradients(
&self,
adjoint: &DMatrix<Complex>,
response: &DMatrix<Complex>,
cluster: &mut SphereClusterGradient,
) -> Result<()>
fn local_gradients( &self, adjoint: &DMatrix<Complex>, response: &DMatrix<Complex>, cluster: &mut SphereClusterGradient, ) -> Result<()>
Radius, permittivity and wavenumber gradients through the Mie coefficients,
whose local cotangent is Y (B + C X)ᴴ restricted to each 2 x 2 block.
SphereResidual::pullback does the
same for the dense path of sphere_cluster, with two
differences in order. It sums the Mie gradients of all degrees and then applies
the chain rule of the size parameter k0 r once; here each degree adds its own
k0 g and r g. It also swaps each 2 x 2 block to helicity order before
summing, where this sums in mode order and swaps once, which gives the same
values. The first difference changes the last bits, so the two paths agree to
rounding, and each keeps its order so that its results stay reproducible.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for IterativeSphereCluster
impl RefUnwindSafe for IterativeSphereCluster
impl Send for IterativeSphereCluster
impl Sync for IterativeSphereCluster
impl Unpin for IterativeSphereCluster
impl UnwindSafe for IterativeSphereCluster
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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
impl<T> Pointable for T
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.