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
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*!
# **kalast**

Thermophysical model for binary systems of asteroids.

## Using **kalast**

You will need the last stable build of the [rust compiler](https://www.rust-lang.org)
and the official package manager: [cargo](https://github.com/rust-lang/cargo).

Simply add the following to your `Cargo.toml` file:

```.ignore
[dependencies]
kalast = "0.1.7"
```

Useful functionalities of **kalast** are grouped in the root module `kalast::`.

## **kalast** in action

```
use kalast::{BinarySystem, Properties, Time, World, ASTRONAUMICAL_UNIT, HOUR, MINUTE, V3, YEAR};

fn main() {
    let binary_system = BinarySystem::new(
        "Two spheres",
        V3::new(1.0, 0.0, 0.0) * ASTRONAUMICAL_UNIT * 1.664,
    )
    .with_primary(
        "rsc/obj/sphere_light.obj",
        Properties::new(
            1.0 * YEAR, // rotation period
            2.7 * HOUR, // revolution period
            0.0,        // obliquity
            100.0,      // thermal inertia
            2146.0,     // density
            600.0,      // heat capacity
            0.1,        // albedo
            0.9,        // emissivity
        ),
    )
    .with_secondary(
        "rsc/obj/ellipsoid_light.obj",
        Properties::new(
            11.92 * HOUR, // rotation period
            11.92 * HOUR, // revolution period
            0.0,          // obliquity 162.0 * TAU / 360.
            500.0,        // thermal inertia
            2146.0,       // density
            600.0,        // heat capacity
            0.07,         // albedo
            0.9,          // emissivity
        ),
        V3::new(-1.0, 0.0, 0.0) * 1e3, // relative position
    );

    binary_system.complete_model(true);
    binary_system.primary_mut().fixed(true);
    binary_system.secondary_mut().fixed(true);

    // Time
    let time = Time::new(
        binary_system.secondary().properties.revolution_period() * 50.,
        30.0 * MINUTE,
    );

    // World
    let mut world = World::new(time, binary_system);
    world.start();
    world.save("rsc/data/tmp.txt");

    println!(
        "{} {}",
        world.environment_system.secondary().temperatures().min(),
        world.environment_system.secondary().temperatures().max()
    );
}
```

You can also read other [examples](https://gitlab-as.oma.be/gregoireh/kalast/-/tree/main/examples).

## Features

**kalast** is meant for binary system of asteroids surface thermophysical modelling. The physics of this engine includes these features:

+ custom shape model
+ celestial body revolution
+ compute surface temperatures from solar flux
+ ground 1D heat transfert conduction
+ celestial body mask view (example only equator)
+ mutual heating from primary/moon
+ self heating
+ TODO: 3D conduction / FEM
+ TODO: mutual occultations
+ TODO: shadowing

## Explore

If your want to explore the documentation, you can visite these pages:

+ [`Object3D`]: parse 3D object file and compute atributes of faces (centers, normals, ...)
+ [`Body`]: the representation for a celestial body
+ [`BinarySystem`]: the environment system for binary system of asteroids
+ [`World`]: the simulation manager
+ [`Properties`]: all the properties to characterise a body
*/

extern crate alga;
extern crate indicatif;
#[macro_use]
extern crate itertools;
extern crate nalgebra as na;
extern crate num_traits;
extern crate obj;

/// Base features.
pub mod base;
/// Collection of generic functions for math, physics, matrix operations, or for the usage of other
/// crates.
pub mod toolbox;

use alga::general::RingCommutative;
use na::Scalar;
use na::{
    DVector, Dynamic, Matrix, Matrix3x1, Matrix3xX, SliceStorage, SliceStorageMut, VecStorage, U1,
    U10,
};
use num_traits::{NumCast, ToPrimitive};
use std::cmp::PartialOrd;

pub use crate::base::*;
pub use crate::toolbox::*;

/// Type alias for [`Matrix3xX`]. The matrix has a fixed number of rows (3) and a dynamical number of
/// columns.
pub type V3X<T> = Matrix3xX<T>;

/// Type alias for [`Matrix3x1`]. The matrix has a fixed number of rows (3) and a fixed number of
/// columns (1).
pub type V3<T> = Matrix3x1<T>;

/// Type alias for [`DVector`]. The matrix is a vector of X columns.
pub type VX<T> = DVector<T>;

/// Type alias for [`Object3D`]. The matrix has a fixed number of rows (10) and a dynamical number
/// of columns.
pub type Matrix10xX<T> = Matrix<T, U10, Dynamic, VecStorage<T, U10, Dynamic>>;

/// Type alias for [`Object3D`]. The slice matrix has a fixed number of rows (10) and a fixed
/// number of columns (1).
pub type MatrixSlice10x1<'a, T, RStride = U1, CStride = U10> =
    Matrix<T, U10, U1, SliceStorage<'a, T, U10, U1, RStride, CStride>>;

/// Type alias for [`Object3D`]. The mutable slice matrix has a fixed number of rows (10) and a
/// fixed number of columns (1).
pub type MatrixSliceMut10x1<'a, T, RStride = U1, CStride = U10> =
    Matrix<T, U10, U1, SliceStorageMut<'a, T, U10, U1, RStride, CStride>>;

/// Trait that extends [`Scalar`] to create integer matrices like float matrices. It aims to be the
/// equivalent of [`RealField`][nalgebra::RealField] but for integer.
pub trait SuperScalar:
    Scalar + RingCommutative + PartialOrd + std::ops::Div + ToPrimitive + NumCast + Copy
{
}

impl<T> SuperScalar for T where
    T: Scalar + RingCommutative + PartialOrd + std::ops::Div + ToPrimitive + NumCast + Copy
{
}