Von Mises truss calculation¶
Description¶
iks007_vonMisesTruss.cpp utilizes the tools and features mentioned in the previous examples to solve the
standard Von-Mises truss example found in literature (refer to Section 21).
Code highlights¶
The struct named Truss is created such that it inherits from AutoDiffFE. It is constructed as shown below:
Truss(const Basis &basis, const typename LocalView::Element &element, double p_EA)
: BaseDisp(basis.flat(), element), BaseAD(basis.flat(), element), EA{p_EA} {
this->localView().bind(element);
}
&basis), the element (&element), and the axial stiffness of the
truss structure (p_EA) as arguments during construction.
ScalarType calculateScalarImpl(const FERequirementType &par, const Eigen::VectorX<ScalarType> &dx) is
then defined, returning a scalar value, in this case the energy.
The energy is defined as 0.5 * EA / sqrt(LRefsquared) * Egl * Egl with Egl being the Green-Lagrange strain defined as
h) and length (L) of the truss system are defined, which is followed by
the addition of the vertices and elements to create a grid as shown below:
Dune::GridFactory<Dune::FoamGrid<1, 2, double>> gridFactory;
const double h = 1.0;
const double L = 1.0;
gridFactory.insertVertex({0, 0});
gridFactory.insertVertex({L, h});
gridFactory.insertVertex({2 * L, 0});
gridFactory.insertElement(Dune::GeometryTypes::line, {0, 1});
gridFactory.insertElement(Dune::GeometryTypes::line, {1, 2});
auto grid = gridFactory.createGrid();
auto gridView = grid->leafGridView();
Truss elements are then created, followed by the fixing of the
degrees of freedom at the boundaries ({0,0} and {2 * L,0}). A vertical downward load is applied to the center node.
The non-linear operator is then constructed. The Newton-Raphson method is used as the non-linear solver, and an nonLinearSolverObserver is
created to write messages as desired by the non-linear solver. An additional lvkObserver is created using the Ikarus::GenericControlObserver
feature. This observer helps to fill up the matrix lambdaAndDisp with the load factor lambda and the two unconstrained degrees of freedom whenever
the solution is changed (ControlMessages::SOLUTION_CHANGED), which means that the Newton-Raphson method has converged to a solution.
This is implemented as depicted in the following:
const int loadSteps = 10;
Eigen::Matrix3Xd lambdaAndDisp;
lambdaAndDisp.setZero(Eigen::NoChange, loadSteps + 1);
auto lvkObserver = std::make_shared<Ikarus::GenericControlObserver>(ControlMessages::SOLUTION_CHANGED, [&](int step) {
lambdaAndDisp(0, step) = lambda;
lambdaAndDisp(1, step) = d[2];
lambdaAndDisp(2, step) = d[3];
});
vtkWriter and lvkObserver.
The features from Matplot++ are then used to plot the load-displacement curve from the matrix lambdaAndDisp.
Takeaways¶
Dune::FoamGridcan be used to embed one or two-dimensional grid entities into a multi-dimensional physical space.- A simple truss element can be constructed using the automatic differentiation procedure.
Ikarus::GenericControlObservercan be used to perform user-desired tasks at any desired point by observing a non-linear solver procedure.
-
R. V. Mises. Über die stabilitätsprobleme der elastizitätstheorie. ZAMM - Journal of Applied Mathematics and Mechanics / Zeitschrift für Angewandte Mathematik und Mechanik, 3(6):406–422, 1923. doi:10.1002/zamm.19230030602. ↩