src/dolfinx_access.rs

changeset 12
a0d61ac3719e
parent 3
c3a4f4bb87f7
--- 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 }
 }

mercurial