Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: SVD Based Field Translation Improvements #160

Merged
merged 16 commits into from
Jan 19, 2024
53 changes: 53 additions & 0 deletions fmm/examples/single_node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::time::Instant;

use itertools::Itertools;

use rlst_dense::traits::RawAccess;

use bempp_field::types::FftFieldTranslationKiFmm;
use bempp_fmm::{
charge::build_charge_dict,
types::{FmmDataUniform, KiFmmLinear},
};
use bempp_kernel::laplace_3d::Laplace3dKernel;
use bempp_traits::{fmm::FmmLoop, tree::Tree};
use bempp_tree::implementations::helpers::points_fixture;
use bempp_tree::types::single_node::SingleNodeTree;

fn main() {
let npoints = 1000000;

let points = points_fixture::<f32>(npoints, None, None);

let global_idxs = (0..npoints).collect_vec();
let charges = vec![1.0; npoints];

let order = 6;
let alpha_inner = 1.05;
let alpha_outer = 2.95;
let depth = 4;

let tree = SingleNodeTree::new(points.data(), false, None, Some(depth), &global_idxs, true);

let kernel = Laplace3dKernel::default();
let m2l_data: FftFieldTranslationKiFmm<f32, Laplace3dKernel<f32>> =
FftFieldTranslationKiFmm::new(kernel.clone(), order, *tree.get_domain(), alpha_inner);
// let m2l_data = SvdFieldTranslationKiFmm::new(
// kernel.clone(),
// Some(80),
// order,
// *tree.get_domain(),
// alpha_inner,
// );

let fmm = KiFmmLinear::new(order, alpha_inner, alpha_outer, kernel, tree, m2l_data);

// Form charge dict, matching charges with their associated global indices
let charge_dict = build_charge_dict(&global_idxs, &charges);

let datatree = FmmDataUniform::new(fmm, &charge_dict).unwrap();

let s = Instant::now();
let times = datatree.run(true);
println!("runtime {:?} operators {:?}", s.elapsed(), times);
}
70 changes: 70 additions & 0 deletions fmm/examples/single_node_matrix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::time::Instant;

use bempp_fmm::types::FmmDataUniformMatrix;
use itertools::Itertools;

use rlst_dense::traits::RawAccess;

use bempp_field::types::SvdFieldTranslationKiFmm;
use bempp_fmm::charge::build_charge_dict;
use bempp_kernel::laplace_3d::Laplace3dKernel;
use bempp_traits::{fmm::FmmLoop, tree::Tree};
use bempp_tree::implementations::helpers::points_fixture;
use bempp_tree::types::single_node::SingleNodeTree;

fn main() {
let npoints = 1000000;

let global_idxs = (0..npoints).collect_vec();

let order = 6;
let alpha_inner = 1.05;
let alpha_outer = 2.95;

// Test matrix input
let points = points_fixture::<f32>(npoints, None, None);
let ncharge_vecs = 3;
let depth = 4;

let mut charge_mat = vec![vec![0.0; npoints]; ncharge_vecs];
charge_mat
.iter_mut()
.enumerate()
.for_each(|(i, charge_mat_i)| *charge_mat_i = vec![i as f32 + 1.0; npoints]);

// SVD based field translations
let kernel = Laplace3dKernel::default();

// Create a tree
let tree = SingleNodeTree::new(points.data(), false, None, Some(depth), &global_idxs, true);

// Precompute the M2L data
let m2l_data = SvdFieldTranslationKiFmm::new(
kernel.clone(),
Some(80),
order,
*tree.get_domain(),
alpha_inner,
);

let fmm = bempp_fmm::types::KiFmmLinearMatrix::new(
order,
alpha_inner,
alpha_outer,
kernel,
tree,
m2l_data,
);

// Form charge dict, matching charges with their associated global indices
let charge_dicts: Vec<_> = (0..ncharge_vecs)
.map(|i| build_charge_dict(&global_idxs, &charge_mat[i]))
.collect();

// Associate data with the FMM
let datatree = FmmDataUniformMatrix::new(fmm, &charge_dicts).unwrap();

let s = Instant::now();
let times = datatree.run(true);
println!("runtime {:?} operators {:?}", s.elapsed(), times);
}
Loading