Page 309 - The Combined Finite-Discrete Element Method
P. 309
292 ALGORITHM IMPLEMENTATION
#define YMATINV2(m,minv,det)\
{ det=m[0][0]*m[1][1]-m[1][0]*m[0][1]; \
minv[0][0]= m[1][1]/det; minv[1][0]=-m[1][0]/det;\
minv[0][1]=-m[0][1]/det; minv[1][1]= m[0][0]/det; \
}
Listing 10.1 The MACRO for small matrices.
#define V3DTranToGl(x1,y1,z1,a,b,c,x2,y2,z2,x3,y3,z3)\
{ (x1)=(a)*(x2)+(b)*(x3)+(c)*((y2)*(z3)-(z2)*(y3)); \
(y1)=(a)*(y2)+(b)*(y3)+(c)*((z2)*(x3)-(x2)*(z3)); \
(z1)=(a)*(z2)+(b)*(z3)+(c)*((x2)*(y3)-(y2)*(x3));\
}
Listing 10.2 Transformation of vector components from the global triad of orthonormal vectors
to a local triad of orthonormal vectors.
combined finite-discrete element algorithms. One of the most important such features
is MACROS. In the C language, a MACRO is almost like a function (subroutine, for
readers familiar with FORTRAN). The difference is that wherever a MACRO is called,
the compiler actually includes the body of the MACRO in the place where the call to the
MACRO is made. In other words, no actual function call occurs. At compilation time, the
body of the MACRO is itself copied into the code together with all the local variables
being passed directly to the MACRO.
For instance, a macro for 2D matrix inversion is shown in Listing 10.1. The macro
takes as input matrix m, calculates the determinant, calculates the inverse matrix and
returns the determinant det and the inverse matrix minv. A very frequent call to this
macro saves the CPU overheads of calling a function, making that part of the program in
whichthis macrois calledrun faster.
Transformation of vector components from one triad of orthogonal unit vectors to
another triad of unit vectors can be elegantly implemented using macros, thus making
the code shorter and more transparent without decreasing the CPU efficiency. The macro
used for the transformation of vector components from a local triad into a global triad is
shown in Listing 10.2.
The macro takes vector components in the local triad (a,b,c) and returns vector com-
ponents in the global triad (x1,y1,z1). Global components of the two unit vectors of the
local triad (components x2,y2,z2 and x3,y3,z3) are used in this transformation. The third
unit vector of the local triad is calculated using the cross product of the first two vectors,
i.e. the third vector is equal to the cross product of vectors (x2,y2,z2)and (x3,y3,z3).
10.2 DYNAMIC MEMORY ALLOCATION
The dynamic memory allocation works in such a way that at the time of compilation of
the code, no memory is allocated for dynamic variables, arrays, etc. Memory is instead
allocated as and when required at run time. As soon as this memory is not required it is
returned, and can be used again. It would appear that allocating the memory during the
run time can only slow down the program. This is not necessarily the case. For instance,