diff --git a/src/JuliaFEM.jl b/src/JuliaFEM.jl index 810a6ac..487dad1 100644 --- a/src/JuliaFEM.jl +++ b/src/JuliaFEM.jl @@ -3,12 +3,6 @@ # __precompile__() -using Logging - -if haskey(ENV, "JULIAFEM_LOGLEVEL") - ENV["JULIAFEM_LOGLEVEL"] == "DEBUG" && Logging.configure(level=DEBUG) -end - """ This is JuliaFEM -- Finite Element Package """ @@ -16,6 +10,17 @@ module JuliaFEM importall Base +using Logging + +Logging.configure(level=INFO) + +if haskey(ENV, "JULIAFEM_LOGLEVEL") + ENV["JULIAFEM_LOGLEVEL"] == "INFO" && Logging.configure(level=INFO) + ENV["JULIAFEM_LOGLEVEL"] == "DEBUG" && Logging.configure(level=DEBUG) +end + +export info, debug + module Testing if VERSION >= v"0.5-" diff --git a/src/elements.jl b/src/elements.jl index 6b77435..513b690 100644 --- a/src/elements.jl +++ b/src/elements.jl @@ -198,9 +198,20 @@ julia> update!(element, "geometry", data) As a result element now have time invariant (variable) vector field "geometry" with data ([0.0, 0.0], [1.0, 2.0]). """ -function update!(element::Element, field_name::AbstractString, data::Dict) +function update!{E}(element::Element{E}, field_name::AbstractString, data::Dict) #element[field_name] = Field(data) - element[field_name] = [data[i] for i in get_connectivity(element)] + element_id = element.id + local_connectivity = get_connectivity(element) + for i in local_connectivity + if !haskey(data, i) + ndata = length(data) + critical("Unable to set field data $field_name for element $E with + id $element_id and connectivity $local_connectivity: no data for + node id $i found. Length of data dict = $ndata") + end + end + local_data = [data[i] for i in local_connectivity] + element[field_name] = local_data end function update!{K,V}(element::Element, field_name, data::Pair{Float64, Dict{K, V}}) diff --git a/src/preprocess.jl b/src/preprocess.jl index eefdc1a..98b5d8b 100644 --- a/src/preprocess.jl +++ b/src/preprocess.jl @@ -95,8 +95,8 @@ function create_element(mesh::Mesh, id::Int) connectivity = mesh.elements[id] element_type = getfield(JuliaFEM, mesh.element_types[id]) element = Element(element_type, connectivity) - update!(element, "geometry", mesh.nodes) element.id = id + update!(element, "geometry", mesh.nodes) return element end diff --git a/src/preprocess_abaqus_reader.jl b/src/preprocess_abaqus_reader.jl index 90c8af2..76e5a30 100644 --- a/src/preprocess_abaqus_reader.jl +++ b/src/preprocess_abaqus_reader.jl @@ -38,21 +38,25 @@ Function for parsing nodes from the file function parse_section(model, lines, key::Symbol, idx_start, idx_end, ::Type{Val{:NODE}}) - info("Parsing nodes") + info("Parsing *NODE block between lines $idx_start .. $idx_end") + nnodes = 0 ids = Integer[] definition = lines[idx_start] + debug("Definition line = $definition") for line in lines[idx_start + 1: idx_end] if !(empty_or_comment_line(line)) m = matchall(r"[-0-9.eE+]+", line) node_id = parse(Int, m[1]) coords = float(m[2:end]) model["nodes"][node_id] = coords + nnodes += 1 end end + info("$nnodes nodes found") has_set_def = match(r"NSET=([\w\_\-]+)", definition) if has_set_def != nothing set_name = has_set_def[1] - info("Creating nset $set_name") + info("Creating node set $set_name") model["nsets"][set_name] = ids end end @@ -163,13 +167,13 @@ end Parse SURFACE keyword """ function parse_section(model, lines, key, idx_start, idx_end, ::Type{Val{:SURFACE}}) - info("Parsing surface") + debug("Parsing surface") #definition = uppercase(lines[idx_start]) definition = lines[idx_start] #has_set_def = match(r"TYPE=([\w\_\-]+),.*NAME=([\w\_\-]+)", definition) has_set_def = Dict(map(y -> lowercase(strip(y[1])) => strip(y[2]), map(x -> split(x, "="), matchall(r"([\w\_\-]+[ ]*=[ ]*[\w\_\-]+)", definition)))) has_set_def != nothing || return - info(has_set_def) + debug(has_set_def) set_type = Symbol(has_set_def["type"]) set_name = Symbol(has_set_def["name"]) data = Vector{Tuple{Int64, Symbol}}() @@ -199,7 +203,6 @@ function find_keywords(lines) push!(indexes, idx) end end - push!(indexes, length(lines) + 1) return indexes end @@ -209,6 +212,10 @@ Main function for parsing Abaqus input file. function parse_abaqus(fid::IOStream) lines = readlines(fid) keyword_indexes = find_keywords(lines) + nkeyword_indexes = length(keyword_indexes) + debug("$nkeyword_indexes keyword indexes found: $keyword_indexes") + + push!(keyword_indexes, length(lines)+1) idx_start = keyword_indexes[1] keyword_sym::Symbol = :none parser::Function = x->() @@ -220,14 +227,16 @@ function parse_abaqus(fid::IOStream) model["surfaces"] = Dict{Symbol, Vector{Tuple{Int64, Symbol}}}() model["surface_types"] = Dict{Symbol, Symbol}() for idx_end in keyword_indexes[2:end] - keyword_line = uppercase(lines[idx_start]) - keyword = regex_match(r"\s*([\w ]+)", keyword_line, 1) + keyword_line = strip(uppercase(lines[idx_start])) + keyword = strip(regex_match(r"\s*([\w ]+)", keyword_line, 1)) k_sym = Symbol(keyword) args = Tuple{Dict, Vector{Int}, Symbol, Int, Int, Type{Val{k_sym}}} if method_exists(parse_section, args) parse_section(model, lines, k_sym, idx_start, idx_end-1, Val{k_sym}) -# else -# warn("Unknown section: $(keyword)") + else + debug("Unknown section: '$(keyword)'") + debug("keyword_line = '$keyword_line'") + debug("idx_start = $idx_start, idx_end = $idx_end") end idx_start = idx_end end diff --git a/test/test_preprocess_abaqus_reader.jl b/test/test_preprocess_abaqus_reader.jl index 2114792..a426d65 100644 --- a/test/test_preprocess_abaqus_reader.jl +++ b/test/test_preprocess_abaqus_reader.jl @@ -61,3 +61,21 @@ end mesh = abaqus_read_mesh(fn) @test length(mesh.nodes) == 3 end + +@testset "parse abaqus .inp created using hypermesh" begin + data = """ +** +** ABAQUS Input Deck Generated by HyperMesh Version : 14.0.120.28 +** Generated using HyperMesh-Abaqus Template Version : 14.0.120 +** +** Template: ABAQUS/STANDARD 3D +** +*NODE , Nset = nset_csys0 + 1, 2.649428 , -21.93735 , 217.2934 + 2, 27.54531 , 1.108443 , 228.8077 +""" + fn = tempname() * ".inp" + open(fn, "w") do fid write(fid, data) end + mesh = abaqus_read_mesh(fn) + @test length(mesh.nodes) == 2 +end