8.1.14 Non-member functions

The following functions operate on or return Formex objects, but are not part of the Formex class.8.2

connect( Flist,nodid=None,bias=None,loop=False)
Return a Formex which connects the formices in Flist.

Flist is a list of formices, nodid is an optional list of nod ids and bias is an optional list of element bias values. All lists should have the same length. The returned Formex has a plexitude equal to the number of formices in Flist. Each element of the Formex consist of a node from the corresponding element of each of the Formices in Flist. By default this will be the first node of that element, but a nodid list may be given to specify the node ids to be used for each of the formices. Finally, a list of bias values may be given to specify an offset in element number for the subsequent Formices.

If loop is False, the length of the Formex will be the minimum length of the formices in Flist, each minus its respective bias. By setting loop True however, each Formex will loop around when its end is encountered, and the length of the resulting Formex is the maximum length in Flist.

interpolate( F,G,div,swap=False)
Create interpolations between two formices.

F and G are two Formices with the same shape. v is a list of floating point values. The result is the concatenation of the interpolations of F and G at all the values in div.

An interpolation of F and G at value v is a Formex H where each coordinate Hijk is obtained from Hijk = Fijk + v * (Gijk-Fijk). Thus, a Formex interpolate(F,G,[0.,0.5,1.0]) will contain all elements of F and G and all elements with mean coordinates between those of F and G.

As a convenience, if an integer is specified for div, it is taken as a number of division for the interval [0..1]. Thus, interpolate(F,G,n) is equivalent with interpolate(F,G,arange(0,n+1)/float(n))

The swap argument sets the order of the elements in the resulting Formex. By default, if $n$ interpolations are created of an $m$-element Formex, the element order is in-Formex first ($n$ sequences of $m$ elements). If swap==True, the order is swapped and you get $m$ sequences of $n$ interpolations.

readfile( file,sep=',',plexitude=1,dimension=3)
Read a Formex from file.

This convenience function uses the numpy fromfile function to read the coordinates of a Formex from file.

file is either an open file object or a string with the name of the file to be read. sep is the separator string between subsequent coordinates. There can be extra blanks around the separator, and the separator can be omitted at the end of line. If an empty string is specified, the file is read in binary mode.

The file is read as a single stream of coordinates; the arguments plexitude and dimension determine how these are structured into a Formex. plexitude is the number of points that make up an element. The default is to return a plex-1 Formex (unconnected points). dimension is the number of coordinates that make up a point (2 or 3). As always, the resulting Formex will be 3D. The total number of coordinates on the file should be a multiple of plexitude * dimension.

vectorPairAreaNormals( vec1,vec2)
Compute area of and normals on parallellograms formed by two vectors.

vec1 and vec2 are (n,3)-shaped arrays holding collections of vectors. The result is a tuple of two arrays:

Both values are calculated from the cross prduct of vec1 and vec2, which indeed results in area * normal.

vectorPairArea( vec1,vec2)
Compute the area of the parallellogram formed by two vectors.

This returns the first part of vectorPairAreaNormals(vec1,vec2).

vectorPairNormals( vec1,vec2,normalized=True)
Compute the normal vectors to pairs of two vectors.

With normalized=True, this returns the second part of vectorPairAreaNormals(vec1,vec2).

With normalized=False, returns unnormalized normal vectors. This does not use the vectorPairAreaNormals function and is provided only to save computing time with very large arrays when normalization is not required. It is equivalent to cross(vec1,vec2).

def polygonNormals( x)
Compute normals in all points of polygons in x.

x is an (nel,nplex,3) coordinate array representing a (possibly not plane) polygon.

The return value is an (nel,nplex,3) array with the unit normals on the two edges ending in each point.

pattern( s)
Return a line segment pattern created from a string.

This function creates a list of line segments where all nodes lie on the gridpoints of a regular grid with unit step. The first point of the list is [0,0,0]. Each character from the given string is interpreted as a code specifying how to move to the next node.
Currently defined are the following codes:
0 = goto origin [0,0,0]
1..8 move in the x,y plane
9 remains at the same place
When looking at the plane with the x-axis to the right,
1 = East, 2 = North, 3 = West, 4 = South, 5 = NE, 6 = NW, 7 = SW, 8 = SE.
Adding 16 to the ordinal of the character causes an extra move of +1 in the z-direction. Adding 48 causes an extra move of -1. This means that 'ABCDEFGHI', resp. 'abcdefghi', correspond with '123456789' with an extra z +/-= 1. This gives the following schema:

                 z+=1             z unchanged            z -= 1
            
             F    B    E          6    2    5         f    b    e 
                  |                    |                   |     
                  |                    |                   |     
             C----I----A          3----9----1         c----i----a  
                  |                    |                   |     
                  |                    |                   |     
             G    D    H          7    4    8         g    d    h
The special character '\' can be put before any character to make the move without making a connection. The effect of any other character is undefined. The resulting list is directly suited to initialize a Formex.

translationVector( dir,dist)
Return a translation vector in direction dir over distance dist

rotationMatrix( angle,axis=None)
Return a rotation matrix over angle, optionally around axis.

The angle is specified in degrees. If axis==None (default), a 2x2 rotation matrix is returned. Else, axis should be one of [ 0,1,2] and specifies the rotation axis in a 3D world. A 3x3 rotation matrix is returned.

rotationAboutMatrix( angle,axis)
Return a rotation matrix over angle around an axis thru the origin.

The angle is specified in degrees. Axis is a list of three components specifying the axis. The result is a 3x3 rotation matrix in list format. Note that: rotationAboutMatrix(angle,[1,0,0]) == rotationMatrix(angle,0) rotationAboutMatrix(angle,[0,1,0]) == rotationMatrix(angle,1) rotationAboutMatrix(angle,[0,0,1]) == rotationMatrix(angle,2) but the latter functions are more efficient.

equivalence( x,nodesperbox=1,shift=0.5,rtol=1.e-5,atol=1.e-5)
Finds (almost) identical nodes and returns a compressed list.

The input x is an (nnod,3) array of nodal coordinates. This functions finds the nodes that are very close and replaces them with a single node. The return value is a tuple of two arrays: the remaining (nunique,3) nodal coordinates, and an integer (nnod) array holding an index in the unique coordinates array for each of the original nodes.

The procedure works by first dividing the 3D space in a number of equally sized boxes, with a mean population of nodesperbox. The boxes are numbered in the 3 directions and a unique integer scalar is computed, that is then used to sort the nodes. Then only nodes inside the same box are compared on almost equal coordinates, using the numpy allclose() function. Two coordinates are considered close if they are within a relative tolerance rtol or absolute tolerance atol. See numpy for detail. The default atol is set larger than in numpy, because pyformex typically runs with single precision. Close nodes are replaced by a single one.

Currently the procedure does not guarantee to find all close nodes: two close nodes might be in adjacent boxes. The performance hit for testing adjacent boxes is rather high, and the probability of separating two close nodes with the computed box limits is very small. Nevertheless we intend to access this problem by repeating the procedure with the boxes shifted in space.



Footnotes

... class.8.2
They might be implemented as class methods in future releases.