Thu, 26 Feb 2026 09:32:12 -0500
Initial working version for known convectivity and diffusivity
/*! Implementation of [`Prox`] for mappings implemented in Python. */ use crate::python_access::process_error; use super::diff_mapping::intern_many; use super::diff_mapping::PythonMapping; use alg_tools::convex::Prox; use alg_tools::mapping::{ClosedSpace, Instance, Mapping, Space}; use pyo3::conversion::FromPyObject; use pyo3::intern; use pyo3::prelude::*; use std::marker::PhantomData; #[derive(Copy, Debug, Clone)] /// Marker for PythonMappings that implement Prox pub struct HasProx; impl<'py, Domain> Prox<Domain> for PythonMapping<'py, Domain, f64, HasProx> where Domain: ClosedSpace + Clone + for<'a> FromPyObject<'a, 'py, Error = PyErr> + IntoPyObject<'py>, { type Prox<'a> = PythonProx<'py, Domain> where Self: 'a; fn prox_mapping(&self, τ: Self::Codomain) -> Self::Prox<'_> { PythonProx { τ, obj: self.get_obj(), _phantoms: PhantomData } } } #[derive(Debug)] pub struct PythonProx<'py, Domain> where Domain: Space + for<'a> FromPyObject<'a, 'py>, { τ: f64, obj: Bound<'py, PyAny>, _phantoms: PhantomData<Domain>, } impl<'py, Domain> Mapping<Domain> for PythonProx<'py, Domain> where Domain: ClosedSpace + for<'a> FromPyObject<'a, 'py, Error = PyErr> + IntoPyObject<'py>, { type Codomain = Domain; /// Compute the value of `self` at `x`. fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { // TODO: use references and internal mutability? let apply = intern!(self.obj.py(), "prox"); process_error( "PythonProx::apply", self.obj.py(), self.obj .call_method1(apply, (self.τ, x.own())) .and_then(|r| r.extract()), ) .unwrap() } } impl<'a, 'py, Domain, Codomain> FromPyObject<'a, 'py> for PythonMapping<'py, Domain, Codomain, HasProx> where Domain: Space, Codomain: ClosedSpace + FromPyObject<'a, 'py>, { type Error = PyErr; fn extract(obj_: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> { let obj = obj_.to_owned(); // Verify that the necessary methods exist for method in intern_many!(obj.py(), "apply", "prox") { obj.getattr(method)?; //.downcast::<PyFunction>()?; } Ok(PythonMapping { obj, _phantoms: PhantomData }) } }