Using cba.exe as external solver for continuous beam analysis

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

Using cba.exe as external solver for continuous beam analysis

Post by chakkree »

1. Download cba from webpage http://cbeam.sourceforge.net/
2. Unzip and find "cba.exe" then copy to folder "FreeCAD_0.1x.xxx/bin".
3. Create floder to save temp file, and assign to variable "data_PATH "
4. Run Macro for test 2 span continuous beam example. using Plot module to display Bending Moment Diagram and Shear Force Diagram.


Code: Select all

"""
SPANS 5.8 4.2              
INERTIA 3.69e-5 3.69e-5     
ELASTICITY 2.1e8          
CONSTRAINTS -1 0 -1 0 -1 0  
LOAD 1 1 10.0 5.0 0 0    
LOAD 2 1 10.0 5.0 0 0    
FACTORS 1.35 1.5  
"""

import Plot
import subprocess


data_PATH = "D:\\your_data_path\\cba\\"

ContBeam1 = {
   'SPANS': [ 5.8 , 4.2] ,
   'INERTIA' : [3.69e-5,3.69e-5 ],
   'ELASTICITY' : 2.1e8 ,
   'CONSTRAINTS' : [ [-1,0] , [-1,0] ,[-1,0] ] ,
   'LOAD' : [
       [  1 ,  1 , 10.0 , 5.0 , 0 , 0] ,
       [  2 ,  1 , 10.0 , 5.0 , 0 , 0] 
   ] ,
   'FACTORS' : { 'DL':1.35 , 'LL':1.5 }
}

def make_cba_inputTextFile(contBeam):
    text1 = "SPANS"    
    for L in contBeam['SPANS']:
        text1 += ' {}'.format(L)
    text1 += '\n'
    
    text1 += "INERTIA"    
    for I in contBeam['INERTIA']:
        text1 += ' {}'.format(I)
    text1 += '\n' 
    
    text1 += "INERTIA {}".format(contBeam['ELASTICITY'])
    text1 += '\n'    
    
    text1 += "CONSTRAINTS"    
    for retrain in contBeam['CONSTRAINTS']:
        text1 += ' {} {}'.format( retrain[0] , retrain[1])
    text1 += '\n' 
    
    for Load in contBeam['LOAD']:
        text1 += "LOAD"
        #text1 += ' {} {} {} {} {} {}' .format( Load[0] , Load[1] )
        for i in Load:
            text1 += ' {}'.format(i)
        text1 += '\n'
    
    
    text1 += "FACTORS {} {}".format( contBeam['FACTORS']['DL'] , contBeam['FACTORS']['LL'])
    text1 += '\n'
    
    return text1

    
#txt1 = make_cba_inputTextFile(ContBeam1)

inputFile = data_PATH + 'tempCBA.cba'
outputFile = data_PATH + 'tempCBA.out'
plotFile = data_PATH + 'tempCBA.plt'


f = open(inputFile, 'w')
f.write(make_cba_inputTextFile(ContBeam1))
f.close()

subprocess.call( ['cba.exe'  , '-i' , inputFile , '-o' , outputFile , '-p' , plotFile ] , shell=True )


f = open(plotFile)
lines =f.read().split('\n')
f.close()

lines.pop(0); lines.pop(0); lines.pop(-1)  ## delete 2 first rows
#x	Mdmax	Mdmin	Vdmax	Vdmin	dmax	dmin
x = []
Mdmax = []
Mdmin = []
Vdmax = []
Vdmin = []
dmax = []
dmin = []

for i in lines:
    data=i.split()
    x.append(  float (data[0]) )
    Mdmax.append( float (data[1]) ); Mdmin.append( float (data[2]) )
    Vdmax.append( float (data[3]) ); Vdmin.append( float (data[4]) )
    dmax.append( float (data[5]) ); dmin.append( float (data[6]) )
    

#Plot.figure("Continuous Beam Analysis Result")
Plot.figure("BMD")
Plot.plot(x,Mdmax) ; Plot.plot(x,Mdmin)

Plot.figure("SFD")
Plot.plot(x,Vdmax) ; Plot.plot(x,Vdmin)

Plot.figure("Deflections")
Plot.plot(x,dmax) ; Plot.plot(x,dmin)

----------------------------------------
OS: Windows 8
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6668 (Git)
Python version: 2.7.8
Attachments
cba_web.png
cba_web.png (145.43 KiB) Viewed 2732 times
BMD.png
BMD.png (41.23 KiB) Viewed 2732 times
SFD.png
SFD.png (37.03 KiB) Viewed 2732 times
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Using cba.exe as external solver for continuous beam analysis

Post by chakkree »

Not Complete. ContBeam.cba can show beam and support(Ry only).
Next, try to read output file to a result properties and use for display analysis results.

Code: Select all

"""
   ContBeam.py  --- Version 0.1.20170108

   cba -- continuous beam analysis

"""

import FreeCAD , Part
from FreeCAD import Vector
from math import radians

class cba:
    def __init__(self,obj):
        obj.addProperty("App::PropertyFloatList","Spans","cba","Length of the cont beam spans").Spans=[4,4]
        obj.addProperty("App::PropertyStringList","Constraints","cba","Constraints of the cont beam").Constraints=['-1 0','-1 0' ,'-1 0']
        obj.addProperty("App::PropertyStringList","Loads","cba","Loads of the cont beam").Loads=['1 1 1000.0  0 0 0','1 1 1000.0  0 0 0' ]
        obj.addProperty("App::PropertyFloatList","Inertia","cba","Inertia of the cont beam").Inertia=[0.2*0.4**2/12. , 0.2*0.4**2/12.]
        obj.addProperty("App::PropertyFloat","E","cba","ELASTICITY of the cont beam").E=2.04e6*100*100
        obj.addProperty("App::PropertyFloatList","Factor","cba","Factor = DL+ LL ").Factor=[1.0,1.0]
        
        obj.addProperty("App::PropertyFloatList","x","results","x").x=[]
        obj.addProperty("App::PropertyFloatList","Mmin","results","Mmin").Mmin=[]
        obj.addProperty("App::PropertyFloatList","Mmax","results","Mmin").Mmax=[]
        obj.addProperty("App::PropertyFloatList","Vmin","results","Vmin").Vmin=[]
        obj.addProperty("App::PropertyFloatList","Vmax","results","Vmin").Vmax=[]
        obj.addProperty("App::PropertyFloatList","dmin","results","dmin").dmin=[]
        obj.addProperty("App::PropertyFloatList","dmax","results","dmin").dmax=[]
        
        obj.setEditorMode("x", 1) 
        obj.setEditorMode("Mmin", 1); obj.setEditorMode("Mmax", 1)
        obj.setEditorMode("Vmin", 1); obj.setEditorMode("Vmax", 1)
        obj.setEditorMode("dmin", 1); obj.setEditorMode("dmax", 1)
        obj.Proxy = self
    
    def execute(self, obj):
        geom = []
        line =Part.LineSegment( Vector(0,0,0),Vector(sum(obj.Spans)*1000,0,0)  )
        geom.append(line.toShape())  

        # support Ry only
        restY = int(obj.Constraints[0].split()[0])
        if restY!=0:
            r1 = Part.makeCone(50,0,100,Vector(0,0,-100))
            geom.append(r1)
        x = 0.0
        for i in range(1, len(obj.Constraints)):
            restY = int(obj.Constraints[i].split()[0])
            
            x += float( obj.Spans[i-1] )
            Msg('%d  %d  %f  \n'%(i,restY,x) );
            if restY!=0:
                iSup = Part.makeCone(50,0,100,Vector(x*1000,0,-100))
                geom.append(iSup)
        # Load
        for iStr in obj.Loads:
            #Msg(iStr)
            iLoad = iStr.strip().split()
            Msg(iLoad)
            Msg('\n')
         


        compound = Part.Compound(geom)
        compound.Placement = obj.Placement
        #obj.Shape = line.toShape()
        obj.Shape = compound

class ViewProvider_cba:
    def __init__(self, obj):
        "Set this object to the proxy object of the actual view provider"
        obj.addProperty("App::PropertyColor","Color","Octahedron","Color of the octahedron").Color=(1.0,0.0,0.0)
        obj.Proxy = self

def makeContBeam(name='cba' , SPANS=[3,3]):
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
    cba(a)
    cba.Spans =SPANS
    ViewProvider_cba(a.ViewObject) 
    return a
    

if __name__=='__main__':
    cBeam_Line1 = makeContBeam('cBeam_Line1' , [4,4])
    cBeam_Line2 = makeContBeam('cBeam_Line2' , [4,4] )
    cBeam_Line2.Placement.Base.y=4000
    cBeam_Line3 = makeContBeam('cBeam_Line3' , [4,4] )
    cBeam_Line3.Placement.Base.y=8000

    cBeam_LineA = makeContBeam('cBeam_LineA' , [4,4])
    cBeam_LineA.Placement.Rotation.Angle=radians(90)
    cBeam_LineB = makeContBeam('cBeam_LineB' , [4,4] )
    cBeam_LineB.Placement.Rotation.Angle=radians(90)
    cBeam_LineB.Placement.Base.x=4000
    cBeam_LineC = makeContBeam('cBeam_LineC' , [4,4] )
    cBeam_LineC.Placement.Rotation.Angle=radians(90)
    cBeam_LineC.Placement.Base.x=8000


    FreeCAD.ActiveDocument.recompute()
    Msg('Done!!\n\n')
result.
ContBeam_cba_01.png
ContBeam_cba_01.png (244.9 KiB) Viewed 1587 times
Post Reply