One of the most challenging parts of a dynamic finite element program is to design a simple and robust contact searching algorithm. The following chapter describes the one used by Impact
There are two major classes of contact algorithms. One searches nodes and checks them against a surface to determine if contact is imminent. The second class searches element surfaces and checks them against other surfaces (and edges) to determine shortest distance and thereby if contact is imminent.
The element to element concept is a bit trickier to implement since we want a concept that is as general as possible and not dependent on any element shape or type. The node to element type is simpler in design and well documented which makes it the Impact choice for now.
The distance from a node to a surface can be tricky to calculate if the surface is complex. If, however, the surface is a simple triangle, it is just a matter of linear algebra. We also want a general method which works for different type of elements. These two reasons has resulted in a concept where contact "finite surfaces" are used.
Any element uses one or several contact surfaces to handle the contact with other elements (or rather nodes). When the element is asked to check its contacts, the element in turn asks each of its surfaces to check for contacts. The resulting contact forces are then distributed onto the element nodes. Each element handles its own surfaces.
An example could be the BLT Quad shell element already implemented in Impact. Since this element is flexible and can bend, two flat triangular contact surfaces cannot accurately model the shell element. In this case, a number of four would be suitable. Each of them connected to a centre point on the shell element and to two corner nodes respectively. It would represent the curvature in a rough but simple way and even allow for self contact, i.e. when the element wraps around and contacts itself. This can happen for example in a fold of a member in crush.
The beauty with this approach is that every new element can use the suitable configuration of these surfaces thus allowing a very general implementation. The logic of contact search etc is all isolated and put inside the contact surface "element", making it easy to upgrade in the future.
Due to the object oriented approach in Impact, it is natural that each node should have a handle to the closest neighbouring node on both sides. This handle is constantly updated for the node when a new position is calculated. The "neighbour" knowledge of the nodes comes in handy now when nodal search must be done. Put simply, the element in question only needs to search the nodes in its immediate vicinity and that means searching all the nodes between it,s own nodes since these are on the edge of the element.
The neighbour search works only in one direction. Currently, this is programmed to be the global x-direction in the solution space. That means that any element must start with the one of it,s nodes with the smallest x-coordinate. Next, ask that one which neighbour node it has with higher x-coordinate. Check this node for contact. Next, ask that node for it,s neighbour and so on until it reaches that of it,s own nodes with the highest x-coordinate.
The amount of nodes to search now becomes much smaller than before and can usually be even smaller if the model is oriented optimally in the x-direction. For the shell element in this example, four contact surfaces needs to be checked against each node. All of this coding is isolated inside the element. The only command given to the element is to check for contact.
Contact handling in Impact is implemented through the use of contact elements. Contact sensing against surfaces are handled by the Contact_Triangle element and sensing against edges or beams are handled by the Contact_Line element. The implementation of these elements will now be described.
The basic element to sense surface contact is the triangle. A triangle defines a plane on which the node to be checked for contact can be projected. The process looks like this:
The Contact_Triangle element can be either used on its own by the user, just like an ordinary element, or embedded into another element to provide contact handling by default.
Embedding is a simple way of providing contact handling to your element. One example is the Shell_C0_3 element which uses one Contact_Triangle element. As the indata file is read in the Parse_GID method, a Contact_Triangle instance is created (unless the user has chosen not to). This instance is immediately fed the appropriate input into it's own Parse method, given the thickness of the element (which is also the contact thickness) and the shell elements own nodes.
The only thing remaining now is to run the appropriate methods on the contact element as the various methods of the shell element are run. For example, as the calculateContactForces method is run, the shell element only executes the same method on the embedded contact element. Some elements may require several embedded contact elements and it is up to the programmer to make sure they are all executed in the right manner. Have a look in the Shell_C0_3 element to see how the implementation has been made.
The Contact_Line element is used to detect contacts between line segments. This type of contact is useful in rods, beams and edges of shell or solid elements. It differs a bit from the surface to node contact in that contact checks are only made between line elements and nodes are not involved. This makes the scan somewhat more complicated and also more difficult to get computationally effective.
The algorithm is as follows:
Similar to the Contact_Triangle element, the Contact_Line element has no stiffness and can therefore be embedded in various elements. The element has a contact diameter. Any other contact_Line element coming within this diameter will sense contact.