Contacts

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

The concept

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.

Nodal Search

Each element (and contact surfaces included in that element) has so search the solution space for nodes which can be in contact. For each node, it has to calculate the distance from the surface and determine if contact is imminent. Imagine now, that you have 100000 nodes in the model you want to solve and almost as many elements and it is easy to conclude that searching each node against each surface for each timestep, can take a considerable amount of time. Clearly, some kind of limitations on how many nodes to search must be made. One method, implemented in Dyna (another code) is to use so called bucket search. This means that the solution space is divided into buckets and the element residing inside a certain bucket will only check the nodes inside that bucket and neighbouring buckets. This approach is brought even further in Impact and has in fact been considered from the start.

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.

The Implementation

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.

Surface contact

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:

  1. Use the three corner nodes to determine the plane of projection
  2. Loop through all nodes between the corner nodes, starting with the node with the smallest x-coordinate
  3. Check if the node is close enough in Y and Z to be in contact range.
  4. Project the node onto the plane
  5. Check if the node is within the triangle surface
  6. If it is, calculate the distance from the plane
  7. If within defined thickness, calculate the repelling force
  8. Apply the force onto the node. Apply reaction force onto the element nodes
  9. Proceed to check the next node until the other end node of the element is reached (the one with the largest x-coordinate).

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

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.

Contact_Line elements

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:

  1. Loop from the node with the smallest x-coordinate to the node with the largest x-coordinate
  2. Check if the node has any contact_line elements attached to it.
  3. If so, loop through these elements one by one and..
  4. Check if parallel (then do a different evaluation)
  5. If not, calculate contact point and distance
  6. Apply contact force to element and reaction force to itself
  7. End loop of elements
  8. End loop of nodes

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.