Figure 5a illustrates a simple mesh discussed in [4] with three
fixed nodes and one free node. Assume linear displacement
constant pressure elements; incompressible (constant
volume) deformation must take place. As a result of
kinematic constraint node N is required to move horizontally
in the lower triangular element, and required to move
vertically as a result of the kinematic constraint in the upper
triangular element; locking results, and obviously the
reasoning can be extended to a n x n mesh (figure 5b). This
kind of locking typically appears when using the full B
matrix as described later. Different methods can be used in
order to avoid this phenomenon [5]. Keeping in mind the
incompressible behavior of Von Misès material, the
B
approach can be applied here.
fixed
N
fixedfixed
fixed
Figure 5a Figure 5b
1.5 Why object-oriented programming?
Object-oriented programming (see e.g. [6], [7], [8] and
references therein) has proven in recent years to be one of the
easiest, fastest and most efficient ways to program robust
scientific software. The basic components of the finite
element method, like the node, the element, the material, can
easily be fitted into an objects world, with their own
behavior, state and identity. We review here the key features
of object-oriented programming:
a) Robustness and modularity: encapsulation of data
An object is a device capable of performing predefined
actions, such as storing information (in its variables),
executing tasks (through his methods), or accessing other
objects (by sending messages). Variables describe the state of
the object, while methods define its behavior. Objects hide
their variables from other components of the application. For
instance, class Element does not have direct access to its
Young Modulus. The Young Modulus is stored in class
Material. The object has to send a message, like
myMaterial
→
giveYoungModulus() to access it.
b) Inheritance and polymorphism: the hierarchy of classes
Every object is an instance of a class. A class is an abstract
data type which can be considered as the mold of the object.
Classes are organised within a hierarchy (class-subclass),
which allows a subclass (say, Truss2D) to inherit the methods
and variables from its superclass (say, Element).
Polymorphism expresses the fact that two different classes
will react differently (in their own manner) to the same
message. For instance, the message myElement
→
giveBMatrix() will be interpreted differently by an object of
the class Quad_U (defining quadrilateral elements) and an
object of the class Truss2D (defining truss elements).
The hierarchy of classes of a simple nonlinear finite element
code, providing an overview of the entire software, is given
in section 3. The fact that the code can be described in such a
compact way can be very valuable, when extensions are
considered.
c) Non-anticipation and state encapsulation
Non-anticipation expresses the fact that the content of a
method should not rely on any assumption on the state of the
variables. Strict obedience to non-anticipation will contribute
significantly to code robustness.
d) Efficiency
As far as numerical performance is concerned, languages
such as C++ have shown performances similar to Fortran.
With respect to code development speed using object-
oriented techniques, the programmer can maximize
reusability of the software and «program like he thinks»,
which leads to faster prototyping.
2 Main tasks of the finite element
program
2.1 Element level (class Element)
2.1.1 Forming the elementary stiffness
The definition of the elemental stiffness matrix K
e
writes:
e
e
T
dVBDBK
ep
e
∫
= (33)
The following method of class Element illustrates how the
element is forming its stiffness matrix.
//-------------------------------------------------------
FloatMatrix* Element :: computeTangentStiffnessMatrix ()
//-------------------------------------------------------
{
Material *mat;
GaussPoint *gp;
FloatMatrix *b,*db,*d;
double dV;
int i;
if (stiffnessMatrix) {
delete stiffnessMatrix;
}
stiffnessMatrix = new FloatMatrix();
mat = this->giveMaterial();
for (i=0; i<numberOfGaussPoints; i++) {
gp = gaussPointArray[i];
b = this->ComputeBmatrixAt(gp);
d = mat->ComputeConstitutiveMatrix(gp,this);
dV = this->computeVolumeAround(gp);
db = d->Times(b);
stiffnessMatrix->plusProduct(b,db,dV);
delete d; delete db; delete b;
}
return stiffnessMatrix->symmetrized();
}
This method shows that the construction of two matrices,
namely
ep
D and B , contribute to build the stiffness matrix.
Integration over the element is achieved with a loop over the
Gauss points of the element. In sections 2.1.1.1 and 2.1.1.2,
the construction of
B (or
B
) matrix will be scrutinized. In