use dex::visuals as dv;
use dexterior as dex;
type Pressure = dex::Cochain<0, dex::Primal>;
type Velocity = dex::Cochain<1, dex::Primal>;
#[derive(Clone, Debug)]
struct State {
p: Pressure,
v: Velocity,
big_layout_active: bool,
}
impl dv::AnimationState for State {
fn interpolate(old: &Self, new: &Self, t: f64) -> Self {
Self {
p: old.p.lerp(&new.p, t),
v: old.v.lerp(&new.v, t),
big_layout_active: new.big_layout_active,
}
}
}
struct Ops {
p_step: dex::Op<Velocity, Pressure>,
v_step: dex::Op<Pressure, Velocity>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let msh_bytes = include_bytes!("./meshes/2d_square_pi_x_pi.msh");
let mesh = dex::gmsh::load_trimesh_2d(msh_bytes)?;
let dt = 1. / 10.;
let wave_speed_sq = 1.0f64.powi(2);
let ops = Ops {
p_step: (-dt * wave_speed_sq * mesh.star() * mesh.d() * mesh.star())
.exclude_subset(&mesh.boundary()),
v_step: dt * mesh.d(),
};
let state = State {
p: mesh.integrate_cochain(dex::quadrature::Pointwise(|v| {
f64::sin(3.0 * v[0]) * f64::sin(2.0 * v[1])
})),
v: mesh.new_zero_cochain(),
big_layout_active: false,
};
let bg_color: dv::palette::LinSrgb = dv::palette::Srgb::new(22, 31, 46).into();
let fg_color: dv::palette::LinSrgb = dv::palette::Srgb::new(245, 245, 245).into();
let mut window = dv::RenderWindow::new(dv::WindowParams {
width: 1200,
height: 800,
background: bg_color,
..Default::default()
})?;
let mut big_layout = dv::Layout::new();
let [_l, r] = big_layout.split_lr(2.);
let [_t, _b] = r.split_tb(1.);
window.run_animation(dv::Animation {
mesh: &mesh,
params: dv::AnimationParams {
color_map_range: Some(-1.0..1.0),
..Default::default()
},
dt,
state,
step: |state| {
state.p += &ops.p_step * &state.v;
state.v += &ops.v_step * &state.p;
},
draw: |state, draw| {
if state.big_layout_active {
draw.set_layout(&big_layout);
}
draw.set_color_map("sunset");
draw.set_margin(0.2);
draw.vertex_colors(&state.p);
draw.wireframe(dv::WireframeParams {
..Default::default()
});
draw.velocity_arrows(
&state.v,
dv::ArrowParams {
..Default::default()
},
);
draw.axes_2d(dv::AxesParams {
color: fg_color,
..Default::default()
});
draw.text(dv::TextParams {
text: "test text\nχξΔ",
position: mesh.vertices()[52],
anchor: dv::TextAnchor::BottomMid,
color: dv::palette::Srgb::new(150, 0, 0).into(),
attrs: dv::default_text_attrs().style(dv::glyphon::Style::Italic),
..Default::default()
});
if !state.big_layout_active {
return;
}
draw.next_pane();
draw.set_color_map("molentum");
draw.wireframe(dv::WireframeParams {
width: dv::LineWidth::ScreenPixels(2.),
color: dv::palette::named::CYAN.into(),
});
draw.axes_2d(dv::AxesParams {
color: fg_color,
..Default::default()
});
draw.next_pane();
draw.vertex_colors(&state.p);
draw.axes_2d(dv::AxesParams {
color: dv::palette::named::TOMATO.into(),
..Default::default()
});
},
on_key: |key, state| {
if key == dv::KeyCode::KeyL {
state.big_layout_active = !state.big_layout_active;
}
},
})?;
Ok(())
}