diff --git a/src/api.jl b/src/api.jl index 1dd3ea3..8d72e42 100644 --- a/src/api.jl +++ b/src/api.jl @@ -1,216 +1,5 @@ # This file is a part of JuliaFEM. # License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md -# define these -abstract Problem -abstract Element - -abstract BoundaryCondition - -type NeumannBC{ S <: AbstractString} <: BoundaryCondition - definition :: S - value :: Any - set_name :: S -end - -type DirichletBC{ S <: AbstractString } <: BoundaryCondition - definition :: S - value :: Any - set_name :: S -end - -typealias DisplacementBC DirichletBC -typealias TemperatureBC DirichletBC - -typealias ForceBC NeumannBC -typealias HeatFluxBC NeumannBC - -""" -""" -type Material{S <: AbstractString, T<:Real} - name :: AbstractString - scalar_data :: Dict{S, T} -end - -Material(name, data) = Material(name, Dict(data)) -Material(name) = Material(name, Dict{AbstractString, Real}()) -Material() = Material("", Dict{AbstractString, Real}()) - -function Base.setindex!{T <: AbstractString }(material::Material, val::Real, name::T) - material.scalar_data[name] = val -end - -""" -""" -type Node{T<:Real} - coords::Array{T, 1} -end - -#""" -#""" -#type MElement{I <: Integer} #, T <: AbstractElement} -# id :: Integer -# connectivity :: Array{I, 1} -# element_type :: Tet4 -#end - -""" -Set of nodes. Holds name and the ids -""" -type NodeSet - name :: AbstractString - node_ids :: Array{Integer, 1} -end - -# NodeSet(arr::Array{Int64, 1}) = myn(arr, Dict(zip(arr, collect(1:length(arr))))) - - -""" -""" -type ElementSet{E<:AbstractElement} - name :: AbstractString - material :: Material - elements :: Vector{E} -end - -ElementSet{E<:AbstractElement}(name::ASCIIString, elements::E...) = -ElementSet(name,Material(), E[elements...]) - -type LoadCase{ P <: Problem } - problem :: P - boundary_conditions :: Vector{Union{NeumannBC, DirichletBC}} -end - -LoadCase{P <: Problem}(a :: P) = LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}()) -LoadCase{P <: Problem, B <: BoundaryCondition}(a :: P, b :: B) = LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}([b])) -LoadCase{P <: Problem, B <: BoundaryCondition}(a :: P, b :: Vector{B}) = -LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}(b)) - - -""" -""" -type Model - name :: ASCIIString - nodes :: Dict{Union{Int64, ASCIIString}, Node} - elements :: Dict{Union{Int64, ASCIIString}, Element} - sets :: Dict{AbstractString, Union{NodeSet, ElementSet}} - load_cases :: Vector{LoadCase} - # settings :: Dict{AbstractString, Real} -end - -Model(name::ASCIIString) = Model(name, - Dict{Union{Int64, ASCIIString}, Node}(), - Dict{Union{Int64, ASCIIString}, Element}(), - Dict{AbstractString, - Union{NodeSet, ElementSet}}(), - LoadCase[], -) - -function Base.convert{T<:AbstractFloat}(::Type{Node}, data::Vector{T}) - Node(data) -end - -function set_material!{S <: AbstractString}(model::Model, material::Material, set_name::S) - model.sets[set_name].material = material -end - - -function get_element_set(model::Model, set_name::ASCIIString) - get_set = model.sets[set_name] - isa(get_set, ElementSet) ? get_set : err("Found set $(set_name) - but it is not a ElementSet. Check if you have used - dublicate set names.") -end - -function add_boundary_condition!{B <: BoundaryCondition}(case::LoadCase, bc::B) - push!(case.boundary_conditions, bc) -end - -function add_boundary_condition!{B <: BoundaryCondition}(case::LoadCase, bc::Vector{B}) - map(x-> push!(case.boundary_conditions, x), bc) -end - -function add_loadcase!(model::Model, case::LoadCase) - push!(model.load_cases, case) -end - -function add_loadcase!{T<:LoadCase}(model::Model, case::Vector{T}) - map(x-> push!(model.load_cases, x), case) -end - -""" -""" -function build_core_elements() - -end - -""" -""" -function set_core_element_material() - -end - -""" -element_has_type( ::Type{Val{:C3D4}}) = Tet4 -""" -function create_problems() - -end - -""" -""" -function add_problems!() - -end - -""" -Get set from model -""" -function get_set{S <: AbstractString}(model::Model, name::S) - try - return model.set[name] - catch - err("Given set: $(name) does not exist in Model") - end -end - -""" -""" -function push!(model::Model, element::Element) - push!(model.elements, element...) -end - -""" -""" -function push!(model::Model, elements::Vector{Element}) - push!(model.element, elements...) -end - -""" -""" -function push!(model::Model, node::Node) - push!(model.nodes, node) -end - -function push!(model::Model, nodes::Vector{Node}) - push!(mode, nodes...) -end - -""" -""" -function add_set!(model::Model, set::Union{NodeSet, ElementSet}) - model.sets[set.name] = set -end - -function add_set!{S <: AbstractString}(model::Model, ::Type{Val{:NSET}}, - name::S, ids::Vector{Integer}) - new_set = NodeSet(name, ids) - add_set!(model, new_set) -end - -function add_set!{S <: AbstractString}(model::Model, ::Type{Val{:ELSET}}, - name::S, ids::Vector{Integer}) - new_set = ElementSet(name, ids) - add_set!(model, new_set) -end - +include("api_types.jl") +include("api_functions.jl") diff --git a/src/api_functions.jl b/src/api_functions.jl new file mode 100644 index 0000000..4bf050b --- /dev/null +++ b/src/api_functions.jl @@ -0,0 +1,120 @@ +# This file is a part of JuliaFEM. +# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md + +function add_boundary_condition!{P<:APIProblem}(case::LoadCase{P}, bc) + push!(case.boundary_conditions, bc) +end + +function add_solver!{P<:APIProblem, S<:APISolver}(case::LoadCase{P}, + bc::Type{S}) + case.solver = bc +end + +#function Base.convert{T<:AbstractFloat}(::Type{Node}, data::Vector{T}) +# Node(data) +#end:q +# +# +#function set_material!{S <: AbstractString}(model::Model, material::Material, set_name::S) +# model.sets[set_name].material = material +#end +# +# +#function get_element_set(model::Model, set_name::ASCIIString) +# get_set = model.sets[set_name] +# isa(get_set, ElementSet) ? get_set : err("Found set $(set_name) +# but it is not a ElementSet. Check if you have used +# dublicate set names.") +#end +# +#function add_boundary_condition!{B <: BoundaryCondition}(case::LoadCase, bc::B) +# push!(case.boundary_conditions, bc) +#end +# +#function add_boundary_condition!{B <: BoundaryCondition}(case::LoadCase, bc::Vector{B}) +# map(x-> push!(case.boundary_conditions, x), bc) +#end +# +#function add_loadcase!(model::Model, case::LoadCase) +# push!(model.load_cases, case) +#end +# +#function add_loadcase!{T<:LoadCase}(model::Model, case::Vector{T}) +# map(x-> push!(model.load_cases, x), case) +#end +# +#""" +#""" +#function build_core_elements() +# +#end +# +#""" +#""" +#function set_core_element_material() +# +#end +# +#""" +#element_has_type( ::Type{Val{:C3D4}}) = Tet4 +#""" +#function create_problems() +# +#end +# +#""" +#""" +#function add_problems!() +# +#end +# +#""" +#Get set from model +#""" +#function get_set{S <: AbstractString}(model::Model, name::S) +# try +# return model.set[name] +# catch +# err("Given set: $(name) does not exist in Model") +# end +#end +# +#""" +#""" +#function push!(model::Model, element::Element) +# push!(model.elements, element...) +#end +# +#""" +#""" +#function push!(model::Model, elements::Vector{Element}) +# push!(model.element, elements...) +#end +# +#""" +#""" +#function push!(model::Model, node::Node) +# push!(model.nodes, node) +#end +# +#function push!(model::Model, nodes::Vector{Node}) +# push!(mode, nodes...) +#end +# +#""" +#""" +#function add_set!(model::Model, set::Union{NodeSet, ElementSet}) +# model.sets[set.name] = set +#end +# +#function add_set!{S <: AbstractString}(model::Model, ::Type{Val{:NSET}}, +# name::S, ids::Vector{Integer}) +# new_set = NodeSet(name, ids) +# add_set!(model, new_set) +#end +# +#function add_set!{S <: AbstractString}(model::Model, ::Type{Val{:ELSET}}, +# name::S, ids::Vector{Integer}) +# new_set = ElementSet(name, ids) +# add_set!(model, new_set) +#end diff --git a/src/api_types.jl b/src/api_types.jl new file mode 100644 index 0000000..50a19ba --- /dev/null +++ b/src/api_types.jl @@ -0,0 +1,156 @@ +# This file is a part of JuliaFEM. +# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md + +#abstract APIType +# +#abstract Mesh <: APIType +#abstract APIElement <: Mesh +#abstract APINode <: Mesh +# +#abstract APIProblem <: APIType +#abstract HeatProblem <: APIProblem +#abstract ElasticityProblem <: APIProblem +# +#abstract APISolver <: APIType +#abstract SolverLinear <: APISolver +# define these +#abstract Problem +#abstract Element + +#abstract BoundaryCondition + +type NeumannBC + set_name :: ASCIIString + value :: Any +end + +type DirichletBC + set_name :: ASCIIString + value :: Any +end + +typealias DisplacementBC DirichletBC +typealias TemperatureBC DirichletBC + +typealias ForceBC NeumannBC +typealias HeatFluxBC NeumannBC + +""" +""" +type Material + name :: ASCIIString + scalar_data :: Dict{ASCIIString, Float64} +end + +#Material(name, data) = Material(name, Dict(data)) +Material(name) = Material(name, Dict{ASCIIString, Float64}()) +Material() = Material("", Dict{ASCIIString, Float64}()) + +function Base.setindex!{T <: AbstractString }(material::Material, val::Real, name::T) + material.scalar_data[name] = val +end + + +type Node{T<:Real} <: APINode + id :: Union{Integer, ASCIIString} + coords :: Array{T, 1} +end + +type Element + id :: Union{Integer, ASCIIString, Void} + connectivity :: Vector{Int64} + element_type :: Symbol + fields :: Any # Dict{} +end + +#Element{I<:Integer}(eltype::Symbol, conn::Vector{I}) = Element( +# nothing, +# conn, +# eltype ) +# +#Element{I<:Integer}(conn::Vector{I}, eltype::ASCIIString) = Element( +# nothing, +# conn, +# eltype) + +#""" +#Set of nodes. Holds name and the ids +#""" +#type NodeSet} +# name :: AbstractString +# node_ids :: Array{Integer, 1} +#end + +# NodeSet(arr::Array{Int64, 1}) = myn(arr, Dict(zip(arr, collect(1:length(arr))))) + + +""" +""" +type ElementSet + name :: ASCIIString + elements :: Vector{Int64} + material :: Material +end# + +ElementSet(name::ASCIIString, elements::Vector{Element}) = + ElementSet(name, map(x-> x.id, elements), Material()) + +ElementSet(name::ASCIIString, ids::Vector{Int64}) = + ElementSet(name, ids, Material()) + +type LoadCase{ P <: APIProblem } + problem :: Type{P} + boundary_conditions #:: Vector{Union{NeumannBC, DirichletBC}} + solver +end + +#LoadCase{P <: APIProblem}(a :: P) = LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}()) +LoadCase(a) = LoadCase(a, [], nothing) +#LoadCase{P <: Problem, B <: BoundaryCondition}(a :: P, b :: B) = LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}([b])) +#LoadCase{P <: Problem, B <: BoundaryCondition}(a :: P, b :: Vector{B}) = +#LoadCase(a, Vector{Union{NeumannBC,DirichletBC}}(b)) + +""" +""" +type Model + name + nodes + elements :: Dict{Union{ASCIIString, Int64}, Element} + elsets + nsets + load_cases + #settings :: Dict{AbstractString, Real} + #results +end + +Model(name::ASCIIString, abq_input::Dict) = Model( + name, + abq_input["nodes"], + abq_input["elements"], + abq_input["elsets"], + abq_input["nsets"], + Dict()) + +Model(name::ASCIIString) = Model( + name, + Dict(), + Dict{Union{ASCIIString, Int64}, Element}(), + Dict(), + Dict(), + Dict(), +) + +#function Base.setindex!(dicti::Dict{Union{ASCIIString, Int64}, Element}, el::Element, idx::Union{ASCIIString, Int64}) +# el.id = idx +# dicti[idx] = el +# return dicti +#end + +#Model(name::ASCIIString) = Model(name, +# Dict{Union{Int64, ASCIIString}, Node}(), +# Dict{Union{Int64, ASCIIString}, Element}(), +# Dict{AbstractString, +# Union{NodeSet, ElementSet}}(), +# LoadCase[], +#) + diff --git a/src/interfaces.jl b/src/interfaces.jl index 7d546b6..aebfcad 100644 --- a/src/interfaces.jl +++ b/src/interfaces.jl @@ -1,5 +1,58 @@ # This file is a part of JuliaFEM. # License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md +using JuliaFEM +using JuliaFEM.API: Model + +function solve!(model::Model, case_name::ASCIIString, time::Float64) + element_ids = keys(model.elements) + all_eles = model.elements + case = model.load_cases[case_name] + bcs = case.boundary_conditions + nodes = model.nodes + field_problem = JuliaFEM.Core.(case.problem)() + # luodaan core elementit + # for each in elements + # end + + # Lisätään Neumann:nin reunaehdot ja listään field probleemaan + # for each in neumann + # end + + # lisätään Dirichlet:in reunaehdot ja lisätään reunaehtoon + # for each in dirichlet + # end + # + # SOLVE ! + + # Adding elements to field problem + # for element in all_eles + # el_type = element.element_type + # el_id = element.id + # mat = element.material + # conn = element.connectivity + # core_element = JuliaFEM.Core.(el_type)(conn) + # core_element["geometry"] = map(x->nodes[x], conn) + # for each in keys(mat) + # core_element[each] = mat[each] + # end + # # TODO ! Lisätään Neumann:nin reunaehdot ennen kuin + # # lisätään probleemaan + # push!(field_problem, core_element) + # model.elements[el_id].fields = core_element.fields + # end + # # käydaan läpi Dirichlet:in reunaehdot + # for bc in bcs + # elset_name = bc.set_name + # elset = model.elsets[elset_name] + # for element in elset.elements + # element_id = element.id + # el_type = element.element_type + # core_element = JuliaFEM.Core.(el_type)(element.connectivity) + # + # model.elements[element_id].fields = core_element.fields + # println(core_element) + end +end function foo() return "bar" diff --git a/test/test_abaqus_reader.jl b/test/test_abaqus_reader.jl index 052bd2e..21ce83b 100644 --- a/test/test_abaqus_reader.jl +++ b/test/test_abaqus_reader.jl @@ -80,6 +80,4 @@ function test_unknown_handler_warning_message() end -test_read_abaqus_model() -test_read_element_section() end diff --git a/test/test_api.jl b/test/test_api.jl index 803be57..b98cec1 100644 --- a/test/test_api.jl +++ b/test/test_api.jl @@ -3,63 +3,71 @@ module APITests -using JuliaFEM -using JuliaFEM.Test -using JuliaFEM: Model, Node, Element, ElementSet, -Material, Quad4, Seg2 +using JuliaFEM.Preprocess: parse_abaqus +using JuliaFEM.API: Model, Element, ElementSet, Material, LoadCase, +HeatConduction, DirichletBC, NeumannBC, SolverLinear, +add_boundary_condition!, add_solver! +using JuliaFEM.Interfaces: solve! + function test_basic() # basic workflow, copied from test_solver.jl - model = Model("my calculation model") + model = Model("Piston Calculation") - # create nodes model.nodes[1] = [0.0, 0.0] model.nodes[2] = [1.0, 0.0] model.nodes[3] = [1.0, 1.0] model.nodes[4] = [0.0, 1.0] # create elements - e1 = Element{Quad4}([1, 2, 3, 4]) - e2 = Element{Seg2}([1, 2]) + e1 = Element(1, [1, 2, 3, 4], :Quad4) + e2 = Element(2, [1, 2], :Seg2) + model.elements[1] = e1 + model.elements[2] = e2 + # element set - elset = ElementSet("body", e1, e2) - elset2 = ElementSet("boundary", e2) - # push!(model, elset, elset2) + elset = ElementSet("body", [e1, e2]) + elset2 = ElementSet("boundary", [1]) + + model.elsets["body"] = elset + model.elsets["boundary"] = elset2 # material properties - # material = Material("my material") - # material["temperature thermal conductivity"] = 6.0 - # material["density"] = 36.0 - # set_material!(model, material, "Es") + material = Material("MatMat") + material["temperature thermal conductivity"] = 6.0 + material["density"] = 36.0 + elset.material = material # Create problem - # field_problem = HeatProblem() + field_problem = LoadCase(HeatConduction) # boundary conditions - # bc = DirichletBC("body", "temperature" => 0.0) - # bc = DirichletBC("Es", 0.0) - # ne = NeumannBC("boundary", "temperature flux" => ((0.0 => 0.0), - # (1.0=>600.0))) + bc = DirichletBC("body", "temperature" => 0.0) + ne = NeumannBC("boundary", "temperature flux" => ((0.0 => 0.0), + (1.0=>600.0))) # LoadCase - # case = LoadCase("Heat problem") - # push!(case, field_problem) - # push!(case, bc, ne) + add_boundary_condition!(field_problem, bc) + add_boundary_condition!(field_problem, ne) # Get solver - # solver = LinearSolver - # push!(case, solver) + add_solver!(field_problem, :LinearSolver) # add case - # push!(model, case) + model.load_cases["Heat problem"] = field_problem # Solve problem - # solve!(model, 1.0, "Heat problem") + results = solve(model, "Heat problem", 1.0) # xi = [0.0, -1.0] # T = el1("temperature", xi, 1.0) # T = model("temperature", [0.5, 0.0], 1) end +function test_piston_8789() + abaqus_input = open(parse_abaqus, "../geometry/piston/piston_8789_P1.inp") + + model = Model("Piston Calculation", abaqus_input) +end test_basic() end