Skip to content

Commit

Permalink
Improvements and simplifications for the dof views
Browse files Browse the repository at this point in the history
  • Loading branch information
stfnp committed Sep 14, 2024
1 parent a922b7f commit 61cda24
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 123 deletions.
6 changes: 3 additions & 3 deletions solver/src/bow/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::fem::elements::beam::{BeamElement, CrossSection, PlanarCurve};
use crate::fem::solvers::eigen::{Mode, natural_frequencies};
use crate::fem::solvers::statics::StaticSolver;
use crate::fem::system::element::Element;
use crate::fem::system::nodes::{Constraints, GebfNode, PointNode};
use crate::fem::system::nodes::{Constraints, OrientedNode, PointNode};
use crate::fem::system::system::{DynamicEval, StaticEval, System};
use crate::bow::sections::section::LayeredCrossSection;
use crate::bow::errors::ModelError;
Expand All @@ -34,7 +34,7 @@ pub enum SystemEval<'a> {
pub struct Simulation<'a> {
model: &'a BowInput,
info: Common,
limb_nodes: Vec<GebfNode>,
limb_nodes: Vec<OrientedNode>,
limb_elements: Vec<usize>,

string_node: PointNode,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl<'a> Simulation<'a> {

let mut system = System::new();

let limb_nodes: Vec<GebfNode> = u_nodes.iter().enumerate().map(|(i, u)| {
let limb_nodes: Vec<OrientedNode> = u_nodes.iter().enumerate().map(|(i, u)| {
let constraints = if i != 0 { Constraints::all_free() } else { Constraints::all_fixed() };
system.create_beam_node(u, constraints)
}).collect();
Expand Down
6 changes: 3 additions & 3 deletions solver/src/fem/solvers/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ impl<'a> StaticSolver<'a> {
// Solve for equilibrium of the system with a displacement constraint in the form of a given target displacement for a dof
pub fn solve_equilibrium_displacement_controlled(&mut self, dof: Dof, u_target: f64) -> Result<IterationInfo, IterationError> {
match dof {
Dof::Free { index, offset, scale} => {
Dof::Free { index, offset } => {
return self.solve_equilibrium_constrained(|u, _lambda, dcdu, dcdλ| {
dcdu.fill(0.0);
dcdu[index] = scale;
dcdu[index] = 1.0;
*dcdλ = 0.0;

return scale*u[index] + offset - u_target;
return u[index] + offset - u_target;
});
},
Dof::Fixed { offset: _ } => {
Expand Down
26 changes: 7 additions & 19 deletions solver/src/fem/system/dof.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Dof {
Free{ index: usize, offset: f64 },
Fixed{ offset: f64 },
Free{ index: usize, offset: f64, scale: f64 }
}

impl Dof {
// Creates a new dof whose local displacement is the scaled value of the displacement of this dof
// Free case: factor * ( scale*u[i] + offset ) = factor*scale*u[i] + factor*offset
// Fixed case: factor * offset
pub fn scaled(&self, factor: f64) -> Self {
match *self {
Dof::Fixed{offset} => {
Self::Fixed {
offset: factor*offset
}
}
Dof::Free{index, offset, scale} => {
Self::Free {
index: index,
offset: factor*offset,
scale: factor*scale
}
}
}
pub fn new_free(index: usize, offset: f64) -> Self {
Self::Free { index, offset }
}

pub fn new_fixed(offset: f64) -> Self {
Self::Fixed { offset }
}

pub fn is_fixed(&self) -> bool {
Expand Down
54 changes: 5 additions & 49 deletions solver/src/fem/system/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,8 @@ impl PointNode {
}
}

pub fn x(&self) -> Dof {
self.dofs[0]
}

pub fn y(&self) -> Dof {
self.dofs[1]
}
}

#[derive(Copy, Clone, Debug)]
pub struct AncfNode {
dofs: [Dof; 6]
}

impl Node for AncfNode {
fn dofs(&self) -> &[Dof] {
&self.dofs
}
}

impl AncfNode {
pub fn new(x: Dof, y: Dof, dxds: Dof, dyds: Dof, dxds2: Dof, dyds2: Dof) -> Self {
Self {
dofs: [x, y, dxds, dyds, dxds2, dyds2]
}
}

pub fn point(&self) -> PointNode {
PointNode::new(self.dofs[0], self.dofs[1])
pub fn oriented(&self) -> OrientedNode {
OrientedNode::new(self.dofs[0], self.dofs[1], Dof::new_fixed(0.0))
}

pub fn x(&self) -> Dof {
Expand All @@ -60,37 +33,20 @@ impl AncfNode {
pub fn y(&self) -> Dof {
self.dofs[1]
}

pub fn dxds(&self) -> Dof {
self.dofs[2]
}

pub fn dyds(&self) -> Dof {
self.dofs[3]
}

pub fn dxds2(&self) -> Dof {
self.dofs[4]
}

pub fn dyds2(&self) -> Dof {
self.dofs[5]
}
}


#[derive(Copy, Clone, Debug)]
pub struct GebfNode {
pub struct OrientedNode {
dofs: [Dof; 3]
}

impl Node for GebfNode {
impl Node for OrientedNode {
fn dofs(&self) -> &[Dof] {
&self.dofs
}
}

impl GebfNode {
impl OrientedNode {
pub fn new(x: Dof, y: Dof, φ: Dof) -> Self {
Self {
dofs: [x, y, φ]
Expand Down
18 changes: 9 additions & 9 deletions solver/src/fem/system/system.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::element::Element;
use super::dof::Dof;
use super::nodes::{Node, PointNode, GebfNode};
use super::nodes::{Node, PointNode, OrientedNode};
use super::views::{PositionView, VelocityView, VectorView, MatrixView};
use super::nodes::Constraints;
use nalgebra::{DMatrix, DVector, SVector};
use crate::fem::system::views::{AccelerationView, ForceView};

// The system struct holds the elements, external forces and their mapping to the dofs that make up the fem system.
// It also holds the current system state: time, displacements and velocities.
Expand Down Expand Up @@ -43,15 +44,15 @@ impl StaticEval {
}

pub fn get_scaled_external_force(&self, dof: Dof) -> f64 {
self.λ*VelocityView::transform(&self.p, dof) // TODO: VelocityView does the right thing, but the name is misleading here. Maybe LinearView/AffineView?
self.λ*ForceView::transform(&self.p, dof)
}

pub fn get_internal_forces(&self) -> &DVector<f64> {
&self.q
}

pub fn get_internal_force(&self, dof: Dof) -> f64 {
VelocityView::transform(&self.q, dof) // TODO: Bad naming "VelocityView"
ForceView::transform(&self.q, dof)
}

pub fn get_tangent_stiffness_matrix(&self) -> &DMatrix<f64> {
Expand Down Expand Up @@ -87,23 +88,23 @@ impl DynamicEval {
}

pub fn get_external_force(&self, dof: Dof) -> f64 {
VelocityView::transform(&self.p, dof) // TODO: Bad naming "VelocityView"
ForceView::transform(&self.p, dof)
}

pub fn get_internal_forces(&self) -> &DVector<f64> {
&self.q
}

pub fn get_internal_force(&self, dof: Dof) -> f64 {
VelocityView::transform(&self.q, dof) // TODO: Bad naming "VelocityView"
ForceView::transform(&self.q, dof)
}

pub fn get_accelerations(&self) -> &DVector<f64> {
&self.a
}

pub fn get_acceleration(&self, dof: Dof) -> f64 {
VelocityView::transform(&self.a, dof) // TODO: Bad naming "VelocityView"
AccelerationView::transform(&self.a, dof)
}
}

Expand Down Expand Up @@ -180,12 +181,12 @@ impl System {

// Creates a planar node with three degrees of freedom, two displacementd and a rotation.
// Displacements: [x, y, φ]
pub fn create_beam_node(&mut self, u: &SVector<f64, 3>, constraints: Constraints) -> GebfNode {
pub fn create_beam_node(&mut self, u: &SVector<f64, 3>, constraints: Constraints) -> OrientedNode {
let dof_x = if constraints.x_pos_fixed { self.create_fixed_dof(u[0]) } else { self.create_free_dof(u[0], 1.0) };
let dof_y = if constraints.y_pos_fixed { self.create_fixed_dof(u[1]) } else { self.create_free_dof(u[1], 1.0) };
let dof_φ = if constraints.y_pos_fixed { self.create_fixed_dof(u[2]) } else { self.create_free_dof(u[2], 1.0) };

GebfNode::new(dof_x, dof_y, dof_φ)
OrientedNode::new(dof_x, dof_y, dof_φ)
}

// Creates a single unconstrained dof. Mainly used internally
Expand All @@ -198,7 +199,6 @@ impl System {
Dof::Free {
index: self.n_dofs() - 1,
offset,
scale
}
}

Expand Down
Loading

0 comments on commit 61cda24

Please sign in to comment.