Test read data from Frame3DD file.

Show off your FreeCAD projects here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Test read data from Frame3DD file.

Post by chakkree »

Try to get joint and element data from Frame3DD file format.
Example file is download from Frame3DD Example.
Now, can show only joints and members not included reactions, loads, displacment, internal forces.
ReadData_from_Frame3DD_3.png
ReadData_from_Frame3DD_3.png (597.45 KiB) Viewed 6145 times

source code : ReadFile2Model.py **** important note: if data file is not correct format,it will be run infinite loop(Fixed in Version2) ****

Code: Select all

import FreeCAD , Draft
from FreeCAD import Vector


class Node:
    def __init__(self, id , x,y,z):
        self.x = x
        self.y = y
        self.z = z
        self.id = str(id)

# elmnt n1     n2    Ax     Asy     Asz     Jx     Iy     Iz     E     G     roll  density
class Member:
    def __init__(self, id , n1,n2):
        self.n1 = n1
        self.n2 = n2
        self.id = str(id)

NodeList = {}
MemberList = {}

ProjectDescription = ''
numNode = 0

state = 1

path = 'D:\\StructurallAnalysis\\Frame3DD\\Data\\'


#factor = 25.42  ; fName = path+'exA.3dd'
#factor = 1.0  ;fName = path+'exB.3dd'
#factor = 25.42  ; fName = path+'exC.3dd'
factor = 25.42  ; fName = path+'exD.3dd'
#factor = 25.42  ; fName = path+'exG.3dd'
#factor = 25.42  ; fName = path+'exF.3dd'

fp = open(fName)
while 1:
    line = fp.readline()
    
    if not line:
        break
    line = line.strip()
    if len(line)==0:
        continue
    if line[0]=='#':
        continue
    # process
    if state==1: 
        ProjectDescription = line
        Msg(ProjectDescription); Msg('\n\n')
        state += 1
        continue
    if state==2: # Node
        Msg('State2: ');Msg(line); Msg('\n')
        data = line.split()
        numNode =  int(data[0])
        nodeCount = 1
        while 1:
            line = fp.readline().strip()
            if len(line)==0 or line[0]=='#':
                continue
            #Msg( line ); Msg('\n')
            dataNode = line.split()
            NodeList[dataNode[0]] =  Node(dataNode[0] , 
                       float(dataNode[1]) ,float( dataNode[2]) , float( dataNode[3]) )
            nodeCount+=1
            if nodeCount>numNode:
                break
        state += 1
        continue
    if state==3: # Reaction
        Msg('State3: '); Msg(line); Msg('\n')
        data = line.split()
        numReaction =  int(data[0])
        if numReaction==0:
            state += 1
            continue
        reactionCount = 1
        while 1:
            line = fp.readline().strip()
            if len(line)==0 or line[0]=='#':
                continue
            #Msg( line ); Msg('\n')
            dataReaction = line.split()
            #NodeList[dataNode[0]] =  Node(dataNode[0] , 
            #           float(dataNode[1]) ,float( dataNode[2]) , float( dataNode[3]) )
            reactionCount+=1
            if reactionCount>numReaction:
                break
        state += 1
        continue
    #Msg('Member Data\n')
    if state==4: # Member
        Msg('State4: '); Msg(line); Msg('\n')
        data = line.split()
        numMember =  int(data[0])
        memberCount = 1
        while 1:
            line = fp.readline().strip()
            if len(line)==0 or line[0]=='#':
                continue
            Msg( line ); Msg('\n')
            dataMember = line.split()
            MemberList[dataMember[0]] =  Member(dataMember[0] ,dataMember[1] , dataMember[2])  
            memberCount+=1
            if memberCount>numMember:
                break
        state += 1
        continue

    #Msg( line ); Msg('\n')


GrpNode =FreeCAD.ActiveDocument.getObject('Nodes')
GrpNode.removeObjectsFromDocument()
for id in NodeList:
    #Msg(id ); Msg( iNode) ; Msg('\n')
    iPoint = Draft.makePoint(NodeList[id].x*factor,NodeList[id].y*factor,NodeList[id].z*factor)
    iPoint.Label = id
    iPoint.ViewObject.PointColor = (0.667,0.000,0.000)
    GrpNode.addObject(iPoint)

