+expr stuff

This commit is contained in:
Alain Emilia Anna Zscheile 2024-07-23 11:33:03 +02:00
parent f1379a2b47
commit 08da77334a
4 changed files with 110 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 31962ce4b2b7d1421b5ede84134b002ba976b33f03b881c4bfe9c05af2181af7 # shrinks to shv = [0]
cc 99135630e97ec4120dda5b152311a94864bbb4393bdbdeb4acc7ff52786becdb # shrinks to shv = [0]

93
src/expr/mod.rs Normal file
View file

@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2024 Emilia Anna Zscheile <fogti+devel@ytrizja.de>
*
* SPDX-License-Identifier: EUPL-1.2
*/
//! tools for handling expressions
use std::collections::BTreeMap;
/// A reference to a PDE variable or derivative of such
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Link(pub u16, pub Box<[u16]>);
#[derive(Clone, Debug)]
pub enum Expr<L> {
Const(f64),
Link(L),
Sum(Vec<Expr<L>>),
Prod(Vec<Expr<L>>),
// useful builtin functions:
Sine(Box<Expr<L>>),
Cosine(Box<Expr<L>>),
Tangens(Box<Expr<L>>),
ArcTan(Box<Expr<L>>),
}
impl<L: Clone + Eq + Ord> Expr<L> {
fn extract_links_intern(&self, out: &mut Vec<L>) {
match self {
Expr::Const(_) => {},
Expr::Link(l) => out.push(l.clone()),
Expr::Sum(xs) => xs.iter().for_each(|i| i.extract_links_intern(out)),
Expr::Prod(xs) => xs.iter().for_each(|i| i.extract_links_intern(out)),
Expr::Sine(x) | Expr::Cosine(x) | Expr::Tangens(x) | Expr::ArcTan(x) => x.extract_links_intern(out),
}
}
pub fn interp(&self, link_data: &BTreeMap<L, f64>) -> f64 {
match self {
Expr::Const(x) => *x,
Expr::Link(l) => link_data[l],
Expr::Sum(xs) => xs.iter().map(|i| i.interp(link_data)).sum(),
Expr::Prod(xs) => xs.iter().map(|i| i.interp(link_data)).product(),
Expr::Sine(x) => x.interp(link_data).sin(),
Expr::Cosine(x) => x.interp(link_data).cos(),
Expr::Tangens(x) => x.interp(link_data).tan(),
Expr::ArcTan(x) => x.interp(link_data).atan(),
}
}
}
/// A system of PDEs and monitors (outputs)
///
/// LHS is always the first derivative to time (it is not possible to refer to time derivatives on RHS)
#[derive(Clone, Debug)]
pub struct System {
pub vs: Vec<Expr<Link>>,
pub mons: Vec<(Vec<Expr<()>>, Expr<Link>)>,
}
impl System {
pub fn extract_links(&self) -> Vec<Link> {
let mut ret = Vec::new();
self.vs.iter().for_each(|i| i.extract_links_intern(&mut ret));
self.mons.iter().for_each(|i| i.1.extract_links_intern(&mut ret));
ret.sort_unstable();
ret.dedup();
ret
}
// this is invoked for each time step times points in space for which the links can be computed
pub fn interp_vs(&self, link_data: &BTreeMap<Link, f64>, out: &mut [f64]) {
self.vs.iter().zip(out.iter_mut()).for_each(|(x, y)| { *y = x.interp(link_data); });
}
// this is invoked once per time step
pub fn interp_mons_loc(&self, t: f64, out: &mut [Box<[f64]>]) {
let link_data = {
let mut ld = BTreeMap::new();
ld.insert((), t);
ld
};
self.mons.iter().zip(out.iter_mut()).for_each(|(x, y)| {
x.0.iter().zip(y.iter_mut()).for_each(|(x, y)| {
*y = x.interp(&link_data);
});
});
}
}

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: EUPL-1.2
*/
pub mod expr;
pub mod mesh;
fn main() {

View file

@ -6,3 +6,11 @@
/// pdxdrive meshes
pub mod grid;
#[derive(Clone)]
pub enum Mesh {
Grid {
shape: grid::Shape,
data: nalgebra::DMatrix<f64>,
}
}