dvcompute 2.0.0

Discrete event simulation library (sequential simulation)
Documentation
// Copyright (c) 2020-2022  David Sorokin <davsor@mail.ru>, based in Yoshkar-Ola, Russia
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use crate::simulation::generator::GeneratorType;

/// It represents the simulation specs.
#[derive(Clone)]
pub struct Specs {

    /// The start simulation time.
    pub start_time: f64,

    /// The final simulation time.
    pub stop_time: f64,

    /// The integration time step.
    pub dt: f64,

    /// The type of random number generator.
    pub generator_type: GeneratorType
}

impl Specs {

    /// Return the indexed time value in the grid by the specified index and size,
    /// where the index changes within `[0, size)`. Index 0 corresponds to the start time,
    /// but the index with value `size-1` corresponds to the stop time.
    #[inline]
    pub fn grid_time(&self, index: usize, size: usize) -> f64 {
        let t0 = self.start_time;
        let t2 = self.stop_time;
        let n2 = if size <= 1 { 1 } else { size - 1 };
        let dt2 = (t2 - t0) / (n2 as f64);

        if index == 0 { t0 } else {
            if index == n2 { t2 } else {
                t0 + (index as f64) * dt2
            }
        }
    }

    /// Return the grid index that would correspond the specified modeling time.
    #[inline]
    pub fn grid_index(&self, t: f64, size: usize) -> usize {
        let t0 = self.start_time;
        let t2 = self.stop_time;
        let n2 = if size <= 1 { 1 } else { size - 1 };

        if t == t0 {
            0
        } else if t == t2 {
            n2
        } else {
            let dt = (t2 - t0) / (n2 as f64);
            ((t - t0) / dt).floor() as usize
        }
    }
}

/// It represents the simulation specs representation.
#[repr(C)]
pub struct SpecsRepr {

    /// The start simulation time.
    pub start_time: f64,

    /// The final simulation time.
    pub stop_time: f64,

    /// The integration time step.
    pub dt: f64
}

impl From<Specs> for SpecsRepr {

    fn from(specs: Specs) -> Self {
        SpecsRepr {
            start_time: specs.start_time,
            stop_time: specs.stop_time,
            dt: specs.dt
        }
    }
}

impl SpecsRepr {

    /// Return the indexed time value in the grid by the specified index and size,
    /// where the index changes within `[0, size)`. Index 0 corresponds to the start time,
    /// but the index with value `size-1` corresponds to the stop time.
    #[inline]
    pub fn grid_time(&self, index: usize, size: usize) -> f64 {
        let t0 = self.start_time;
        let t2 = self.stop_time;
        let n2 = if size <= 1 { 1 } else { size - 1 };
        let dt2 = (t2 - t0) / (n2 as f64);

        if index == 0 { t0 } else {
            if index == n2 { t2 } else {
                t0 + (index as f64) * dt2
            }
        }
    }

    /// Return the grid index that would correspond the specified modeling time.
    #[inline]
    pub fn grid_index(&self, t: f64, size: usize) -> usize {
        let t0 = self.start_time;
        let t2 = self.stop_time;
        let n2 = if size <= 1 { 1 } else { size - 1 };

        if t == t0 {
            0
        } else if t == t2 {
            n2
        } else {
            let dt = (t2 - t0) / (n2 as f64);
            ((t - t0) / dt).floor() as usize
        }
    }
}