Consider a rigid body with mass but without rotation inertia, constrained to maintain a constant distance from a grounded point and subject to gravity. In MBDyn such a model can be implemented in different ways. In this tutorial some of the possible ways will be used simultaneously.
The constraint can be implemented as a revolute hinge: in this case the mass performs a revolute movement, so its inertia about the revolute axis must be zero; or it can be a distance constraint: in this case the mass does not rotate provided the point the distance is measured from is the CM of the mass.
The following cases will be considered:
In MBDyn there's no direct knowledge or implicit definition of a ``ground node''. There are special constraints that operate between one node and the ground. One of these constraints is the ``revolute pin'', which allows a node to rotate about one axis with respect to ground. In the case of the distance constraint, which must operate between two nodes, we will use a dummy node that will be grounded by a clamp constraint. The solution of the dummy node is trivial: its position and orientation cannot change, and the clamp constraint simply yields the reaction forces and couples that the system exchanges with the ground at that point.
The input file for our simple example is:
begin: data;
problem: initial value; # the default
end: data;
begin: initial value;
initial time: 0.;
final time: 1.;
time step: 1.e-3;
max iterations: 10;
tolerance: 1.e-6;
end: initial value;
begin: control data;
structural nodes:
+1 # node in the constraint
+1 # node in the mass
+2 # distance: mass+ground
;
rigid bodies:
+1 # node in the constraint
+1 # node in the mass
+1 # distance: mass
;
joints:
+1 # node in the constraint: revolute
+1 # node in the mass: revolute
+2 # distance: distance+ground
;
gravity;
end: control data;
set: integer Pendulum = 1;
set: integer Mass = 2;
set: real M = 1.;
set: real L = .5;
set: real Omega0 = .2;
reference: Pendulum,
reference, global, null,
reference, global, eye,
reference, global, null,
reference, global, 0., Omega0, 0.;
reference: Mass,
reference, Pendulum, 0., 0., -L,
reference, Pendulum, eye,
reference, Pendulum, null,
reference, Pendulum, null;
begin: nodes;
structural: 1000+Pendulum, dynamic,
reference, Pendulum, null,
reference, Pendulum, eye,
reference, Pendulum, null,
reference, Pendulum, null;
structural: 2000+Mass, dynamic,
reference, Mass, null,
reference, Mass, eye,
reference, Mass, null,
reference, Mass, null;
# no dynamic dofs (it will be fully grounded)
structural: 3000+Pendulum, static,
reference, Pendulum, null,
reference, Pendulum, eye,
reference, Pendulum, null,
reference, global, null;
# "global" means no angular velocity!
structural: 3000+Mass, dynamic,
reference, Mass, null,
reference, Mass, eye,
reference, Mass, null,
reference, global, null;
# "global" means no angular velocity!
end: nodes;
begin: elements;
body: 1000+Mass, 1000+Pendulum,
M,
reference, Mass, null,
null; /* The problem is non-singular
* because of the constraint */
joint: 1000+Mass, revolute pin,
1000+Pendulum,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.;
body: 2000+Mass, 2000+Mass,
M,
reference, Mass, null,
null; /* The problem is non-singular
* because of the constraint */
joint: 2000+Mass, revolute pin,
2000+Mass,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.;
body: 3000+Mass, 3000+Mass,
M,
reference, Mass, null,
eye; # Otherwise the problem will be singular ...
joint: 3000+Pendulum, clamp,
3000+Pendulum, node, node;
joint: 3000+Mass, distance,
3000+Pendulum,
3000+Mass,
const, L;
gravity: 0., 0., -1., const, 9.81;
end: elements;
Let's have a look at each portion of the input separately.
First we notice the structural nodes card in the control data block:
structural nodes:
+1 # node in the constraint
+1 # node in the mass
+2 # distance: mass+ground
;
Every time a numeric data is expected in a field,
a mathematical interpreter is invoked.
The rules of the interpreter are rather sophisticated;
let's skip over them and use the interpreter in a trivial manner.
As a result, the number ``4'' (the total number of nodes we expect
to read) is split in the sum of each contribution with a one-line
remark to increase the readability of the statement.
The same applies to the following rigid bodies and joints cards.
We introduced two new types of elements: the joints and the gravity. The latter is the first example of a statement made of a card with no arguments.
Let's now go to a seemingly unstructured block of statements:
set: integer Pendulum = 1;
set: integer Mass = 2;
set: real M = 1.;
set: real L = .5;
set: real Omega0 = .2;
reference: Pendulum,
reference, global, null,
reference, global, eye,
reference, global, null,
reference, global, 0., Omega0, 0.;
reference: Mass,
reference, Pendulum, 0., 0., -L,
reference, Pendulum, eye,
reference, Pendulum, null,
reference, Pendulum, null;
these statements appear out of any structured block because
they may appear anywhere, since they are not related to the analysis
or the model, but are directly interpreted by the parser;
they represent helpers the parser allows to ease the input
of the data.
The first group of statements represents declarations and definitions of variables that will be later used by the parser. Variables are typed (integer or real) scalars. A variable must always be declared before it's first used. The declaration may occur anywhere.
The second group of statements represents the declaration and definition of reference frames that can be used when placing entities around in the model. Each frame is defined by the three coordinates, the orientation matrix, the three components of the velocity and the three components of the angular velocity. It may be defined both in absolute coordinates (the default) or referred to other reference frames in a hierarchical manner. The hierarchy is discarded as soon as the reference is used, and the data is transformed in the global/local frame as appropriate. The hierarchy is preserved across runs by maintaining the symbolic form of the input.
The Pendulum reference frame is placed in the origin of the global (builtin) frame and oriented as the global frame itself. However it has an initial angular velocity about axis 2 that represents the initial conditions of our analysis. The Mass reference frame is placed relative to the Pendulum reference frame at a distance L in the negative direction of axis 3. As a result, the Mass reference frame has the angular velocity of the Pendulum reference frame, plus a velocity in the direction of axis 1 of magnitude -Omega0*L.
Let's now look at each example separately.
In the first case, the node is written as:
structural: 1000+Pendulum, dynamic,
reference, Pendulum, null,
reference, Pendulum, eye,
reference, Pendulum, null,
reference, Pendulum, null;
which means that the node, called ``1000+Pendulum'', namely ``1001'',
is placed in the origin (``null'') of Pendulum reference
and is oriented as the reference itself.
It also inherits the velocities of the reference, so it is rotating
with angular velocity Omega0 about axis 2.
An equivalent definition without the use of references would have been:
structural: 1000+Pendulum, dynamic,
null,
eye,
null,
0., Omega0, 0.;
where the global reference frame is implicitly assumed when defining
the configuration of a node.
The corresponding rigid body is written as:
body: 1000+Mass, 1000+Pendulum,
M,
reference, Mass, null,
null;
which means that a rigid body called ``1000+Mass'', i.e. ``1002'',
is attached to node ``1000+Pendulum'', i.e. "1001"; the mass is ``M'',
i.e. ``1.'', and this mass is offset from the node.
The position of the mass expressed in reference frame Mass
is given; it is automatically transformed in an offset by transforming
it in the global frame, subtracting the position of the node,
and transforming the result in the reference frame of the node.
A null inertia matrix is give because we want to neglect it
(i.e. consider a point with mass).
As the remark says, there's no danger to drive the problem singular,
because the constraint that will be added will make the problem
statically determined.
An equivalent definition with no frames would have been:
body: 1000+Mass, 1000+Pendulum,
M,
0., 0., -L,
null;
where the offset is input in the reference frame of the node
(i.e. a local frame).
Finally, the corresponding joint is written as:
joint: 1000+Mass, revolute pin,
1000+Pendulum,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.,
reference, Pendulum, null,
hinge, reference, Pendulum,
1, 1.,0.,0., 3, 0.,1.,0.;
which means that a joint called ``1000+Mass'' (labels need be unique
only within an entity type) representing a ``revolute pin''
(``revolute'' means it allows rotation about one specific axis only;
``pin'' means that it connects one node to the ground) is connected
to a node called ``1000+Pendulum'' and to the ground itself.
The connection, with regards to the node, is in the origin
of the Pendulum reference frame, while the absolute position
of the pin is again in the absolute position of the origin
of the Pendulum reference.
The orientation of the joint (which means the orientation
of the axis about which the joint allows rotation) is axis 2
of the Pendulum reference frame.
The orientation is specified by giving two arbitrary
non-parallel vectors, as shown in Figure
.
The first is taken as is and becomes the direction it was named after
(``1'' in the case at hand); the other concurs in determining
the remaining direction by performing a vector multiplication
(being i, j and k the unit vectors
of the coordinate axes, if i and j are given,
k is determined by multiplying i cross j).
There are other means to specify an orientation; see the input manual
for details.
The second case is straightforward.
The third case is slightly different because there is no orientation constraint. However the problem is a little more difficult because we need to generate a grounded node (in a straightforward manner, though) to use an imposed distance joint.
Finally, notice how the gravity has been introduced: its orientation is defined first; then its amplitude is set to the desired (constant!) value.
The interpretation of the results requires some care. Cases 2 and 3 should yield the same results in terms of displacements, because nodes ``X+Mass'' are coincident. On the contrary, the results of case 1 should be transformed to the position of the mass to compare with the others. However cases 1 and 2 should match with regard to orientation and angular velocity.
A new output file, with extension jnt, appears. It contains the output of the joints with the format:
The revolute pin joints add the three components of the rotation and of the angular velocity (only the one about axis 3 can be non null, of course). The rotation is expressed by means of the Euler-like angles in the 1, 2, 3 sequence.