mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-17 01:02:13 +00:00
abaqus_reader.jl not independent from Model
This commit is contained in:
+2
-2
@@ -12,14 +12,14 @@ include("core.jl")
|
||||
end
|
||||
|
||||
module API
|
||||
include("api.jl")
|
||||
#include("api.jl")
|
||||
|
||||
# export ....
|
||||
|
||||
end
|
||||
|
||||
module Preprocess
|
||||
# include("abaqus_reader.jl") <-- ERROR: LoadError: LoadError: UndefVarError: Model not defined
|
||||
include("abaqus_reader.jl")
|
||||
include("aster_reader.jl")
|
||||
end
|
||||
|
||||
|
||||
+58
-23
@@ -1,13 +1,21 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
import Base: parse
|
||||
|
||||
element_has_nodes(::Type{Val{:C3D4}}) = 4
|
||||
element_has_type( ::Type{Val{:C3D4}}) = Tet4
|
||||
element_has_type( ::Type{Val{:C3D4}}) = :Tet4
|
||||
|
||||
element_has_nodes(::Type{Val{:C3D10}}) = 10
|
||||
element_has_type(::Type{Val{:C3D10}}) = :Tet10
|
||||
|
||||
element_has_nodes(::Type{Val{:C3D10}}) = 10
|
||||
element_has_nodes(::Type{Val{:C3D20}}) = 20
|
||||
|
||||
element_has_nodes(::Type{Val{:C3D20E}}) = 20
|
||||
|
||||
element_has_nodes(::Type{Val{:S3}}) = 3
|
||||
element_has_type( ::Type{Val{:S3}}) = Seg3
|
||||
element_has_type( ::Type{Val{:S3}}) = :Seg3
|
||||
|
||||
"""
|
||||
Checks for if line is a comment line or just empty
|
||||
@@ -19,8 +27,9 @@ end
|
||||
"""
|
||||
Function for parsing nodes from the file
|
||||
"""
|
||||
function parse_section(model::Model,
|
||||
lines, key::Symbol, idx_start, idx_end, ::Type{Val{:NODE}})
|
||||
function parse_section(model, lines, key::Symbol, idx_start,
|
||||
idx_end, ::Type{Val{:NODE}})
|
||||
|
||||
info("Parsing nodes")
|
||||
ids = Integer[]
|
||||
definition = lines[idx_start]
|
||||
@@ -29,15 +38,13 @@ function parse_section(model::Model,
|
||||
m = matchall(r"[-0-9.]+", line)
|
||||
node_id = parse(Int, m[1])
|
||||
coords = float(m[2:end])
|
||||
node = Node(node_id, coords)
|
||||
add_node!(model, node)
|
||||
push!(ids, node_id)
|
||||
model["nodes"][node_id] = coords
|
||||
end
|
||||
end
|
||||
has_set_def = match(r"NSET=([\w\_\-]+)", definition)
|
||||
if has_set_def != nothing
|
||||
set_name = has_set_def[1]
|
||||
add_set!(model, Val{:NSET}, set_name, ids)
|
||||
model["nsets"][set_name] = ids
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,6 +53,7 @@ Custon regex to find match from string. Index used if there are multiple matches
|
||||
"""
|
||||
function regex_match(regex_str, line, idx)
|
||||
return match(regex_str, line).captures[idx]
|
||||
println(eltype_sym)
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -66,7 +74,7 @@ end
|
||||
"""
|
||||
Parse elements from input.
|
||||
"""
|
||||
function parse_section(model::Model, lines, key, idx_start, idx_end, ::Type{Val{:ELEMENT}})
|
||||
function parse_section(model, lines, key, idx_start, idx_end, ::Type{Val{:ELEMENT}})
|
||||
definition = uppercase(lines[idx_start])
|
||||
element_type = regex_match(r"TYPE=([\w\-\_]+)", definition, 1)
|
||||
eltype_sym = symbol(element_type)
|
||||
@@ -81,24 +89,24 @@ function parse_section(model::Model, lines, key, idx_start, idx_end, ::Type{Val{
|
||||
numbers = map(x-> parse(Int, x), arr_num_as_str)
|
||||
if !(empty_or_comment_line(line))
|
||||
id = numbers[1]
|
||||
push!(ids, id)
|
||||
connectivity = numbers[2:end]
|
||||
while length(connectivity) != eltype_nodes
|
||||
@assert length(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!(connectivity, x), numbers)
|
||||
push!(connectivity, numbers...)
|
||||
end
|
||||
element = Element{element_type}(connectivity)
|
||||
add_element!(model, element)
|
||||
push!(ids, id)
|
||||
model["elements"][id] = Dict(("type"=>element_type),
|
||||
("connectivity"=>connectivity))
|
||||
end
|
||||
line = consume(list_iterator)
|
||||
end
|
||||
has_set_def = match(r"ELSET=([\w\_\-]+)", definition)
|
||||
if has_set_def != nothing
|
||||
set_name = has_set_def[1]
|
||||
add_set!(model, Val{:ELSET}, set_name, ids)
|
||||
model["elsets"][set_name] = ids
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,21 +126,44 @@ function parse_section(model, lines, key, idx_start, idx_end, ::Union{Type{Val{:
|
||||
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)
|
||||
push!(data, 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)
|
||||
push!(data, set_ids...)
|
||||
end
|
||||
end
|
||||
end
|
||||
selected_set = key == :NSET ? NodeSet : ElementSet
|
||||
set_alloc = selected_set(set_name, data)
|
||||
add_set!(model, set_alloc)
|
||||
end
|
||||
selected_set = key == :NSET ? "nsets" : "elsets"
|
||||
model[selected_set][set_name] = data
|
||||
end
|
||||
|
||||
"""
|
||||
TODO ! Parse surface keyword
|
||||
"""
|
||||
function parse_section(model, lines, key, idx_start, idx_end,
|
||||
::Type{Val{:SURFACE}})
|
||||
info("Parsing surface")
|
||||
definition = uppercase(lines[idx_start])
|
||||
ids = Vector{Tuple(Int, Int)}()
|
||||
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])
|
||||
nodes[node_id] = coords
|
||||
model["nodes"][node_id] = coords
|
||||
end
|
||||
end
|
||||
has_set_def = match(r"NSET=([\w\_\-]+)", definition)
|
||||
if has_set_def != nothing
|
||||
set_name = has_set_def[1]
|
||||
model["nsets"][set_name] = ids
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
"""
|
||||
Find lines, which contain keywords, for example "*NODE"
|
||||
@@ -144,7 +175,7 @@ function find_keywords(lines)
|
||||
push!(indexes, idx)
|
||||
end
|
||||
end
|
||||
push!(indexes, length(lines))
|
||||
push!(indexes, length(lines) + 1)
|
||||
indexes
|
||||
end
|
||||
|
||||
@@ -152,17 +183,21 @@ end
|
||||
Main function for parsing Abaqus input file.
|
||||
"""
|
||||
function parse_abaqus(fid::IOStream)
|
||||
model = Model()
|
||||
lines = readlines(fid)
|
||||
keyword_indexes = find_keywords(lines)
|
||||
idx_start = keyword_indexes[1]
|
||||
keyword_sym::Symbol = :none
|
||||
parser::Function = x->()
|
||||
model = Dict{AbstractString, Any}()
|
||||
model["nodes"] = Dict{Int, Vector{AbstractFloat}}()
|
||||
model["nsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
model["elsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
model["elements"] = Dict{Integer, Any}()
|
||||
for idx_end in keyword_indexes[2:end]
|
||||
keyword_line = uppercase(lines[idx_start])
|
||||
keyword = regex_match(r"\s*(\w+)", keyword_line, 1)
|
||||
k_sym = symbol(keyword)
|
||||
if method_exists(parse_section, Tuple{Model, Array{Integer, 1}, Symbol,
|
||||
if method_exists(parse_section, Tuple{Dict, Array{Integer, 1}, Symbol,
|
||||
Integer, Integer, Type{Val{k_sym}}})
|
||||
parse_section(model, lines, k_sym, idx_start, idx_end-1, Val{k_sym})
|
||||
else
|
||||
|
||||
+30
-27
@@ -3,17 +3,17 @@
|
||||
|
||||
module AbaqusReaderTests
|
||||
|
||||
using JuliaFEM
|
||||
#using JuliaFEM
|
||||
using JuliaFEM.Test
|
||||
|
||||
using JuliaFEM: parse_abaqus, parse_element_section
|
||||
using JuliaFEM.Preprocess: parse_abaqus, parse_section
|
||||
|
||||
function test_read_abaqus_model()
|
||||
# FIXME: get_test_data()
|
||||
model = open(parse_abaqus, Pkg.dir("JuliaFEM")*"/geometry/3d_beam/palkki.inp")
|
||||
@test length(model["nodes"]) == 298
|
||||
@test length(model["elements"]) == 120
|
||||
@test length(model["elsets"]["Body1"]) == 120
|
||||
@test length(model["elsets"]["BODY1"]) == 120
|
||||
@test length(model["nsets"]["SUPPORT"]) == 9
|
||||
@test length(model["nsets"]["LOAD"]) == 9
|
||||
@test length(model["nsets"]["TOP"]) == 83
|
||||
@@ -33,50 +33,53 @@ end
|
||||
=#
|
||||
|
||||
function test_read_element_section()
|
||||
data = """
|
||||
data = """*ELEMENT, TYPE=C3D10, ELSET=BEAM
|
||||
1, 243, 240, 191, 117, 245, 242, 244,
|
||||
1, 2, 196
|
||||
2, 204, 199, 175, 130, 207, 208, 209,
|
||||
3, 4, 176
|
||||
"""
|
||||
model = Dict()
|
||||
header = Dict(
|
||||
"section" => "ELEMENT",
|
||||
"options" => Dict("TYPE" => "C3D10", "ELSET" => "BEAM"))
|
||||
parse_element_section(model, header, data)
|
||||
data = split(data, "\n")
|
||||
model = Dict{AbstractString, Any}()
|
||||
model["nsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
model["elsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
model["elements"] = Dict{Integer, Any}()
|
||||
parse_section(model, data, :ELEMENT, 1, 5, Val{:ELEMENT})
|
||||
@test length(model["elements"]) == 2
|
||||
@test model["elements"][1] == [243, 240, 191, 117, 245, 242, 244, 1, 2, 196]
|
||||
@test model["elements"][2] == [204, 199, 175, 130, 207, 208, 209, 3, 4, 176]
|
||||
@test model["elements"][1]["connectivity"] == [243, 240, 191, 117, 245, 242, 244, 1, 2, 196]
|
||||
@test model["elements"][2]["connectivity"] == [204, 199, 175, 130, 207, 208, 209, 3, 4, 176]
|
||||
@test model["elsets"]["BEAM"] == [1, 2]
|
||||
end
|
||||
|
||||
function test_read_surface_set_section()
|
||||
data = """
|
||||
31429,S1
|
||||
31481,S3
|
||||
"""
|
||||
model = Dict()
|
||||
header = Dict(
|
||||
"section" => "SURFACE",
|
||||
"options" => Dict("TYPE" => "ELEMENT", "NAME" => "LOAD"))
|
||||
parse_surface_section(model, header, data)
|
||||
@test model["surfaces"]["LOAD"] = [(31429,1), (31481,3)]
|
||||
|
||||
end
|
||||
#function test_read_surface_set_section()
|
||||
# data = """*SURFACE, TYPE=ELEMENT, NAME=LOAD
|
||||
# 31429,S1
|
||||
# 31481,S3
|
||||
# """
|
||||
# model = Dict{AbstractString, Any}()
|
||||
# model["nsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
# model["elsets"] = Dict{AbstractString, Vector{Int}}()
|
||||
# model["elements"] = Dict{Integer, Any}()
|
||||
# parse_section(model, data, :SURFACE, 1, 3, Val{:SURFACE})
|
||||
# @test model["surfaces"]["LOAD"] = [(31429,1), (31481,3)]
|
||||
#
|
||||
#end
|
||||
|
||||
function test_unknown_handler_warning_message()
|
||||
fn = tempname()
|
||||
fid = open(fn, "w")
|
||||
testdata = """
|
||||
*ELEMENT2, TYPE=C3D10, ELSET=Body1
|
||||
testdata = """*ELEMENT2, TYPE=C3D10, ELSET=Body1
|
||||
1, 243, 240, 191, 117, 245, 242, 244,
|
||||
1, 2, 196
|
||||
"""
|
||||
write(fid, testdata)
|
||||
close(fid)
|
||||
model = open(parse_abaqus, fn)
|
||||
# empty model expected, parser doesn't know what to do with unknown section
|
||||
# empty model expected, parser doesn't know what to do with unknown section
|
||||
@test length(model) == 0
|
||||
end
|
||||
|
||||
|
||||
test_read_abaqus_model()
|
||||
test_read_element_section()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user