GrpMember =FreeCAD.ActiveDocument.getObject('Members')
GrpMember.removeObjectsFromDocument()
for id in MemberList:
    n1 = MemberList[id].n1
    n2 = MemberList[id].n2
    points=[ Vector(NodeList[n1].x*factor,NodeList[n1].y*factor,NodeList[n1].z*factor ) ,
                 Vector(NodeList[n2].x*factor,NodeList[n2].y*factor,NodeList[n2].z*factor) ] 
    iMember = Draft.makeWire(points,closed=False,face=True,support=None)
    iMember.Label = id
    GrpMember.addObject(iMember)

Msg('Done!!\n\n')
result file.
TestFrame3DD.zip
(406.6 KiB) Downloaded 148 times
Last edited by chakkree on Tue Dec 27, 2016 10:35 am, edited 1 time in total.
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Test read data from Frame3DD file.

Post by microelly2 »

Thank you for sharing this.
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Test read data from Frame3DD file.

Post by chakkree »

ReadFile2Model.py Version 2 : Fixed trap of infinite loop.

Code: Select all

"""
   Version2
"""

import datetime

import FreeCAD , Draft
from FreeCAD import Vector


class Node:
    def __init__(self, id , x,y,z):
        self.x = x
        self.y = y
        self.z = z
        self.id = str(id)

# elmnt n1     n2    Ax     Asy     Asz     Jx     Iy     Iz     E     G     roll  density
class Member:
    def __init__(self, id , n1,n2):
        self.n1 = n1
        self.n2 = n2
        self.id = str(id)

NodeList = {}
MemberList = {}

ProjectDescription = ''
numNode = 0

state = 1

path = 'D:\\StructurallAnalysis\\Frame3DD\\Data\\'


#factor = 25.42  ; fName = path+'exA.3dd'
#factor = 1.0  ;fName = path+'exB.3dd'
#factor = 25.42  ; fName = path+'exC.3dd'
#factor = 25.42  ; fName = path+'exD.3dd'
#factor = 25.42  ; fName = path+'exG.3dd'
factor = 25.42  ; fName = path+'exH.3dd'


# read file to list
lines = [line.rstrip('\n') for line in open(fName)]
# strip remark #
lines2 = []
for iLine in lines:
    pos = iLine.find('#')
    if pos>-1:
        lines2.append( iLine[:pos] )
    else:
        lines2.append( iLine )
# remove blank line
lines3 = []
for iLine in lines2:
    if len(iLine.strip())>0:
        lines3.append(iLine)

#for iLine in lines3:
#    Msg(iLine); Msg('\n')

ProjectDescription = lines3[0]
numNode = int(  lines3[1] )
numReactions = int(  lines3[numNode +2] )
numMembers = int(  lines3[numNode+ numReactions +3] )

Msg('numNode = %d\n'% numNode);
Msg('numReactions = %d\n'% numReactions);
Msg('numMembers = %d\n'% numMembers);

for i in range(0, numNode):
    dataNode = lines3[i+2].split()
    NodeList[dataNode[0]] =  Node(dataNode[0] , 
              float(dataNode[1]) ,float( dataNode[2]) , float( dataNode[3]) )

for i in range(0, numMembers):
    dataMember = lines3[i+numNode+ numReactions +4].split()
    MemberList[dataMember[0]] =  Member(dataMember[0] ,dataMember[1] , dataMember[2]) 
     

GrpNode =FreeCAD.ActiveDocument.getObject('Nodes')
if GrpNode!=None:
    GrpNode.removeObjectsFromDocument()
else:
    FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup","Nodes")
    GrpNode =FreeCAD.ActiveDocument.getObject('Nodes')
for id in NodeList:
    #Msg(id ); Msg( iNode) ; Msg('\n')
    iPoint = Draft.makePoint(NodeList[id].x*factor,NodeList[id].y*factor,NodeList[id].z*factor)
    iPoint.Label = 'N'+id
    iPoint.ViewObject.PointColor = (0.667,0.000,0.000)
    GrpNode.addObject(iPoint)

GrpMember =FreeCAD.ActiveDocument.getObject('Members')
if GrpMember!=None:
    GrpMember.removeObjectsFromDocument()
else:
    FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup","Members")
    GrpMember =FreeCAD.ActiveDocument.getObject('Members')

for id in MemberList:
    n1 = MemberList[id].n1
    n2 = MemberList[id].n2
    points=[ Vector(NodeList[n1].x*factor,NodeList[n1].y*factor,NodeList[n1].z*factor ) ,
                 Vector(NodeList[n2].x*factor,NodeList[n2].y*factor,NodeList[n2].z*factor) ] 
    iMember = Draft.makeWire(points,closed=False,face=True,support=None)
    iMember.Label = 'M'+id
    GrpMember.addObject(iMember)


