Fem constraint contact

About the development of the FEM module/workbench.

Moderator: bernd

User avatar
Posts: 7711
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Fem constraint contact

Postby bernd » Thu Mar 21, 2019 2:17 pm

Qumbetlian wrote:
Sun Mar 17, 2019 7:34 pm
If someone can tell me how to bind my scrypt to "Create auto contact for compound object" button, I would be gratefully.
check branch https://github.com/berndhahnebach/FreeC ... utocontact there is only one commit in the regard of autocontact, the head commit. You should find your way through. If not do not hestiate to ask ...
Posts: 4
Joined: Fri Mar 15, 2019 6:28 am

Re: Fem constraint contact

Postby Qumbetlian » Fri Mar 22, 2019 1:57 pm

I improved my python script for automatically detecting contacts.
Now it can be set to not detect unuseful contacts between faces that are in contact but they are located on the same side (are not face to face) or if are perpendicular each other. Even more than that, by setting some parameters It can detect only contacts that are on a surface, or only contacts between faces that are tangent or virtually tangent if they get closer with a specified distance. This is useful for assembly that have screw joints.
Here is the new cod:

Code: Select all

from PySide import QtCore, QtGui
import FreeCAD
import Fem

MinimumDistance=0.2                             # Minimum distance between faces for which they are considered in contact
DetectOnlyFullSurfaceContacts=False              # Only that faces that have contact between them on a surface whose area is non zero are detected 
DetectOnlyTangencyContacts=True                 # Only that faces that have a tangential contact or can have a tangential contact if getting closer each other, with  a distance defined in "MinimumDistance", are detected. Intersected faces are excluded
DetectTangencyOnlyByLine=False                   # Among faces that have a tangential contact, only faces that have a contact between them along a line or curve, are detected (not point contact)
# If all above variable are "False", then any pair of faces closer than "MinimumDistance" are considered in contact, including intersected faces
Slope = 1000000                         # Contact stiffness
Friction = 0.3                          # Friction 
Scale = 1                               # Scale
TangencyError = 0.0001

def areSurfacesInContact(face_1,face_2):        # Detect if faces are in contact on a surface whose area is not zero
    _result = _com.Area > 0
    return _result

def areSurfacesTangent(face_1, face_2, distance, only_by_line=False):   # Detect if faces are in tangential contact or can be in tangential contact
    # Getting the normal on the surface through the first point closest toward another one surface
#    print("Difference of tangent vectors = ", (_norm_1+_norm_2).Length)
    if (_norm_1+_norm_2).Length < TangencyError:
        if only_by_line:
            if len(distance[1]) < 2: return False
            # Getting the normal on the surface through the second point closest toward another one surface
            if (_norm_1+_norm_2).Length < TangencyError: return True
        else: return True
    return False

def searchContacts(bodiesGroup): # Find the contacts between each surface of first body and surfaces of the rest of bodies
    if len(bodiesGroup) <= 1:
        return _contacts
    _contacts=searchContacts(_rest_of_bodies) # Recursively search contacts
    for _face in _first_body.Shape.Faces:  # Browse the list of shapes of the first body
        for _neighbour_body in _rest_of_bodies: # Browse the list of neighbour body
            for _neighbour_face in _neighbour_body.Shape.Faces: # browse the list of shapes for each body
#                print("    ****Distance from face ", i, " of ", _first_body.Name, " to the face ", j, " of ", _neighbour_body.Name, " is ", _dist)
                if _dist[0] <= MinimumDistance:
                    if DetectOnlyFullSurfaceContacts:   # Add only full surface contacts
                        if areSurfacesInContact(_face, _neighbour_face):
                            print("Adding contact due to surfaces in full contact")
                            _contacts.append([i,j]) # Appending indexes of faces in contact.Iindexes are according to number of faces checked in current instance of function
                    elif DetectOnlyTangencyContacts:    # Add only tangential contacts
                        if areSurfacesTangent(_face, _neighbour_face, _dist, DetectTangencyOnlyByLine):
                            print("Adding contact due to surfaces tangency")
                        print("Adding all contacts between surfaces closer than ", MinimumDistance)
    for k in range(0,_prev_faces): # Correcting the indexes returned from the previous instance according to number of faces founded in the current instance
    for k in range(_prev_faces,len(_contacts)): # Correcting the index of faces belonging to the rest of bodies according to number of faces belonging to the first body
    return _contacts

def addContacts(facesPairs, group): # Adding contacts according to the faces pairs given in first argument
    _active = FemGui.getActiveAnalysis()
    for _pair in facesPairs:
        _obj = FreeCAD.activeDocument().addObject("Fem::ConstraintContact","FemConstraintContact")
        _obj.Slope = Slope
        _obj.Friction = Friction
        _obj.Scale = Scale
        _obj.References = [(group,"Face"+str(_pair[0]+1)),(group,"Face"+str(_pair[1]+1))]
def errorDialog(msg):
    # Create a simple dialog QMessageBox
    # The first argument indicates the icon used: one of QtGui.QMessageBox.{NoIcon, Information, Warning, Critical, Question} 
    _diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error in AutoContacts', msg)

class Error(Exception):
   """Base class for other exceptions"""

class ActiveAnalysis(Error):
   """Raised when something go wrong with analyse"""

    if not FemGui.getActiveAnalysis():
        raise ActiveAnalysis
    for obj in FreeCAD.ActiveDocument.Objects:  # seach all objects in document
        objName = obj.Name
        objLabel = obj.Label
        if 'Compound' in objName: # detect if an oject is compound
            group=App.ActiveDocument.getObject(objName).OutList # get the list of members object
            for member in group:
                if member.Shape.Faces:  # If member is having faces, then add him in group
                    print("Not a Shape")
            if len(contacts): addContacts(contacts, obj)
except ActiveAnalysis:
    errorDialog("There is not an active analysis.\nPlease create a FEM analyse first!")
except Exception:
    print("Not object")
But now my problem is about Calculix. I have the following example: a body made in TPU through is passing a steel wire. I want to simulate the deformation of TPU body and wire, but Calculix give me a lot of errors. It's seem That Calculix not interact well with sliding contacts that have large displacements. This is may supposition after I tried two days to solve this problem. Can someone tell me if Calculix can solve this problem or not?

Here is a snapshot:
FEA sliding contact problem.jpg
FEA sliding contact problem.jpg (152.06 KiB) Viewed 185 times
Posts: 382
Joined: Wed Apr 29, 2015 12:41 pm

Re: Fem constraint contact

Postby makkemal » Wed Apr 10, 2019 11:17 am

Sorry for being absent
I figured out what was going wrong it seems some of the functions I used was for python 2.7 switching over to 3.6 gives different results
Hopefully I get enough time to fix this

Posts: 382
Joined: Wed Apr 29, 2015 12:41 pm

Re: Fem constraint contact

Postby makkemal » Wed Apr 24, 2019 10:49 am

Basic code working again

Code: Select all

Con2.PNG (34.68 KiB) Viewed 81 times
Con1.PNG (70.08 KiB) Viewed 81 times

Some minor issue with the more complicated ones