Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial truss implementation #176

Closed
wants to merge 7 commits into from
Closed

Conversation

jtveiten
Copy link

Still need a lot of improvements and testing

I'm not sure how to set up the support features, where the global transformations should go when making a truss model and how to put in point loads

Still need a lot of improvements and testing
@ahojukka5
Copy link
Member

Hi. I comment more later on. As a quick comment, discrete boundary conditions like point loads or fixed nodes, one needs to define Element{Poi1}, i.e.

el = Element(Poi1, [node_id])

After that, to fix some dof of that node:

update!(el, "displacement 1", 0.0)

To add point load:

update!(el, "displacement traction force 1", 10.0)

And so on.

element::Element, time, ::Type{Val{:plane_stress}})
#Require that the num ber pof nodes = 2
nnodes = length(element)
K = ones(4, 4)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually you want to integrate this numerically, i.e.

K = zeros(2, 2)
for ip in get_integration_points(element)
    dN = element(ip, time, Val{:Grad})
    detJ = element(ip, time, Val{:detJ})
    A = element("cross section area", ip, time)
    E = element("youngs modulus", ip, time)
    K += ip.weight*E*A*dN'*dN*detJ
end

E = element("youngs modulus", 1, time) # Should we do it this way
A = element("cross section area", 1, time)
# Do I need to find the length of the Truss
L=1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Length is not explicitly required as it comes from the "size factor" detJ

@ahojukka5
Copy link
Member

Looks that test_truss.jl is empty, you can add more commits to this PR simply by git add, git commit, git push and so on.

Have changed the implementation according to Jukka's advice. Still missing where to do the local to global transformation for trusses in 2d and 3d.

And my solving of the model isn't quite right either.
@jtveiten
Copy link
Author

jtveiten commented Aug 31, 2017 via email

The K matrix was forgotten.
Tried a variable field
@ahojukka5
Copy link
Member

Hi.

I think we could include file problems_truss.jl in JuliaFEM.jl and export Truss to get problem type automatically to namespace, maybe something like this to the end of other problem definitions:

# structural elements
include("problems_truss.jl")
export Truss

We can then do other structural elements with the same concept.

Yes, E and A can be spatially varying, to test that, they must be defined in each nodes, in the same way like geometry is done, e.g.

E = Dict(1 => 100e9, 2 => 200e9)
update!(element, "youngs modulus", E)

About that transformation matrix, let that be Q. It's for 2d problems 2x4, I quess for 3d it's 3x6. It can be done just before adding local matrix (which is size 2x2 in 2d setting) to global matrix K, where it's expanded to 4x4 matrix in 2d setting by Q' * Ke * Q. We need somehow pass the information, is our truss in 2d or 3d setting, to the assembly procedure. That is done in problem definition, when we write

p = Problem(Truss, "test problem", 2)

means basically that we have 2 unknown dofs for each node, so total number of dofs for 2 node truss element is then 4. In asssembly procedure, we then have dim = get_unknown_field_dimension(problem) returning that number 2 for Truss problem. Of course we could have several different problems like Truss1D, Truss2D, Truss3D and so on, e.g. in ABAQUS there is T2D2 and T2D3, but I think that would lead to lot of boilerplate code.

Number of nodes = number of basis functions = length(element), so I would write

nnodes = length(element)
ndim = get_unknown_field_dimension(problem)
ndofs = nnodes*ndim

Then you can allocate empty K, K = zeros(ndofs, ndofs).

For that transformation matrix we need to use some trigonometric functions and calculate angles from original geometry, we can get the geometry of element by X = element("geometry", time), when we can access to e.g. second dof of first node by X[1][2], X is basically a list of vectors.

"""
type Truss <: FieldProblem
# these are found from problem.properties for type Problem{Elasticity}
formulation :: Symbol
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think we don't need even this at this point, type definition can be empty:

type Truss <: FieldProblem
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Later on we can define here for example, how do we want to calculate our local stiffness matrix. For example, we can have finite_strain :: Bool and access this inside assembly procedure from problem.properties.finite_strain and in that case calculate also geometric stiffness and have finite strain truss element.

error("3d elements not implemented in this example")
end

function assemble!(assembly::Assembly, problem::Problem{Truss},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point we can remove the assemble! functions above and have here

function assemble!(assembly::Assembly, problem::Problem{Truss}, element::Element{Seg2}, time)


function assemble!(assembly::Assembly, problem::Problem{Truss},
element::Element{Seg2}, time, ::Type{Val{:plane_stress}})
#Require that the number of nodes = 2 ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number of nodes will always be here 2 if definition of element is Element{Seg2}. In principle you could write the same function for Seg3 elements also, but they can be assembled in same function also.

end
function Truss()
# formulations: plane_stress, plane_strain, continuum
return Truss(:plane_stress)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove that formulation definition from the type, here we just return Truss(). Actually, this initializator can be in that case removed because it's not doing anything else than giving infinite loop. The use of initializator is needed only when we have internal properties for Problem to have some good default.

@jtveiten
Copy link
Author

jtveiten commented Sep 1, 2017 via email

@ahojukka5
Copy link
Member

Do you have the whole JuliaFEM cloned somewhere in your disk, to other place than ~/.julia/v0.6, or have JuliaFEM installed using Pkg.add(...) and problems_truss.jl file somewhere outside of installation?

@jtveiten
Copy link
Author

jtveiten commented Sep 1, 2017 via email

@ahojukka5
Copy link
Member

Well, yes. You can do the changes directly to the version in ~/.julia/v0.6/JuliaFEM. I think you can just rename the old JuliaFEM directory to something else and then move the cloned copy to ~/.julia/v0.6. Alternatively, create symbolic link if working with Linux. Third option is to add path where you have cloned JuliaFEM to LOAD_PATH, i.e. push!(LOAD_PATH, "path_to_repositories").

@ahojukka5
Copy link
Member

ahojukka5 commented Sep 1, 2017

https://docs.julialang.org/en/latest/manual/packages/#Making-changes-to-an-existing-package-1

This is how Julia community thinks developing should be done.

Added to the juliaFEM.jl and test
@jtveiten
Copy link
Author

jtveiten commented Sep 20, 2017 via email

@ahojukka5
Copy link
Member

Ok this should now be possible to develop in own package e.g. Truss.jl, I create a new package and let's move discussion to there.

@jtveiten
Copy link
Author

jtveiten commented Nov 13, 2017 via email

@jtveiten
Copy link
Author

jtveiten commented Dec 20, 2017 via email

@ahojukka5
Copy link
Member

Yes, FEMBase.jl, but I'm still working with documentation for that. We can however start with this one, let's create a new package and move development to there.

@ahojukka5
Copy link
Member

Ok now we have https://github.com/JuliaFEM/FEMTruss.jl. About this technical details, I think we should try official JuliaFEM Gitter channel.

@jtveiten jtveiten closed this Jan 9, 2018
@jtveiten jtveiten deleted the truss_intro branch January 9, 2018 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants