Years ago I wrote a program in Fortran for a structural analysis class. At the time I had very little programming experience and mottled my way through the assignment. Fast forward to now and I'm attempting to teach myself Python 3. I figured I'd would try to convert the old program from Fortran to Python. I've made some good progress but I've hit a wall. I've got the program running to the point where all the element stiffness matrices are defined and combined into the structure stiffness matrix using the code number technique. The structure stiffness matrix is triangular. At this point in the Fortran code, it calls a subroutine which I believe solves for d in [K]d = p using Gauss Elimination. Here's the Fortran code:

      DIMENSION BGK(100,30),XL(60),COSX(60),COSY(60),COSZ(60),SK(6,6),
     1AR(60),NC(60,6),QL(100),P(60)
      OPEN(UNIT = 2, FILE = '3DTRUSS.OUT', STATUS = 'UNKNOWN')
      PRINT 4
    4 FORMAT(///" ***2D OR 3D TRUSS ANALYSIS***"/,
     1/" INPUT IS IN FREE FORM."/)
      PRINT 8
    8 FORMAT(" TYPE THE NUMBER OF MEMBERS, THE NUMBER OF DEGREES ",
     1"OF FREEDOM."/" AND THE VALUE OF THE MODULUS E.")
      READ*,NM,ND,E
      PRINT 12
   12 FORMAT(" TYPE THE MEMBER END COORDINATES, MEMBER 1, 2, ETC.,"/
     1" IN THE ORDER:"/"  XI  YI  ZI  XJ  YJ  ZJ")
      DO 16 I=1,NM
      READ*,XI,YI,ZI,XJ,YJ,ZJ
      XL(I)=SQRT((ZJ-ZI)**2+(YJ-YI)**2+(XJ-XI)**2)
      COSX(I)=(XJ-XI)/XL(I)
      COSY(I)=(YJ-YI)/XL(I)
   16 COSZ(I)=(ZJ-ZI)/XL(I)
      PRINT 20
   20 FORMAT(" TYPE THE MEMBER AREAS - A(1), A(2), ETC.")
      READ*,(AR(I),I=1,NM)
      PRINT 24
   24 FORMAT(" TYPE THE LOCATION VECTORS; MEMBER 1, 2, ETC.")
      DO 28 I=1,NM
   28 READ*,(NC(I,J),J=1,6)
      PRINT 32
   32 FORMAT(" TYPE THE EXTERNAL LOADS(Q).")
      READ*,(QL(I),I=1,ND)
      WRITE (2,36)
   36 FORMAT(//" INPUT VALUES:"//" MEMBER",30X,"LOCATION VECTORS"/,
     1" NUMBER    LENGTH        AREA       NUMBERS"/)
      DO 40 I=1,NM
   40 WRITE (2,44) I,XL(I),AR(I),(NC(I,J),J=1,6)
   44 FORMAT(2X,I4,2E13.5,1X,6I3)
      WRITE (2,48) E
   48 FORMAT(/" THE VALUE OF E IS ",E11.5)
      WRITE (2,52)
   52 FORMAT(1X/" ID NO.   LOADS APPLIED "/)
      DO 56 I=1,ND
   56 WRITE (2,60) I,QL(I)
   60 FORMAT(2X,I3,4X,E13.5)
      IBND=0
      DO 64 I=1,NM
      DO 64 J=1,5
      JJ=J+1
      DO 64 K=JJ,6
      IF(NC(I,J).EQ.0.OR.NC(I,K).EQ.0)GO TO 64
      M=IABS(NC(I,J)-NC(I,K))
      IF(M.GT.IBND)IBND=M
   64 CONTINUE
      IBND=IBND+1
      WRITE (2,68) IBND
   68 FORMAT(/" THE BANDWIDTH IS ",I2)
      IF(IBND.LE.30)GO TO 72
      WRITE (2,70)
   70 FORMAT(/" BANDWIDTH EXCEEDS DIMENSION."/)
      STOP
   72 DO 76 I=1,ND
      DO 76 J=1,IBND
   76 BGK(I,J)=0.
      DO 84 N=1,NM
      SK(1,1)=COSX(N)**2
      SK(4,4)=COSX(N)**2
      SK(1,2)=COSX(N)*COSY(N)
      SK(4,5)=COSX(N)*COSY(N)
      SK(1,3)=COSX(N)*COSZ(N)
      SK(4,6)=COSX(N)*COSZ(N)
      SK(1,4)=-SK(1,1)
      SK(1,5)=-SK(1,2)
      SK(2,4)=-SK(1,2)
      SK(1,6)=-SK(1,3)
      SK(3,4)=-SK(1,3)
      SK(2,2)=COSY(N)**2
      SK(5,5)=COSY(N)**2
      SK(2,3)=COSY(N)*COSZ(N)
      SK(5,6)=COSY(N)*COSZ(N)
      SK(2,5)=-SK(2,2)
      SK(2,6)=-SK(2,3)
      SK(3,5)=-SK(2,3)
      SK(3,3)=COSZ(N)**2
      SK(6,6)=COSZ(N)**2
      SK(3,6)=-SK(3,3)
      DO 80 I=1,6
      DO 80 J=I,6
   80 SK(I,J)=(E*AR(N)/XL(N))*SK(I,J)
      DO 84 I=1,6
      DO 84 J=I,6
      K=NC(N,I)
      L=NC(N,J)
      IF(K.EQ.0.OR.L.EQ.0)GO TO 84
      IF(K.LE.L)GO TO 82
      IT=K
      K=L
      L=IT
   82 IPOS=L-K+1
      BGK(K,IPOS)=BGK(K,IPOS)+SK(I,J)
   84 CONTINUE
      CALL BNDSOL(BGK,QL,ND,IBND)
      DO 88 N=1,NM
      C=E*AR(N)/XL(N)
      SK(1,4)=COSX(N)
      SK(1,1)=-SK(1,4)
      SK(1,5)=COSY(N)
      SK(1,2)=-SK(1,5)
      SK(1,6)=COSZ(N)
      SK(1,3)=-SK(1,6)
      P(N)=0.
      DO 88 J=1,6
      K=NC(N,J)
      IF(K.EQ.0)GO TO 88
      P(N)=P(N)+C*SK(1,J)*QL(K)
   88 CONTINUE
      WRITE (2,92)
   92 FORMAT(//" OUTPUT VALUES "//"  ID NO.   DEFLECTIONS",3X,
     1"AXIAL FORCE"/)
      IF(NM-ND)96,106,106
   96 DO 98 I=1,NM
   98 WRITE (2,100) I,QL(I),P(I)
  100 FORMAT(3X,I3,2X,2E14.5)
      J=NM+1
      DO 102 I=J,ND
  102 WRITE (2,104) I,QL(I)
  104 FORMAT(3X,I3,2X,E14.5)
      GO TO 120
  106 DO 108 I=1,ND
  108 WRITE (2,100) I,QL(I),P(I)
      IF(NM.EQ.ND)GO TO 120
      J=ND+1
      DO 110 I=J,NM
  110 WRITE (2,112) I,P(I)
  112 FORMAT(3X,I3,16X,E14.5)
  120 WRITE (2,124)
  124 FORMAT(/" ANALYSIS COMPLETE."///)
      STOP
      END
      SUBROUTINE BNDSOL(BGK,Q,NDIS,MB)
      DIMENSION BGK(100,30),Q(100),F(30)
      N=0
  500 N=N+1
      Q(N)=Q(N)/BGK(N,1)
      IF(N-NDIS)550,700,550
  550 DO 600 K=2,MB
      F(K)=BGK(N,K)
  600 BGK(N,K)=BGK(N,K)/BGK(N,1)
      DO 660 L=2,MB
      I=N+L-1
      IF(NDIS-I)660,640,640
  640 J=0
      DO 650 K=L,MB
      J=J+1
  650 BGK(I,J)=BGK(I,J)-F(L)*BGK(N,K)
      Q(I)=Q(I)-F(L)*Q(N)
  660 CONTINUE
      GO TO 500
  700 N=N-1
      IF(N)750,900,750
  750 DO 800 K=2,MB
      L=N+K-1
      IF(NDIS-L)800,770,770
  770 Q(N)=Q(N)-BGK(N,K)*Q(L)
  800 CONTINUE
      GO TO 700
  900 RETURN
      END

I make it the continue statement after line 84 and my head fogs up. I would appreciate it immensely if someone could help me understand the rest of the code so I can convert it to python. I've attached my python code and am open to any suggestions on how I could make it better. This is my first attempt at writing in python.

import math
import os
from numpy import array, zeros
from numpy.linalg import solve

def buildMember(temp,coords):
    mbr = []
    mno = temp[0]
    jti = temp[1]
    jtj = temp[2]
    mbr.append(mno)
    for row in range(len(coords)):
        if jti == coords[row][0]:
            xyzi = coords[row][1:]
    mbr.append(xyzi)
    for row in range(len(coords)):    
        if jtj == coords[row][0]:
            xyzj = coords[row][1:]
    mbr.append(xyzj)
    return mbr

def codeMatrix(temp,table):
    codeno = []
    n = temp[0]
    pt1 = temp[1]
    pt2 = temp[2]
    codeno.append(n)
    for row in range(len(table)):
        if pt1 == table[row][0]:
            x1 = table[row][1]
            y1 = table[row][2]
            z1 = table[row][3]
    codeno.append(x1)
    codeno.append(y1)
    codeno.append(z1)
    for row in range(len(table)):
        if pt2 == table[row][0]:
            x2 = table[row][1]
            y2 = table[row][2]
            z2 = table[row][3]
    codeno.append(x2)
    codeno.append(y2)
    codeno.append(z2)
    B = []
    for i in range(1,len(codeno)):
        if codeno[i] != 0:
            B.append(codeno[i])

    band = max(B)-min(B)+1   
    return codeno, band

os.chdir(r'c:/users/colby/documents/dropbox/dropbox/3dtruss')
#os.chdir('c:/pyzo2013c/projects')   

print("  ***2D or 3D Truss Analysis***   ")
infile = open(input("Enter input file name; name.txt:"),'r')
output = open(input("Enter output file name; name.txt:"), "w+")
tempfile = open('tempfile.txt','w+')
NM, DOF, E = eval(infile.readline())
#NM, DOF, E = eval(input("Enter the number of members, the number of degrees"+\
    #"of freedom and \nthe value of the modulus E. Separate with commas:"))

# Read in joint coordinates and create point table
#jts = eval(input("Enter number of joints:"))
jts = eval(infile.readline())
output.write('{0:^8}{1:^6}{2:^6}{3:^6}\n'.format('Joint','X','Y','Z'))
points =[]
for i in range(jts):
    #tempjt = eval(input("Enter joint {} coordinates; [jt no.,x,y,z]:".format(i+1)))
    tempjt = eval(infile.readline())
    points.append(tempjt)
    output.write('{0:^8d}{1:^6.1f}{2:^6.1f}{3:^6.1f}\n'.format(tempjt[0],tempjt[1],tempjt[2],tempjt[3]))
print(points)

dtable = []
for i in range(jts):
    #tempd = eval(input("Enter the code-number for point {}; [pt no,x,y,z]:".format(i+1)))
    tempd = eval(infile.readline())
    dtable.append(tempd)
print(dtable)

# Assign joints to members
members = []
area = []
codes = []
xl=[]
cosx=[]
cosy=[]
cosz=[]
bndwth = []
output.write('\n{0:^8} {1:^9} {2:^8} {3:^18}\n'.format('MEMBER','LENGTH','AREA','CODE NUMBERS'))
for i in range(1,NM+1):
    #tempmbr = eval(input("Enter member {} data; [no, i, j] where i & j are pt numbers:".format(i)))
    tempmbr = eval(infile.readline())
    m = buildMember(tempmbr, points)
    members.append(m)
    codenumbers, bw = codeMatrix(tempmbr,dtable)
    codes.append(codenumbers)
    xlen = math.sqrt((m[2][2]-m[1][2])**2+(m[2][1]-m[1][1])**2+(m[2][0]-m[1][0])**2)
    cos_x = (m[2][0]-m[1][0])/xlen
    cos_y = (m[2][1]-m[1][1])/xlen
    cos_z = (m[2][2]-m[1][2])/xlen
    #a = eval(input("Enter area of member {}:".format(i)))
    a = eval(infile.readline())
    area.append(a)
    xl.append(xlen)
    cosx.append(cos_x)
    cosy.append(cos_y)
    cosz.append(cos_z)
    print('{0:8.4f},{1:7.3f},{2:7.3f},{3:7.3f}'.format(xlen,cos_x,cos_y,cos_z))
    print('Bandwidth is {}\n'.format(bw))
    #code_str = str(codenumbers[1:])
    output.write('{0:^8} {1:>8.4f} {2:>8.4f}  {3:^}\n'.format(i,xlen,a,str(codenumbers[1:])))
    bndwth.append(bw)
print(members)
print(codes)


#q = eval(input("Enter the external loads. Loads must be ordered per code numbering:"))
q = eval(infile.readline())
Q = array(q)
print(q)
output.write('The value of modulus E is {:10.1f}\n\n'.format(E))
output.write('Applied loads corresponding to structure node labels:\n{}\n\n'.format(q))
B = max(bndwth) # defines bandwith
print('Bandwidth is {}\n'.format(B))
output.write('The bandwidth is {}\n\n'.format(B))
k = zeros((6,6))
K = zeros((DOF,B))
print(k)
print(K)
for n in range(NM):
    k[0,0]=cosx[n]**2
    k[3,3]=cosx[n]**2
    k[0,1]=cosx[n]*cosy[n]
    k[3,4]=cosx[n]*cosy[n]
    k[0,2]=cosx[n]*cosz[n]
    k[3,5]=cosx[n]*cosz[n]
    k[0,3]=-k[0,0]
    k[0,4]=-k[0,1]
    k[1,3]=-k[0,1]
    k[0,5]=-k[0,2]
    k[2,3]=-k[0,2]
    k[1,1]=cosy[n]**2
    k[4,4]=cosy[n]**2
    k[1,2]=cosy[n]*cosz[n]
    k[4,5]=cosy[n]*cosz[n]
    k[1,4]=-k[1,1]
    k[1,5]=-k[1,2]
    k[2,4]=-k[1,2]
    k[2,2]=cosz[n]**2
    k[5,5]=cosz[n]**2
    k[2,5]=-k[2,2]
    for i in range(6):
        for j in range(6):
            k[i,j] = (E*area[n]/xl[n])*k[i,j]
            print('k[{},{}] = {:7.3f}'.format(i+1,j+1,k[i,j]))
    print('n i j m l K k',end='\n')
    for i in range(DOF):
        for j in range(B):
            m = codes[n][i+1]
            l = codes[n][j+1]
            if m != 0:
                if l != 0:
                    K[m-1,l-1] = K[m-1,l-1]+k[i,j]
                    print(n,i,j,m,l,K[m-1,l-1],k[i,j],end='\n')
                    tempfile.write('{} {} {} {} {} {} {}\n'.format(n+1,i+1,j+1,m,l,K[m-1,l-1],k[i,j]))
print(K)
output.write('Global Stiffness Matrix\n{}'.format(K))

D = solve(K,Q)
print(D)
infile.close()
output.close()
tempfile.close()

Thanks

may i ask?, can the fortran code read every example of truss??.
i really want to know, cause i have home work to do. thank you very much

Hello colby,

I tried to run your FORTRAN code on OPEN WATCOM and the log says:

cd C:\WATCOM\Programas\2dy3ddeinternet
wmake -f C:\WATCOM\Programas\2dy3ddeinternet\noname.mk -h -e C:\WATCOM\Programas\2dy3ddeinternet\noname.exe
wfc386 deinternet.FOR -d2 -q -dep
deinternet.FOR(1): ERR CC-02 invalid character in statement number columns
deinternet.FOR(5): ERR FM-06 column 17, unrecognizable edit descriptor in for
mat string
deinternet.FOR(6): ERR FM-06 column 8, unrecognizable edit descriptor in form
at string
deinternet.FOR(8): ERR FM-06 column 14, unrecognizable edit descriptor in for
mat string
deinternet.FOR(8): ERR FM-02 column 45, missing or invalid constant
deinternet.FOR(8): ERR FM-06 column 73, unrecognizable edit descriptor in for
mat string
deinternet.FOR(9): ERR FM-06 column 21, unrecognizable edit descriptor in for
mat string
deinternet.FOR(12): ERR FM-06 column 14, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(12): ERR FM-06 column 49, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(12): ERR FM-11 column 62, repeat specification not allowed for
this format code
deinternet.FOR(12): ERR FM-06 column 67, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(12): ERR FM-06 column 73, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(13): ERR FM-06 column 22, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(13): ERR FM-06 column 24, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(16): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(17): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(18): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(19): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(19): ERR ST-03 statement must not be branched to but was in l
ine 14
deinternet.FOR(19): ERR DO-02 ‚) statement not allowed at termination of DO r
ange
deinternet.FOR(21): ERR FM-06 column 14, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(21): ERR FM-06 column 43, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(21): ERR FM-06 column 49, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(21): ERR FM-02 column 53, missing or invalid constant
deinternet.FOR(22): ERR EQ-02 column 14, cannot assign value to FUNCTION
deinternet.FOR(24): ERR FM-06 column 14, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(24): ERR FM-11 column 56, repeat specification not allowed for
this format code
deinternet.FOR(26): ERR EQ-02 column 14, cannot assign value to FUNCTION
deinternet.FOR(28): ERR FM-06 column 14, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(28): ERR FM-02 column 41, missing or invalid constant
deinternet.FOR(28): ERR FM-06 column 42, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(29): ERR EQ-02 column 14, cannot assign value to FUNCTION
deinternet.FOR(31): ERR FM-06 column 16, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(31): ERR FM-06 column 31, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(31): ERR FM-06 column 34, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(31): ERR FM-06 column 48, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(31): ERR FM-06 column 73, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(37): ERR FM-06 column 15, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(39): ERR FM-06 column 17, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(54): ERR FM-06 column 15, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(57): ERR FM-06 column 15, unrecognizable edit descriptor in fo
rmat string
deinternet.FOR(61): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(61): ERR ST-03 ~) statement must not be branched to but was in
line 60
deinternet.FOR(61): ERR DO-02 ) statement not allowed at termination of DO r
ange
deinternet.FOR(61): ERR DO-02 ) statement not allowed at termination of DO r
ange
deinternet.FOR(63): ERR ST-02 statement function definition appears after fir
st executable statement
deinternet.FOR(63): ERR SX-11 column 10, expecting statement function argumen
t name
deinternet.FOR(63): ERR SX-11 column 12, expecting statement function argumen
t name
deinternet.FOR(64): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(65): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(66): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(67): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(68): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(69): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(70): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(71): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(72): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(73): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(74): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(75): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(76): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(77): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(78): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(79): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(80): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(81): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(82): ERR SF-06 column 10, incorrect number of arguments passed
to statement function SK
deinternet.FOR(83): ERR SF-06 column 19, incorrect number of arguments passed
to statement function SK
deinternet.FOR(86): ERR SF-06 column 34, incorrect number of arguments passed
to statement function SK
deinternet.FOR(97): ERR SF-06 column 34, incorrect number of arguments passed
to statement function SK
deinternet.FOR(99): ERR VA-01 column 19, illegal use of statement function na
me BGK in CALL statement
deinternet.FOR(102): ERR SF-06 column 10, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(103): ERR SF-06 column 19, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(104): ERR SF-06 column 10, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(105): ERR SF-06 column 19, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(106): ERR SF-06 column 10, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(107): ERR SF-06 column 19, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(108): ERR ST-02 statement function definition appears after fi
rst executable statement
deinternet.FOR(112): ERR SF-06 column 22, incorrect number of arguments passe
d to statement function SK
deinternet.FOR(115): ERR FM-06 column 16, unrecognizable edit descriptor in f
ormat string
deinternet.FOR(115): ERR FM-06 column 35, unrecognizable edit descriptor in f
ormat string
deinternet.FOR(115): ERR FM-06 column 73, unrecognizable edit descriptor in f
ormat string
deinternet.FOR(134): ERR FM-06 column 15, unrecognizable edit descriptor in f
ormat string
Error(E42): Last command making (C:\WATCOM\Programas\2dy3ddeinternet\deinternet.obj) returned a bad status
Error(E02): Make execution terminated
Execution complete

I could not run it...
Please tell me whats happening

Regards

First of all, veblinriche, I apologize. I did not see that you had commented. It calculates the axial force in each member and the displacement of each joint. It is only valid for plane trusses with no zero force members, meaning it cannot do buckled analysis.

MrEfgo, the program prompts for geometric information for a plane truss and then calculates the axial force in each member and the displacement of each joint.

This article has been dead for over six months. Start a new discussion instead.