use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{
BurgersRiemann, CurvatureFlowSim, DeGiorgiNashMoser, DispersiveEstimateChecker, HeatSolver1D,
HomogenizationApprox, KPZEquation, Mesh1D, MinimalSurface, NonlinearSchrodinger,
ParabolicSolver, PseudodiffOperatorSim, SchauderEstimate, StiffnessMatrix1D,
StochasticHeatEquation, StrichartzData,
};
pub fn app(f: Expr, a: Expr) -> Expr {
Expr::App(Box::new(f), Box::new(a))
}
pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
app(app(f, a), b)
}
pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
app(app2(f, a, b), c)
}
pub fn cst(s: &str) -> Expr {
Expr::Const(Name::str(s), vec![])
}
pub fn prop() -> Expr {
Expr::Sort(Level::zero())
}
pub fn type0() -> Expr {
Expr::Sort(Level::succ(Level::zero()))
}
pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn arrow(a: Expr, b: Expr) -> Expr {
pi(BinderInfo::Default, "_", a, b)
}
pub fn bvar(n: u32) -> Expr {
Expr::BVar(n)
}
pub fn nat_ty() -> Expr {
cst("Nat")
}
pub fn real_ty() -> Expr {
cst("Real")
}
pub fn set_of(ty: Expr) -> Expr {
app(cst("Set"), ty)
}
pub fn fn_ty(dom: Expr, cod: Expr) -> Expr {
arrow(dom, cod)
}
pub fn sobolev_space_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn l2_space_ty() -> Expr {
type0()
}
pub fn h1_space_ty() -> Expr {
type0()
}
pub fn h10_space_ty() -> Expr {
type0()
}
pub fn hk_space_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn weak_derivative_ty() -> Expr {
pi(
BinderInfo::Default,
"V",
type0(),
arrow(nat_ty(), arrow(cst("L2Space"), prop())),
)
}
pub fn sobolev_norm_ty() -> Expr {
arrow(cst("H1Space"), real_ty())
}
pub fn sobolev_embedding_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn trace_map_ty() -> Expr {
arrow(cst("H1Space"), cst("L2Space"))
}
pub fn elliptic_operator_ty() -> Expr {
type0()
}
pub fn parabolic_operator_ty() -> Expr {
type0()
}
pub fn hyperbolic_operator_ty() -> Expr {
type0()
}
pub fn is_elliptic_ty() -> Expr {
arrow(cst("EllipticOperator"), prop())
}
pub fn bilinear_form_ty() -> Expr {
arrow(cst("H1Space"), arrow(cst("H1Space"), real_ty()))
}
pub fn is_coercive_ty() -> Expr {
arrow(cst("BilinearForm"), prop())
}
pub fn is_continuous_bf_ty() -> Expr {
arrow(cst("BilinearForm"), prop())
}
pub fn weak_solution_ty() -> Expr {
arrow(
cst("EllipticOperator"),
arrow(cst("L2Space"), arrow(cst("H10Space"), prop())),
)
}
pub fn weak_solution_heat_ty() -> Expr {
arrow(
cst("ParabolicOperator"),
arrow(
cst("L2Space"),
arrow(fn_ty(real_ty(), cst("H10Space")), prop()),
),
)
}
pub fn weak_solution_wave_ty() -> Expr {
arrow(
cst("HyperbolicOperator"),
arrow(
cst("L2Space"),
arrow(
cst("H10Space"),
arrow(fn_ty(real_ty(), cst("H10Space")), prop()),
),
),
)
}
pub fn lax_milgram_ty() -> Expr {
pi(
BinderInfo::Default,
"V",
type0(),
arrow(
app(cst("IsCoercive"), bvar(0)),
arrow(app(cst("IsContinuous_bf"), bvar(1)), prop()),
),
)
}
pub fn elliptic_regularity_ty() -> Expr {
pi(
BinderInfo::Default,
"k",
nat_ty(),
arrow(
app3(
cst("WeakSolution"),
cst("EllipticOperator"),
cst("L2Space"),
cst("H10Space"),
),
prop(),
),
)
}
pub fn maximum_principle_ty() -> Expr {
pi(
BinderInfo::Default,
"L",
cst("EllipticOperator"),
arrow(app(cst("IsElliptic"), bvar(0)), prop()),
)
}
pub fn sobolev_embedding_thm_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
}
pub fn poincare_inequality_ty() -> Expr {
arrow(cst("H10Space"), prop())
}
pub fn heat_equation_existence_ty() -> Expr {
arrow(
cst("L2Space"),
arrow(fn_ty(real_ty(), cst("H10Space")), prop()),
)
}
pub fn wave_equation_existence_ty() -> Expr {
arrow(cst("H10Space"), arrow(cst("L2Space"), prop()))
}
pub fn navier_stokes_weak_existence_ty() -> Expr {
arrow(
cst("L2Space"),
arrow(fn_ty(real_ty(), cst("H10Space")), prop()),
)
}
pub fn riemann_problem_solution_ty() -> Expr {
arrow(cst("ConservationLaw"), arrow(cst("InitialData"), prop()))
}
pub fn galerkin_approximation_ty() -> Expr {
arrow(cst("H10Space"), arrow(nat_ty(), cst("H10Space")))
}
pub fn cea_lemma_ty() -> Expr {
pi(
BinderInfo::Default,
"u",
cst("H10Space"),
arrow(
app2(cst("GalerkinApproximation"), bvar(0), cst("Nat")),
prop(),
),
)
}
pub fn finite_element_space_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn apriori_error_ty() -> Expr {
arrow(nat_ty(), arrow(real_ty(), prop()))
}
pub fn inf_sup_condition_ty() -> Expr {
arrow(cst("BilinearForm"), prop())
}
pub fn conservation_law_ty() -> Expr {
arrow(fn_ty(real_ty(), real_ty()), type0())
}
pub fn entropy_solution_ty() -> Expr {
arrow(
cst("ConservationLaw"),
arrow(
cst("InitialData"),
arrow(fn_ty(real_ty(), fn_ty(real_ty(), real_ty())), prop()),
),
)
}
pub fn kruzkov_theorem_ty() -> Expr {
arrow(cst("L2Space"), prop())
}
pub fn rankine_hugoniot_ty() -> Expr {
arrow(cst("ConservationLaw"), arrow(real_ty(), prop()))
}
pub fn strichartz_estimate_ty() -> Expr {
pi(
BinderInfo::Default,
"u",
cst("SolutionSpace"),
app2(
cst("Le"),
app(cst("StrichartzNorm"), bvar(0)),
app(cst("InitialDataNorm"), bvar(0)),
),
)
}
pub fn admissible_pair_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn dispersive_estimate_ty() -> Expr {
arrow(real_ty(), arrow(real_ty(), prop()))
}
pub fn kdv_soliton_ty() -> Expr {
arrow(real_ty(), arrow(real_ty(), arrow(real_ty(), real_ty())))
}
pub fn nls_gwp_ty() -> Expr {
arrow(cst("H1Space"), prop())
}
pub fn nls_blowup_ty() -> Expr {
arrow(cst("H1Space"), arrow(real_ty(), prop()))
}
pub fn paraproduct_decomposition_ty() -> Expr {
arrow(cst("L2Space"), arrow(cst("L2Space"), cst("L2Space")))
}
pub fn bilinear_estimate_ty() -> Expr {
arrow(
cst("L2Space"),
arrow(cst("L2Space"), arrow(real_ty(), prop())),
)
}
pub fn littlewood_paley_projection_ty() -> Expr {
arrow(nat_ty(), arrow(cst("L2Space"), cst("L2Space")))
}
pub fn calderon_zygmund_operator_ty() -> Expr {
type0()
}
pub fn cz_boundedness_ty() -> Expr {
arrow(cst("CalderonZygmundOperator"), prop())
}
pub fn weak_type_11_ty() -> Expr {
arrow(cst("CalderonZygmundOperator"), prop())
}
pub fn hardy_littlewood_maximal_ty() -> Expr {
arrow(cst("L2Space"), cst("L2Space"))
}
pub fn hilbert_transform_ty() -> Expr {
arrow(cst("L2Space"), cst("L2Space"))
}
pub fn symbol_class_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn pseudodiff_operator_ty() -> Expr {
arrow(cst("SymbolClass"), type0())
}
pub fn pseudodiff_composition_ty() -> Expr {
arrow(
cst("PseudodiffOperator"),
arrow(cst("PseudodiffOperator"), cst("PseudodiffOperator")),
)
}
pub fn fourier_integral_operator_ty() -> Expr {
type0()
}
pub fn wavefront_set_ty() -> Expr {
arrow(cst("L2Space"), type0())
}
pub fn elliptic_regularity_micro_ty() -> Expr {
arrow(cst("PseudodiffOperator"), arrow(cst("L2Space"), prop()))
}
pub fn propagation_of_singularities_ty() -> Expr {
arrow(cst("HyperbolicOperator"), arrow(cst("L2Space"), prop()))
}
pub fn ladyzhenskaya_prodi_serrin_ty() -> Expr {
arrow(real_ty(), arrow(real_ty(), prop()))
}
pub fn caffarelli_kohn_nirenberg_ty() -> Expr {
arrow(cst("L2Space"), prop())
}
pub fn vorticity_formulation_ty() -> Expr {
arrow(cst("L2Space"), cst("L2Space"))
}
pub fn ricci_flow_solution_ty() -> Expr {
type0()
}
pub fn mean_curvature_flow_solution_ty() -> Expr {
type0()
}
pub fn short_time_existence_geom_flow_ty() -> Expr {
arrow(cst("RicciFlowSolution"), prop())
}
pub fn neck_pinch_singularity_ty() -> Expr {
arrow(cst("MeanCurvatureFlowSolution"), arrow(real_ty(), prop()))
}
pub fn free_boundary_ty() -> Expr {
type0()
}
pub fn obstacle_problem_ty() -> Expr {
arrow(
cst("H10Space"),
arrow(cst("L2Space"), arrow(cst("FreeBoundary"), prop())),
)
}
pub fn stefan_problem_ty() -> Expr {
arrow(cst("FreeBoundary"), arrow(real_ty(), prop()))
}
pub fn free_boundary_regularity_ty() -> Expr {
arrow(cst("FreeBoundary"), prop())
}
pub fn hamilton_jacobi_equation_ty() -> Expr {
type0()
}
pub fn viscosity_solution_ty() -> Expr {
arrow(cst("HamiltonJacobiEquation"), arrow(cst("L2Space"), prop()))
}
pub fn crandall_lions_uniqueness_ty() -> Expr {
arrow(cst("HamiltonJacobiEquation"), prop())
}
pub fn hopf_lax_formula_ty() -> Expr {
arrow(
cst("HamiltonJacobiEquation"),
arrow(real_ty(), arrow(real_ty(), real_ty())),
)
}
pub fn homogenized_coefficient_ty() -> Expr {
arrow(real_ty(), real_ty())
}
pub fn two_scale_convergence_ty() -> Expr {
arrow(cst("L2Space"), arrow(cst("L2Space"), prop()))
}
pub fn gamma_convergence_ty() -> Expr {
type0()
}
pub fn homogenization_thm_ty() -> Expr {
arrow(real_ty(), arrow(cst("L2Space"), prop()))
}
pub fn reaction_diffusion_system_ty() -> Expr {
type0()
}
pub fn turing_instability_ty() -> Expr {
arrow(cst("ReactionDiffusionSystem"), prop())
}
pub fn traveling_wave_ty() -> Expr {
arrow(cst("ReactionDiffusionSystem"), arrow(real_ty(), prop()))
}
pub fn fisher_kpp_equation_ty() -> Expr {
arrow(real_ty(), arrow(real_ty(), prop()))
}
pub fn variational_inequality_ty() -> Expr {
arrow(cst("H10Space"), arrow(cst("L2Space"), prop()))
}
pub fn convex_minimizer_ty() -> Expr {
arrow(cst("H10Space"), arrow(cst("L2Space"), cst("H10Space")))
}
pub fn penalty_method_convergence_ty() -> Expr {
arrow(cst("VariationalInequality"), arrow(real_ty(), prop()))
}
pub fn build_pde_theory_env(env: &mut Environment) {
let axioms: &[(&str, Expr)] = &[
("L2Space", type0()),
("H1Space", type0()),
("H10Space", type0()),
("BilinearForm", type0()),
("ConservationLaw", type0()),
("InitialData", type0()),
("SobolevSpace", sobolev_space_ty()),
("HkSpace", hk_space_ty()),
("WeakDerivative", weak_derivative_ty()),
("SobolevNorm", sobolev_norm_ty()),
("SobolevEmbedding", sobolev_embedding_ty()),
("TraceMap", trace_map_ty()),
("EllipticOperator", elliptic_operator_ty()),
("ParabolicOperator", parabolic_operator_ty()),
("HyperbolicOperator", hyperbolic_operator_ty()),
("IsElliptic", is_elliptic_ty()),
("IsCoercive", is_coercive_ty()),
("IsContinuous_bf", is_continuous_bf_ty()),
("WeakSolution", weak_solution_ty()),
("WeakSolutionHeat", weak_solution_heat_ty()),
("WeakSolutionWave", weak_solution_wave_ty()),
("lax_milgram", lax_milgram_ty()),
("elliptic_regularity", elliptic_regularity_ty()),
("maximum_principle", maximum_principle_ty()),
("sobolev_embedding_thm", sobolev_embedding_thm_ty()),
("poincare_inequality", poincare_inequality_ty()),
("heat_equation_existence", heat_equation_existence_ty()),
("wave_equation_existence", wave_equation_existence_ty()),
(
"navier_stokes_weak_existence",
navier_stokes_weak_existence_ty(),
),
("riemann_problem_solution", riemann_problem_solution_ty()),
("GalerkinApproximation", galerkin_approximation_ty()),
("cea_lemma", cea_lemma_ty()),
("FiniteElementSpace", finite_element_space_ty()),
("apriori_error", apriori_error_ty()),
("InfSupCondition", inf_sup_condition_ty()),
("EntropySolution", entropy_solution_ty()),
("kruzkov_theorem", kruzkov_theorem_ty()),
("rankine_hugoniot", rankine_hugoniot_ty()),
("SolutionSpace", type0()),
("StrichartzNorm", arrow(cst("SolutionSpace"), real_ty())),
("InitialDataNorm", arrow(cst("SolutionSpace"), real_ty())),
("strichartz_estimate", strichartz_estimate_ty()),
("AdmissiblePair", admissible_pair_ty()),
("dispersive_estimate", dispersive_estimate_ty()),
("KdVSoliton", kdv_soliton_ty()),
("nls_gwp", nls_gwp_ty()),
("nls_blowup", nls_blowup_ty()),
("paraproduct_decomposition", paraproduct_decomposition_ty()),
("bilinear_estimate", bilinear_estimate_ty()),
(
"LittlewoodPaleyProjection",
littlewood_paley_projection_ty(),
),
("CalderonZygmundOperator", calderon_zygmund_operator_ty()),
("cz_boundedness", cz_boundedness_ty()),
("WeakType11", weak_type_11_ty()),
("HardyLittlewoodMaximal", hardy_littlewood_maximal_ty()),
("HilbertTransform", hilbert_transform_ty()),
("SymbolClass", symbol_class_ty()),
("PseudodiffOperator", pseudodiff_operator_ty()),
("pseudodiff_composition", pseudodiff_composition_ty()),
("FourierIntegralOperator", fourier_integral_operator_ty()),
("WavefrontSet", wavefront_set_ty()),
("elliptic_regularity_micro", elliptic_regularity_micro_ty()),
(
"propagation_of_singularities",
propagation_of_singularities_ty(),
),
(
"ladyzhenskaya_prodi_serrin",
ladyzhenskaya_prodi_serrin_ty(),
),
("caffarelli_kohn_nirenberg", caffarelli_kohn_nirenberg_ty()),
("VorticityFormulation", vorticity_formulation_ty()),
("RicciFlowSolution", ricci_flow_solution_ty()),
(
"MeanCurvatureFlowSolution",
mean_curvature_flow_solution_ty(),
),
(
"short_time_existence_geom_flow",
short_time_existence_geom_flow_ty(),
),
("neck_pinch_singularity", neck_pinch_singularity_ty()),
("FreeBoundary", free_boundary_ty()),
("obstacle_problem", obstacle_problem_ty()),
("stefan_problem", stefan_problem_ty()),
("free_boundary_regularity", free_boundary_regularity_ty()),
("HamiltonJacobiEquation", hamilton_jacobi_equation_ty()),
("viscosity_solution", viscosity_solution_ty()),
("crandall_lions_uniqueness", crandall_lions_uniqueness_ty()),
("hopf_lax_formula", hopf_lax_formula_ty()),
("HomogenizedCoefficient", homogenized_coefficient_ty()),
("two_scale_convergence", two_scale_convergence_ty()),
("GammaConvergence", gamma_convergence_ty()),
("homogenization_thm", homogenization_thm_ty()),
("ReactionDiffusionSystem", reaction_diffusion_system_ty()),
("turing_instability", turing_instability_ty()),
("traveling_wave", traveling_wave_ty()),
("fisher_kpp_equation", fisher_kpp_equation_ty()),
("VariationalInequality", variational_inequality_ty()),
("ConvexMinimizer", convex_minimizer_ty()),
(
"penalty_method_convergence",
penalty_method_convergence_ty(),
),
];
for (name, ty) in axioms {
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty: ty.clone(),
})
.ok();
}
}
pub fn discrete_h1_seminorm(u: &[f64], h: f64) -> f64 {
if u.len() < 2 {
return 0.0;
}
let sum_sq: f64 = u
.windows(2)
.map(|w| {
let du = (w[1] - w[0]) / h;
du * du * h
})
.sum();
sum_sq.sqrt()
}
pub fn discrete_l2_norm(u: &[f64], h: f64) -> f64 {
if u.is_empty() {
return 0.0;
}
let n = u.len();
let sum_sq: f64 = (0..n)
.map(|i| {
let w = if i == 0 || i == n - 1 { 0.5 } else { 1.0 };
w * u[i] * u[i] * h
})
.sum();
sum_sq.sqrt()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_pde_theory_env_populates() {
let mut env = Environment::new();
build_pde_theory_env(&mut env);
assert!(env.get(&Name::str("lax_milgram")).is_some());
assert!(env.get(&Name::str("SobolevSpace")).is_some());
assert!(env.get(&Name::str("EllipticOperator")).is_some());
assert!(env
.get(&Name::str("navier_stokes_weak_existence"))
.is_some());
assert!(env.get(&Name::str("poincare_inequality")).is_some());
}
#[test]
fn test_mesh1d_uniform() {
let mesh = Mesh1D::uniform(0.0, 1.0, 4);
assert_eq!(mesh.nodes.len(), 5);
assert!((mesh.nodes[0] - 0.0).abs() < 1e-12);
assert!((mesh.nodes[4] - 1.0).abs() < 1e-12);
assert!((mesh.mesh_size() - 0.25).abs() < 1e-12);
assert_eq!(mesh.num_interior(), 3);
}
#[test]
fn test_stiffness_matrix_assemble() {
let mesh = Mesh1D::uniform(0.0, 1.0, 3);
let k = StiffnessMatrix1D::assemble(&mesh);
assert_eq!(k.dim, 2);
let h = mesh.mesh_size();
assert!((k.data[0][0] - 2.0 / h).abs() < 1e-10);
assert!((k.data[0][1] + 1.0 / h).abs() < 1e-10);
}
#[test]
fn test_stiffness_matrix_solve() {
let n = 20;
let mesh = Mesh1D::uniform(0.0, 1.0, n + 1);
let k = StiffnessMatrix1D::assemble(&mesh);
let h = mesh.mesh_size();
let rhs = vec![h; k.dim];
let u = k.solve_tridiagonal(&rhs);
let mid = u.len() / 2;
let x_mid = mesh.nodes[1 + mid];
let exact = x_mid * (1.0 - x_mid) / 2.0;
assert!(
(u[mid] - exact).abs() < 0.01,
"FEM solution differs: got {}, expected {}",
u[mid],
exact
);
}
#[test]
fn test_heat_solver_decay() {
let alpha = 1.0;
let n = 50;
let mesh = Mesh1D::uniform(0.0, 1.0, n + 1);
let dt = 0.5 * mesh.mesh_size().powi(2) / alpha;
let mut solver = HeatSolver1D::new(alpha, mesh, |x| (std::f64::consts::PI * x).sin());
let t_end = 0.1;
solver.advance_to(t_end, dt);
let decay = (-std::f64::consts::PI * std::f64::consts::PI * alpha * t_end).exp();
let norm = solver.l2_norm();
let initial_norm = 1.0 / std::f64::consts::SQRT_2;
let expected = initial_norm * decay;
assert!(
(norm - expected).abs() < 0.05,
"Heat decay: got {}, expected ~{}",
norm,
expected
);
}
#[test]
fn test_burgers_shock() {
let rp = BurgersRiemann::new(2.0, 0.0);
assert!((rp.shock_speed() - 1.0).abs() < 1e-12);
assert!((rp.eval(-0.5, 1.0) - 2.0).abs() < 1e-12);
assert!((rp.eval(1.5, 1.0) - 0.0).abs() < 1e-12);
}
#[test]
fn test_burgers_rarefaction() {
let rp = BurgersRiemann::new(0.0, 1.0);
assert!((rp.eval(0.5, 1.0) - 0.5).abs() < 1e-12);
assert!((rp.eval(-0.1, 1.0) - 0.0).abs() < 1e-12);
assert!((rp.eval(1.5, 1.0) - 1.0).abs() < 1e-12);
}
#[test]
fn test_discrete_norms() {
let n = 100;
let h = 1.0 / n as f64;
let u: Vec<f64> = (0..=n).map(|i| i as f64 * h).collect();
let l2 = discrete_l2_norm(&u, h);
assert!((l2 - 1.0 / 3.0_f64.sqrt()).abs() < 0.01, "L2 norm: {}", l2);
let h1 = discrete_h1_seminorm(&u, h);
assert!((h1 - 1.0).abs() < 0.01, "H1 seminorm: {}", h1);
}
#[test]
fn test_axiom_types_are_props_or_types() {
let ty = lax_milgram_ty();
assert!(matches!(ty, Expr::Pi(_, _, _, _)));
let ty2 = sobolev_space_ty();
assert!(matches!(ty2, Expr::Pi(_, _, _, _)));
let ty3 = poincare_inequality_ty();
assert!(matches!(ty3, Expr::Pi(_, _, _, _)));
}
#[test]
fn test_new_axioms_registered() {
let mut env = Environment::new();
build_pde_theory_env(&mut env);
assert!(env.get(&Name::str("strichartz_estimate")).is_some());
assert!(env.get(&Name::str("AdmissiblePair")).is_some());
assert!(env.get(&Name::str("dispersive_estimate")).is_some());
assert!(env.get(&Name::str("nls_gwp")).is_some());
assert!(env.get(&Name::str("nls_blowup")).is_some());
assert!(env.get(&Name::str("paraproduct_decomposition")).is_some());
assert!(env.get(&Name::str("bilinear_estimate")).is_some());
assert!(env.get(&Name::str("LittlewoodPaleyProjection")).is_some());
assert!(env.get(&Name::str("CalderonZygmundOperator")).is_some());
assert!(env.get(&Name::str("cz_boundedness")).is_some());
assert!(env.get(&Name::str("WeakType11")).is_some());
assert!(env.get(&Name::str("HilbertTransform")).is_some());
assert!(env.get(&Name::str("SymbolClass")).is_some());
assert!(env.get(&Name::str("PseudodiffOperator")).is_some());
assert!(env.get(&Name::str("FourierIntegralOperator")).is_some());
assert!(env.get(&Name::str("WavefrontSet")).is_some());
assert!(env
.get(&Name::str("propagation_of_singularities"))
.is_some());
assert!(env.get(&Name::str("ladyzhenskaya_prodi_serrin")).is_some());
assert!(env.get(&Name::str("caffarelli_kohn_nirenberg")).is_some());
assert!(env.get(&Name::str("RicciFlowSolution")).is_some());
assert!(env.get(&Name::str("MeanCurvatureFlowSolution")).is_some());
assert!(env.get(&Name::str("neck_pinch_singularity")).is_some());
assert!(env.get(&Name::str("FreeBoundary")).is_some());
assert!(env.get(&Name::str("obstacle_problem")).is_some());
assert!(env.get(&Name::str("stefan_problem")).is_some());
assert!(env.get(&Name::str("free_boundary_regularity")).is_some());
assert!(env.get(&Name::str("HamiltonJacobiEquation")).is_some());
assert!(env.get(&Name::str("viscosity_solution")).is_some());
assert!(env.get(&Name::str("crandall_lions_uniqueness")).is_some());
assert!(env.get(&Name::str("hopf_lax_formula")).is_some());
assert!(env.get(&Name::str("HomogenizedCoefficient")).is_some());
assert!(env.get(&Name::str("two_scale_convergence")).is_some());
assert!(env.get(&Name::str("GammaConvergence")).is_some());
assert!(env.get(&Name::str("homogenization_thm")).is_some());
assert!(env.get(&Name::str("ReactionDiffusionSystem")).is_some());
assert!(env.get(&Name::str("turing_instability")).is_some());
assert!(env.get(&Name::str("traveling_wave")).is_some());
assert!(env.get(&Name::str("fisher_kpp_equation")).is_some());
assert!(env.get(&Name::str("VariationalInequality")).is_some());
assert!(env.get(&Name::str("ConvexMinimizer")).is_some());
assert!(env.get(&Name::str("penalty_method_convergence")).is_some());
}
#[test]
fn test_new_axiom_expr_shapes() {
assert!(matches!(strichartz_estimate_ty(), Expr::Pi(_, _, _, _)));
assert!(matches!(viscosity_solution_ty(), Expr::Pi(_, _, _, _)));
assert!(matches!(turing_instability_ty(), Expr::Pi(_, _, _, _)));
assert!(matches!(calderon_zygmund_operator_ty(), Expr::Sort(_)));
assert!(matches!(free_boundary_ty(), Expr::Sort(_)));
assert!(matches!(ricci_flow_solution_ty(), Expr::Sort(_)));
}
#[test]
fn test_pseudodiff_operator_identity() {
let op = PseudodiffOperatorSim::new(0.0, 8);
let u: Vec<f64> = (0..8).map(|i| (i as f64).sin()).collect();
let v = op.apply(&u);
for (a, b) in u.iter().zip(v.iter()) {
assert!(
(a - b).abs() < 1e-9,
"Expected identity, got diff {}",
a - b
);
}
}
#[test]
fn test_pseudodiff_operator_norm_bound() {
let op = PseudodiffOperatorSim::new(1.0, 16);
let bound = op.l2_operator_norm_bound(16);
assert!(bound > 1.0, "Norm bound should be > 1 for order 1");
}
#[test]
fn test_dispersive_l2_conservation() {
let checker = DispersiveEstimateChecker::new(16, 0.01);
let u_re: Vec<f64> = (0..16)
.map(|i| (i as f64 / 16.0 * 2.0 * std::f64::consts::PI).cos())
.collect();
let u_im: Vec<f64> = vec![0.0; 16];
assert!(
checker.check_l2_conservation(&u_re, &u_im, 1e-8),
"L² should be conserved by Schrödinger propagator"
);
}
#[test]
fn test_parabolic_solver_decay() {
let alpha = 1.0;
let n = 50;
let mesh = Mesh1D::uniform(0.0, 1.0, n + 1);
let dt = 0.01;
let mut solver = ParabolicSolver::new(alpha, mesh, |x| (std::f64::consts::PI * x).sin());
let t_end = 0.1;
solver.advance_to(t_end, dt);
let decay = (-std::f64::consts::PI * std::f64::consts::PI * alpha * t_end).exp();
let norm = solver.l2_norm();
let initial_norm = 1.0 / std::f64::consts::SQRT_2;
let expected = initial_norm * decay;
assert!(
(norm - expected).abs() < 0.05,
"Implicit Euler heat decay: got {}, expected ~{}",
norm,
expected
);
}
#[test]
fn test_curvature_flow_circle_shrinks() {
let mut sim = CurvatureFlowSim::circle(0.0, 0.0, 1.0, 32);
let area_init = sim.area();
sim.advance_to(0.1, 0.001);
let area_final = sim.area();
assert!(
area_final < area_init,
"Circle area should shrink under MCF: {} → {}",
area_init,
area_final
);
}
#[test]
fn test_homogenization_approx_constant_coeff() {
let hom = HomogenizationApprox::new(1000);
let c = 3.0;
let a_hom = hom.compute(|_y| c);
assert!(
(a_hom - c).abs() < 0.01,
"Constant coefficient: got {}, expected {}",
a_hom,
c
);
}
#[test]
fn test_homogenization_two_phase() {
let hom = HomogenizationApprox::new(1000);
let (a1, a2, theta) = (1.0, 4.0, 0.5);
let a_hom = hom.compute(|y| if y < theta { a1 } else { a2 });
let exact = HomogenizationApprox::two_phase_exact(a1, a2, theta);
assert!(
(a_hom - exact).abs() < 0.01,
"Two-phase homogenization: got {}, expected {}",
a_hom,
exact
);
}
}
#[cfg(test)]
mod tests_pde_ext {
use super::*;
#[test]
fn test_stochastic_heat() {
let spde = StochasticHeatEquation::new(1.0, 0.5, 1);
assert!(spde.is_well_posed_l2());
let energy = spde.energy_at_time(1.0, 2.0);
assert!(energy > 2.0);
let reg = spde.mild_solution_regularity();
assert!(reg.contains("L2"));
}
#[test]
fn test_kpz_equation() {
let kpz = KPZEquation::new(1.0, 0.5);
let (chi, beta, z) = kpz.kpz_exponents();
assert!((chi - 0.5).abs() < 1e-10);
assert!((beta - 1.0 / 3.0).abs() < 1e-10);
assert!((z - 1.5).abs() < 1e-10);
assert!(kpz.is_kpz_universality_class());
let hc = kpz.hopf_cole_transform();
assert!(hc.contains("Hopf-Cole"));
}
#[test]
fn test_minimal_surface() {
let cat = MinimalSurface::catenoid();
assert_eq!(cat.mean_curvature(), 0.0);
assert_eq!(cat.ambient_dimension, 3);
let plane = MinimalSurface::plane(4);
let simons = plane.simons_gap_theorem();
assert!(simons.contains("hyperplane"));
}
#[test]
fn test_de_giorgi_nash_moser() {
let dgnm = DeGiorgiNashMoser::new(0.5, 2.0, 3);
assert!(dgnm.holder_exponent > 0.0);
assert!(dgnm.ellipticity_ratio() == 4.0);
let harnack = dgnm.harnack_inequality_constant();
assert!(harnack > 1.0);
}
#[test]
fn test_schauder_estimate() {
let est = SchauderEstimate::second_order(0.3);
assert_eq!(est.operator_order, 2);
assert!((est.holder_solution - 2.3).abs() < 1e-10);
let desc = est.interior_estimate();
assert!(desc.contains("Schauder"));
}
#[test]
fn test_strichartz() {
let schr = StrichartzData::schrodinger(3);
let desc = schr.strichartz_estimate_description();
assert!(desc.contains("Strichartz"));
assert!(schr.is_energy_critical());
let wave = StrichartzData::wave(2);
assert!(!wave.is_energy_critical());
}
#[test]
fn test_nonlinear_schrodinger() {
let nls = NonlinearSchrodinger::new(2.0, 3);
assert!(nls.global_well_posedness_h1());
let desc = nls.scattering_theory_description();
assert!(desc.contains("NLS"));
}
}