Msg( datetime.datetime.now() )
Msg(' Done!!\n\n')
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Test read data from Frame3DD file.

Post by chakkree »

If Frame3DD file has many nodes and elements, speed of display model will slow.
Improve display speed by using pivy.coin.
ReadData_from_Frame3DD_5.png
ReadData_from_Frame3DD_5.png (303.66 KiB) Viewed 6077 times
ReadFile2Model_V3.py : use Coin3D for display nodes and elements.

Code: Select all

"""
   Version3
   improve display's speed using pivy.coin
"""

import datetime

import FreeCAD, FreeCADGui , Draft
from FreeCAD import Vector
from pivy import coin

class Node:
    def __init__(self, id , x,y,z):
        self.x = x
        self.y = y
        self.z = z
        self.id = str(id)

# elmnt n1     n2    Ax     Asy     Asz     Jx     Iy     Iz     E     G     roll  density
class Member:
    def __init__(self, id , n1,n2):
        self.n1 = n1
        self.n2 = n2
        self.id = str(id)

NodeList = {}
MemberList = {}

ProjectDescription = ''
numNode = 0

state = 1

path = 'D:\\StructurallAnalysis\\Frame3DD\\Data\\'


#factor = 25.42  ; fName = path+'exA.3dd'
#factor = 1.0  ;fName = path+'exB.3dd'
#factor = 25.42  ; fName = path+'exC.3dd'
#factor = 25.42  ; fName = path+'exD.3dd'
#factor = 25.42  ; fName = path+'exG.3dd'
factor = 25.42  ; fName = path+'exH.3dd'

# read file to list
lines = [line.rstrip('\n') for line in open(fName)]
# strip remark #
lines2 = []
for iLine in lines:
    pos = iLine.find('#')
    if pos>-1:
        lines2.append( iLine[:pos] )
    else:
        lines2.append( iLine )
# remove blank line
lines3 = []
for iLine in lines2:
    if len(iLine.strip())>0:
        lines3.append(iLine)

#for iLine in lines3:
#    Msg(iLine); Msg('\n')

ProjectDescription = lines3[0]
numNode = int(  lines3[1] )
numReactions = int(  lines3[numNode +2] )
numMembers = int(  lines3[numNode+ numReactions +3] )

Msg('numNode = %d\n'% numNode);
Msg('numReactions = %d\n'% numReactions);
Msg('numMembers = %d\n'% numMembers);

for i in range(0, numNode):
    dataNode = lines3[i+2].split()
    NodeList[dataNode[0]] =  Node(dataNode[0] , 
              float(dataNode[1]) ,float( dataNode[2]) , float( dataNode[3]) )

for i in range(0, numMembers):
    dataMember = lines3[i+numNode+ numReactions +4].split()
    MemberList[dataMember[0]] =  Member(dataMember[0] ,dataMember[1] , dataMember[2]) 
     

sg =FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
nodeGrpSep = coin.SoSeparator()
#nodeGrpSep = coin.SoGroup()

ma = coin.SoBaseColor()
ma.rgb = (170/255.,0,0)
nodeGrpSep.addChild(ma)

sg.addChild(nodeGrpSep)
for id in NodeList:
    iNodeSep = coin.SoSeparator()
    iNode = coin.SoSphere()
    iNode.radius.setValue(120.0)
    tr =  coin.SoTransform()
    tr.translation = Vector(NodeList[id].x*factor,NodeList[id].y*factor,NodeList[id].z*factor)

    iNodeSep.addChild(tr)
    iNodeSep.addChild(iNode)
    nodeGrpSep.addChild(iNodeSep)

memberGrpSep = coin.SoSeparator()
mat = coin.SoBaseColor()
mat.rgb = (0.1,0.1,0.1)
memberGrpSep.addChild(mat)
sg.addChild(memberGrpSep)
for id in MemberList:
    n1 = MemberList[id].n1
    n2 = MemberList[id].n2
    iMemberSep = coin.SoSeparator()
    pts = [[NodeList[n1].x*factor,NodeList[n1].y*factor,NodeList[n1].z*factor ],
           [NodeList[n2].x*factor,NodeList[n2].y*factor,NodeList[n2].z*factor]]
    co = coin.SoCoordinate3()
    co.point.setValues(0,len(pts),pts)
    iMember = coin.SoLineSet()
    iMember.numVertices.setValue(2)
    
    iMemberSep.addChild(co)
    iMemberSep.addChild(iMember)
    memberGrpSep.addChild(iMemberSep)

