JuliaFEM / JuliaFEM.jl

The JuliaFEM software library is a framework that allows for the distributed processing of large Finite Element Models across clusters of computers using simple programming models. It is designed to scale up from single servers to thousands of machines, each offering local computation and storage.
http://juliafem.github.io/JuliaFEM.jl/latest/
MIT License
250 stars 66 forks source link

xdmf export: bounds error with Dirichnet nodal displacement boundary #202

Open AndiMD opened 6 years ago

AndiMD commented 6 years ago

Hi,

A simple 3d linear elastic problem with prescribed nodal displacements cannot be exported. See attached case. I am using Julia 0.6.3 with JuliaFEM version is 0.4.0. bug.tar.gz

EDIT: This issue might be due to the following inconsistency: update!(element, "geometry", mesh.nodes) does not work for element==Poi1, so it contains no coordinate.

Cheers, Andi

ERROR: LoadError: BoundsError: attempt to access (0,)
  at index [2]
Stacktrace:
 [1] indexed_next(::Tuple{Int64}, ::Int64, ::Int64) at ./tuple.jl:54
 [2] update_xdmf!(::JuliaFEM.Xdmf, ::FEMBase.Problem{JuliaFEM.Dirichlet}, ::Float64, ::Array{String,1}) at /home/andi/.julia/v0.6/JuliaFEM/src/io.jl:416
 [3] write_results!(::FEMBase.Analysis{JuliaFEM.Nonlinear}, ::Float64) at /home/andi/.julia/v0.6/JuliaFEM/src/solvers.jl:537
 [4] solve!(::FEMBase.Analysis{JuliaFEM.Nonlinear}, ::Float64) at /home/andi/.julia/v0.6/JuliaFEM/src/solvers.jl:618
 [5] (::FEMBase.Analysis{JuliaFEM.Nonlinear})() at /home/andi/.julia/v0.6/JuliaFEM/src/solvers.jl:679
 [6] include_from_node1(::String) at ./loading.jl:576
 [7] include(::String) at ./sysimg.jl:14
while loading /home/[...]/3d_mechanical.jl, in expression starting on line 65
ahojukka5 commented 6 years ago

You can actually get around with this one by updating geometry to the nodal elements, update!([p0,p1,p2,p3], "geometry", mesh.nodes) or using create_nodal_elements(mesh, node_set_name). Anyway, Xdmf writer should definite give more clear error message what is going on (cannot write vertex data because geometry is missing).

Updating geometry should work for all nodes:

X = Dict(1 => [1.0, 2.0])
p = Element(Poi1, [1])
update!(p, "geometry", X)
p("geometry", 0.0)

# output

([1.0, 2.0],)
AndiMD commented 6 years ago

Thanks for your explanation. This works.

ahojukka5 commented 6 years ago

We have a function create_node_set_from_element_set!, which takes mesh and element set as input argument and creates node set.

About strings and symbols, I'm not that sure which ones are better to use. Symbols work well as long as there is no whitespaces in names and colon syntax works, like in set names, :FIXED. However, when you have whitespace, e.g. youngs modulus, you should write Symbol("youngs modulus") to get it to symbol (or have :youngs_modulus). If we get serious performance penalty from using strings, then we should go to the symbols. The performance is not measured by anyone yet.

AndiMD commented 6 years ago

I would argue that the performance penalty is hard to measure in general, since people may come up with unconventional, dictionary-heavy problems. Besides that, naming variables identically to dict keys may be nicer coding style (of course, its a matter of taste): youngs_modulus = d[:youngs_modulus] vs youngs_modulus = d["Youngs Modulus"]

ahojukka5 commented 6 years ago

This is a very good point. We then could also use macros to unpack fields from the element:

@unpack youngs_modulus displacement poissons_ratio

Another thing to consider is that strings implement string manipulation routines which we don't actually use anywhere. So the use of symbols instead of strings would be more appropriate.