Skip to main content

oxiphysics_gpu/kernels/md_force/
pppmchargeassignkernel_traits.rs

1//! # PppmChargeAssignKernel - Trait Implementations
2//!
3//! This module contains trait implementations for `PppmChargeAssignKernel`.
4//!
5//! ## Implemented Traits
6//!
7//! - `ComputeKernel`
8//!
9//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
10use crate::compute::ComputeKernel;
11
12use super::types::PppmChargeAssignKernel;
13
14impl ComputeKernel for PppmChargeAssignKernel {
15    fn name(&self) -> &str {
16        "PppmChargeAssignKernel"
17    }
18    fn execute(&self, inputs: &[&[f64]], outputs: &mut [Vec<f64>], work_size: usize) {
19        if inputs.len() < 3 || outputs.is_empty() {
20            return;
21        }
22        let pos = inputs[0];
23        let charges = inputs[1];
24        let grid_params = inputs[2];
25        if grid_params.len() < 4 {
26            return;
27        }
28        let nx = grid_params[0] as usize;
29        let ny = grid_params[1] as usize;
30        let nz = grid_params[2] as usize;
31        let box_len = grid_params[3];
32        let dx = box_len / nx as f64;
33        let dy = box_len / ny as f64;
34        let dz = box_len / nz as f64;
35        let n = work_size;
36        let mut mesh = vec![0.0f64; nx * ny * nz];
37        for i in 0..n {
38            let x = pos[i * 3].rem_euclid(box_len);
39            let y = pos[i * 3 + 1].rem_euclid(box_len);
40            let z = pos[i * 3 + 2].rem_euclid(box_len);
41            let ix = ((x / dx) as usize).min(nx - 1);
42            let iy = ((y / dy) as usize).min(ny - 1);
43            let iz = ((z / dz) as usize).min(nz - 1);
44            let grid_idx = ix * ny * nz + iy * nz + iz;
45            mesh[grid_idx] += charges[i];
46        }
47        outputs[0] = mesh;
48    }
49}