From 29d7ccf223a192cea7d2f792b086b4e5b32e4355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Robert?= Date: Fri, 29 Nov 2024 14:28:28 +0100 Subject: [PATCH] Split long line and run cargo fmt Still it does not work properly. See: * https://github.com/rust-lang/rustfmt/issues/3391 * https://github.com/rust-lang/rustfmt/issues/3863 * https://github.com/rust-lang/rustfmt/issues/8 --- src/geometry.rs | 29 ++++++++-------- src/mesh.rs | 89 +++++++++++++++++++++++++++++++------------------ src/parallel.rs | 52 ++++++++++++++++++++--------- src/remesher.rs | 82 ++++++++++++++++++++++++++++++--------------- 4 files changed, 163 insertions(+), 89 deletions(-) diff --git a/src/geometry.rs b/src/geometry.rs index 49a2348..40a0702 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -10,7 +10,8 @@ use tucanos::{ }; macro_rules! create_geometry { ($name: ident, $dim: expr, $etype: ident, $mesh: ident, $geom: ident) => { - #[doc = concat!("Piecewise linear geometry consisting of ", stringify!($etype), " in ", stringify!($dim), "D")] + #[doc = concat!("Piecewise linear geometry consisting of ", stringify!($etype), " in ", + stringify!($dim), "D")] #[pyclass] // #[derive(Clone)] pub struct $name { @@ -22,11 +23,7 @@ macro_rules! create_geometry { #[new] #[must_use] #[pyo3(signature = (mesh, geom=None))] - pub fn new( - mesh: &$mesh, - geom: Option<&$geom>, - ) -> Self { - + pub fn new(mesh: &$mesh, geom: Option<&$geom>) -> Self { let mut gmesh = if let Some(geom) = geom { geom.mesh.clone() } else { @@ -51,19 +48,23 @@ macro_rules! create_geometry { } /// Compute the curvature - pub fn compute_curvature(&mut self) { - self.geom.compute_curvature() + pub fn compute_curvature(&mut self) { + self.geom.compute_curvature() } /// Export the curvature to a vtk file pub fn write_curvature_vtk(&self, fname: &str) -> PyResult<()> { - self.geom + self.geom .write_curvature(fname) .map_err(|e| PyRuntimeError::new_err(e.to_string())) } /// Project vertices - pub fn project<'py>(&self, py: Python<'py>, mesh: &$mesh) -> PyResult>> { + pub fn project<'py>( + &self, + py: Python<'py>, + mesh: &$mesh, + ) -> PyResult>> { let vtags = mesh.mesh.get_vertex_tags().unwrap(); let mut coords = Vec::with_capacity(mesh.mesh.n_verts() as usize * $dim); @@ -74,14 +75,10 @@ macro_rules! create_geometry { coords.extend(pt.iter().copied()); } - Ok(to_numpy_2d( - py, - coords, - $dim, - )) + Ok(to_numpy_2d(py, coords, $dim)) } } - } + }; } create_geometry!(LinearGeometry3d, 3, Triangle, Mesh33, Mesh32); diff --git a/src/mesh.rs b/src/mesh.rs index 6a4ee6e..4a9d290 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -66,10 +66,12 @@ macro_rules! create_mesh { ).collect(); let elems = elems.as_slice()?; - let elems = elems.chunks($etype::N_VERTS as usize).map(|e| $etype::from_slice(e)).collect(); + let elems = elems.chunks($etype::N_VERTS as usize).map( + |e| $etype::from_slice(e)).collect(); let faces = faces.as_slice()?; - let faces = faces.chunks(<$etype as Elem>::Face::N_VERTS as usize).map(|e| <$etype as Elem>::Face::from_slice(e)).collect(); + let faces = faces.chunks(<$etype as Elem>::Face::N_VERTS as usize).map( + |e| <$etype as Elem>::Face::from_slice(e)).collect(); Ok(Self { mesh: SimplexMesh::<$dim, $etype>::new( @@ -99,7 +101,8 @@ macro_rules! create_mesh { /// Write a solution to a .sol(b) file pub fn write_solb(&self, fname: &str, arr: PyReadonlyArray2) -> PyResult<()> { - self.mesh.write_solb(&arr.to_vec().unwrap(), fname).map_err(|e| PyRuntimeError::new_err(e.to_string())) + self.mesh.write_solb(&arr.to_vec().unwrap(), fname).map_err( + |e| PyRuntimeError::new_err(e.to_string())) } @@ -222,9 +225,11 @@ macro_rules! create_mesh { } } - /// Add the missing boundary faces and make sure that boundary faces are oriented outwards + /// Add the missing boundary faces and make sure that boundary faces are oriented + /// outwards. /// If internal faces are present, these are keps - pub fn add_boundary_faces<'py>(&mut self, py: Python<'py>) -> PyResult<(Bound<'py, PyDict>, Bound<'py, PyDict>)> { + pub fn add_boundary_faces<'py>(&mut self, py: Python<'py>) -> + PyResult<(Bound<'py, PyDict>, Bound<'py, PyDict>)> { let (bdy, ifc) = self.mesh.add_boundary_faces(); let dict_bdy = PyDict::new_bound(py); for (k, v) in bdy.iter() { @@ -277,7 +282,9 @@ macro_rules! create_mesh { Ok(()) } - #[doc = concat!("Get a copy of the mesh coordinates as a numpy array of shape (# of vertices, ", stringify!($dim), ")")] + #[doc = concat!( + "Get a copy of the mesh coordinates as a numpy array of shape (# of vertices, ", + stringify!($dim), ")")] pub fn get_coords<'py>(&mut self, py: Python<'py>) -> Bound<'py, PyArray2> { let mut coords = Vec::with_capacity(self.mesh.n_verts() as usize * $dim); for v in self.mesh.verts() { @@ -318,8 +325,11 @@ macro_rules! create_mesh { } /// Reorder the vertices, element and faces using a Hilbert SFC - pub fn reorder_hilbert<'py>(&mut self, py: Python<'py>) -> PyResult<(Bound<'py, PyArray1>, Bound<'py, PyArray1>, Bound<'py, PyArray1>)>{ - let (new_vertex_indices, new_elem_indices, new_face_indices) = self.mesh.reorder_hilbert(); + pub fn reorder_hilbert<'py>(&mut self, py: Python<'py>) -> + PyResult<(Bound<'py, PyArray1>, Bound<'py, PyArray1>, + Bound<'py, PyArray1>)>{ + let (new_vertex_indices, new_elem_indices, new_face_indices) = + self.mesh.reorder_hilbert(); Ok( ( to_numpy_1d(py, new_vertex_indices), @@ -330,8 +340,8 @@ macro_rules! create_mesh { } - /// Convert a (scalar or vector) field defined at the element centers (P0) to a field defined at the vertices (P1) - /// using a weighted average. + /// Convert a (scalar or vector) field defined at the element centers (P0) to a field + /// defined at the vertices (P1) using a weighted average. pub fn elem_data_to_vertex_data<'py>( &mut self, py: Python<'py>, @@ -349,8 +359,8 @@ macro_rules! create_mesh { Ok(to_numpy_2d(py, res.unwrap(), arr.shape()[1])) } - /// Convert a field (scalar or vector) defined at the vertices (P1) to a field defined at the - /// element centers (P0) + /// Convert a field (scalar or vector) defined at the vertices (P1) to a field defined + /// at the element centers (P0) pub fn vertex_data_to_elem_data<'py>( &mut self, py: Python<'py>, @@ -363,7 +373,8 @@ macro_rules! create_mesh { Ok(to_numpy_2d(py, res.unwrap(), arr.shape()[1])) } - /// Interpolate a field (scalar or vector) defined at the vertices (P1) to a different mesh using linear interpolation + /// Interpolate a field (scalar or vector) defined at the vertices (P1) to a different + /// mesh using linear interpolation #[pyo3(signature = (other, arr, tol=None))] pub fn interpolate_linear<'py>( &mut self, @@ -376,11 +387,13 @@ macro_rules! create_mesh { return Err(PyValueError::new_err("Invalid dimension 0")); } let tree = self.mesh.compute_elem_tree(); - let res = self.mesh.interpolate_linear(&tree, &other.mesh, arr.as_slice().unwrap(), tol); + let res = self.mesh.interpolate_linear(&tree, &other.mesh, arr.as_slice().unwrap(), + tol); Ok(to_numpy_2d(py, res.unwrap(), arr.shape()[1])) } - /// Interpolate a field (scalar or vector) defined at the vertices (P1) to a different mesh using nearest neighbor interpolation + /// Interpolate a field (scalar or vector) defined at the vertices (P1) to a different + /// mesh using nearest neighbor interpolation pub fn interpolate_nearest<'py>( &mut self, py: Python<'py>, @@ -391,11 +404,13 @@ macro_rules! create_mesh { return Err(PyValueError::new_err("Invalid dimension 0")); } let tree = self.mesh.compute_vert_tree(); - let res = self.mesh.interpolate_nearest(&tree, &other.mesh, arr.as_slice().unwrap()); + let res = self.mesh.interpolate_nearest(&tree, &other.mesh, + arr.as_slice().unwrap()); Ok(to_numpy_2d(py, res.unwrap(), arr.shape()[1])) } - /// Smooth a field defined at the mesh vertices using a 1st order least-square approximation + /// Smooth a field defined at the mesh vertices using a 1st order least-square + /// approximation #[pyo3(signature = (arr, weight_exp=None))] pub fn smooth<'py>( &self, @@ -419,7 +434,8 @@ macro_rules! create_mesh { Ok(to_numpy_2d(py, res.unwrap(), arr.shape()[1])) } - /// Compute the gradient of a field defined at the mesh vertices using a 1st order least-square approximation + /// Compute the gradient of a field defined at the mesh vertices using a 1st order + /// least-square approximation #[pyo3(signature = (arr, weight_exp=None))] pub fn compute_gradient<'py>( &self, @@ -447,9 +463,10 @@ macro_rules! create_mesh { )) } - /// Compute the hessian of a field defined at the mesh vertices using a 2nd order least-square approximation - /// if `weight_exp` is `None`, the vertex has a weight 10, its first order neighbors have - /// a weight 1 and the 2nd order neighbors (if used) have a weight of 0.1 + /// Compute the hessian of a field defined at the mesh vertices using a 2nd order + /// least-square approximation + /// if `weight_exp` is `None`, the vertex has a weight 10, its first order neighbors + /// have a weight 1 and the 2nd order neighbors (if used) have a weight of 0.1 #[pyo3(signature = (arr, weight_exp=None, use_second_order_neighbors=None))] pub fn compute_hessian<'py>( &self, @@ -467,7 +484,8 @@ macro_rules! create_mesh { let res = self .mesh - .hessian(arr.as_slice().unwrap(), weight_exp, use_second_order_neighbors.unwrap_or(true)); + .hessian(arr.as_slice().unwrap(), weight_exp, + use_second_order_neighbors.unwrap_or(true)); if let Err(res) = res { return Err(PyRuntimeError::new_err(res.to_string())); } @@ -530,7 +548,8 @@ macro_rules! create_mesh { } /// Automatically tag the elements based on a feature angle - pub fn autotag<'py>(&mut self, py: Python<'py>, angle_deg: f64) -> PyResult> { + pub fn autotag<'py>(&mut self, py: Python<'py>, angle_deg: f64) + -> PyResult> { let res = self.mesh.autotag(angle_deg); if let Err(res) = res { Err(PyRuntimeError::new_err(res.to_string())) @@ -544,7 +563,8 @@ macro_rules! create_mesh { } /// Automatically tag the faces based on a feature angle - pub fn autotag_bdy<'py>(&mut self, py: Python<'py>, angle_deg: f64) -> PyResult> { + pub fn autotag_bdy<'py>(&mut self, py: Python<'py>, angle_deg: f64) + -> PyResult> { let res = self.mesh.autotag_bdy(angle_deg); if let Err(res) = res { Err(PyRuntimeError::new_err(res.to_string())) @@ -572,7 +592,9 @@ impl Mesh33 { #[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_lines)] #[classmethod] - #[pyo3(signature = (coords, hexs=None, hex_tags=None, pris=None, pri_tags=None, pyrs=None, pyr_tags=None, tets=None, tet_tags=None, quas=None, qua_tags=None, tris=None, tri_tags=None))] + #[pyo3(signature = (coords, hexs=None, hex_tags=None, pris=None, pri_tags=None, pyrs=None, + pyr_tags=None, tets=None, tet_tags=None, quas=None, qua_tags=None, tris=None, + tri_tags=None))] pub fn from_basic_elems( _cls: &Bound<'_, PyType>, coords: PyReadonlyArray2, @@ -734,10 +756,11 @@ impl Mesh33 { } /// Get a metric defined on all the mesh vertices such that - /// - for boundary vertices, the principal directions are aligned with the principal curvature directions - /// and the sizes to curvature radius ratio is r_h + /// - for boundary vertices, the principal directions are aligned with the principal curvature + /// directions and the sizes to curvature radius ratio is r_h /// - the metric is entended into the volume with gradation beta - /// - if an implied metric is provided, the result is limited to (1/step,step) times the implied metric + /// - if an implied metric is provided, the result is limited to (1/step,step) times the + /// implied metric /// - if a normal size array is not provided, the minimum of the tangential sizes is used. #[allow(clippy::too_many_arguments)] #[pyo3(signature = (geom, r_h, beta, h_min=None, h_n=None, h_n_tags=None))] @@ -786,7 +809,8 @@ impl Mesh32 { /// Create a Mesh32 from basic elements #[classmethod] #[allow(clippy::too_many_arguments)] - #[pyo3(signature = (coords, quas=None, qua_tags=None, tris=None, tri_tags=None, edgs=None, edg_tags=None))] + #[pyo3(signature = (coords, quas=None, qua_tags=None, tris=None, tri_tags=None, edgs=None, + edg_tags=None))] pub fn from_basic_elems( _cls: &Bound<'_, PyType>, coords: PyReadonlyArray2, @@ -895,7 +919,8 @@ impl Mesh22 { /// Create a Mesh22 from basic elements #[allow(clippy::too_many_arguments)] #[classmethod] - #[pyo3(signature = (coords, quas=None, qua_tags=None, tris=None, tri_tags=None, edgs=None, edg_tags=None))] + #[pyo3(signature = (coords, quas=None, qua_tags=None, tris=None, tri_tags=None, edgs=None, + edg_tags=None))] pub fn from_basic_elems( _cls: &Bound<'_, PyType>, coords: PyReadonlyArray2, @@ -993,8 +1018,8 @@ impl Mesh22 { } /// Get a metric defined on all the mesh vertices such that - /// - for boundary vertices, the principal directions are aligned with the principal curvature directions - /// and the sizes to curvature radius ratio is r_h + /// - for boundary vertices, the principal directions are aligned with the principal curvature + /// directions and the sizes to curvature radius ratio is r_h /// - the metric is entended into the volume with gradation beta /// - if a normal size array is not provided, the minimum of the tangential sizes is used. #[allow(clippy::too_many_arguments)] diff --git a/src/parallel.rs b/src/parallel.rs index b986fde..1ffc433 100644 --- a/src/parallel.rs +++ b/src/parallel.rs @@ -21,15 +21,20 @@ use tucanos::{ macro_rules! create_parallel_remesher { ($name: ident, $dim: expr, $etype: ident, $metric: ident, $mesh: ident, $geom: ident) => { - #[doc = concat!("Parallel remesher for a meshes consisting of ", stringify!($etype), " in ", stringify!($dim), "D")] - #[doc = concat!("using ", stringify!($metric), " as metric and a piecewise linear representation of the geometry")] + #[doc = concat!("Parallel remesher for a meshes consisting of ", stringify!($etype), + " in ", stringify!($dim), "D")] + #[doc = concat!("using ", stringify!($metric), + " as metric and a piecewise linear representation of the geometry")] #[pyclass] pub struct $name { dd: ParallelRemesher<$dim, $etype>, } - #[doc = concat!("Create a parallel remesher from a ", stringify!($mesh), " and a ",stringify!($metric) ," metric defined at the mesh vertices")] - #[doc = concat!("A piecewise linear representation of the geometry is used, either from the ", stringify!($geom), " given or otherwise from the mesh boundary.")] + #[doc = concat!("Create a parallel remesher from a ", stringify!($mesh), " and a ", + stringify!($metric) ," metric defined at the mesh vertices")] + #[doc = concat!( + "A piecewise linear representation of the geometry is used, either from the ", + stringify!($geom), " given or otherwise from the mesh boundary.")] #[pymethods] impl $name { #[new] @@ -48,7 +53,8 @@ macro_rules! create_parallel_remesher { } else if partition_type == "hilbert" { PartitionType::Hilbert(n_partitions) } else { - return Err(PyValueError::new_err("Invalid partition type: allowed values are scotch, metis_kway, metis_recursive")); + return Err(PyValueError::new_err( +"Invalid partition type: allowed values are scotch, metis_kway, metis_recursive")); }; let dd = ParallelRemesher::new(mesh.mesh.clone(), partition_type); @@ -69,7 +75,14 @@ macro_rules! create_parallel_remesher { } #[allow(clippy::too_many_arguments)] - #[pyo3(signature = (geometry, m, num_iter=None, two_steps=None, split_max_iter=None, split_min_l_rel=None, split_min_l_abs=None, split_min_q_rel=None, split_min_q_abs=None, collapse_max_iter=None, collapse_max_l_rel=None, collapse_max_l_abs=None, collapse_min_q_rel=None, collapse_min_q_abs=None, swap_max_iter=None, swap_max_l_rel=None, swap_max_l_abs=None, swap_min_l_rel=None, swap_min_l_abs=None, smooth_iter=None, smooth_type=None, smooth_relax=None, smooth_keep_local_minima=None, max_angle=None, debug=None, n_layers=None, n_levels=None, min_verts=None))] + #[pyo3(signature = (geometry, m, num_iter=None, two_steps=None, split_max_iter=None, + split_min_l_rel=None, split_min_l_abs=None, split_min_q_rel=None, + split_min_q_abs=None, collapse_max_iter=None, collapse_max_l_rel=None, + collapse_max_l_abs=None, collapse_min_q_rel=None, collapse_min_q_abs=None, + swap_max_iter=None, swap_max_l_rel=None, swap_max_l_abs=None, swap_min_l_rel=None, + swap_min_l_abs=None, smooth_iter=None, smooth_type=None, smooth_relax=None, + smooth_keep_local_minima=None, max_angle=None, debug=None, n_layers=None, + n_levels=None, min_verts=None))] pub fn remesh<'py>(&mut self, py: Python<'py>, geometry: &$geom, @@ -134,11 +147,16 @@ macro_rules! create_parallel_remesher { split_min_l_abs: split_min_l_abs.unwrap_or(default_params.split_min_l_abs), split_min_q_rel: split_min_q_rel.unwrap_or(default_params.split_min_q_rel), split_min_q_abs: split_min_q_abs.unwrap_or(default_params.split_min_q_abs), - collapse_max_iter: collapse_max_iter.unwrap_or(default_params.collapse_max_iter), - collapse_max_l_rel: collapse_max_l_rel.unwrap_or(default_params.collapse_max_l_rel), - collapse_max_l_abs: collapse_max_l_abs.unwrap_or(default_params.collapse_max_l_abs), - collapse_min_q_rel: collapse_min_q_rel.unwrap_or(default_params.collapse_min_q_rel), - collapse_min_q_abs: collapse_min_q_abs.unwrap_or(default_params.collapse_min_q_abs), + collapse_max_iter: collapse_max_iter.unwrap_or( + default_params.collapse_max_iter), + collapse_max_l_rel: collapse_max_l_rel.unwrap_or( + default_params.collapse_max_l_rel), + collapse_max_l_abs: collapse_max_l_abs.unwrap_or( + default_params.collapse_max_l_abs), + collapse_min_q_rel: collapse_min_q_rel.unwrap_or( + default_params.collapse_min_q_rel), + collapse_min_q_abs: collapse_min_q_abs.unwrap_or( + default_params.collapse_min_q_abs), swap_max_iter: swap_max_iter.unwrap_or(default_params.swap_max_iter), swap_max_l_rel: swap_max_l_rel.unwrap_or(default_params.swap_max_l_rel), swap_max_l_abs: swap_max_l_abs.unwrap_or(default_params.swap_max_l_abs), @@ -146,8 +164,10 @@ macro_rules! create_parallel_remesher { swap_min_l_abs: swap_min_l_abs.unwrap_or(default_params.swap_min_l_abs), smooth_iter: smooth_iter.unwrap_or(default_params.smooth_iter), smooth_type, - smooth_relax: smooth_relax.map(|x| x.to_vec().unwrap()).unwrap_or(default_params.smooth_relax), - smooth_keep_local_minima: smooth_keep_local_minima.unwrap_or(default_params.smooth_keep_local_minima), + smooth_relax: smooth_relax.map(|x| x.to_vec().unwrap()).unwrap_or( + default_params.smooth_relax), + smooth_keep_local_minima: smooth_keep_local_minima.unwrap_or( + default_params.smooth_keep_local_minima), max_angle: max_angle.unwrap_or(default_params.max_angle), debug: debug.unwrap_or(default_params.debug), }; @@ -158,7 +178,8 @@ macro_rules! create_parallel_remesher { min_verts.unwrap_or(0) ); - let (mesh, info, m) = py.allow_threads(|| self.dd.remesh(&m, &geometry.geom, params, dd_params).unwrap()); + let (mesh, info, m) = py.allow_threads(|| + self.dd.remesh(&m, &geometry.geom, params, dd_params).unwrap()); let mesh = $mesh{mesh}; @@ -188,7 +209,8 @@ macro_rules! create_parallel_remesher { let m: Vec<_> = m.chunks($metric::N).map(|x| $metric::from_slice(x)).collect(); let q = mesh.mesh.qualities(&m); - let l = mesh.mesh.edge_lengths(&m).map_err(|e| PyRuntimeError::new_err(e.to_string()))?; + let l = mesh.mesh.edge_lengths(&m).map_err( + |e| PyRuntimeError::new_err(e.to_string()))?; Ok((to_numpy_1d(py, q), to_numpy_1d(py, l))) } diff --git a/src/remesher.rs b/src/remesher.rs index e001945..485c192 100644 --- a/src/remesher.rs +++ b/src/remesher.rs @@ -22,15 +22,20 @@ use tucanos::{ macro_rules! create_remesher { ($name: ident, $dim: expr, $etype: ident, $metric: ident, $mesh: ident, $geom: ident) => { - #[doc = concat!("Remesher for a meshes consisting of ", stringify!($etype), " in ", stringify!($dim), "D")] - #[doc = concat!("using ", stringify!($metric), " as metric and a piecewise linear representation of the geometry")] + #[doc = concat!("Remesher for a meshes consisting of ", stringify!($etype), " in ", + stringify!($dim), "D")] + #[doc = concat!("using ", stringify!($metric), + " as metric and a piecewise linear representation of the geometry")] #[pyclass] pub struct $name { remesher: Remesher<$dim, $etype, $metric>, } - #[doc = concat!("Create a remesher from a ", stringify!($mesh), " and a ",stringify!($metric) ," metric defined at the mesh vertices")] - #[doc = concat!("A piecewise linear representation of the geometry is used, either from the ", stringify!($geom), " given or otherwise from the mesh boundary.")] + #[doc = concat!("Create a remesher from a ", stringify!($mesh), " and a ", + stringify!($metric) ," metric defined at the mesh vertices")] + #[doc = concat!( + "A piecewise linear representation of the geometry is used, either from the ", + stringify!($geom), " given or otherwise from the mesh boundary.")] #[pymethods] impl $name { #[new] @@ -95,10 +100,12 @@ macro_rules! create_remesher { return Ok(to_numpy_2d(py, res, <$metric as Metric<$dim>>::N)); } - /// Scale a metric field to reach the desired (ideal) number of elements using min / max bounds on the cell size + /// Scale a metric field to reach the desired (ideal) number of elements using + /// min / max bounds on the cell size #[classmethod] #[allow(clippy::too_many_arguments)] - #[pyo3(signature = (mesh, m, h_min, h_max, n_elems, fixed_m=None, implied_m=None, step=None, max_iter=None))] + #[pyo3(signature = (mesh, m, h_min, h_max, n_elems, fixed_m=None, implied_m=None, + step=None, max_iter=None))] pub fn scale_metric<'py>( _cls: &Bound<'_, PyType>, py: Python<'py>, @@ -124,24 +131,31 @@ macro_rules! create_remesher { let res = if let Some(fixed_m) = fixed_m { let fixed_m = fixed_m.as_slice().unwrap(); - let fixed_m: Vec<_> = fixed_m.chunks($metric::N).map(|x| $metric::from_slice(x)).collect(); + let fixed_m: Vec<_> = fixed_m.chunks($metric::N).map(|x| + $metric::from_slice(x)).collect(); if let Some(implied_m) = implied_m { let implied_m = implied_m.as_slice().unwrap(); - let implied_m: Vec<_> = implied_m.chunks($metric::N).map(|x| $metric::from_slice(x)).collect(); + let implied_m: Vec<_> = implied_m.chunks($metric::N).map(|x| + $metric::from_slice(x)).collect(); mesh.mesh - .scale_metric(&mut m, h_min, h_max, n_elems, Some(&fixed_m), Some(&implied_m), step, max_iter.unwrap_or(10)) + .scale_metric(&mut m, h_min, h_max, n_elems, Some(&fixed_m), + Some(&implied_m), step, max_iter.unwrap_or(10)) } else { mesh.mesh - .scale_metric(&mut m, h_min, h_max, n_elems, Some(&fixed_m), None, step, max_iter.unwrap_or(10)) + .scale_metric(&mut m, h_min, h_max, n_elems, Some(&fixed_m), None, + step, max_iter.unwrap_or(10)) } } else if let Some(implied_m) = implied_m { let implied_m = implied_m.as_slice().unwrap(); - let implied_m: Vec<_> = implied_m.chunks($metric::N).map(|x| $metric::from_slice(x)).collect(); + let implied_m: Vec<_> = implied_m.chunks($metric::N).map(|x| + $metric::from_slice(x)).collect(); mesh.mesh - .scale_metric(&mut m, h_min, h_max, n_elems, None, Some(&implied_m), step, max_iter.unwrap_or(10)) + .scale_metric(&mut m, h_min, h_max, n_elems, None, Some(&implied_m), step, + max_iter.unwrap_or(10)) } else { mesh.mesh - .scale_metric(&mut m, h_min, h_max, n_elems, None, None, None, max_iter.unwrap_or(10)) + .scale_metric(&mut m, h_min, h_max, n_elems, None, None, None, + max_iter.unwrap_or(10)) }; if let Err(res) = res { @@ -211,8 +225,8 @@ macro_rules! create_remesher { } } - /// Convert a metic field defined at the element centers (P0) to a field defined at the vertices (P1) - /// using a weighted average. + /// Convert a metic field defined at the element centers (P0) to a field defined at the + /// vertices (P1) using a weighted average. #[classmethod] pub fn elem_data_to_vertex_data_metric<'py>( _cls: &Bound<'_, PyType>, @@ -302,7 +316,8 @@ macro_rules! create_remesher { let m_other = m_other.as_slice().unwrap(); let m_other = m_other.chunks($metric::N).map(|x| $metric::from_slice(x)); - let mut res = Vec::with_capacity(mesh.mesh.n_verts() as usize * <$metric as Metric<$dim>>::N); + let mut res = Vec::with_capacity(mesh.mesh.n_verts() as usize * + <$metric as Metric<$dim>>::N); for (mut m_i, m_other_i) in m.zip(m_other) { m_i.control_step(&m_other_i, step); @@ -397,7 +412,8 @@ macro_rules! create_remesher { tucanos::remesher::SmoothingType::Laplacian2 => "laplacian2", }; dict.set_item("smooth_type", smooth_type).unwrap(); - dict.set_item("smooth_relax", to_numpy_1d(py, default_params.smooth_relax)).unwrap(); + dict.set_item("smooth_relax", to_numpy_1d(py, default_params.smooth_relax) + ).unwrap(); dict.set_item("max_angle", default_params.max_angle).unwrap(); dict @@ -405,7 +421,13 @@ macro_rules! create_remesher { /// Perform a remeshing iteration #[allow(clippy::too_many_arguments)] - #[pyo3(signature = (geometry, num_iter=None, two_steps=None, split_max_iter=None, split_min_l_rel=None, split_min_l_abs=None, split_min_q_rel=None, split_min_q_abs=None, collapse_max_iter=None, collapse_max_l_rel=None, collapse_max_l_abs=None, collapse_min_q_rel=None, collapse_min_q_abs=None, swap_max_iter=None, swap_max_l_rel=None, swap_max_l_abs=None, swap_min_l_rel=None, swap_min_l_abs=None, smooth_iter=None, smooth_type=None, smooth_relax=None, smooth_keep_local_minima=None, max_angle=None, debug=None))] + #[pyo3(signature = (geometry, num_iter=None, two_steps=None, split_max_iter=None, + split_min_l_rel=None, split_min_l_abs=None, split_min_q_rel=None, + split_min_q_abs=None, collapse_max_iter=None, collapse_max_l_rel=None, + collapse_max_l_abs=None, collapse_min_q_rel=None, collapse_min_q_abs=None, + swap_max_iter=None, swap_max_l_rel=None, swap_max_l_abs=None, swap_min_l_rel=None, + swap_min_l_abs=None, smooth_iter=None, smooth_type=None, smooth_relax=None, + smooth_keep_local_minima=None, max_angle=None, debug=None))] pub fn remesh( &mut self, geometry: &$geom, @@ -455,11 +477,16 @@ macro_rules! create_remesher { split_min_l_abs: split_min_l_abs.unwrap_or(default_params.split_min_l_abs), split_min_q_rel: split_min_q_rel.unwrap_or(default_params.split_min_q_rel), split_min_q_abs: split_min_q_abs.unwrap_or(default_params.split_min_q_abs), - collapse_max_iter: collapse_max_iter.unwrap_or(default_params.collapse_max_iter), - collapse_max_l_rel: collapse_max_l_rel.unwrap_or(default_params.collapse_max_l_rel), - collapse_max_l_abs: collapse_max_l_abs.unwrap_or(default_params.collapse_max_l_abs), - collapse_min_q_rel: collapse_min_q_rel.unwrap_or(default_params.collapse_min_q_rel), - collapse_min_q_abs: collapse_min_q_abs.unwrap_or(default_params.collapse_min_q_abs), + collapse_max_iter: collapse_max_iter.unwrap_or( + default_params.collapse_max_iter), + collapse_max_l_rel: collapse_max_l_rel.unwrap_or( + default_params.collapse_max_l_rel), + collapse_max_l_abs: collapse_max_l_abs.unwrap_or( + default_params.collapse_max_l_abs), + collapse_min_q_rel: collapse_min_q_rel.unwrap_or( + default_params.collapse_min_q_rel), + collapse_min_q_abs: collapse_min_q_abs.unwrap_or( + default_params.collapse_min_q_abs), swap_max_iter: swap_max_iter.unwrap_or(default_params.swap_max_iter), swap_max_l_rel: swap_max_l_rel.unwrap_or(default_params.swap_max_l_rel), swap_max_l_abs: swap_max_l_abs.unwrap_or(default_params.swap_max_l_abs), @@ -467,12 +494,15 @@ macro_rules! create_remesher { swap_min_l_abs: swap_min_l_abs.unwrap_or(default_params.swap_min_l_abs), smooth_iter: smooth_iter.unwrap_or(default_params.smooth_iter), smooth_type, - smooth_relax: smooth_relax.map(|x| x.to_vec().unwrap()).unwrap_or(default_params.smooth_relax), - smooth_keep_local_minima: smooth_keep_local_minima.unwrap_or(default_params.smooth_keep_local_minima), + smooth_relax: smooth_relax.map(|x| x.to_vec().unwrap()).unwrap_or( + default_params.smooth_relax), + smooth_keep_local_minima: smooth_keep_local_minima.unwrap_or( + default_params.smooth_keep_local_minima), max_angle: max_angle.unwrap_or(default_params.max_angle), debug: debug.unwrap_or(default_params.debug), }; - self.remesher.remesh(params, &geometry.geom).map_err(|e| PyRuntimeError::new_err(e.to_string())) + self.remesher.remesh(params, &geometry.geom).map_err(|e| + PyRuntimeError::new_err(e.to_string())) } /// Get the element qualities as a numpy array of size (# or elements)