mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-26 11:51:31 +00:00
Abaqus_reader: can read nodes, elements and sets
This commit is contained in:
+131
-62
@@ -2,69 +2,135 @@
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
global ABQ_ELTYPE_HAS_NODES = Dict(
|
||||
:C3D10 => 10,
|
||||
:C3D4 => 4,
|
||||
:C3D10 => 10,
|
||||
:C3D20 => 20,
|
||||
:C3D20E => 20,
|
||||
:S3 => 3,
|
||||
)
|
||||
|
||||
|
||||
function parse_nodes(model, header, data)
|
||||
nodes = create_or_get(model, "nodes")
|
||||
for line in split(data, "\n")
|
||||
m = matchall(r"[-0-9.]+", line)
|
||||
id = parse(Int, m[1])
|
||||
coords = float(m[2:end])
|
||||
nodes[id] = coords
|
||||
type AbaqusModel
|
||||
nodes::Array{INode, 1}
|
||||
elements::Array{IElement, 1}
|
||||
node_sets::Array{INodeSet, 1}
|
||||
element_sets::Array{IElementSet, 1}
|
||||
end
|
||||
|
||||
|
||||
AbaqusModel() = AbaqusModel(INode[],
|
||||
IElement[],
|
||||
INodeSet[],
|
||||
IElementSet[])
|
||||
|
||||
"""
|
||||
"""
|
||||
function empty_or_comment_line(line)
|
||||
val_bool = false
|
||||
if startswith(line, "**") || length(line) == 0
|
||||
val_bool = true
|
||||
end
|
||||
val_bool
|
||||
end
|
||||
|
||||
"""
|
||||
Function for parsing nodes from the file
|
||||
"""
|
||||
function parse_nodes(model, lines, key, idx_start, idx_end)
|
||||
info("Parsing nodes")
|
||||
definition = lines[idx_start]
|
||||
for line in lines[idx_start + 1: idx_end]
|
||||
if !(empty_or_comment_line(line))
|
||||
m = matchall(r"[-0-9.]+", line)
|
||||
node_id = parse(Int, m[1])
|
||||
coords = float(m[2:end])
|
||||
node = INode(node_id, coords)
|
||||
push!(model.nodes, node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#function parse_elements(model, header, data)
|
||||
# info("Parsing elements")
|
||||
# eldims = Dict(
|
||||
# "C3D10" => 10,
|
||||
# "C3D4" => 4)
|
||||
# eltype = header["options"]["TYPE"]
|
||||
# if !(eltype in keys(eldims))
|
||||
# throw("Element $eltype dimension information missing")
|
||||
# end
|
||||
# eldim = eldims[eltype]
|
||||
# test_match = matchall(r"[0-9]+", "234, 242")
|
||||
# m = matchall(r"[0-9]+", data)
|
||||
# m = map((s) -> parse(Int, s), m)
|
||||
# elements = create_or_get(model, "elements")
|
||||
# m = reshape(m, eldim+1, round(Int, length(m)/(eldim+1)))
|
||||
# nel = size(m)[2]
|
||||
# info("$nel elements found")
|
||||
# for i=1:nel
|
||||
# elements[m[1,i]] = m[2:end,i]
|
||||
# end
|
||||
# if "ELSET" in keys(header["options"])
|
||||
# elsets = create_or_get(model, "elsets")
|
||||
# elset_name = header["options"]["ELSET"]
|
||||
# info("Creating ELSET $elset_name")
|
||||
# elsets[elset_name] = Int64[]
|
||||
# for i=1:nel
|
||||
# push!(elsets[elset_name], m[1,i])
|
||||
# end
|
||||
# end
|
||||
#end
|
||||
#
|
||||
#function parse_nodeset(model, header, data)
|
||||
# nset_name = header["options"]["NSET"]
|
||||
# info("Creating node set $nset_name")
|
||||
# data = ASCIIString[]
|
||||
# m = matchall(r"[0-9]+", data)
|
||||
# node_ids = map((s) -> parse(Int, s), m)
|
||||
# nsets = create_or_get(model, "nsets")
|
||||
# nsets[nset_name] = Int64[]
|
||||
# for j in node_ids
|
||||
# push!(nsets[nset_name], j)
|
||||
# end
|
||||
#end
|
||||
"""
|
||||
Custon regex to find match from string
|
||||
"""
|
||||
function regex_match(regex_str, line, idx)
|
||||
return match(regex_str, line).captures[idx]
|
||||
end
|
||||
|
||||
parse_section = Dict(:NODE => parse_nodes) # ,
|
||||
#:ELEMENT => parse_elements,
|
||||
#:NSET => parse_nodeset,
|
||||
#:ELSET => parse_elementset)
|
||||
"""
|
||||
"""
|
||||
function consumeList(arr, start, stop)
|
||||
function _it()
|
||||
for i=start:stop
|
||||
produce(arr[i])
|
||||
end
|
||||
end
|
||||
Task(_it)
|
||||
end
|
||||
|
||||
"""
|
||||
"""
|
||||
function parse_elements(model, lines, key, idx_start, idx_end)
|
||||
info("Parsing elements")
|
||||
definition = uppercase(lines[idx_start])
|
||||
element_type = regex_match(r"TYPE=([\w\-\_]+)", definition, 1)
|
||||
eltype_sym = symbol(element_type)
|
||||
eltype_nodes = ABQ_ELTYPE_HAS_NODES[eltype_sym]
|
||||
list_iterator = consumeList(lines, idx_start+1, idx_end)
|
||||
line = consume(list_iterator)
|
||||
while line != nothing
|
||||
arr_num_as_str = matchall(r"[0-9]+", line)
|
||||
numbers = map(x-> parse(Int, x), arr_num_as_str)
|
||||
if !(empty_or_comment_line(line))
|
||||
id = numbers[1]
|
||||
connectivity = numbers[2:end]
|
||||
element = IElement(id, connectivity, element_type)
|
||||
while length(element.connectivity) != eltype_nodes
|
||||
@assert length(element.connectivity) < eltype_nodes
|
||||
line = consume(list_iterator)
|
||||
arr_num_as_str = matchall(r"[0-9]+", line)
|
||||
numbers = map(x-> parse(Int, x), arr_num_as_str)
|
||||
map(x->push!(element.connectivity, x), numbers)
|
||||
end
|
||||
end
|
||||
line = consume(list_iterator)
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
"""
|
||||
function parse_set(model, lines, key, idx_start, idx_end)
|
||||
set_regex_string = Dict(:NSET => r"NSET=([\w\-\_]+)",
|
||||
:ELSET => r"ELSET=([\w\-\_]+)" )
|
||||
definition = uppercase(lines[idx_start])
|
||||
regex_string = set_regex_string[key]
|
||||
set_name = regex_match(regex_string, definition, 1)
|
||||
info("Creating set $set_name")
|
||||
data = Integer[]
|
||||
if endswith(strip(definition), "GENERATE")
|
||||
line = lines[idx_start + 1]
|
||||
m = matchall(r"[0-9]+", line)
|
||||
first_id, last_id, step = map(x-> parse(Int, x), m)
|
||||
set_ids = collect(first_id:step:last_id)
|
||||
map(x->push!(data, x), set_ids)
|
||||
else
|
||||
for line in lines[idx_start + 1: idx_end]
|
||||
if !(empty_or_comment_line(line))
|
||||
m = matchall(r"[0-9]+", line)
|
||||
set_ids = map(s -> parse(Int, s), m)
|
||||
map(x->push!(data, x), set_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
selected_set = key == :NSET ? INodeSet : IElementSet
|
||||
set_alloc = selected_set(set_name, data)
|
||||
end
|
||||
|
||||
#
|
||||
parse_section = Dict(:NODE => parse_nodes,
|
||||
:ELEMENT => parse_elements,
|
||||
:NSET => parse_set,
|
||||
:ELSET => parse_set)
|
||||
|
||||
"""
|
||||
Find lines, which contain keywords, for example "*NODE"
|
||||
@@ -80,27 +146,30 @@ function find_keywords(lines)
|
||||
indexes
|
||||
end
|
||||
|
||||
"""
|
||||
"""
|
||||
function parse_abaqus(fid::IOStream)
|
||||
# model = Dict()
|
||||
model = AbaqusModel()
|
||||
lines = readlines(fid)
|
||||
info("Registered handlers: $(keys(parse_section))")
|
||||
keyword_indexes = find_keywords(lines)
|
||||
idx_start = keyword_indexes[1]
|
||||
keyword_sym::Symbol = :none
|
||||
parser::Function = x->()
|
||||
for idx_end in keyword_indexes[2:end]
|
||||
keyword_line = lines[idx_start]
|
||||
keyword = match(r"\s*(\w+)", keyword_line).match
|
||||
keyword_sym = :($(uppercase(keyword)))
|
||||
keyword_line = uppercase(lines[idx_start])
|
||||
keyword = regex_match(r"\s*(\w+)", keyword_line, 1)
|
||||
keyword_sym = symbol(keyword)
|
||||
try
|
||||
parser = parse_section(keyword_sym)
|
||||
parser = parse_section[keyword_sym]
|
||||
catch
|
||||
warn("Keyword not implemented: ", keyword_sym)
|
||||
idx_start = idx_end
|
||||
continue
|
||||
end
|
||||
parser(model, lines, keyword_sym, idx_start, idx_end-1)
|
||||
idx_start = idx_end
|
||||
# parser(model, lines, idx_start, idx_end)
|
||||
end
|
||||
# return model
|
||||
return model
|
||||
end
|
||||
|
||||
|
||||
+14
-4
@@ -1,6 +1,12 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
abstract calculation_model
|
||||
|
||||
type Model <: calculation_model
|
||||
jotain
|
||||
end
|
||||
|
||||
|
||||
type INode{T<:Real}
|
||||
id::Integer
|
||||
@@ -11,14 +17,18 @@ type IElement{T<:Real}
|
||||
id::Integer
|
||||
connectivity::Array{T, 1}
|
||||
element_type::AbstractString
|
||||
# fields :: Dict{AbstractString, Field}
|
||||
end
|
||||
|
||||
# IElement(id, conn, eltype) = IElement(id, conn, eltype, Dict())
|
||||
|
||||
type INodeset
|
||||
node_ids
|
||||
type INodeSet
|
||||
name::AbstractString
|
||||
node_ids::Array{Integer, 1}
|
||||
end
|
||||
|
||||
type IElementset
|
||||
jotain
|
||||
type IElementSet
|
||||
name::AbstractString
|
||||
element_ids::Array{Integer, 1}
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user