Skip to content
Snippets Groups Projects
BeamFEM.jl 8.63 KiB
Newer Older
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
# // Amira Abdel-Rahman
# // (c) Massachusetts Institute of Technology 2020

using LinearAlgebra
import JSON


function rotation_matrix(element_vector, x_axis, y_axis,z_axis)
    # find the direction cosines
    L=norm(element_vector)
    l = (element_vector[1])/L
	m = (element_vector[2])/L
	n = (element_vector[3])/L
	D = ( l^2+ m^2+n^2)^0.5
    
    transMatrix=[[l m  n  0  0  0  0  0  0  0  0  0];[-m/D l/D  0  0  0  0  0  0  0  0  0  0];[ -l*n/D  -m*n/D  D  0  0  0  0  0  0  0  0  0];[ 0  0  0       l       m  n  0  0  0  0  0  0];[ 0  0  0    -m/D     l/D  0  0  0  0  0  0  0];[ 0  0  0  -l*n/D  -m*n/D  D  0  0  0  0  0  0];[ 0  0  0  0  0  0       l       m  n  0  0  0];[ 0  0  0  0  0  0    -m/D     l/D  0  0  0  0];[ 0  0  0  0  0  0  -l*n/D  -m*n/D  D  0  0  0];[ 0  0  0  0  0  0  0  0  0       l       m  n];[ 0  0  0  0  0  0  0  0  0    -m/D     l/D  0];[ 0  0  0  0  0  0  0  0  0  -l*n/D  -m*n/D  D]]
	
    return transMatrix
end

function get_stresses(setup)
    nodes      = setup["nodes"]
    edges      = setup["edges"]
    ndofs      = length(nodes)*6

    x_axis     = [1 0 0]
    y_axis     = [0 1 0]
    z_axis     = [0 0 1]

    # find the stresses in each member
    stresses=zeros(length(edges))
    max11=-10e6
    min11=10e6
    for edge in edges
        #degrees_of_freedom = properties["degrees_of_freedom"]

        element=parse(Int,edge["id"][2:end])

        # find the nodes that the lements connects
        fromNode = nodes[edge["source"]+1]
        toNode = nodes[edge["target"]+1]

        # the coordinates for each node
        fromPoint = [fromNode["position"]["x"] fromNode["position"]["y"] fromNode["position"]["z"]]
        toPoint = [toNode["position"]["x"] toNode["position"]["y"] toNode["position"]["z"]]

        # find the degrees of freedom for each node
        dofs = convert(Array{Int}, fromNode["degrees_of_freedom"])
        dofs=vcat(dofs,convert(Array{Int}, toNode["degrees_of_freedom"]))

        element_vector=toPoint-fromPoint
       

        # find rotated mass and stifness matrices
        tau = rotation_matrix(element_vector, x_axis,y_axis,z_axis)
        
        # i1=parse(Int,fromNode["id"][2:end])
        # i2=parse(Int,toNode["id"][2:end])
        
        # global_displacements=[X[(i1)*6+1] X[(i1)*6+2] X[(i1)*6+3] X[(i1)*6+4] X[(i1)*6+5] X[(i1)*6+6] X[(i2)*6+1] X[(i2)*6+2] X[(i2)*6+3] X[(i2)*6+4] X[(i2)*6+5] X[(i2)*6+6]] # todo change
        global_displacements=[fromNode["displacement"]["x"] fromNode["displacement"]["y"] fromNode["displacement"]["z"] fromNode["angle"]["x"] fromNode["angle"]["y"] fromNode["angle"]["z"] toNode["displacement"]["x"] toNode["displacement"]["y"] toNode["displacement"]["z"] toNode["angle"]["x"] toNode["angle"]["y"] toNode["angle"]["z"]] # todo change

        # nodal displacement

        q=tau*transpose(global_displacements)
        # println(q)
        # calculate the strain and stresses
        strain =(q[7]-q[1])/norm(element_vector)
        E = edge["stiffness"]# youngs modulus
        stress=E.*strain
        edge["stress"]=stress
        if stress>max11
            max11=stress
        end
        if stress<min11
            min11=stress
        end
        # println(element)
        # println(stress)
    end

    
    
    setup["viz"]["minStress"]=min11
    setup["viz"]["maxStress"]=max11
    return stresses
end

