Skip to main content

Crate oxiflow

Crate oxiflow 

Source
Expand description

§oxiflow

Generic numerical engine for transport, reaction, and diffusion problems.

§The canonical form

Every problem solved by oxiflow is expressed as a conservation law or field equation of the form:

$$\frac{\partial u}{\partial t} + \nabla \cdot F(u, \nabla u) = S(u, \mathbf{x}, t)$$

where:

  • u(x, t) — the primary field: concentration, temperature, velocity, pressure, magnetic flux density, or any other quantity that evolves in time and space.
  • F(u, ∇u) — the flux tensor, which may combine:
    • advective flux v·u (transport by a flow field),
    • diffusive flux -D·∇u (Fick, Fourier, Darcy),
    • dispersive flux (higher-order spreading, e.g. in chromatography).
  • S(u, x, t) — source or reaction term: chemical reactions, heat generation, gravity, electromagnetic forcing, adsorption isotherms.

Second-order-in-time problems (∂²u/∂t², structural dynamics, wave propagation) are reduced to this form by introducing v = ∂u/∂t as a second field component: the state (u, v) evolves as a first-order system. Newmark-β and HHT-α integrators are planned for J4+.

§Physical domains

oxiflow covers any problem expressible as the canonical form above.

DomainPrimary field uMilestone
Chromatographic transportconcentration c(z,t)J1
Transient heat conductiontemperature T(x,t)J2+
Reaction-diffusionspecies (u,v)J2+
Flow in porous media (Darcy)water content θJ2+
Shallow water (Saint-Venant)depth h, momentum hvJ3
Electrochemical (Nernst-Planck)ionic concentrations cᵢJ3+
Resistive magnetic diffusionflux density BJ7
Structural dynamicsdisplacement u, velocity vJ4+

For full equations, physical derivations, and numerical details, see the project wiki.

§Numerical structure

In each domain above, u changes physical meaning, but the engine abstraction is identical:

Physical conceptEngine abstraction
Field u(x,t)ContextValue::ScalarField / VectorField
Spatial domainMesh (INV-1) — UniformGrid1D (J1), FEM (J7)
Flux F, source SPhysicalModel::compute_physics(u, ctx)
Auxiliary quantitiesComputeContextContextCalculator chain
Time integrationSolver — Euler, RK4, … (J4)
Boundary conditionsBoundaryCondition: RequiresContext (J2)
Multi-domain couplingCouplingOperator (INV-3, J3)
Spatial operatorsDiscreteOperator<M: Mesh> (INV-2, J4b)

§Architecture — WHAT / HOW separation

Three strictly separated responsibilities:

TypePoleRole
solver::ScenarioWHATDeclares the problem: model, mesh, domains, BCs
solver::SolverConfigurationHOWConfigures solving: integrator, step control, calculators
solver::SolverExecutionOrchestrates the time integration loop

The engine enforces a contractual execution order at each time step:

  1. Context calculators populate context::ComputeContext
  2. Boundary conditions are applied to the current state (J2)
  3. model::PhysicalModel::compute_physics computes du/dt
  4. The integrator advances the state by dt

§Modules

§FEM invariants — forward compatibility

All abstractions from v0.1 are designed to extend naturally to FEM at v2.0 without any breaking change on existing code.

InvariantGuaranteeActive from
INV-1No dx/nx in public API — all spatial access via mesh::Meshv0.1.0
INV-2Integrators decoupled from spatial scheme via DiscreteOperator<M>v0.5.0
INV-3Inter-domain coupling only via CouplingOperatorv0.3.0
INV-4All public traits object-safe — external crates can implement themv2.0.0

§Getting started (J1)

use oxiflow::{
    context::ContextVariable,
    mesh::{Mesh, UniformGrid1D},
    model::{PhysicalModel, RequiresContext},
    solver::{Scenario, SolverConfiguration, TimeConfiguration,
             StepControl, IntegratorKind},
};

// 1. Declare the physical model
struct MyModel;
impl RequiresContext for MyModel {
    fn required_variables(&self) -> Vec<ContextVariable> {
        vec![ContextVariable::Time]
    }
}
impl PhysicalModel for MyModel { /* … */ }

// 2. Declare the problem (WHAT)
let mesh = UniformGrid1D::new(100, 0.0, 1.0).unwrap();
let scenario = Scenario::single(Box::new(MyModel), Box::new(mesh));

// 3. Configure solving (HOW)
let config = SolverConfiguration::new(
    TimeConfiguration::new(600.0, StepControl::Fixed { dt: 0.1 }),
    IntegratorKind::Euler,
);

// 4. Solve (J4 — integrator implementations land at v0.4.0)
// let result = EulerSolver.solve(&scenario, &config)?;

Modules§

boundary
Module boundary
context
Module context
coupling
Module coupling
mesh
Module mesh
model
Module model
operators
Module operators
solver
Module solver