1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Physical models
//!
//! This module provides traits and implementations for physical models.
//! A physical model encapsulates the physics equations of a system
//! (e.g., chromatography, heat transfer, reaction-diffusion).
//!
//! # Core Concepts
//!
//! - **Physical Model**: Computes the physics equations at a given state
//! - **Physical State**: Container for all physical quantities (concentration, temperature, etc.)
//! - **Physical Quantity**: Type-safe identifier for physical variables
//!
//! # Architecture
//!
//! Physical models are **separate from numerical solvers**:
//! - The model provides the **equations** (physics)
//! - The solver provides the **method** to solve them (numerics)
//!
//! This separation allows:
//! - Same model with different solvers (Euler, Runge-Kutta, etc.)
//! - Same solver with different models (chromatography, thermal, etc.)
//!
//! # Example
//!
//! ```rust
//! use chrom_rs::physics::{PhysicalModel, PhysicalState, PhysicalQuantity, PhysicalData};
//! use serde::{Deserialize, Serialize};
//!
//! # #[derive(Deserialize, Serialize)]
//! # struct MyModel;
//! # #[typetag::serde]
//! # impl PhysicalModel for MyModel {
//! # fn points(&self) -> usize { 1 }
//! # fn compute_physics(&self, state: &PhysicalState, _ctx: &chrom_rs::physics::ComputeContext) -> PhysicalState { state.clone() }
//! # fn setup_initial_state(&self) -> PhysicalState {
//! # PhysicalState::new(PhysicalQuantity::Concentration, PhysicalData::Vector(nalgebra::DVector::from_vec(vec![1.0])))
//! # }
//! # fn name(&self) -> &str { "MyModel" }
//! # }
//! # fn main() {
//! // Create a physical model
//! let model = MyModel;
//!
//! // Get initial state
//! let initial_state = model.setup_initial_state();
//!
//! // Compute physics at current state
//! # let ctx = chrom_rs::physics::ComputeContext::new(0.0, 0.01);
//! let physics_result = model.compute_physics(&initial_state, &ctx);
//! # }
//! ```
//!
//! # Implementing a New Physical Model
//!
//! To create a new physical model, implement the `PhysicalModel` trait:
//!
//! ```rust
//! use chrom_rs::physics::{PhysicalModel, PhysicalState};
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Deserialize, Serialize)]
//! struct MyCustomModel {
//! // Model parameters
//! }
//!
//! #[typetag::serde]
//! impl PhysicalModel for MyCustomModel {
//! fn points(&self) -> usize {
//! // Return number of spatial points
//! 1
//! }
//!
//! fn compute_physics(&self, state: &PhysicalState, _ctx: &chrom_rs::physics::ComputeContext) -> PhysicalState {
//! // Compute and return the physics equations
//! state.clone()
//! }
//!
//! fn setup_initial_state(&self) -> PhysicalState {
//! // Create initial state
//! # use chrom_rs::physics::{PhysicalQuantity, PhysicalData};
//! # PhysicalState::new(PhysicalQuantity::Concentration, PhysicalData::Vector(nalgebra::DVector::from_vec(vec![1.0])))
//! /* ... */
//! }
//!
//! fn name(&self) -> &str {
//! "My Custom Model"
//! }
//! }
//! ```
//!
//! # Available Models
//!
//! Currently implemented physical models:
//! - **Langmuir 1D**: 1D chromatography with modified Langmuir isotherm
// module declaration
/// Typed compute context: [`ComputeContext`], [`ContextVariable`], [`ContextValue`].
/// Core data types: [`PhysicalData`], [`PhysicalState`], and [`PhysicalQuantity`].
/// Core traits: [`PhysicalModel`] and [`Exportable`].
// re-export commonly used types for convenience
pub use ;
pub use PhysicalData;
pub use ;