function get_matrices(setup)
    
    nodes      = setup["nodes"]
    edges      = setup["edges"]
    ndofs      = length(nodes)*6

    x_axis     = [1 0 0]
    y_axis     = [0 1 0]
    z_axis     = [0 0 1]

    M = zeros((ndofs,ndofs))
    K = zeros((ndofs,ndofs))

    for edge in edges
        #degrees_of_freedom = properties["degrees_of_freedom"]

        element=parse(Int,edge["id"][2:end])

        # find the nodes that the lements connects
        fromNode = nodes[edge["source"]+1]
        toNode = nodes[edge["target"]+1]

        # the coordinates for each node
        fromPoint = [fromNode["position"]["x"] fromNode["position"]["y"] fromNode["position"]["z"]]
        toPoint = [toNode["position"]["x"] toNode["position"]["y"] toNode["position"]["z"]]

        # find the degrees of freedom for each node
        dofs = convert(Array{Int}, fromNode["degrees_of_freedom"])
        dofs=vcat(dofs,convert(Array{Int}, toNode["degrees_of_freedom"]))

        element_vector=toPoint-fromPoint

        # find element mass and stifness matrices
        length   = norm(element_vector)
        rho      = edge["density"]
        area     = edge["area"]
        E        = edge["stiffness"]# youngs modulus

        A = edge["area"]
        G=1.0#todo shear_modulus
        ixx = 1.0#todo section ixx
        iyy = 1.0#todo section.iyy#
        l0=length
        j=1.0;#todo check
        l02 = l0 * l0
        l03 = l0 * l0 * l0

        # Cm = rho * area * length /6.0
        # Ck= E * area / length 

        # m = [[2 1];[1 2]]
        # k = [[1 -1];[-1 1]]

        k = [[E*A/l0  0  0  0  0  0  -E*A/l0  0  0  0  0  0];[0  12*E*ixx/l03  0  0  0  6*E*ixx/l02  0  -12*E*ixx/l03  0  0  0  6*E*ixx/l02];[0  0  12*E*iyy/l03  0  -6*E*iyy/l02  0  0  0  -12*E*iyy/l03  0  -6*E*iyy/l02  0];[0  0  0  G*j/l0  0  0  0  0  0  -G*j/l0  0  0];[0  0  -6*E*iyy/l02  0  4*E*iyy/l0  0  0  0  6*E*iyy/l02  0  2*E*iyy/l0  0];[0  6*E*ixx/l02  0  0  0  4*E*ixx/l0  0  -6*E*ixx/l02  0  0  0  2*E*ixx/l0];[-E*A/l0  0  0  0  0  0  E*A/l0  0  0  0  0  0];[0  -12*E*ixx/l03  0  0  0  -6*E*ixx/l02  0  12*E*ixx/l03  0  0  0  -6*E*ixx/l02];[0  0  -12*E*iyy/l03  0  6*E*iyy/l02  0  0  0  12*E*iyy/l03  0  6*E*iyy/l02  0];[0  0  0  -G*j/l0  0  0  0  0  0  G*j/l0  0  0];[0  0  -6*E*iyy/l02  0  2*E*iyy/l0  0  0  0  6*E*iyy/l02  0  4*E*iyy/l0  0];[0  6*E*ixx/l02  0  0  0  2*E*ixx/l0  0  -6*E*ixx/l02  0  0  0  4*E*ixx/l0]]

        # find rotated mass and stifness matrices
        tau = rotation_matrix(element_vector, x_axis,y_axis,z_axis)

        # m_r=transpose(tau)*m*tau
        k_r=transpose(tau)*k*tau


        # change from element to global coordinate
        index= dofs.+1

        B=zeros((12,ndofs))
        for i in 1:12
              B[i,index[i]]=1.0
        end


        # M_rG= transpose(B)*m_r*B
        K_rG= transpose(B)*k_r*B

        # M += Cm .* M_rG
        # K += Ck .* K_rG
        K +=  K_rG

    end

    # construct the force vector
    F=zeros(ndofs)
    remove_indices=[];
    for node in nodes
        #insert!(F,i, value);
        #F=vcat(F,value)
        i=parse(Int,node["id"][2:end])
        f=node["force"]
        # println(f)
        F[(i)*6+1]=f["x"]
        F[(i)*6+2]=f["y"]
        F[(i)*6+3]=f["z"]
        F[(i)*6+4]=0
        F[(i)*6+5]=0
        F[(i)*6+6]=0
        dofs = convert(Array{Int}, node["degrees_of_freedom"]).+1
        restrained_dofs=node["restrained_degrees_of_freedom"]
        for (index, value) in enumerate(dofs)
            if restrained_dofs[index]
                append!( remove_indices, value)
            end
        end
    end

    # println(remove_indices)
    # print(K)
    # print(F)

    # M = M[setdiff(1:end, remove_indices), :]
    K = K[setdiff(1:end, remove_indices), :]

    # M = M[:,setdiff(1:end, remove_indices)]
    K = K[:,setdiff(1:end, remove_indices)]

    F = F[setdiff(1:end, remove_indices)]
    return M,K,F
end

function updateDisplacement(setup, X)
    nodes= setup["nodes"]
    i=0
    for node in nodes
        if !node["restrained_degrees_of_freedom"][1]
            #i=parse(Int,node["id"][2:end])
            node["displacement"]["x"]=X[(i)*6+1]
            node["displacement"]["y"]=X[(i)*6+2]
            node["displacement"]["z"]=X[(i)*6+3]
            node["angle"]["x"]=X[(i)*6+4]
            node["angle"]["y"]=X[(i)*6+5]
            node["angle"]["z"]=X[(i)*6+6]
            i=i+1
        end
    end
end

function solveFea(setup)
	// # determine the global matrices
	M,K,F=get_matrices(setup)
    
    #println(M)
    #println(K)
    #println(F)
    
    #evals=eigvals(K,M)
    #evecs=eigvecs(K,M)
    #frequencies=sqrt.(evals)
    X=inv(K)*F
    
    
    #updateDisplacement(displacements);
    updateDisplacement(setup, X)
    
    # determine the stresses in each element
    stresses=get_stresses(setup)

end


###################
### Read data #####
###################
setup = Dict()
open("./json/setupChiral3.json", "r") do f
    global setup
    dicttxt = String(read(f))  # file information to string
    setup=JSON.parse(dicttxt)  # parse and transform data
end

setup=setup["setup"]


###################
### Solve FEA data #####
###################
solveFea(setup)


###################
### Write data #####
###################

# pass data as a json string (how it shall be displayed in a file)
stringdata = JSON.json(setup)

# write the file with the stringdata variable information
open("./json/trialJulia.json", "w") do f
        write(f, stringdata)
     end