1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! This module defines a simple container structure to store source particles and target particles
//! in a convenient way.

use crate::RealType;
use ndarray::{Array2, ArrayView2};

// This traits describes any type that provides an array of sources and
// an array of targets.
pub trait ParticleContainerAccessor {
    type FloatingPointType: RealType;

    /// Return a non-owning representation of the sources.
    fn sources(&self) -> ArrayView2<Self::FloatingPointType>;
    /// Return a non-owning representation of the targets.
    fn targets(&self) -> ArrayView2<Self::FloatingPointType>;
}

/// The basic data structure for sources and targets that are owned.
pub struct ParticleContainer<T: RealType> {
    sources: Array2<T>,
    targets: Array2<T>,
}

/// Create a new particle container and transfer ownership to it.
pub fn make_particle_container_owned<T: RealType>(
    sources: Array2<T>,
    targets: Array2<T>,
) -> ParticleContainer<T> {
    ParticleContainer { sources, targets }
}

/// Create a new particle container that does not take over ownership.
pub fn make_particle_container<'a, T: RealType>(
    sources: ArrayView2<'a, T>,
    targets: ArrayView2<'a, T>,
) -> ParticleContainerView<'a, T> {
    ParticleContainerView { sources, targets }
}

// The basic data structure of for sources and targets that are not owned.
pub struct ParticleContainerView<'a, T: RealType> {
    sources: ArrayView2<'a, T>,
    targets: ArrayView2<'a, T>,
}

impl<T: RealType> ParticleContainerAccessor for ParticleContainer<T> {
    type FloatingPointType = T;

    /// Return a non-owning representation of the sources.
    fn sources(&self) -> ArrayView2<Self::FloatingPointType> {
        self.sources.view()
    }

    /// Return a non-owning representation of the targets.
    fn targets(&self) -> ArrayView2<Self::FloatingPointType> {
        self.targets.view()
    }
}

impl<'a, T: RealType> ParticleContainerAccessor for ParticleContainerView<'a, T> {
    type FloatingPointType = T;

    /// Return a non-owning representation of the sources.
    fn sources(&self) -> ArrayView2<Self::FloatingPointType> {
        self.sources.view()
    }

    /// Return a non-owning representation of the targets.
    fn targets(&self) -> ArrayView2<Self::FloatingPointType> {
        self.targets.view()
    }
}