more api functionality + tests.

This commit is contained in:
Olli Väinölä
2015-12-01 16:03:23 +02:00
parent bde6ed9508
commit 266cd13b50
6 changed files with 366 additions and 242 deletions
+2 -213
View File
@@ -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")
+120
View File
@@ -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
+156
View File
@@ -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[],
#)
+53
View File
@@ -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"
-2
View File
@@ -80,6 +80,4 @@ function test_unknown_handler_warning_message()
end
test_read_abaqus_model()
test_read_element_section()
end
+35 -27
View File
@@ -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