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)
10
11#[allow(unused_imports)]
12use super::functions::*;
13use crate::compute::ComputeKernel;
14
15use super::types::PppmChargeAssignKernel;
16
17impl ComputeKernel for PppmChargeAssignKernel {
18    fn name(&self) -> &str {
19        "PppmChargeAssignKernel"
20    }
21    fn execute(&self, inputs: &[&[f64]], outputs: &mut [Vec<f64>], work_size: usize) {
22        if inputs.len() < 3 || outputs.is_empty() {
23            return;
24        }
25        let pos = inputs[0];
26        let charges = inputs[1];
27        let grid_params = inputs[2];
28        if grid_params.len() < 4 {
29            return;
30        }
31        let nx = grid_params[0] as usize;
32        let ny = grid_params[1] as usize;
33        let nz = grid_params[2] as usize;
34        let box_len = grid_params[3];
35        let dx = box_len / nx as f64;
36        let dy = box_len / ny as f64;
37        let dz = box_len / nz as f64;
38        let n = work_size;
39        let mut mesh = vec![0.0f64; nx * ny * nz];
40        for i in 0..n {
41            let x = pos[i * 3].rem_euclid(box_len);
42            let y = pos[i * 3 + 1].rem_euclid(box_len);
43            let z = pos[i * 3 + 2].rem_euclid(box_len);
44            let ix = ((x / dx) as usize).min(nx - 1);
45            let iy = ((y / dy) as usize).min(ny - 1);
46            let iz = ((z / dz) as usize).min(nz - 1);
47            let grid_idx = ix * ny * nz + iy * nz + iz;
48            mesh[grid_idx] += charges[i];
49        }
50        outputs[0] = mesh;
51    }
52}