--- a/src/dolfinx_access.rs Mon Jun 29 00:20:42 2026 +0300 +++ b/src/dolfinx_access.rs Sun Oct 04 13:02:26 2026 -0500 @@ -10,7 +10,6 @@ use anyhow::bail; use pyo3::ffi::PyImport_AppendInittab; use std::ffi::CString; -use std::mem::MaybeUninit; /// Import helper required for the linking to the sys crates to actually happen. #[allow(unused_imports)] @@ -98,6 +97,8 @@ max: bool, ) -> Result<CoordValuePair>; + pub unsafe fn cell_dofs_Function_f64_p2(f: *const Function_f64, cell:i32, coords: &mut [f64; 18], vals: &mut [f64; 6]); + /// Checks if a Dolfinx `Function` is supported (P2 elements on triangular mesh) pub unsafe fn check_Function_f64(o: *const PyObject) -> bool; @@ -147,10 +148,9 @@ /// `f` is the function, `simplex_coords` the coorindates of the triangle /// see [`cell_coords_Function_f64_triangle`], `cell` is the cell number, /// and `max` indicates whether to maximise or minimise. - unsafe fn minmax_dolfinx_p2_cell( - f: *const Function_f64, - simplex_coords: &[f64; 9], - cell: i32, + unsafe fn minmax_dolfinx_p2( + simplex_coords: [f64; 18], + vals: [f64; 6], max: bool, ) -> CoordValuePair; } @@ -158,59 +158,25 @@ use ffi::CoordValuePair; -/// Convert an array of 2D oordinates obtained from Fenics, which hard-codes weird 3D coordinates. -#[inline] -fn coords_from_fenics(&[x1, x2, _, y1, y2, _, z1, z2, _]: &[f64; 9]) -> [Loc<2, f64>; 3] { - [Loc([x1, x2]), Loc([y1, y2]), Loc([z1, z2])] -} -// fn coords_from_fenics<const N: usize>(coords: &[[f64; 3]; N]) -> [Loc<F, 2>; N] { -// coords.map(|[x1, x2, _]| Loc([x1, x2])) -// } - -/// Convert an array of 2D oordinates to Fenics, which hard-codes weird 3D coordinates. -#[inline] -fn coords_to_fenics([Loc([x1, x2]), Loc([y1, y2]), Loc([z1, z2])]: [Loc<2, f64>; 3]) -> [f64; 9] { - [x1, x2, 0.0, y1, y2, 0.0, z1, z2, 0.0] -} -// fn coords_to_fenics<const N: usize>(coords: [Loc<F, 2>; N]) -> [[f64; 3]; N] { -// coords.map(|Loc([x1, x2])| [x1, x2, 0.0]) -// } - /// Given a dolphinx `Function` `f`, as well as 6 coordinates on a simplex in its mesh /// (the corners and midpoints), construct a new internal P2 model on `cell`. /// If `max` is true, the model is negated compared to `f`. +#[inline] unsafe fn model_dolfinx_p2_cell( - f: *const ffi::Function_f64, - simplex_coords: &[f64; 9], - cell: i32, + [p0x, p0y, _, p1x, p1y, _, p2x, p2y, _, p12x, p12y, _, p20x, p20y, _, p01x, p01y, _]: [f64; 18], + [v0, v1, v2, v12, v20, v01]: [f64; 6], max: bool, ) -> (P2LocalModel<f64, 2, 3>, Simplex<f64, 2, 3>) { // Form simplex - let simplex = Simplex(coords_from_fenics(simplex_coords)); - // Form an array of all coordinates - let midpoints = simplex.midpoints(); - let mut all_coords_uninit: [MaybeUninit<f64>; 6 * 3] = [const { MaybeUninit::uninit() }; 6 * 3]; - all_coords_uninit - .iter_mut() - .zip( - simplex_coords - .iter() - .copied() - .chain(coords_to_fenics(midpoints).into_iter()), - ) - .for_each(|(a, b)| { - a.write(b); - }); - let all_coords = MaybeUninit::array_assume_init(all_coords_uninit); - // Evaluate the function, and invert the signs of maximising - let mut values = ffi::eval_Function_f64_cell_6(f, &all_coords, cell); - if max { - values.iter_mut().for_each(|v| *v = -*v); - } + let coords = [Loc([p0x, p0y]), Loc([p1x, p1y]), Loc([p2x, p2y])]; + let simplex = Simplex(coords); + let values = if max { + [-v0, -v1, -v2, -v01, -v12, -v20] + } else { + [v0, v1, v2, v01, v12, v20] + }; // Form local model - let [ref n0, ref n1, ref n2] = simplex.0; - let [ref n01, ref n12, ref n20] = midpoints; - let nodes = [*n0, *n1, *n2, *n01, *n12, *n20]; + let nodes = [Loc([p0x, p0y]), Loc([p1x, p1y]), Loc([p2x, p2y]), Loc([p01x, p01y]), Loc([p12x, p12y]), Loc([p20x, p20y])]; let model = P2LocalModel::<f64, 2, 3>::new(&nodes, &values); return (model, simplex); @@ -221,13 +187,12 @@ /// in `simplex_doords`, as well as edge midpoints). Then it minimises this /// model. The result should be accurate, given that `f` is assumed to have a /// P2 model on the simplex. -pub unsafe fn minmax_dolfinx_p2_cell( - f: *const ffi::Function_f64, - simplex_coords: &[f64; 9], - cell: i32, +pub unsafe fn minmax_dolfinx_p2( + simplex_coords: [f64; 18], + vals: [f64; 6], max: bool, ) -> ffi::CoordValuePair { - let (model, simplex) = model_dolfinx_p2_cell(f, simplex_coords, cell, max); + let (model, simplex) = model_dolfinx_p2_cell(simplex_coords, vals, max); let (x, v) = model.minimise(&simplex); CoordValuePair { x: x.into(), v } }