Commit 451d6f06 authored by Stefan Pfeifer's avatar Stefan Pfeifer

Unify interface for displacements and external forces

parent 25693a0c
* Find a way to handle comma vs dot as decimal separator, otherwise note in docs
GUI
===
* Find a way to prevent changing element properties during simulation. Could be done by having the system own
the elements and only pass a const& of the system in the simulation callbacks.
* Find a way to handle comma vs dot as decimal separator, otherwise note in docs
* Make simulation callbacks in System templates
FEM
===
* get_u, get_v, get_a in system could be public fields instead of methods. Saves some parenthesis when calling.
* Find a way to prevent changing element properties during simulation. Could be done by having the system own
the elements and only pass a const& of the system in the simulation callbacks.
* Make simulation callbacks in System templates
General
=======
* Restructure. Put code in cpp files, include less stuff in headers to reduce compile times.
\ No newline at end of file
......@@ -22,15 +22,17 @@ private:
VectorXd uf; // Displacements of fixed DOFs
public:
const VectorView<Dof> get_u; // Todo: Rename to view_u, view_v, view_a or something better?
const VectorView<Dof> get_v;
const VectorView<Dof> get_a;
VectorView<Dof> get_u; // Todo: Rename to view_u, view_v, view_a or something better?
VectorView<Dof> get_v;
VectorView<Dof> get_a;
VectorView<Dof> get_p;
System()
: t(0.0),
get_u([&](Dof dof){ return dof.active ? u(dof.index) : uf(dof.index); }, nullptr),
get_v([&](Dof dof){ return dof.active ? v(dof.index) : 0.0; }, nullptr),
get_a([&](Dof dof){ return dof.active ? a(dof.index) : 0.0; }, nullptr)
get_u([&](Dof dof){ return dof.active ? u(dof.index) : uf(dof.index); }, nullptr, nullptr),
get_v([&](Dof dof){ return dof.active ? v(dof.index) : 0.0; }, nullptr, nullptr),
get_a([&](Dof dof){ return dof.active ? a(dof.index) : 0.0; }, nullptr, nullptr),
get_p([&](Dof dof){ return dof.active ? p(dof.index) : 0.0; }, [&](Dof dof, double val){ if(dof.active) p(dof.index) = val; }, nullptr)
{
}
......@@ -88,22 +90,6 @@ public:
return t;
}
// Todo: Should this be done via a View instead? Problem: Add vs set
// One solution: Replace get, add with get, set. Implement add as set(get+add)
double get_external_force(Dof dof)
{
if(dof.active)
return p(dof.index);
else
return 0.0;
}
void set_external_force(Dof dof, double val)
{
if(dof.active)
p(dof.index) = val;
}
// Euclidean distance between node_a and node_b
double get_distance(Node node_a, Node node_b)
{
......@@ -354,12 +340,7 @@ private:
{
M.setZero();
VectorView<Dof> view(
[&](Dof)
{
return 0.0; // Todo: Unreachable
},
VectorView<Dof> view(nullptr, nullptr,
[&](Dof dof, double val)
{
if(dof.active)
......@@ -376,12 +357,7 @@ private:
{
q.setZero();
VectorView<Dof> view(
[&](Dof)
{
return 0.0; // Todo: Unreachable
},
VectorView<Dof> view(nullptr, nullptr,
[&](Dof dof, double val)
{
if(dof.active)
......
......@@ -21,6 +21,7 @@ class LocalVectorEntry
{
public:
std::function<double(Key)>& get;
std::function<void(Key, double)>& set;
std::function<void(Key, double)>& add;
Key key;
......@@ -31,6 +32,11 @@ public:
}
// Write
LocalVectorEntry<Key>& operator=(double rhs)
{
set(key, rhs);
}
void operator+=(double rhs)
{
add(key, rhs);
......@@ -47,6 +53,7 @@ class LocalVectorView
{
public:
std::function<double(Key)>& get;
std::function<void(Key, double)>& set;
std::function<void(Key, double)>& add;
const std::array<Key, N>& keys;
......@@ -80,12 +87,12 @@ public:
// Index
LocalVectorEntry<Key> operator()(size_t i)
{
return LocalVectorEntry<Key>{get, add, keys[i]};
return LocalVectorEntry<Key>{get, set, add, keys[i]};
}
const LocalVectorEntry<Key> operator()(size_t i) const
{
return LocalVectorEntry<Key>{get, add, keys[i]};
return LocalVectorEntry<Key>{get, set, add, keys[i]};
}
};
......@@ -94,12 +101,15 @@ class VectorView
{
private:
mutable std::function<double(Key)> get;
mutable std::function<void(Key, double)> set;
mutable std::function<void(Key, double)> add;
public:
VectorView(std::function<double(Key)> get,
std::function<void(Key, double)> set,
std::function<void(Key, double)> add)
: get(get),
set(set),
add(add)
{
......@@ -109,24 +119,24 @@ public:
template<size_t N>
LocalVectorView<Key, N> operator()(const std::array<Key, N>& keys)
{
return LocalVectorView<Key, N>{get , add, keys};
return LocalVectorView<Key, N>{get, set, add, keys};
}
template<size_t N>
const LocalVectorView<Key, N> operator()(const std::array<Key, N>& keys) const
{
return LocalVectorView<Key, N>{get, add, keys};
return LocalVectorView<Key, N>{get, set, add, keys};
}
// Single indes
// Single indices
LocalVectorEntry<Key> operator()(Key key)
{
return LocalVectorEntry<Key>{get, add, key};
return LocalVectorEntry<Key>{get, set, add, key};
}
const LocalVectorEntry<Key> operator()(Key key) const
{
return LocalVectorEntry<Key>{get, add, key};
return LocalVectorEntry<Key>{get, set, add, key};
}
};
......
......@@ -4,7 +4,7 @@ double Element::get_kinetic_energy(const VectorView<Dof> v) const
{
double T = 0.0;
get_masses(VectorView<Dof>(nullptr, [&](Dof dof, double val)
get_masses(VectorView<Dof>(nullptr, nullptr, [&](Dof dof, double val)
{
T += 0.5*val*std::pow(v(dof), 2);
}));
......
......@@ -189,7 +189,7 @@ private:
{
// Adjust arrow contact based on static results
double max_penetration = 1e-4*(input.operation.draw_length - input.operation.brace_height); // Todo: Magic number
double max_force = system.get_external_force(nodes_string[0].x); // Todo: Better way to get static results, maybe pass reference. // Todo: Assumes that max draw force is reached at end of draw
double max_force = system.get_p(nodes_string[0].x); // Todo: Better way to get static results, maybe pass reference. // Todo: Assumes that max draw force is reached at end of draw
double kc = max_force/max_penetration;
double ml = input.operation.arrow_mass;
......@@ -201,7 +201,7 @@ private:
contact_arrow.set_one_sided(true);
// Remove draw force // Todo: Doesn't really belong in this method
system.set_external_force(nodes_string[0].x, 0.0);
system.get_p(nodes_string[0].x) = 0.0;
double T = 0.05;
double t = 0.0;
......@@ -222,10 +222,10 @@ private:
return states;
}
void get_bow_state(BowStates& states)
void get_bow_state(BowStates& states) const
{
states.time.push_back(system.get_time());
states.draw_force.push_back(system.get_external_force(nodes_string[0].x));
states.draw_force.push_back(system.get_p(nodes_string[0].x));
states.pos_string.push_back(system.get_u(nodes_string[0].x));
states.pos_arrow.push_back(system.get_u(node_arrow.x));
......
......@@ -61,8 +61,8 @@ TEST_CASE("Small deformation bar truss")
system.add_element(element_03_09);
system.add_element(element_09_05);
system.set_external_force(node_02.y, -F);
system.set_external_force(node_04.y, -F);
system.get_p(node_02.y) = -F;
system.get_p(node_04.y) = -F;
system.solve_statics_lc();
......@@ -95,7 +95,7 @@ TEST_CASE("Large deformation bar truss")
system.solve_statics_dc(node02.y, 0.6*H, 100, [&]()
{
double s = system.get_u(node02.y);
double f_num = system.get_external_force(node02.y);
double f_num = system.get_p(node02.y);
double L0 = M_SQRT2*H;
double L = std::hypot(H, s);
......
......@@ -43,7 +43,7 @@ TEST_CASE("Large deformation cantilever")
system.add_elements(elements);
system.set_external_force(nodes[N].y, F0);
system.get_p(nodes[N].y) = F0;
system.solve_statics_lc();
// Tip displacements
......@@ -106,7 +106,7 @@ TEST_CASE("Large deformation circular beam")
//std::cout << "phi = " << system.get_u()(nodes[N].phi) << "\n";
});
double M_num = -system.get_external_force(nodes[N].phi);
double M_num = -system.get_p(nodes[N].phi);
double M_ref = EI*R;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment