pub struct LoMaC {
pub kfvs: KfvsSolver,
pub spatial_shape: [usize; 3],
pub velocity_shape: [usize; 3],
pub dv: [f64; 3],
pub v_min: [f64; 3],
pub active: bool,
pub delta_f_truncation: bool,
pub delta_f_refresh_interval: u64,
pub delta_f_refresh_threshold: f64,
pub casimir_drift_history: Vec<(f64, f64)>,
/* private fields */
}Expand description
LoMaC conservation manager.
Maintains the macroscopic state alongside the kinetic solution, and provides the projection step after each truncation.
Fields§
§kfvs: KfvsSolverKFVS macroscopic solver for evolving (ρ, J, e).
spatial_shape: [usize; 3]Spatial grid shape [nx, ny, nz].
velocity_shape: [usize; 3]Velocity grid shape [nv1, nv2, nv3].
dv: [f64; 3]Velocity cell spacings.
v_min: [f64; 3]Minimum velocity coordinates.
active: boolWhether LoMaC is active. When false, acts as passthrough.
delta_f_truncation: boolEnable delta-f rank-adaptive truncation.
delta_f_refresh_interval: u64Steps between f_ref refreshes (0 = never refresh).
delta_f_refresh_threshold: f64Relative norm threshold for f_ref refresh: refresh when ||delta_f|| / ||f_ref|| exceeds this value.
casimir_drift_history: Vec<(f64, f64)>History of Casimir C₂ drift: (pre_lomac, post_lomac) pairs per step. Tracks how much the LoMaC projection alters the Casimir invariant.
Implementations§
Source§impl LoMaC
impl LoMaC
Sourcepub fn new(
spatial_shape: [usize; 3],
velocity_shape: [usize; 3],
dx: [f64; 3],
dv: [f64; 3],
v_min: [f64; 3],
) -> Self
pub fn new( spatial_shape: [usize; 3], velocity_shape: [usize; 3], dx: [f64; 3], dv: [f64; 3], v_min: [f64; 3], ) -> Self
Create a new LoMaC manager with the given grid geometry.
Initializes an internal KFVS solver for macroscopic transport. The manager
starts in active mode; set active = false for passthrough behavior.
Sourcepub fn set_progress(&mut self, p: Arc<StepProgress>)
pub fn set_progress(&mut self, p: Arc<StepProgress>)
Attach shared progress state for intra-step TUI visibility.
Sourcepub fn initialize_from_kinetic(&mut self, f: &[f64])
pub fn initialize_from_kinetic(&mut self, f: &[f64])
Initialize from a kinetic distribution function.
Extracts macroscopic moments from f and initializes the KFVS solver. If delta-f truncation is enabled, stores f as the reference distribution.
Sourcepub fn advance_macroscopic(
&mut self,
dt: f64,
gx: &[f64],
gy: &[f64],
gz: &[f64],
)
pub fn advance_macroscopic( &mut self, dt: f64, gx: &[f64], gy: &[f64], gz: &[f64], )
Step 2: Advance macroscopic state by dt using KFVS.
gx, gy, gz are the gravitational acceleration components at each
spatial cell (flat arrays of length nxnynz).
Call this BEFORE advancing the kinetic equation.
Sourcepub fn project(&mut self, f_truncated: &[f64]) -> Vec<f64>
pub fn project(&mut self, f_truncated: &[f64]) -> Vec<f64>
Step 4: Project the truncated kinetic solution to restore moments.
Call this AFTER advancing and truncating the kinetic equation. Returns the corrected distribution function with exact conservation.
Sourcepub fn apply(
&mut self,
dt: f64,
gx: &[f64],
gy: &[f64],
gz: &[f64],
f_truncated: &[f64],
) -> Vec<f64>
pub fn apply( &mut self, dt: f64, gx: &[f64], gy: &[f64], gz: &[f64], f_truncated: &[f64], ) -> Vec<f64>
Combined step: advance macroscopic, then project kinetic solution.
This is the main LoMaC entry point for use after each time step:
- Advance KFVS: (ρ,J,e)^n → (ρ,J,e)^{n+1}
- Project: f̃^{n+1} → f^{n+1} matching (ρ,J,e)^{n+1}
Sourcepub fn total_mass(&self) -> f64
pub fn total_mass(&self) -> f64
Returns the current total mass (integral of rho over the spatial domain) from the KFVS state.
Sourcepub fn total_momentum(&self) -> [f64; 3]
pub fn total_momentum(&self) -> [f64; 3]
Returns the current total momentum vector [Jx, Jy, Jz] from the KFVS state.
Sourcepub fn total_energy(&self) -> f64
pub fn total_energy(&self) -> f64
Returns the current total energy (integral of e over the spatial domain) from the KFVS state.
Sourcepub fn project_ht(&self, ht: &HtTensor) -> Vec<f64>
pub fn project_ht(&self, ht: &HtTensor) -> Vec<f64>
Project an HtTensor directly to restore conservation, without dense conversion.
Algorithm:
- Extract macro state from HT via tree contraction (no dense expansion)
- Compute per-cell moment deficits vs KFVS target
- Convert the HT to snapshot, apply standard conservative_truncation
Note: Full HT-native projection (f_ref splitting + δf truncation) is a future optimization. This version avoids the dense LoMaC path in Simulation::step() by using HT moment extraction for the KFVS advance, then falls back to dense projection for the correction step.
Sourcepub fn initialize_from_ht(&mut self, ht: &HtTensor)
pub fn initialize_from_ht(&mut self, ht: &HtTensor)
Initialize LoMaC from an HtTensor’s moments directly (no dense conversion for the moment extraction step — only the KFVS initialization needs flat arrays).
Sourcepub fn enable_delta_f(&mut self, f_ref: Vec<f64>, refresh_interval: u64)
pub fn enable_delta_f(&mut self, f_ref: Vec<f64>, refresh_interval: u64)
Enable delta-f truncation mode with the given reference distribution. Truncation will act on the perturbation delta_f = f - f_ref instead of f directly.
Sourcepub fn apply_delta_f(
&mut self,
dt: f64,
gx: &[f64],
gy: &[f64],
gz: &[f64],
f: &[f64],
) -> Vec<f64>
pub fn apply_delta_f( &mut self, dt: f64, gx: &[f64], gy: &[f64], gz: &[f64], f: &[f64], ) -> Vec<f64>
Apply delta-f aware projection: truncate only the perturbation delta_f = f - f_ref, then reconstruct and project for exact conservation.
This yields lower post-truncation ranks because the smooth reference f_ref is preserved exactly and only the (small) perturbation is truncated.
Sourcepub fn update_f_ref(&mut self, f_new: &[f64])
pub fn update_f_ref(&mut self, f_new: &[f64])
Replace the reference distribution for delta-f mode with a new snapshot.
Auto Trait Implementations§
impl Freeze for LoMaC
impl RefUnwindSafe for LoMaC
impl Send for LoMaC
impl Sync for LoMaC
impl Unpin for LoMaC
impl UnsafeUnpin for LoMaC
impl UnwindSafe for LoMaC
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> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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