From 1e3146daf15ff6d2636e318cf83691d9cec49c4f Mon Sep 17 00:00:00 2001 From: Matthew Scroggs Date: Wed, 21 Aug 2024 16:53:14 +0100 Subject: [PATCH] trying something --- src/assembly/boundary.rs | 3 - src/assembly/boundary/assemblers.rs | 204 +++++++++--------- .../assemblers/adjoint_double_layer.rs | 55 ++--- .../boundary/assemblers/double_layer.rs | 53 ++--- .../boundary/assemblers/hypersingular.rs | 80 ++----- .../boundary/assemblers/single_layer.rs | 55 ++--- 6 files changed, 163 insertions(+), 287 deletions(-) diff --git a/src/assembly/boundary.rs b/src/assembly/boundary.rs index ba7668d3..99adbccc 100644 --- a/src/assembly/boundary.rs +++ b/src/assembly/boundary.rs @@ -4,9 +4,6 @@ pub(crate) mod cell_pair_assemblers; mod integrands; pub use assemblers::BoundaryAssembler; -pub use assemblers::{ - AdjointDoubleLayerAssembler, DoubleLayerAssembler, HypersingularAssembler, SingleLayerAssembler, -}; #[cfg(test)] mod test { diff --git a/src/assembly/boundary/assemblers.rs b/src/assembly/boundary/assemblers.rs index 4f2dae9b..7a208d32 100644 --- a/src/assembly/boundary/assemblers.rs +++ b/src/assembly/boundary/assemblers.rs @@ -3,10 +3,6 @@ pub mod adjoint_double_layer; pub mod double_layer; pub mod hypersingular; pub mod single_layer; -pub use adjoint_double_layer::AdjointDoubleLayerAssembler; -pub use double_layer::DoubleLayerAssembler; -pub use hypersingular::HypersingularAssembler; -pub use single_layer::SingleLayerAssembler; use super::cell_pair_assemblers::{NonsingularCellPairAssembler, SingularCellPairAssembler}; use crate::assembly::common::{equal_grids, RawData2D, RlstArray, SparseMatrixData}; @@ -156,8 +152,9 @@ fn assemble_batch_singular< TestGrid: Grid, TrialGrid: Grid, Element: FiniteElement + Sync, + Integrand: BoundaryIntegrand, Kernel: KernelEvaluator >( - assembler: &impl BoundaryAssembler, + assembler: &BoundaryAssembler, deriv_size: usize, shape: [usize; 2], trial_cell_type: ReferenceCellType, @@ -235,8 +232,9 @@ fn assemble_batch_nonadjacent< TestGrid: Grid, TrialGrid: Grid, Element: FiniteElement + Sync, + Integrand: BoundaryIntegrand, Kernel: KernelEvaluator >( - assembler: &impl BoundaryAssembler, + assembler: &BoundaryAssembler, deriv_size: usize, output: &RawData2D, trial_cell_type: ReferenceCellType, @@ -322,8 +320,9 @@ fn assemble_batch_singular_correction< TestGrid: Grid, TrialGrid: Grid, Element: FiniteElement + Sync, + Integrand: BoundaryIntegrand, Kernel: KernelEvaluator >( - assembler: &impl BoundaryAssembler, + assembler: &BoundaryAssembler, deriv_size: usize, shape: [usize; 2], trial_cell_type: ReferenceCellType, @@ -443,71 +442,67 @@ impl Default for BoundaryAssemblerOptions { } } -// TODO: make this a struct, with HasBoundaryAssemblerOptions trait -pub trait BoundaryAssembler: Sync + Sized { - //! Boundary assembler - //! - //! Assemble operators by processing batches of cells in parallel - - /// Scalar type - type T: RlstScalar + MatrixInverse; - /// Integrand type - type Integrand: BoundaryIntegrand; - /// Kernel type - type Kernel: KernelEvaluator; - /// Number of derivatives - const DERIV_SIZE: usize; - /// Number of derivatives needed in basis function tables - const TABLE_DERIVS: usize; - - /// Get integrand - fn integrand(&self) -> &Self::Integrand; +/// Boundary assembler +/// +/// Assembles operators by processing batches of cells in parallel +pub struct BoundaryAssembler, Kernel: KernelEvaluator> { + pub(crate) integrand: Integrand, + pub(crate) kernel: Kernel, + pub(crate) options: BoundaryAssemblerOptions, + pub(crate) deriv_size: usize, + pub(crate) table_derivs: usize, +} - /// Get integrand - fn kernel(&self) -> &Self::Kernel; +unsafe impl, Kernel: KernelEvaluator> + Sync for BoundaryAssembler {} - /// Get assembler options - fn options(&self) -> &BoundaryAssemblerOptions; +impl, Kernel: KernelEvaluator> + BoundaryAssembler { - /// Get mutable assembler options - fn options_mut(&mut self) -> &mut BoundaryAssemblerOptions; + /// Create new + fn new(integrand: Integrand, + kernel: Kernel, +deriv_size: usize, +table_derivs: usize) -> Self { + Self { + integrand, kernel, options: BoundaryAssemblerOptions::default(), deriv_size, table_derivs + } + } /// Set (non-singular) quadrature degree for a cell type - fn quadrature_degree(&mut self, cell: ReferenceCellType, degree: usize) { + pub fn quadrature_degree(&mut self, cell: ReferenceCellType, degree: usize) { *self - .options_mut() + .options .quadrature_degrees .get_mut(&cell) .unwrap() = degree; } /// Set singular quadrature degree for a pair of cell types - fn singular_quadrature_degree( + pub fn singular_quadrature_degree( &mut self, cells: (ReferenceCellType, ReferenceCellType), degree: usize, ) { *self - .options_mut() + .options .singular_quadrature_degrees .get_mut(&cells) .unwrap() = degree; } /// Set the maximum size of a batch of cells to send to an assembly function - fn batch_size(&mut self, size: usize) { - self.options_mut().batch_size = size; + pub fn batch_size(&mut self, size: usize) { + self.options.batch_size = size; } -} -trait InternalAssemblyFunctions: BoundaryAssembler { /// Assemble the singular contributions - fn assemble_singular + Sync>( + fn assemble_singular + Sync>( &self, shape: [usize; 2], trial_space: &Space, test_space: &Space, - ) -> SparseMatrixData { + ) -> SparseMatrixData { if !equal_grids(test_space.grid(), trial_space.grid()) { // If the test and trial grids are different, there are no neighbouring triangles return SparseMatrixData::new(shape); @@ -579,11 +574,11 @@ trait InternalAssemblyFunctions: BoundaryAssembler { ); let npts = qrule.weights.len(); - let mut points = rlst_dynamic_array2!(::Real, [2, npts]); + let mut points = rlst_dynamic_array2!(::Real, [2, npts]); for i in 0..npts { for j in 0..2 { *points.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule.trial_points[2 * i + j], ) .unwrap(); @@ -591,18 +586,18 @@ trait InternalAssemblyFunctions: BoundaryAssembler { } let trial_element = trial_space.element(*trial_cell_type); let mut table = rlst_dynamic_array4!( - Self::T, - trial_element.tabulate_array_shape(Self::TABLE_DERIVS, points.shape()[1]) + T, + trial_element.tabulate_array_shape(self.table_derivs, points.shape()[1]) ); - trial_element.tabulate(&points, Self::TABLE_DERIVS, &mut table); + trial_element.tabulate(&points, self.table_derivs, &mut table); trial_points.push(points); trial_tables.push(table); - let mut points = rlst_dynamic_array2!(::Real, [2, npts]); + let mut points = rlst_dynamic_array2!(::Real, [2, npts]); for i in 0..npts { for j in 0..2 { *points.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule.test_points[2 * i + j], ) .unwrap(); @@ -610,17 +605,17 @@ trait InternalAssemblyFunctions: BoundaryAssembler { } let test_element = test_space.element(*test_cell_type); let mut table = rlst_dynamic_array4!( - Self::T, - test_element.tabulate_array_shape(Self::TABLE_DERIVS, points.shape()[1]) + T, + test_element.tabulate_array_shape(self.table_derivs, points.shape()[1]) ); - test_element.tabulate(&points, Self::TABLE_DERIVS, &mut table); + test_element.tabulate(&points, self.table_derivs, &mut table); test_points.push(points); test_tables.push(table); qweights.push( qrule .weights .iter() - .map(|w| num::cast::::Real>(*w).unwrap()) + .map(|w| num::cast::::Real>(*w).unwrap()) .collect::>(), ); } @@ -655,7 +650,7 @@ trait InternalAssemblyFunctions: BoundaryAssembler { ) }) .reduce( - || SparseMatrixData::::new(shape), + || SparseMatrixData::::new(shape), |mut a, b| { a.add(b); a @@ -666,12 +661,12 @@ trait InternalAssemblyFunctions: BoundaryAssembler { /// Assemble the singular correction /// /// The singular correction is the contribution is the terms for adjacent cells are assembled using an (incorrect) non-singular quadrature rule - fn assemble_singular_correction + Sync>( + fn assemble_singular_correction + Sync>( &self, shape: [usize; 2], trial_space: &Space, test_space: &Space, - ) -> SparseMatrixData { + ) -> SparseMatrixData { if !equal_grids(test_space.grid(), trial_space.grid()) { // If the test and trial grids are different, there are no neighbouring triangles return SparseMatrixData::new(shape); @@ -707,11 +702,11 @@ trait InternalAssemblyFunctions: BoundaryAssembler { let qrule_test = simplex_rule(*test_cell_type, npts_test).unwrap(); let mut test_pts = - rlst_dynamic_array2!(::Real, [2, npts_test]); + rlst_dynamic_array2!(::Real, [2, npts_test]); for i in 0..npts_test { for j in 0..2 { *test_pts.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule_test.points[2 * i + j], ) .unwrap(); @@ -721,25 +716,25 @@ trait InternalAssemblyFunctions: BoundaryAssembler { qrule_test .weights .iter() - .map(|w| num::cast::::Real>(*w).unwrap()) + .map(|w| num::cast::::Real>(*w).unwrap()) .collect::>(), ); let test_element = test_space.element(*test_cell_type); let mut test_table = rlst_dynamic_array4!( - Self::T, - test_element.tabulate_array_shape(Self::TABLE_DERIVS, npts_test) + T, + test_element.tabulate_array_shape(self.table_derivs, npts_test) ); - test_element.tabulate(&test_pts, Self::TABLE_DERIVS, &mut test_table); + test_element.tabulate(&test_pts, self.table_derivs, &mut test_table); test_tables.push(test_table); qpoints_test.push(test_pts); let qrule_trial = simplex_rule(*trial_cell_type, npts_trial).unwrap(); let mut trial_pts = - rlst_dynamic_array2!(::Real, [2, npts_trial]); + rlst_dynamic_array2!(::Real, [2, npts_trial]); for i in 0..npts_trial { for j in 0..2 { *trial_pts.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule_trial.points[2 * i + j], ) .unwrap(); @@ -749,15 +744,15 @@ trait InternalAssemblyFunctions: BoundaryAssembler { qrule_trial .weights .iter() - .map(|w| num::cast::::Real>(*w).unwrap()) + .map(|w| num::cast::::Real>(*w).unwrap()) .collect::>(), ); let trial_element = trial_space.element(*trial_cell_type); let mut trial_table = rlst_dynamic_array4!( - Self::T, - trial_element.tabulate_array_shape(Self::TABLE_DERIVS, npts_trial) + T, + trial_element.tabulate_array_shape(self.table_derivs, npts_trial) ); - trial_element.tabulate(&trial_pts, Self::TABLE_DERIVS, &mut trial_table); + trial_element.tabulate(&trial_pts, self.table_derivs, &mut trial_table); trial_tables.push(trial_table); qpoints_trial.push(trial_pts); } @@ -793,7 +788,7 @@ trait InternalAssemblyFunctions: BoundaryAssembler { ) }) .reduce( - || SparseMatrixData::::new(shape), + || SparseMatrixData::::new(shape), |mut a, b| { a.add(b); a @@ -801,9 +796,9 @@ trait InternalAssemblyFunctions: BoundaryAssembler { ) } /// Assemble the non-singular contributions into a dense matrix - fn assemble_nonsingular + Sync>( + fn assemble_nonsingular + Sync>( &self, - output: &RawData2D, + output: &RawData2D, trial_space: &Space, test_space: &Space, trial_colouring: &HashMap>>, @@ -826,11 +821,11 @@ trait InternalAssemblyFunctions: BoundaryAssembler { let npts_trial = self.options().quadrature_degrees[trial_cell_type]; let qrule_test = simplex_rule(*test_cell_type, npts_test).unwrap(); let mut qpoints_test = - rlst_dynamic_array2!(::Real, [2, npts_test]); + rlst_dynamic_array2!(::Real, [2, npts_test]); for i in 0..npts_test { for j in 0..2 { *qpoints_test.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule_test.points[2 * i + j], ) .unwrap(); @@ -839,15 +834,15 @@ trait InternalAssemblyFunctions: BoundaryAssembler { let qweights_test = qrule_test .weights .iter() - .map(|w| num::cast::::Real>(*w).unwrap()) + .map(|w| num::cast::::Real>(*w).unwrap()) .collect::>(); let qrule_trial = simplex_rule(*trial_cell_type, npts_trial).unwrap(); let mut qpoints_trial = - rlst_dynamic_array2!(::Real, [2, npts_trial]); + rlst_dynamic_array2!(::Real, [2, npts_trial]); for i in 0..npts_trial { for j in 0..2 { *qpoints_trial.get_mut([j, i]).unwrap() = - num::cast::::Real>( + num::cast::::Real>( qrule_trial.points[2 * i + j], ) .unwrap(); @@ -856,22 +851,22 @@ trait InternalAssemblyFunctions: BoundaryAssembler { let qweights_trial = qrule_trial .weights .iter() - .map(|w| num::cast::::Real>(*w).unwrap()) + .map(|w| num::cast::::Real>(*w).unwrap()) .collect::>(); let test_element = test_space.element(*test_cell_type); let mut test_table = rlst_dynamic_array4!( - Self::T, - test_element.tabulate_array_shape(Self::TABLE_DERIVS, npts_test) + T, + test_element.tabulate_array_shape(self.table_derivs, npts_test) ); - test_element.tabulate(&qpoints_test, Self::TABLE_DERIVS, &mut test_table); + test_element.tabulate(&qpoints_test, self.table_derivs, &mut test_table); let trial_element = trial_space.element(*trial_cell_type); let mut trial_table = rlst_dynamic_array4!( - Self::T, - trial_element.tabulate_array_shape(Self::TABLE_DERIVS, npts_trial) + T, + trial_element.tabulate_array_shape(self.table_derivs, npts_trial) ); - trial_element.tabulate(&qpoints_test, Self::TABLE_DERIVS, &mut trial_table); + trial_element.tabulate(&qpoints_test, self.table_derivs, &mut trial_table); for test_c in &test_colouring[test_cell_type] { for trial_c in &trial_colouring[trial_cell_type] { @@ -931,12 +926,13 @@ trait InternalAssemblyFunctions: BoundaryAssembler { } } -impl InternalAssemblyFunctions for A {} -impl BoundaryAssembly for A { - type T = A::T; - fn assemble_singular_into_dense + Sync>( +impl, Kernel: KernelEvaluator> +BoundaryAssembly for + BoundaryAssembler { + type T = T; + fn assemble_singular_into_dense + Sync>( &self, - output: &mut RlstArray, + output: &mut RlstArray, trial_space: &Space, test_space: &Space, ) { @@ -949,15 +945,15 @@ impl BoundaryAssembly for A { } } - fn assemble_singular_into_csr + Sync>( + fn assemble_singular_into_csr + Sync>( &self, trial_space: &Space, test_space: &Space, - ) -> CsrMatrix { + ) -> CsrMatrix { let shape = [test_space.global_size(), trial_space.global_size()]; let sparse_matrix = self.assemble_singular(shape, trial_space, test_space); - CsrMatrix::::from_aij( + CsrMatrix::::from_aij( sparse_matrix.shape, &sparse_matrix.rows, &sparse_matrix.cols, @@ -966,9 +962,9 @@ impl BoundaryAssembly for A { .unwrap() } - fn assemble_singular_correction_into_dense + Sync>( + fn assemble_singular_correction_into_dense + Sync>( &self, - output: &mut RlstArray, + output: &mut RlstArray, trial_space: &Space, test_space: &Space, ) { @@ -982,15 +978,15 @@ impl BoundaryAssembly for A { } } - fn assemble_singular_correction_into_csr + Sync>( + fn assemble_singular_correction_into_csr + Sync>( &self, trial_space: &Space, test_space: &Space, - ) -> CsrMatrix { + ) -> CsrMatrix { let shape = [test_space.global_size(), trial_space.global_size()]; let sparse_matrix = self.assemble_singular_correction(shape, trial_space, test_space); - CsrMatrix::::from_aij( + CsrMatrix::::from_aij( sparse_matrix.shape, &sparse_matrix.rows, &sparse_matrix.cols, @@ -999,9 +995,9 @@ impl BoundaryAssembly for A { .unwrap() } - fn assemble_into_dense + Sync>( + fn assemble_into_dense + Sync>( &self, - output: &mut RlstArray, + output: &mut RlstArray, trial_space: &Space, test_space: &Space, ) { @@ -1018,9 +1014,9 @@ impl BoundaryAssembly for A { self.assemble_singular_into_dense(output, trial_space, test_space); } - fn assemble_nonsingular_into_dense + Sync>( + fn assemble_nonsingular_into_dense + Sync>( &self, - output: &mut RlstArray, + output: &mut RlstArray, trial_space: &Space, test_space: &Space, trial_colouring: &HashMap>>, @@ -1053,23 +1049,23 @@ impl BoundaryAssembly for A { impl ParallelBoundaryAssembly for A { fn parallel_assemble_singular_into_csr< C: Communicator, - Space: ParallelFunctionSpace, + Space: ParallelFunctionSpace, >( &self, trial_space: &Space, test_space: &Space, - ) -> CsrMatrix { + ) -> CsrMatrix { self.assemble_singular_into_csr(trial_space.local_space(), test_space.local_space()) } fn parallel_assemble_singular_correction_into_csr< C: Communicator, - Space: ParallelFunctionSpace, + Space: ParallelFunctionSpace, >( &self, trial_space: &Space, test_space: &Space, - ) -> CsrMatrix { + ) -> CsrMatrix { self.assemble_singular_correction_into_csr( trial_space.local_space(), test_space.local_space(), diff --git a/src/assembly/boundary/assemblers/adjoint_double_layer.rs b/src/assembly/boundary/assemblers/adjoint_double_layer.rs index ee6ed46b..f8ad1a7a 100644 --- a/src/assembly/boundary/assemblers/adjoint_double_layer.rs +++ b/src/assembly/boundary/assemblers/adjoint_double_layer.rs @@ -7,60 +7,31 @@ use crate::assembly::{ use green_kernels::{helmholtz_3d::Helmholtz3dKernel, laplace_3d::Laplace3dKernel, traits::Kernel}; use rlst::{MatrixInverse, RlstScalar}; -/// Assembler for a adjoint double layer operator -pub struct AdjointDoubleLayerAssembler> { - integrand: AdjointDoubleLayerBoundaryIntegrand, - kernel: KernelEvaluator, - options: BoundaryAssemblerOptions, -} -impl> AdjointDoubleLayerAssembler { +impl> BoundaryAssembler, KernelEvaluator> { /// Create a new adjoint double layer assembler - pub fn new(kernel: KernelEvaluator) -> Self { - Self { - integrand: AdjointDoubleLayerBoundaryIntegrand::new(), + pub fn new_adjoint_double_layer(kernel: KernelEvaluator) -> Self { + Self::new( + AdjointDoubleLayerBoundaryIntegrand::new(), kernel, - options: BoundaryAssemblerOptions::default(), - } + 4, + 0 + ) } } -impl AdjointDoubleLayerAssembler> { +impl> BoundaryAssembler, KernelEvaluator>> { /// Create a new Laplace adjoint double layer assembler - pub fn new_laplace() -> Self { - Self::new(KernelEvaluator::new_laplace( + pub fn new_laplace_adjoint_double_layer() -> Self { + Self::new_adjoint_double_layer(KernelEvaluator::new_laplace( GreenKernelEvalType::ValueDeriv, )) } } -impl + MatrixInverse> - AdjointDoubleLayerAssembler> -{ +impl, K: Kernel> BoundaryAssembler, KernelEvaluator>> { /// Create a new Helmholtz adjoint double layer assembler - pub fn new_helmholtz(wavenumber: T::Real) -> Self { - Self::new(KernelEvaluator::new_helmholtz( + pub fn new_helmholtz_adjoint_double_layer(wavenumber: T::Real) -> Self { + Self::new_adjoint_double_layer(KernelEvaluator::new_helmholtz( wavenumber, GreenKernelEvalType::ValueDeriv, )) } } - -impl> BoundaryAssembler - for AdjointDoubleLayerAssembler -{ - const DERIV_SIZE: usize = 4; - const TABLE_DERIVS: usize = 0; - type T = T; - type Integrand = AdjointDoubleLayerBoundaryIntegrand; - type Kernel = KernelEvaluator; - fn integrand(&self) -> &AdjointDoubleLayerBoundaryIntegrand { - &self.integrand - } - fn kernel(&self) -> &KernelEvaluator { - &self.kernel - } - fn options(&self) -> &BoundaryAssemblerOptions { - &self.options - } - fn options_mut(&mut self) -> &mut BoundaryAssemblerOptions { - &mut self.options - } -} diff --git a/src/assembly/boundary/assemblers/double_layer.rs b/src/assembly/boundary/assemblers/double_layer.rs index 8e441cd2..793bd1cf 100644 --- a/src/assembly/boundary/assemblers/double_layer.rs +++ b/src/assembly/boundary/assemblers/double_layer.rs @@ -7,58 +7,31 @@ use crate::assembly::{ use green_kernels::{helmholtz_3d::Helmholtz3dKernel, laplace_3d::Laplace3dKernel, traits::Kernel}; use rlst::{MatrixInverse, RlstScalar}; -/// Assembler for a double layer operator -pub struct DoubleLayerAssembler> { - integrand: DoubleLayerBoundaryIntegrand, - kernel: KernelEvaluator, - options: BoundaryAssemblerOptions, -} -impl> DoubleLayerAssembler { +impl> BoundaryAssembler, KernelEvaluator> { /// Create a new double layer assembler - pub fn new(kernel: KernelEvaluator) -> Self { - Self { - integrand: DoubleLayerBoundaryIntegrand::new(), + pub fn new_double_layer(kernel: KernelEvaluator) -> Self { + Self::new( + DoubleLayerBoundaryIntegrand::new(), kernel, - options: BoundaryAssemblerOptions::default(), - } + 4, + 0 + ) } } -impl DoubleLayerAssembler> { +impl> BoundaryAssembler, KernelEvaluator>> { /// Create a new Laplace double layer assembler - pub fn new_laplace() -> Self { - Self::new(KernelEvaluator::new_laplace( + pub fn new_laplace_double_layer() -> Self { + Self::new_double_layer(KernelEvaluator::new_laplace( GreenKernelEvalType::ValueDeriv, )) } } -impl + MatrixInverse> DoubleLayerAssembler> { +impl, K: Kernel> BoundaryAssembler, KernelEvaluator>> { /// Create a new Helmholtz double layer assembler - pub fn new_helmholtz(wavenumber: T::Real) -> Self { - Self::new(KernelEvaluator::new_helmholtz( + pub fn new_helmholtz_double_layer(wavenumber: T::Real) -> Self { + Self::new_double_layer(KernelEvaluator::new_helmholtz( wavenumber, GreenKernelEvalType::ValueDeriv, )) } } - -impl> BoundaryAssembler - for DoubleLayerAssembler -{ - const DERIV_SIZE: usize = 4; - const TABLE_DERIVS: usize = 0; - type T = T; - type Integrand = DoubleLayerBoundaryIntegrand; - type Kernel = KernelEvaluator; - fn integrand(&self) -> &DoubleLayerBoundaryIntegrand { - &self.integrand - } - fn kernel(&self) -> &KernelEvaluator { - &self.kernel - } - fn options(&self) -> &BoundaryAssemblerOptions { - &self.options - } - fn options_mut(&mut self) -> &mut BoundaryAssemblerOptions { - &mut self.options - } -} diff --git a/src/assembly/boundary/assemblers/hypersingular.rs b/src/assembly/boundary/assemblers/hypersingular.rs index e0fb5a1a..8a9791bd 100644 --- a/src/assembly/boundary/assemblers/hypersingular.rs +++ b/src/assembly/boundary/assemblers/hypersingular.rs @@ -18,73 +18,37 @@ type HelmholtzIntegrand = BoundaryIntegrandSum< HypersingularNormalNormalBoundaryIntegrand, >; -/// Assembler for a hypersingular operator -pub struct HypersingularAssembler< - T: RlstScalar + MatrixInverse, - K: Kernel, - I: BoundaryIntegrand + Sync, -> { - kernel: KernelEvaluator, - integrand: I, - options: BoundaryAssemblerOptions, -} - -impl, I: BoundaryIntegrand + Sync> - HypersingularAssembler -{ - /// Create a new hypersingular assembler - pub fn new(kernel: KernelEvaluator, integrand: I) -> Self { - Self { - kernel, +impl, I: BoundaryIntegrand> BoundaryAssembler> { + /// Create a new adjoint double layer assembler + pub fn new_hypersingular(integrand: I, kernel: KernelEvaluator) -> Self { + Self::new( integrand, - options: BoundaryAssemblerOptions::default(), - } + kernel, + 4, + 1 + ) } } -impl - HypersingularAssembler, HypersingularCurlCurlBoundaryIntegrand> -{ - /// Create a new Laplace hypersingular assembler - pub fn new_laplace() -> Self { - Self::new( - KernelEvaluator::new_laplace(GreenKernelEvalType::ValueDeriv), +impl> BoundaryAssembler, KernelEvaluator>> { + /// Create a new Laplace adjoint double layer assembler + pub fn new_laplace_hypersingular() -> Self { + Self::new_hypersingular( HypersingularCurlCurlBoundaryIntegrand::new(), + KernelEvaluator::new_laplace(GreenKernelEvalType::ValueDeriv), ) } } -impl + MatrixInverse> - HypersingularAssembler, HelmholtzIntegrand> -{ - /// Create a new Helmholtz hypersingular assembler - pub fn new_helmholtz(wavenumber: T::Real) -> Self { - Self::new( - KernelEvaluator::new_helmholtz(wavenumber, GreenKernelEvalType::ValueDeriv), - BoundaryIntegrandSum::new( +impl, K: Kernel> BoundaryAssembler, KernelEvaluator>> { + /// Create a new Helmholtz adjoint double layer assembler + pub fn new_helmholtz_hypersingular(wavenumber: T::Real) -> Self { + Self::new_hypersingular( + BoundaryIntegrandSum::new( HypersingularCurlCurlBoundaryIntegrand::new(), HypersingularNormalNormalBoundaryIntegrand::new(wavenumber), ), - ) - } -} - -impl, I: BoundaryIntegrand + Sync> - BoundaryAssembler for HypersingularAssembler -{ - const DERIV_SIZE: usize = 4; - const TABLE_DERIVS: usize = 1; - type T = T; - type Integrand = I; - type Kernel = KernelEvaluator; - fn integrand(&self) -> &I { - &self.integrand - } - fn kernel(&self) -> &KernelEvaluator { - &self.kernel - } - fn options(&self) -> &BoundaryAssemblerOptions { - &self.options - } - fn options_mut(&mut self) -> &mut BoundaryAssemblerOptions { - &mut self.options +KernelEvaluator::new_helmholtz( + wavenumber, + GreenKernelEvalType::ValueDeriv, + )) } } diff --git a/src/assembly/boundary/assemblers/single_layer.rs b/src/assembly/boundary/assemblers/single_layer.rs index 4bf9f81a..1f63da28 100644 --- a/src/assembly/boundary/assemblers/single_layer.rs +++ b/src/assembly/boundary/assemblers/single_layer.rs @@ -7,56 +7,31 @@ use crate::assembly::{ use green_kernels::{helmholtz_3d::Helmholtz3dKernel, laplace_3d::Laplace3dKernel, traits::Kernel}; use rlst::{MatrixInverse, RlstScalar}; -/// Assembler for a single layer operator -pub struct SingleLayerAssembler> { - integrand: SingleLayerBoundaryIntegrand, - kernel: KernelEvaluator, - options: BoundaryAssemblerOptions, -} -impl> SingleLayerAssembler { +impl> BoundaryAssembler, KernelEvaluator> { /// Create a new single layer assembler - pub fn new(kernel: KernelEvaluator) -> Self { - Self { - integrand: SingleLayerBoundaryIntegrand::new(), + pub fn new_single_layer(kernel: KernelEvaluator) -> Self { + Self::new( + SingleLayerBoundaryIntegrand::new(), kernel, - options: BoundaryAssemblerOptions::default(), - } + 1, + 0 + ) } } -impl SingleLayerAssembler> { +impl> BoundaryAssembler, KernelEvaluator>> { /// Create a new Laplace single layer assembler - pub fn new_laplace() -> Self { - Self::new(KernelEvaluator::new_laplace(GreenKernelEvalType::Value)) + pub fn new_laplace_single_layer() -> Self { + Self::new_single_layer(KernelEvaluator::new_laplace( + GreenKernelEvalType::Value, + )) } } -impl + MatrixInverse> SingleLayerAssembler> { +impl, K: Kernel> BoundaryAssembler, KernelEvaluator>> { /// Create a new Helmholtz single layer assembler - pub fn new_helmholtz(wavenumber: T::Real) -> Self { - Self::new(KernelEvaluator::new_helmholtz( + pub fn new_helmholtz_single_layer(wavenumber: T::Real) -> Self { + Self::new_single_layer(KernelEvaluator::new_helmholtz( wavenumber, GreenKernelEvalType::Value, )) } } - -impl> BoundaryAssembler - for SingleLayerAssembler -{ - const DERIV_SIZE: usize = 1; - const TABLE_DERIVS: usize = 0; - type T = T; - type Integrand = SingleLayerBoundaryIntegrand; - type Kernel = KernelEvaluator; - fn integrand(&self) -> &SingleLayerBoundaryIntegrand { - &self.integrand - } - fn kernel(&self) -> &KernelEvaluator { - &self.kernel - } - fn options(&self) -> &BoundaryAssemblerOptions { - &self.options - } - fn options_mut(&mut self) -> &mut BoundaryAssemblerOptions { - &mut self.options - } -}