Msg( datetime.datetime.now() )
Msg(' Done!!\n\n')
User avatar
yorik
Founder
Posts: 13665
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: Test read data from Frame3DD file.

Post by yorik »

Awesome work as usual, chakkree! BTW, a user on my blog mentioned also Mastan2 and Bramantesap I had never heard about these two...
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Test read data from Frame3DD file.

Post by chakkree »

@microelly2 Thank you.

@Yorik I'm interested to find external solver for frame structure that can be used in FreeCAD.
I have two choices that can call by 'subprocess.Popen' command.
1) Frame3DD for 3d Frame and Truss analysis
2) cba continuous beam analysis

Frame3DD and cba have the same process like Calculix. Input Data is a text file and output is a text file, that can be manipulated like FEM Workbench. At First stage, I try to read a data file and display in graphic or 3D model.

Next, I'll use Spreadsheet for input and save data from a spreadsheet to CSV format and use subprocess to call Frame3DD compute the Frame data.

Mastan2 and Bramante, I'm no experience on both.
ulrich1a
Veteran
Posts: 1957
Joined: Sun Jul 07, 2013 12:08 pm

Re: Test read data from Frame3DD file.

Post by ulrich1a »

chakkree wrote:I'm interested to find external solver for frame structure that can be used in FreeCAD.
Calculix can do a frame analysis too. Calculix gives bending moment and shear forces, if asked for it. See here: http://web.mit.edu/calculix_v2.7/Calcul ... ode53.html

Code: Select all

By using the OUTPUT=2D parameter in the first step one can trigger the storage in the original beam nodes. The same averaging procedure applies as for the *NODE PRINT command. Section forces can be requested by means of the parameter SECTION FORCES. If selected, the stresses in the beam nodes are replaced by the section forces. They are calculated in a local coordinate system consisting of the 1-direction $ \mathbf{n_1}$, the 2-direction $ \mathbf{n_2}$ and 3-direction or tangential direction $ \mathbf{t}$ (Figure 70). Accordingly, the stress components now have the following meaning:

    xx: Shear force in 1-direction
    yy: Shear force in 2-direction
    zz: Normal force
    xy: Torque
    xz: Bending moment about the 2-direction
    yz: Bending moment about the 1-direction

The section forces are calculated by a numerical integration of the stresses over the cross section. To this end the stress tensor is needed at the integration points of the cross section. It is determined from the stress tensors at the nodes belonging to the cross section by use of the shape functions. Therefore, if the section forces look wrong, look at the stresses in the expanded beams (omitting the SECTION FORCES and OUTPUT=2D parameter). The SECTION FORCES parameter automatically triggers the OUTPUT=2D parameter for all results but the stresses. 
What you need to do, is to set up your frame in FreeCAD and write the inp-file. You have to edit the inp-file and add the parameters "SECTION FORCES" and "OUTPUT=2D" to *NODE FILE and *EL FILE.

At opening of the results, you will find the results under the following parameter:
shear force under SXX and SYY
normal force under SZZ
torque under SXY
Bending moments under SZX and SZY

Ulrich
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Test read data from Frame3DD file.

Post by chakkree »

@Ulrich Thank you so much.
Now, I already install CalculiX/Windows and start to learn about frame input. :D
paul18
Posts: 202
Joined: Sat Jul 19, 2014 7:44 pm
Location: France

Re: Test read data from Frame3DD file.

Post by paul18 »

I would suggest you to have a look to Code Aster ( http://www.code-aster.org/spip.php?rubrique2 ) - in my opinion Calculix is "light" for 1D elements. CAD can be imported into GMSH ( http://gmsh.info ) in Iges, Step tep or Brep format since the kernel is based on OpenCascade one (as FreeCAD).

Nb: have a look as well to Salomé project

Paul
ulrich1a
Veteran
Posts: 1957
Joined: Sun Jul 07, 2013 12:08 pm

Re: Test read data from Frame3DD file.

Post by ulrich1a »

paul18 wrote:I would suggest you to have a look to Code Aster
This could be true. Calculix has the advantage, that FreeCAD does the preprocessing for calculix in the FEM workbench. The frame construction can be done in FreeCAD. Although some build in restrictions should be removed, so that it is possible to constrain vertexes from sketches. But this should be discussed in the FEM-board.

The FEM-workbench is needing someone who writes a solver class for code aster, so we can also use code aster as a solver from the FEM workbench.

Ulrich
Post Reply