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,
   304   305   306   307   308   309   310   311   312   313   314