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
//! # kryst
//! PETSc-like Krylov solvers (KSP) and preconditioners (PC) in Rust.
//!
//! ## Quick start (serial)
//! ```rust,no_run
//! use kryst::prelude::*;
//! use kryst::matrix::MatShell;
//! use kryst::algebra::prelude::KrystScalar;
//! use std::sync::Arc;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let n = 4;
//! let a = MatShell::<S>::new(n, n, move |x, y| {
//! for i in 0..n {
//! let mut sum = S::from_real(2.0) * x[i];
//! if i > 0 {
//! sum -= x[i - 1];
//! }
//! if i + 1 < n {
//! sum -= x[i + 1];
//! }
//! y[i] = sum;
//! }
//! });
//! let a = Arc::new(a) as Arc<dyn LinOp<S = S>>;
//! let b = vec![S::from_real(1.0); n];
//! let mut x = vec![S::zero(); n];
//!
//! let mut ksp = KspContext::new();
//! ksp.set_type(SolverType::Gmres)?;
//! ksp.set_pc_type(PcType::None, None)?;
//! ksp.set_operators(a, None);
//! ksp.setup()?;
//! let stats = ksp.solve(&b, &mut x)?;
//! println!("reason={:?} residual={:.3e}", stats.reason, stats.final_residual);
//! # Ok(()) }
//! ```
//!
//! ## Lifecycle
//! 1. `set_type` / `set_pc_type` / `set_from_options`
//! 2. `set_operators(Amat, Pmat)`
//! 3. `setup()` (idempotent; reuses structure/values when possible)
//! 4. `solve(b, x)` (may call `setup()` automatically if needed)
//!
//! ## Reuse model
//! - `LinOp::structure_id` changes when the sparsity pattern or dimensions change.
//! - `LinOp::values_id` changes when only numeric values change.
//! - `StructureId(0)` / `ValuesId(0)` mean "unknown" and force conservative rebuilds.
//! - Wrappers like `CsrOp` / `DenseOp` expose `mark_structure_changed` and
//! `mark_values_changed` helpers.
//!
//! ## MPI communicator rules
//! - `KspContext` is bound to the operator communicator when operators are set.
//! - `try_set_operators` checks communicator congruence and dimension congruence.
//! - `try_set_operators_with_comm` wraps operators with an explicit communicator.
//! - Communicators must be IDENT or CONGRUENT (MPI_Comm_compare semantics).
//!
//! ## Feature flags
//! | Feature | Enables | Notes |
//! | --- | --- | --- |
//! | `mpi` | MPI communication backend | Requires MPI installed; MPI examples run via `mpirun` |
//! | `complex` | Complex scalar `S` (Complex64) | Classical and pipelined GMRES/FGMRES variants are supported |
//! | `backend-faer` | Dense/CSR backends and most PCs | Default feature |
//!
//! `S` is the internal scalar alias and `R` is its real partner. In real builds
//! `S = R = f64`. In complex builds `S = Complex64` and `R = f64`.
//!
//! ## Next steps
//! - `docs/communicators.md` for communicator details
//! - `docs/petsc_mapping.md` for PETSc to kryst mapping
//! - `examples/` for runnable demos
pub use crate;
pub use crate;
pub use crateKspContext;
pub use crateSolverType;
pub use cratePcType;
pub use crateKError;
pub use crateLinOp;
pub use crate;
pub use crate;
pub use crate;