This commit is contained in:
ovainola
2015-08-31 21:21:42 +03:00
6 changed files with 277 additions and 87 deletions
+1 -2
View File
@@ -7,10 +7,9 @@ using Lexicon
using Logging
@Logging.configure(level=DEBUG)
Logging.info("loading types")
include("types.jl") # type definitions
Logging.info("loading elements")
include("elements.jl") # elements
include("equations.jl") # formulations
include("math.jl") # basic mathematical operations
include("elasticity_solver.jl")
+76 -4
View File
@@ -1,16 +1,70 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
using FactCheck
abstract Element
get_element(eq::Equation) = eq.element
export get_number_of_nodes
get_number_of_nodes(el::Type{Element}) = -1
get_element_dimension(el::Element) = -1
get_dbasisdx(el::Element) = nothing
get_basis(el::Element) = nothing
function test_element(eltype)
local el
n = get_number_of_nodes(eltype)
Logging.info("number of connectivity points (nodes) in this element: $n")
@fact n --> not(-1) """Unable to determine number of nodes for $eltype
define a function 'get_number_of_nodes' which returns the number of nodes for this element."""
Logging.info("Constructing element..")
try
el = eltype(collect(1:n))
catch
Logging.error("""Unable to create element with default constructor
define function $eltype(connectivity) which initializes this element.
""")
end
dim = get_element_dimension(el)
Logging.info("Element dimension: $dim")
@fact dim --> not(-1) """Unable to get element dimension
define function 'get_element_dimension' which return the dimension of this element (1, 2, 3)"""
# try to interpolate some scalar field
fld = collect(1:n)'
Logging.info("Setting scalar field $fld to element.")
set_field(el, "field1", fld)
@fact get_field(el, "field1") --> fld
try
get_basis(el, zeros(dim))
catch
Logging.error("""Unable to evaluate basis, define function 'get_basis' for this element.
""")
end
try
get_dbasisdxi(el, zeros(dim))
catch
Logging.error("""Unable to evaluate partial derivatives of basis, define function 'get_dbasisdxi' for this element.
""")
end
xi = zeros(dim)
Logging.info("Interpolating scalar field at $xi")
i = interpolate(el, "field1", zeros(dim))
Logging.info("Value: $i")
Logging.info("Element $eltype passed tests.")
end
"""
Get jacobian of element evaluated at point xi
"""
function get_jacobian(el::Element, xi)
dbasisdxi = get_dbasisdxi(el, xi)
X = get_field(el, "coordinates")
X = get_field(el, :coordinates)
#J = interpolate(X, dbasisdxi, xi)'
J = X*dbasisdxi
return J
@@ -40,11 +94,29 @@ function get_field(el::Element, field_name)
el.fields[field_name]
end
#"""
#Evaluate field in point xi using basis functions.
#"""
#function interpolate(el::Element, field::ASCIIString, xi::Array{Float64,1})
# (get_basis(el, xi)'*get_field(el, field))'
#end
"""
Evaluate field in point xi using basis functions.
"""
function interpolate(el::Element, field::ASCIIString, xi::Array{Float64,1})
(get_basis(el, xi)'*get_field(el, field))'
function interpolate(el::Element, field::Union(ASCIIString, Symbol), xi::Array{Float64,1})
f = get_field(el, field)
basis = get_basis(el, xi)
dim, nnodes = size(f)
result = zeros(dim)
for i=1:nnodes
result += basis[i]*f[:,i]
end
if dim == 1
return result[1]
else
return result
end
end
### Lagrange family ###
+69
View File
@@ -0,0 +1,69 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
abstract Equation
"""
Integration point
xi :: Array{Float64, 1}
(dimensionless) coordinates of integration point
weight :: Float64
Integration weight
attributes :: Dict{Any, Any}
This is used to save internal variables of IP needed e.g. for incremental
material models.
"""
type IntegrationPoint
xi :: Array{Float64, 1}
weight :: Float64
attributes :: Dict{Any, Any}
end
IntegrationPoint(xi, weight) = IntegrationPoint(xi, weight, Dict{ASCIIString, Any}())
get_lhs(eq::Equation, xi) = nothing
get_rhs(eq::Equation, xi) = nothing
get_element(eq::Equation) = eq.element
get_integration_points(eq::Equation) = eq.integration_points
# couple convenient functions -- could make weak form definition easier
get_basis(eq::Equation, ip::IntegrationPoint) = get_basis(get_element(eq), ip.xi)
get_dbasisdx(eq::Equation, ip::IntegrationPoint) = get_dbasisdx(get_element(eq), ip.xi)
interpolate(eq::Equation, field::Union(ASCIIString, Symbol), ip::IntegrationPoint) = interpolate(get_element(el), field, ip.xi)
integrate_lhs(eq::Equation) = integrate(eq, get_lhs)
integrate_rhs(eq::Equation) = integrate(eq, get_rhs)
"""
Return determinant of Jacobian for numerical integration.
"""
function get_detJ(eq::Equation, ip::IntegrationPoint)
el = get_element(eq)
get_detJ(el, ip)
end
function get_detJ(el::Element, ip::IntegrationPoint)
J = get_jacobian(el, ip.xi)
n, m = size(J)
if n != m # for manifolds
return norm(J)
else
return det(J)
end
end
"""
Integrate f over element
Parameters
----------
eq::Equation
f::Function
Function to integrate
"""
function integrate(eq::Equation, f::Function)
target = []
for ip in get_integration_points(eq)
push!(target, ip.weight*f(eq, ip)*get_detJ(eq, ip))
end
return sum(target)
end
-48
View File
@@ -129,32 +129,6 @@ end
"""
Integrate f over element using Gaussian quadrature rules.
Parameters
----------
el::Element
well defined element
f::Function
Function to integrate
"""
function integrate(f::Function, el::Element)
target = []
for ip in el.integration_points
J = interpolate(el, "coordinates", ip.xi; derivative=true)
push!(target, ip.weight*f(el, ip)*det(J))
end
return sum(target)
end
#function integrate(f::Function, integration_points::Array{IntegrationPoint, 1}, Xargs...)
# target = []
# for ip in integration_points
# J = interpolate(el, "coordinates", ip.xi; derivative=true)
# push!(target, ip.weight*f(ip, args...)*det(J))
# end
# return sum(target)
#end
"""
This version returns a function which must be operated with element e
@@ -183,28 +157,6 @@ function integrate!(f::Function, el::Element, target)
end
end
get_integration_points(eq::Equation) = eq.integration_points
"""
Integrate f over element using Gaussian quadrature rules.
Parameters
----------
el::Element
well defined element
f::Function
Function to integrate
"""
function integrate(eq::Equation, f::Function)
target = []
for ip in get_integration_points(eq)
J = get_jacobian(eq.element, ip.xi)
push!(target, ip.weight*f(eq, ip)*det(J))
end
return sum(target)
end
"""
Evaluate field in point xi using basis functions.
"""
-21
View File
@@ -1,27 +1,6 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
abstract Equation
"""
Integration point
xi :: Array{Float64, 1}
(dimensionless) coordinates of integration point
weight :: Float64
Integration weight
attributes :: Dict{ASCIIString, Any}
This is used to save internal variables of IP needed e.g. for incremental
material models.
"""
type IntegrationPoint
xi :: Array{Float64, 1}
weight :: Float64
attributes :: Dict{ASCIIString, Any}
end
IntegrationPoint(xi, weight) = IntegrationPoint(xi, weight, Dict{ASCIIString, Any}())
type Assembly
# LHS
I :: Array{Int64, 1}