mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-06 04:21:33 +00:00
Calculate shape functions using FEMBasis.jl
A lot of code is moved to FEMBasis.jl regarding calculating basis / shape functions of finite elements. * add FEMBasis to REQUIRE * remove obsolete files * remove obsolete test files * make integration point iterable * loosen type definitions * get length of element rather from basis than connectivity * calculate midpoint of reference element * wrong input argument to eval_basis! fixed
This commit is contained in:
@@ -7,5 +7,6 @@ Formatting
|
||||
Logging
|
||||
TimerOutputs
|
||||
AbaqusReader
|
||||
FEMQuad
|
||||
AsterReader
|
||||
FEMBasis
|
||||
FEMQuad
|
||||
|
||||
+7
-6
@@ -19,6 +19,12 @@ import Base: getindex, setindex!, convert, length, size, isapprox, similar,
|
||||
start, first, next, done, last, endof, vec, ==, +, -, *, /, haskey, copy,
|
||||
push!, isempty, empty!, append!, sparse, full, read
|
||||
|
||||
using FEMBasis
|
||||
using FEMBasis: AbstractBasis
|
||||
using FEMQuad
|
||||
using AbaqusReader
|
||||
using AsterReader
|
||||
|
||||
using Logging
|
||||
|
||||
Logging.configure(level=INFO)
|
||||
@@ -45,7 +51,7 @@ export AbstractPoint, Point, IntegrationPoint, IP, Node
|
||||
|
||||
### ELEMENTS ###
|
||||
include("elements.jl") # common element routines
|
||||
export Node, AbstractElement, Element, update!, get_connectivity, get_basis,
|
||||
export Node, Element, update!, get_connectivity, get_basis,
|
||||
get_dbasis, inside, get_local_coordinates, get_element_type,
|
||||
filter_by_element_type, get_element_id
|
||||
|
||||
@@ -62,11 +68,6 @@ export Poi1,
|
||||
Wedge6,
|
||||
Hex8, Hex20, Hex27
|
||||
|
||||
include("elements_nurbs.jl")
|
||||
export NSeg, NSurf, NSolid, is_nurbs
|
||||
|
||||
#include("hierarchical.jl") # P-elements
|
||||
|
||||
include("integrate.jl") # default integration points for elements
|
||||
export get_integration_points
|
||||
|
||||
|
||||
+15
-4
@@ -1,9 +1,7 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
abstract type AbstractElement end
|
||||
|
||||
type Element{E<:AbstractElement}
|
||||
type Element{E<:AbstractBasis}
|
||||
id :: Int
|
||||
connectivity :: Vector{Int}
|
||||
integration_points :: Vector{IP}
|
||||
@@ -17,10 +15,23 @@ Examples
|
||||
--------
|
||||
julia> element = Element(Tri3, [1, 2, 3])
|
||||
"""
|
||||
function Element{E<:AbstractElement}(::Type{E}, connectivity::Vector{Int})
|
||||
function Element{E<:AbstractBasis}(::Type{E}, connectivity::Vector{Int})
|
||||
return Element{E}(-1, connectivity, [], Dict(), E())
|
||||
end
|
||||
|
||||
"""
|
||||
length(element::Element)
|
||||
|
||||
Return the number of nodes in element.
|
||||
"""
|
||||
function length{B}(element::Element{B})
|
||||
return length(B)
|
||||
end
|
||||
|
||||
function size{B}(element::Element{B})
|
||||
return size(B)
|
||||
end
|
||||
|
||||
function getindex(element::Element, field_name::AbstractString)
|
||||
return element.fields[field_name]
|
||||
end
|
||||
|
||||
+25
-589
@@ -1,66 +1,11 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
global const ELEMENT_DESCRIPTIONS = Dict(
|
||||
"Poi1" => "1 node discrete point element",
|
||||
"Seg2" => "2 node linear segment/line element",
|
||||
"Seg3" => "3 node quadratic segment/line element",
|
||||
"Tri3" => "3 node linear triangle element",
|
||||
"Tri6" => "6 node quadratic triangle element",
|
||||
"Tri7" => "7 node quadratic triangle element (has middle node)",
|
||||
"Quad4" => "4 node linear quadrangle element",
|
||||
"Quad8" => "8 node quadratic quadrangle element (Serendip)",
|
||||
"Quad9" => "9 node quadratic quadrangle element",
|
||||
"Tet4" => "4 node linear tetrahedral element",
|
||||
"Tet10" => "10 node quadratic tetrahedral element",
|
||||
"Pyr5" => "5 node linear pyramid element",
|
||||
"Wedge6" => "6 node linear prismatic element (wedge)",
|
||||
"Wedge15" => "15 node quadratic prismatic element (wedge)",
|
||||
"Hex8" => "8 node linear hexahedral element",
|
||||
"Hex20" => "20 node biquadratic hexahedral element",
|
||||
"Hex27" => "27 node quadratic hexahedral element")
|
||||
using FEMBasis
|
||||
|
||||
global const ELEMENT_SIZES = Dict(
|
||||
"Poi1" => (0, 1),
|
||||
"Seg2" => (1, 2),
|
||||
"Seg3" => (1, 3),
|
||||
"Tri3" => (2, 3),
|
||||
"Tri6" => (2, 6),
|
||||
"Tri7" => (2, 7),
|
||||
"Quad4" => (2, 4),
|
||||
"Quad8" => (2, 8),
|
||||
"Quad9" => (2, 9),
|
||||
"Tet4" => (3, 4),
|
||||
"Tet10" => (3, 10),
|
||||
"Pyr5" => (3,5),
|
||||
"Wedge6" => (3, 6),
|
||||
"Wedge15" => (3, 15),
|
||||
"Hex8" => (3, 8),
|
||||
"Hex20" => (3, 20),
|
||||
"Hex27" => (3, 27))
|
||||
|
||||
""" Return description line of element. """
|
||||
function description{T}(element::Element{T})
|
||||
element_type = last(split("$T", '.'))
|
||||
return get(ELEMENT_DESCRIPTIONS, element_type, "Unknown element description")
|
||||
end
|
||||
|
||||
""" Return size of element, i.e. tuple (n, m) where n is dimension of element
|
||||
(0, 1, 2, 3) and m is number of nodes. """
|
||||
function size{T}(element::Element{T})
|
||||
element_type = last(split("$T", '.'))
|
||||
return ELEMENT_SIZES[element_type]
|
||||
end
|
||||
|
||||
""" Return length of element, i.e. number of nodes. """
|
||||
function length{T}(element::Element{T})
|
||||
return size(element)[end]
|
||||
end
|
||||
|
||||
### 0d element
|
||||
|
||||
|
||||
type Poi1 <: AbstractElement
|
||||
# "Poi1" => (0, 1),
|
||||
"1 node discrete point element",
|
||||
type Poi1 <: AbstractBasis
|
||||
end
|
||||
|
||||
function get_basis(element::Element{Poi1}, ip, time)
|
||||
@@ -83,541 +28,32 @@ function get_integration_points(element::Poi1, order::Int64)
|
||||
return [ (1.0, [] ) ]
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Poi1})
|
||||
function size(::Type{Poi1})
|
||||
return (0, 1)
|
||||
end
|
||||
|
||||
function length(::Type{Poi1})
|
||||
return 1
|
||||
end
|
||||
|
||||
function FEMBasis.get_reference_element_coordinates(::Type{Poi1})
|
||||
Vector{Float64}[[0.0]]
|
||||
end
|
||||
|
||||
### 1d elements
|
||||
|
||||
type Seg2 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Seg2})
|
||||
Vector{Float64}[
|
||||
[-1.0], # N1
|
||||
[ 1.0]] # N2
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Seg2}, xi)
|
||||
[1.0 xi[1]]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Seg2}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[0.0 1.0]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Seg3 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Seg3})
|
||||
Vector{Float64}[
|
||||
[-1.0], # N1
|
||||
[ 1.0], # N2
|
||||
[ 0.0]] # N3
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Seg3}, xi)
|
||||
[1.0 xi[1] xi[1]^2]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Seg3}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[0.0 1.0 2.0*xi[1]]
|
||||
end
|
||||
|
||||
### 2d elements
|
||||
|
||||
type Tri3 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Tri3})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0], # N1
|
||||
[1.0, 0.0], # N2
|
||||
[0.0, 1.0]] # N3
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri3}, xi)
|
||||
[
|
||||
1 xi[1] xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri3}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0.0 1.0 0.0
|
||||
0.0 0.0 1.0
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Tri6 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Tri6})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0], # N1
|
||||
[1.0, 0.0], # N2
|
||||
[0.0, 1.0], # N3
|
||||
[0.5, 0.0], # N4
|
||||
[0.5, 0.5], # N5
|
||||
[0.0, 0.5]] # N6
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri6}, xi)
|
||||
[
|
||||
1 xi[1] xi[2] xi[1]^2 xi[1]*xi[2] xi[2]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri6}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 1 0 2*xi[1] xi[2] 0
|
||||
0 0 1 0 xi[1] 2*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Tri7 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Tri7})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0], # N1
|
||||
[1.0, 0.0], # N2
|
||||
[0.0, 1.0], # N3
|
||||
[0.5, 0.0], # N4
|
||||
[0.5, 0.5], # N5
|
||||
[0.0, 0.5], # N6
|
||||
[1/3, 1/3]] # N7
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri7}, xi)
|
||||
[
|
||||
1 xi[1] xi[2] xi[1]^2 xi[1]*xi[2] xi[2]^2 xi[1]^2*xi[2]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tri7}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 1 0 2*xi[1] xi[2] 0 2*xi[1]*xi[2]^2
|
||||
0 0 1 0 xi[1] 2*xi[2] 2*xi[1]^2*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Quad4 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Quad4})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0], # N1
|
||||
[ 1.0, -1.0], # N2
|
||||
[ 1.0, 1.0], # N3
|
||||
[-1.0, 1.0]] # N4
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad4}, xi)
|
||||
[
|
||||
1.0 xi[1] xi[2] xi[1]*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad4}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 1 0 xi[2]
|
||||
0 0 1 xi[1]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Quad8 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Quad8})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0], # N1
|
||||
[ 1.0, -1.0], # N2
|
||||
[ 1.0, 1.0], # N3
|
||||
[-1.0, 1.0], # N4
|
||||
[ 0.0, -1.0], # N5
|
||||
[ 1.0, 0.0], # N6
|
||||
[ 0.0, 1.0], # N7
|
||||
[-1.0, 0.0]] # N8
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad8}, xi)
|
||||
[
|
||||
1 xi[2] xi[1] xi[2]^2 xi[1]*xi[2] xi[1]^2 xi[1]*xi[2]^2 xi[1]^2*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad8}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 1 0 xi[2] 2*xi[1] xi[2]^2 2*xi[1]*xi[2]
|
||||
0 1 0 2*xi[2] xi[1] 0 2*xi[1]*xi[2] xi[1]^2
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Quad9 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Quad9})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0], # N1
|
||||
[ 1.0, -1.0], # N2
|
||||
[ 1.0, 1.0], # N3
|
||||
[-1.0, 1.0], # N4
|
||||
[ 0.0, -1.0], # N5
|
||||
[ 1.0, 0.0], # N6
|
||||
[ 0.0, 1.0], # N7
|
||||
[-1.0, 0.0], # N8
|
||||
[ 0.0, 0.0]] # N9
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad9}, xi)
|
||||
[
|
||||
1 xi[2] xi[1] xi[2]^2 xi[1]*xi[2] xi[1]^2 xi[1]*xi[2]^2 xi[1]^2*xi[2] xi[1]^2*xi[2]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Quad9}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 1 0 xi[2] 2*xi[1] xi[2]^2 2*xi[1]*xi[2] 2*xi[1]*xi[2]^2
|
||||
0 1 0 2*xi[2] xi[1] 0 2*xi[1]*xi[2] xi[1]^2 2*xi[1]^2*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
### 3d elements
|
||||
|
||||
type Tet4 <: AbstractElement
|
||||
function get_basis{B}(element::Element{B}, ip, time)
|
||||
T = typeof(first(ip))
|
||||
N = zeros(T, 1, length(B))
|
||||
eval_basis!(B, N, tuple(ip...))
|
||||
return N
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Tet4})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0, 0.0], # N1
|
||||
[1.0, 0.0, 0.0], # N2
|
||||
[0.0, 1.0, 0.0], # N3
|
||||
[0.0, 0.0, 1.0]] # N4
|
||||
function get_dbasis{B}(element::Element{B}, ip, time)
|
||||
T = typeof(first(ip))
|
||||
dN = zeros(T, size(B)...)
|
||||
eval_dbasis!(B, dN, tuple(ip...))
|
||||
return dN
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tet4}, xi)
|
||||
[
|
||||
1.0 xi[1] xi[2] xi[3]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tet4}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0.0 1.0 0.0 0.0
|
||||
0.0 0.0 1.0 0.0
|
||||
0.0 0.0 0.0 1.0
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Tet10 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Tet10})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0, 0.0], # N1
|
||||
[1.0, 0.0, 0.0], # N2
|
||||
[0.0, 1.0, 0.0], # N3
|
||||
[0.0, 0.0, 1.0], # N4
|
||||
[0.5, 0.0, 0.0], # N5
|
||||
[0.5, 0.5, 0.0], # N6
|
||||
[0.0, 0.5, 0.0], # N7
|
||||
[0.0, 0.0, 0.5], # N8
|
||||
[0.5, 0.0, 0.5], # N9
|
||||
[0.0, 0.5, 0.5]] # N10
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tet10}, xi)
|
||||
[
|
||||
1.0 xi[3] xi[2] xi[1] xi[3]^2 xi[2]*xi[3] xi[2]^2 xi[1]*xi[3] xi[1]*xi[2] xi[1]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Tet10}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 0 1 0 0 0 xi[3] xi[2] 2*xi[1]
|
||||
0 0 1 0 0 xi[3] 2*xi[2] 0 xi[1] 0
|
||||
0 1 0 0 2*xi[3] xi[2] 0 xi[1] 0 0
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Pyr5 <: AbstractElement
|
||||
end
|
||||
|
||||
|
||||
function get_reference_coordinates(::Type{Pyr5})
|
||||
Vector{Float64}[
|
||||
[-1.0,-1.0,-1.0], # N1
|
||||
[ 1.0,-1.0,-1.0], # N2
|
||||
[ 1.0, 1.0,-1.0], # N3
|
||||
[-1.0, 1.0,-1.0], # N4
|
||||
[ 0.0, 0.0, 1.0]] # N5
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Pyr5}, xi)
|
||||
[
|
||||
1.0/8.0*(1.0-1.0*xi[1])*(1.0-1.0*xi[2])*(1.0-1.0*xi[3])
|
||||
1.0/8.0*(1.0+1.0*xi[1])*(1.0-1.0*xi[2])*(1.0-1.0*xi[3])
|
||||
1.0/8.0*(1.0+1.0*xi[1])*(1.0+1.0*xi[2])*(1.0-1.0*xi[3])
|
||||
1.0/8.0*(1.0-1.0*xi[1])*(1.0+1.0*xi[2])*(1.0-1.0*xi[3])
|
||||
1.0/2.0*(1.0+xi[3])
|
||||
]'
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Pyr5}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
-0.125*(1.0-xi[2])*(1.0-xi[3]) 0.125*(1.0-xi[2])*(1.0-xi[3]) 0.125*(1.0+xi[2])*(1.0-xi[3]) -0.125*(1.0+xi[2])*(1.0-xi[3]) 0.0
|
||||
-0.125*(1.0-xi[1])*(1.0-xi[3]) -0.125*(1.0+xi[1])*(1.0-xi[3]) 0.125*(1.0+xi[1])*(1.0-xi[3]) 0.125*(1.0-xi[1])*(1.0-xi[3]) 0.0
|
||||
-0.125*(1.0-xi[1])*(1.0-xi[2]) -0.125*(1.0+xi[1])*(1.0-xi[2]) -0.125*(1.0+xi[1])*(1.0+xi[2]) -0.125*(1.0-xi[1])*(1.0+xi[2]) 0.5
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Wedge6 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Wedge6})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0, -1.0], # N1
|
||||
[1.0, 0.0, -1.0], # N2
|
||||
[0.0, 1.0, -1.0], # N3
|
||||
[0.0, 0.0, 1.0], # N4
|
||||
[1.0, 0.0, 1.0], # N5
|
||||
[0.0, 1.0, 1.0]] # N6
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Wedge6}, x)
|
||||
[
|
||||
1 x[1] x[2] x[3] x[1]*x[3] x[2]*x[3]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Wedge6}, x, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 1 0 0 x[3] 0
|
||||
0 0 1 0 0 x[3]
|
||||
0 0 0 1 x[1] x[2]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Wedge15 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Wedge15})
|
||||
Vector{Float64}[
|
||||
[0.0, 0.0, -1.0], # N1
|
||||
[1.0, 0.0, -1.0], # N2
|
||||
[0.0, 1.0, -1.0], # N3
|
||||
[0.0, 0.0, 1.0], # N4
|
||||
[1.0, 0.0, 1.0], # N5
|
||||
[0.0, 1.0, 1.0], # N6
|
||||
[0.5, 0.0, -1.0], # N7
|
||||
[0.5, 0.5, -1.0], # N8
|
||||
[0.0, 0.5, -1.0], # N9
|
||||
[0.5, 0.0, 1.0], # N10
|
||||
[0.5, 0.5, 1.0], # N11
|
||||
[0.0, 0.5, 1.0], # N12
|
||||
[0.0, 0.0, 0.0], # N13
|
||||
[1.0, 0.0, 0.0], # N14
|
||||
[0.0, 1.0, 0.0]] # N15
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Wedge15}, x)
|
||||
[
|
||||
1 x[1] x[1]^2 x[2] x[1]*x[2] x[2]^2 x[3] x[1]*x[3] x[1]^2*x[3] x[2]*x[3] x[1]*x[2]*x[3] x[2]^2*x[3] x[3]^2 x[1]*x[3]^2 x[2]*x[3]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Wedge15}, x, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 1 2*x[1] 0 x[2] 0 0 x[3] 2*x[1]*x[3] 0 x[2]*x[3] 0 0 x[3]^2 0
|
||||
0 0 0 1 x[1] 2*x[2] 0 0 0 x[3] x[1]*x[3] 2*x[2]*x[3] 0 0 x[3]^2
|
||||
0 0 0 0 0 0 1 x[1] x[1]^2 x[2] x[1]*x[2] x[2]^2 2*x[3] 2*x[1]*x[3] 2*x[2]*x[3]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Hex8 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Hex8})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0, -1.0], # N1
|
||||
[ 1.0, -1.0, -1.0], # N2
|
||||
[ 1.0, 1.0, -1.0], # N3
|
||||
[-1.0, 1.0, -1.0], # N4
|
||||
[-1.0, -1.0, 1.0], # N5
|
||||
[ 1.0, -1.0, 1.0], # N6
|
||||
[ 1.0, 1.0, 1.0], # N7
|
||||
[-1.0, 1.0, 1.0]] # N8
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex8}, xi)
|
||||
[
|
||||
1 xi[3] xi[2] xi[1] xi[2]*xi[3] xi[1]*xi[3] xi[1]*xi[2] xi[1]*xi[2]*xi[3]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex8}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 0 1 0 xi[3] xi[2] xi[2]*xi[3]
|
||||
0 0 1 0 xi[3] 0 xi[1] xi[1]*xi[3]
|
||||
0 1 0 0 xi[2] xi[1] 0 xi[1]*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
type Hex20 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Hex20})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0, -1.0], # N1
|
||||
[ 1.0, -1.0, -1.0], # N2
|
||||
[ 1.0, 1.0, -1.0], # N3
|
||||
[-1.0, 1.0, -1.0], # N4
|
||||
[-1.0, -1.0, 1.0], # N5
|
||||
[ 1.0, -1.0, 1.0], # N6
|
||||
[ 1.0, 1.0, 1.0], # N7
|
||||
[-1.0, 1.0, 1.0], # N8
|
||||
[ 0.0, -1.0, -1.0], # N9
|
||||
[ 1.0, 0.0, -1.0], # N10
|
||||
[ 0.0, 1.0, -1.0], # N11
|
||||
[-1.0, 0.0, -1.0], # N12
|
||||
[-1.0, -1.0, 0.0], # N13
|
||||
[ 1.0, -1.0, 0.0], # N14
|
||||
[ 1.0, 1.0, 0.0], # N15
|
||||
[-1.0, 1.0, 0.0], # N16
|
||||
[ 0.0, -1.0, 1.0], # N17
|
||||
[ 1.0, 0.0, 1.0], # N18
|
||||
[ 0.0, 1.0, 1.0], # N19
|
||||
[-1.0, 0.0, 1.0]] # N20
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex20}, xi)
|
||||
[
|
||||
1 xi[3] xi[2] xi[1] xi[2]*xi[3] xi[1]*xi[3] xi[1]*xi[2] xi[1]*xi[2]*xi[3] xi[3]^2 xi[2]^2 xi[1]^2 xi[2]*xi[3]^2 xi[2]^2*xi[3] xi[1]*xi[3]^2 xi[1]*xi[2]^2 xi[1]^2*xi[3] xi[1]^2*xi[2] xi[1]*xi[2]*xi[3]^2 xi[1]*xi[2]^2*xi[3] xi[1]^2*xi[2]*xi[3]
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex20}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 0 1 0 xi[3] xi[2] xi[2]*xi[3] 0 0 2*xi[1] 0 0 xi[3]^2 xi[2]^2 2*xi[1]*xi[3] 2*xi[1]*xi[2] xi[2]*xi[3]^2 xi[2]^2*xi[3] 2*xi[1]*xi[2]*xi[3]
|
||||
0 0 1 0 xi[3] 0 xi[1] xi[1]*xi[3] 0 2*xi[2] 0 xi[3]^2 2*xi[2]*xi[3] 0 2*xi[1]*xi[2] 0 xi[1]^2 xi[1]*xi[3]^2 2*xi[1]*xi[2]*xi[3] xi[1]^2*xi[3]
|
||||
0 1 0 0 xi[2] xi[1] 0 xi[1]*xi[2] 2*xi[3] 0 0 2*xi[2]*xi[3] xi[2]^2 2*xi[1]*xi[3] 0 xi[1]^2 0 2*xi[1]*xi[2]*xi[3] xi[1]*xi[2]^2 xi[1]^2*xi[2]
|
||||
]
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
type Hex27 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_reference_coordinates(::Type{Hex27})
|
||||
Vector{Float64}[
|
||||
[-1.0, -1.0, -1.0], # N1
|
||||
[ 1.0, -1.0, -1.0], # N2
|
||||
[ 1.0, 1.0, -1.0], # N3
|
||||
[-1.0, 1.0, -1.0], # N4
|
||||
[-1.0, -1.0, 1.0], # N5
|
||||
[ 1.0, -1.0, 1.0], # N6
|
||||
[ 1.0, 1.0, 1.0], # N7
|
||||
[-1.0, 1.0, 1.0], # N8
|
||||
[ 0.0, -1.0, -1.0], # N9
|
||||
[ 1.0, 0.0, -1.0], # N10
|
||||
[ 0.0, 1.0, -1.0], # N11
|
||||
[-1.0, 0.0, -1.0], # N12
|
||||
[-1.0, -1.0, 0.0], # N13
|
||||
[ 1.0, -1.0, 0.0], # N14
|
||||
[ 1.0, 1.0, 0.0], # N15
|
||||
[-1.0, 1.0, 0.0], # N16
|
||||
[ 0.0, -1.0, 1.0], # N17
|
||||
[ 1.0, 0.0, 1.0], # N18
|
||||
[ 0.0, 1.0, 1.0], # N19
|
||||
[-1.0, 0.0, 1.0], # N20
|
||||
[ 0.0, 0.0, -1.0], # N21
|
||||
[ 0.0, -1.0, 0.0], # N22
|
||||
[ 1.0, 0.0, 0.0], # N23
|
||||
[ 0.0, 1.0, 0.0], # N24
|
||||
[-1.0, 0.0, 0.0], # N25
|
||||
[ 0.0, 0.0, 1.0], # N26
|
||||
[ 0.0, 0.0, 0.0]] # N27
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex27}, xi)
|
||||
[
|
||||
1 xi[3] xi[2] xi[1] xi[2]*xi[3] xi[1]*xi[3] xi[1]*xi[2] xi[1]*xi[2]*xi[3] xi[3]^2 xi[2]^2 xi[1]^2 xi[2]*xi[3]^2 xi[2]^2*xi[3] xi[1]*xi[3]^2 xi[1]*xi[2]^2 xi[1]^2*xi[3] xi[1]^2*xi[2] xi[2]^2*xi[3]^2 xi[1]*xi[2]*xi[3]^2 xi[1]*xi[2]^2*xi[3] xi[1]^2*xi[3]^2 xi[1]^2*xi[2]*xi[3] xi[1]^2*xi[2]^2 xi[1]*xi[2]^2*xi[3]^2 xi[1]^2*xi[2]*xi[3]^2 xi[1]^2*xi[2]^2*xi[3] xi[1]^2*xi[2]^2*xi[3]^2
|
||||
]
|
||||
end
|
||||
|
||||
function get_interpolation_polynomial(::Type{Hex27}, xi, ::Type{Val{:partial_derivatives}})
|
||||
[
|
||||
0 0 0 1 0 xi[3] xi[2] xi[2]*xi[3] 0 0 2*xi[1] 0 0 xi[3]^2 xi[2]^2 2*xi[1]*xi[3] 2*xi[1]*xi[2] 0 xi[2]*xi[3]^2 xi[2]^2*xi[3] 2*xi[1]*xi[3]^2 2*xi[1]*xi[2]*xi[3] 2*xi[1]*xi[2]^2 xi[2]^2*xi[3]^2 2*xi[1]*xi[2]*xi[3]^2 2*xi[1]*xi[2]^2*xi[3] 2*xi[1]*xi[2]^2*xi[3]^2
|
||||
0 0 1 0 xi[3] 0 xi[1] xi[1]*xi[3] 0 2*xi[2] 0 xi[3]^2 2*xi[2]*xi[3] 0 2*xi[1]*xi[2] 0 xi[1]^2 2*xi[2]*xi[3]^2 xi[1]*xi[3]^2 2*xi[1]*xi[2]*xi[3] 0 xi[1]^2*xi[3] 2*xi[1]^2*xi[2] 2*xi[1]*xi[2]*xi[3]^2 xi[1]^2*xi[3]^2 2*xi[1]^2*xi[2]*xi[3] 2*xi[1]^2*xi[2]*xi[3]^2
|
||||
0 1 0 0 xi[2] xi[1] 0 xi[1]*xi[2] 2*xi[3] 0 0 2*xi[2]*xi[3] xi[2]^2 2*xi[1]*xi[3] 0 xi[1]^2 0 2*xi[2]^2*xi[3] 2*xi[1]*xi[2]*xi[3] xi[1]*xi[2]^2 2*xi[1]^2*xi[3] xi[1]^2*xi[2] 0 2*xi[1]*xi[2]^2*xi[3] 2*xi[1]^2*xi[2]*xi[3] xi[1]^2*xi[2]^2 2*xi[1]^2*xi[2]^2*xi[3]
|
||||
]
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
macro create_basis(T)
|
||||
quote
|
||||
T = $T
|
||||
global get_basis, get_dbasis, length, size
|
||||
X = get_reference_coordinates(T)
|
||||
nbasis = length(X)
|
||||
A = zeros(nbasis, nbasis)
|
||||
for i=1:nbasis
|
||||
A[i,:] = get_interpolation_polynomial(T, X[i])
|
||||
end
|
||||
invA = inv(A)
|
||||
function get_basis(element::Element{$T}, ip, time)
|
||||
return get_interpolation_polynomial($T, ip)*invA
|
||||
end
|
||||
function get_dbasis(element::Element{$T}, ip, time)
|
||||
return get_interpolation_polynomial($T, ip, Val{:partial_derivatives})*invA
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@create_basis Seg2
|
||||
@create_basis Seg3
|
||||
@create_basis Tri3
|
||||
@create_basis Tri6
|
||||
@create_basis Tri7
|
||||
@create_basis Quad4
|
||||
@create_basis Quad8
|
||||
@create_basis Quad9
|
||||
@create_basis Tet4
|
||||
@create_basis Tet10
|
||||
@create_basis Pyr5
|
||||
@create_basis Wedge6
|
||||
@create_basis Wedge15
|
||||
@create_basis Hex8
|
||||
@create_basis Hex20
|
||||
@create_basis Hex27
|
||||
|
||||
function inside(::Union{Type{Seg2}, Type{Seg3}, Type{Quad4}, Type{Quad8},
|
||||
Type{Quad9}, Type{Pyr5}, Type{Hex8}, Type{Hex20},
|
||||
Type{Hex27}}, xi)
|
||||
@@ -628,7 +64,7 @@ function inside(::Union{Type{Tri3}, Type{Tri6}, Type{Tri7}, Type{Tet4}, Type{Tet
|
||||
return all(xi .>= 0.0) && (sum(xi) <= 1.0)
|
||||
end
|
||||
|
||||
function get_reference_coordinates{E}(element::Element{E})
|
||||
get_reference_coordinates(E)
|
||||
function get_reference_coordinates{B}(element::Element{B})
|
||||
return get_reference_element_coordinates(B)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
using ForwardDiff
|
||||
# TODO: evaluate partial derivatives of basis functions without forwarddiff
|
||||
|
||||
""" NURBS segment. """
|
||||
type NSeg <: AbstractElement
|
||||
order :: Int
|
||||
knots :: Vector{Float64}
|
||||
weights :: Vector{Float64}
|
||||
end
|
||||
|
||||
function NSeg()
|
||||
NSeg(1,
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
ones(4))
|
||||
end
|
||||
|
||||
type NSurf <: AbstractElement
|
||||
order_u :: Int
|
||||
order_v :: Int
|
||||
knots_u :: Vector{Float64}
|
||||
knots_v :: Vector{Float64}
|
||||
weights :: Matrix{Float64}
|
||||
end
|
||||
|
||||
function NSurf()
|
||||
NSurf(1, 1,
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
ones(2, 2))
|
||||
end
|
||||
|
||||
type NSolid <: AbstractElement
|
||||
order_u :: Int
|
||||
order_v :: Int
|
||||
order_w :: Int
|
||||
knots_u :: Vector{Float64}
|
||||
knots_v :: Vector{Float64}
|
||||
knots_w :: Vector{Float64}
|
||||
weights :: Array{Float64, 3}
|
||||
end
|
||||
|
||||
function NSolid()
|
||||
NSolid(1, 1, 1,
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
[-1.0, -1.0, 1.0, 1.0],
|
||||
ones(2, 2, 2))
|
||||
end
|
||||
|
||||
function NURBS(i, p, u, t)
|
||||
p == 0 && return t[i] <= u <= t[i+1] ? 1.0 : 0.0
|
||||
anom = u-t[i]
|
||||
adenom = t[i+p]-t[i]
|
||||
a = isapprox(adenom, 0.0) ? 0.0 : anom/adenom
|
||||
bnom = t[i+p+1]-u
|
||||
bdenom = t[i+p+1]-t[i+1]
|
||||
b = isapprox(bdenom, 0.0) ? 0.0 : bnom/bdenom
|
||||
result = a*NURBS(i,p-1,u,t) + b*NURBS(i+1,p-1,u,t)
|
||||
return result
|
||||
end
|
||||
|
||||
function get_basis(element::Element{NSeg}, xi::Vector, time)
|
||||
pu = element.properties.order
|
||||
tu = element.properties.knots
|
||||
w = element.properties.weights
|
||||
nu = length(tu)-pu-1
|
||||
u = xi[1]
|
||||
N = vec([w[j]*NURBS(j,pu,u,tu) for j=1:nu])'
|
||||
return N/sum(N)
|
||||
end
|
||||
|
||||
function get_basis(element::Element{NSurf}, xi::Vector, time)
|
||||
pu = element.properties.order_u
|
||||
pv = element.properties.order_v
|
||||
tu = element.properties.knots_u
|
||||
tv = element.properties.knots_v
|
||||
w = element.properties.weights
|
||||
nu = length(tu)-pu-1
|
||||
nv = length(tv)-pv-1
|
||||
u, v = xi
|
||||
N = vec([w[i,j]*NURBS(i,pu,u,tu)*NURBS(j,pv,v,tv) for i=1:nu, j=1:nv])'
|
||||
return N / sum(N)
|
||||
end
|
||||
|
||||
function get_basis(element::Element{NSolid}, xi::Vector, time)
|
||||
pu = element.properties.order_u
|
||||
pv = element.properties.order_v
|
||||
pw = element.properties.order_w
|
||||
tu = element.properties.knots_u
|
||||
tv = element.properties.knots_v
|
||||
tw = element.properties.knots_w
|
||||
weights = element.properties.weights
|
||||
nu = length(tu)-pu-1
|
||||
nv = length(tv)-pv-1
|
||||
nw = length(tw)-pw-1
|
||||
u, v, w = xi
|
||||
N = vec([weights[i,j,k]*NURBS(i,pu,u,tu)*NURBS(j,pv,v,tv)*NURBS(k,pw,w,tw) for i=1:nu, j=1:nv, k=1:nw])'
|
||||
return N / sum(N)
|
||||
end
|
||||
|
||||
# TODO: evaluate partial derivatives of basis functions without forwarddiff
|
||||
""" Evaluate partial derivatives of basis functions using ForwardDiff. """
|
||||
function get_dbasis{E<:Union{NSeg, NSurf, NSolid}}(element::Element{E}, ip, time)
|
||||
xi = isa(ip, IP) ? ip.coords : ip
|
||||
basis(xi) = vec(get_basis(element, xi, time))
|
||||
return ForwardDiff.jacobian(basis, xi)'
|
||||
end
|
||||
|
||||
function length(element::Element{NSeg})
|
||||
nu = length(element.properties.knots) - element.properties.order - 1
|
||||
return nu
|
||||
end
|
||||
|
||||
function size(element::Element{NSeg})
|
||||
return (1, length(element))
|
||||
end
|
||||
|
||||
function length(element::Element{NSurf})
|
||||
nu = length(element.properties.knots_u) - element.properties.order_u - 1
|
||||
nv = length(element.properties.knots_v) - element.properties.order_v - 1
|
||||
return nu*nv
|
||||
end
|
||||
|
||||
function size(element::Element{NSurf})
|
||||
return (2, length(element))
|
||||
end
|
||||
|
||||
function length(element::Element{NSolid})
|
||||
nu = length(element.properties.knots_u) - element.properties.order_u - 1
|
||||
nv = length(element.properties.knots_v) - element.properties.order_v - 1
|
||||
nw = length(element.properties.knots_w) - element.properties.order_w - 1
|
||||
return nu*nv*nw
|
||||
end
|
||||
|
||||
function size(element::Element{NSolid})
|
||||
return (3, length(element))
|
||||
end
|
||||
|
||||
function is_nurbs(element::Element)
|
||||
return false
|
||||
end
|
||||
|
||||
function is_nurbs{E<:Union{NSeg, NSurf, NSolid}}(element::Element{E})
|
||||
return true
|
||||
end
|
||||
|
||||
+1
-1
@@ -416,7 +416,7 @@ function (field::CCTV)(xi::Vector, time::Number)
|
||||
return field.data(time)
|
||||
end
|
||||
|
||||
function (field::CVTV)(xi::Vector, time::Number)
|
||||
function (field::CVTV)(xi, time)
|
||||
return field.data(xi, time)
|
||||
end
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
|
||||
Q3 = create_rotation_matrix(slave_element, time)
|
||||
|
||||
# project slave nodes to auxiliary plane (x0, Q)
|
||||
xi = mean(get_reference_coordinates(slave_element))
|
||||
xi = get_mean_xi(slave_element)
|
||||
N = vec(get_basis(slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
n0 = N*n1
|
||||
@@ -280,7 +280,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
|
||||
#la = sub_slave_element("lambda", time)
|
||||
|
||||
# create auxiliary plane
|
||||
xi = mean(get_reference_coordinates(sub_slave_element))
|
||||
xi = get_mean_xi(sub_slave_element)
|
||||
N = vec(get_basis(sub_slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
n0 = N*n1
|
||||
@@ -356,7 +356,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
|
||||
n1 = sub_slave_element("normal", time)
|
||||
|
||||
# create auxiliary plane
|
||||
xi = mean(get_reference_coordinates(sub_slave_element))
|
||||
xi = get_mean_xi(sub_slave_element)
|
||||
N = vec(get_basis(sub_slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
n0 = N*n1
|
||||
|
||||
@@ -56,7 +56,7 @@ function assemble!(problem::Problem{Dirichlet}, time::Float64=0.0;
|
||||
for i=1:field_dim
|
||||
haskey(element, field_name*" $i") || continue
|
||||
ldofs = gdofs[i:field_dim:end]
|
||||
xis = get_reference_coordinates(typeof(element.properties))
|
||||
xis = get_reference_coordinates(element)
|
||||
vals = Float64[]
|
||||
for xi in xis
|
||||
g = element(field_name*" $i", xi, time)
|
||||
|
||||
@@ -146,7 +146,7 @@ function diagnose_interface(problem::Problem{Mortar}, time::Float64)
|
||||
n1 = Field([normals[j] for j in slave_element_nodes])
|
||||
|
||||
# project slave nodes to auxiliary plane (x0, Q)
|
||||
xi = mean(get_reference_coordinates(slave_element))
|
||||
xi = get_mean_xi(slave_element)
|
||||
N = vec(get_basis(slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
n0 = N*n1
|
||||
|
||||
@@ -103,11 +103,11 @@ function approx_in{T}(q::T, P::Vector{T}; rtol=1.0e-4, atol=0.0)
|
||||
return false
|
||||
end
|
||||
|
||||
function get_polygon_clip(xs, xm, n)
|
||||
function get_polygon_clip{T}(xs::Vector{T}, xm::Vector{T}, n::T)
|
||||
# objective: search does line xm1 - xm2 clip xs
|
||||
nm = length(xm)
|
||||
ns = length(xs)
|
||||
P = Vector[]
|
||||
P = T[]
|
||||
|
||||
# 1. test is master point inside slave, if yes, add to clip
|
||||
for i=1:nm
|
||||
@@ -330,6 +330,17 @@ function split_quadratic_elements(elements::Vector, time::Float64)
|
||||
return new_elements
|
||||
end
|
||||
|
||||
function get_mean_xi(element::Element)
|
||||
xi = zeros(2)
|
||||
coords = get_reference_coordinates(element)
|
||||
for (xi1,xi2) in coords
|
||||
xi[1] += xi1
|
||||
xi[2] += xi2
|
||||
end
|
||||
xi /= length(coords)
|
||||
return xi
|
||||
end
|
||||
|
||||
""" Assemble linear surface element to problem.
|
||||
|
||||
Dual basis is constructed such that partially integrated slave segments are taken into account in a proper way.
|
||||
@@ -357,7 +368,7 @@ function assemble!{E<:Union{Tri3, Quad4}}(problem::Problem{Mortar}, slave_elemen
|
||||
n1 = slave_element("normal", time)
|
||||
|
||||
# project slave nodes to auxiliary plane (x0, Q)
|
||||
xi = mean(get_reference_coordinates(slave_element))
|
||||
xi = get_mean_xi(slave_element)
|
||||
first_slave_element && debug("midpoint xi = $xi")
|
||||
N = vec(get_basis(slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
@@ -465,7 +476,7 @@ function assemble!{E<:Union{Tri3, Quad4}}(problem::Problem{Mortar}, slave_elemen
|
||||
all_cells = get_cells(P, C0)
|
||||
for cell in all_cells
|
||||
virtual_element = Element(Tri3, Int[])
|
||||
update!(virtual_element, "geometry", cell)
|
||||
virtual_element.fields["geometry"] = DVTI(cell)
|
||||
|
||||
# 5. loop integration point of integration cell
|
||||
for ip in get_integration_points(virtual_element, 3)
|
||||
@@ -579,7 +590,7 @@ function assemble!{E<:Union{Tri6}}(problem::Problem{Mortar}, slave_element::Elem
|
||||
n1 = sub_slave_element("normal", time)
|
||||
|
||||
# create auxiliary plane
|
||||
xi = mean(get_reference_coordinates(sub_slave_element))
|
||||
xi = get_mean_xi(sub_slave_element)
|
||||
first_slave_element && debug("midpoint xi = $xi")
|
||||
N = vec(get_basis(sub_slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
@@ -662,7 +673,7 @@ function assemble!{E<:Union{Tri6}}(problem::Problem{Mortar}, slave_element::Elem
|
||||
n1 = sub_slave_element("normal", time)
|
||||
|
||||
# create auxiliary plane
|
||||
xi = mean(get_reference_coordinates(sub_slave_element))
|
||||
xi = get_mean_xi(sub_slave_element)
|
||||
first_slave_element && debug("midpoint xi = $xi")
|
||||
N = vec(get_basis(sub_slave_element, xi, time))
|
||||
x0 = N*X1
|
||||
|
||||
@@ -33,6 +33,18 @@ function (point::Point)(field_name, time=0.0)
|
||||
point.fields[field_name](time).data
|
||||
end
|
||||
|
||||
function start(point::Point)
|
||||
return start(point.coords)
|
||||
end
|
||||
|
||||
function done(point::Point, i)
|
||||
return done(point.coords, i)
|
||||
end
|
||||
|
||||
function next(point::Point, i)
|
||||
return next(point.coords, i)
|
||||
end
|
||||
|
||||
function update!{T}(point::Point, field_name, val::Pair{Float64, T})
|
||||
if haskey(point, field_name)
|
||||
update!(point[field_name], val)
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
# 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.Testing
|
||||
importall Base
|
||||
import JuliaFEM: get_basis, get_dbasis
|
||||
|
||||
type TestElement <: AbstractElement
|
||||
end
|
||||
|
||||
function get_basis(element::Element{TestElement}, xi, time)
|
||||
1/4*[
|
||||
(1-xi[1])*(1-xi[2])
|
||||
(1+xi[1])*(1-xi[2])
|
||||
(1+xi[1])*(1+xi[2])
|
||||
(1-xi[1])*(1+xi[2])]'
|
||||
end
|
||||
|
||||
function get_dbasis(element::Element{TestElement}, xi, time)
|
||||
1/4*[
|
||||
-(1-xi[2]) (1-xi[2]) (1+xi[2]) -(1+xi[2])
|
||||
-(1-xi[1]) -(1+xi[1]) (1+xi[1]) (1-xi[1])]
|
||||
end
|
||||
|
||||
function length(element::Element{TestElement})
|
||||
return 4
|
||||
end
|
||||
|
||||
function size(element::Element{TestElement})
|
||||
return (2, 4)
|
||||
end
|
||||
|
||||
function get_element()
|
||||
element = Element(TestElement, [1, 2, 3, 4])
|
||||
X = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [1.0, 0.0],
|
||||
3 => [1.0, 1.0],
|
||||
4 => [0.0, 1.0])
|
||||
T = Dict{Int64, Float64}(
|
||||
1 => 1.0,
|
||||
2 => 2.0,
|
||||
3 => 3.0,
|
||||
4 => 4.0)
|
||||
u1 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [0.0, 0.0],
|
||||
3 => [1/4, 0.0],
|
||||
4 => [0.0, 0.0])
|
||||
u2 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [1.0, -1.0],
|
||||
3 => [2.0, 3.0],
|
||||
4 => [0.0, 0.0])
|
||||
update!(element, "geometry", X)
|
||||
update!(element, "temperature", T)
|
||||
update!(element, "displacement1", u1)
|
||||
update!(element, "displacement2", u2)
|
||||
return element
|
||||
end
|
||||
|
||||
@testset "spatial interpolation in basis" begin
|
||||
element = get_element()
|
||||
@test isapprox(element([0.0, 0.0], 0.0), 1/4*[1 1 1 1])
|
||||
@test isapprox(element([0.0, 0.0], 1.0), 1/4*[1 1 1 1])
|
||||
end
|
||||
|
||||
@testset "gradient of shape functions" begin
|
||||
element = get_element()
|
||||
grad = element([0.0, 0.0], 0.0, Val{:Grad})
|
||||
@test isapprox(grad, 1/2*[-1 1 1 -1; -1 -1 1 1])
|
||||
end
|
||||
|
||||
@testset "interpolation of scalar field in spatial domain" begin
|
||||
# in unit square: T(X,t) = t*(1 + X[1] + 3*X[2] - 2*X[1]*X[2])
|
||||
element = get_element()
|
||||
T_known(X) = 1 + X[1] + 3*X[2] - 2*X[1]*X[2]
|
||||
T_interpolated = element("temperature", [0.0, 0.0], 0.0)
|
||||
@test isapprox(T_interpolated, T_known([0.5, 0.5]))
|
||||
end
|
||||
|
||||
@testset "interpolation of gradient of scalar field in spatial domain" begin
|
||||
# in unit square: grad(T)(X) = [1-2X[2], 3-2*X[1]]
|
||||
element = get_element()
|
||||
gradT = element("temperature", [0.0, 0.0], 0.0, Val{:Grad})
|
||||
gradT_expected(X) = [1-2*X[2] 3-2*X[1]]
|
||||
@test isapprox(gradT, gradT_expected([0.5, 0.5]))
|
||||
end
|
||||
|
||||
@testset "test interpolation of vector field" begin
|
||||
# in unit square, u(X,t) = [1/4*t*X[1]*X[2], 0, 0]
|
||||
element = get_element()
|
||||
u = element("displacement1", [0.0, 0.0], 0.0)
|
||||
# x = X+u
|
||||
u_expected(X) = [1/4*X[1]*X[2], 0]
|
||||
# @test isapprox(x, [9/16, 1/2])
|
||||
@test isapprox(u, u_expected([0.5, 0.5]))
|
||||
end
|
||||
|
||||
@testset "interpolation of gradient of vector_field" begin
|
||||
# in unit square, u(X) = t*[X[1]*(X[2]+1), X[1]*(4*X[2]-1)]
|
||||
# => u_i,j = t*[X[2]+1 X[1]; 4*X[2]-1 4*X[1]]
|
||||
element = get_element()
|
||||
# displacement = Field(
|
||||
# (0.5, Vector[[0.0, 0.0], [0.5, -0.5], [1.0, 1.5], [0.0, 0.0]]),
|
||||
# (1.5, Vector[[0.0, 0.0], [1.5, -1.5], [3.0, 4.5], [0.0, 0.0]]))
|
||||
gradu = element("displacement2", [0.0, 0.0], 0.0, Val{:Grad})
|
||||
gradu_expected(X) = [X[2]+1 X[1]; 4*X[2]-1 4*X[1]]
|
||||
@test isapprox(gradu, gradu_expected([0.5, 0.5]))
|
||||
end
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "linear time extrapolation of field" begin
|
||||
#T_known(X,t) = t*(1 + X[1] + 3*X[2] - 2*X[1]*X[2])
|
||||
T = DVTV()
|
||||
update!(T, 0.0 => [0.0, 0.0, 0.0, 0.0])
|
||||
update!(T, 1.0 => [1.0, 2.0, 3.0, 4.0])
|
||||
@test T(-1.0) == -1.0*[1.0, 2.0, 3.0, 4.0]
|
||||
@test T( 3.0) == 3.0*[1.0, 2.0, 3.0, 4.0]
|
||||
# when going to \pm infinity, return the last one.
|
||||
@test T(-Inf) == 0.0*[1.0, 2.0, 3.0, 4.0]
|
||||
@test T(+Inf) == 1.0*[1.0, 2.0, 3.0, 4.0]
|
||||
end
|
||||
=#
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "constant time extrapolation of field" begin
|
||||
#T_known(X,t) = t*(1 + X[1] + 3*X[2] - 2*X[1]*X[2])
|
||||
T = DVTV()
|
||||
update!(T, 0.0 => [0.0, 0.0, 0.0, 0.0])
|
||||
update!(T, 1.0 => [1.0, 2.0, 3.0, 4.0])
|
||||
@test isapprox(T(-1.0, Val{:constant}), [0.0, 0.0, 0.0, 0.0])
|
||||
@test isapprox(T( 3.0, Val{:constant}), [1.0, 2.0, 3.0, 4.0])
|
||||
end
|
||||
=#
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "time extrapolation of field with only one timestep" begin
|
||||
T = DVTV()
|
||||
update!(T, 0.0 => [1.0, 2.0, 3.0, 4.0])
|
||||
@test isapprox(T(1.0), [1.0, 2.0, 3.0, 4.0])
|
||||
end
|
||||
=#
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "interpolation in temporal direction" begin
|
||||
field = DCTV()
|
||||
update!(field, 0.0 => 0.0)
|
||||
update!(field, 2.0 => 1.0)
|
||||
update!(field, 4.0 => 2.0)
|
||||
@test isapprox(field(-Inf), 0.0)
|
||||
@test isapprox(field( 0.0), 0.0)
|
||||
@test isapprox(field( 1.0), 0.5)
|
||||
@test isapprox(field( 2.0), 1.0)
|
||||
@test isapprox(field( 3.0), 1.5)
|
||||
@test isapprox(field( 4.0), 2.0)
|
||||
@test isapprox(field(+Inf), 2.0)
|
||||
end
|
||||
=#
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "time derivative interpolation in temporal basis in constant velocity" begin
|
||||
field = DCTV()
|
||||
update!(field, 0.0 => 0.0)
|
||||
update!(field, 2.0 => 1.0)
|
||||
update!(field, 4.0 => 2.0)
|
||||
@test isapprox(field(+Inf, Val{:diff}), 0.5)
|
||||
@test isapprox(field(-Inf, Val{:diff}), 0.5)
|
||||
@test isapprox(field( 0.0, Val{:diff}), 0.5)
|
||||
@test isapprox(field( 0.5, Val{:diff}), 0.5)
|
||||
@test isapprox(field( 1.0, Val{:diff}), 0.5)
|
||||
@test isapprox(field( 1.5, Val{:diff}), 0.5)
|
||||
@test isapprox(field( 2.0, Val{:diff}), 0.5)
|
||||
end
|
||||
=#
|
||||
|
||||
#= TODO: Fix test
|
||||
@testset "time derivative interpolation in temporal basis in variable velocity" begin
|
||||
pos = DCTV()
|
||||
for ti in linspace(0, 2, 5)
|
||||
update!(pos, ti => 1/2*ti^2)
|
||||
end
|
||||
# => ((0.0,0.0),(0.5,0.125),(1.0,0.5),(1.5,1.125),(2.0,2.0))
|
||||
velocity = pos(1.0, Val{:diff})
|
||||
v1 = (0.500 - 0.125)/0.5
|
||||
v2 = (1.125 - 0.500)/0.5
|
||||
@test isapprox(velocity, mean([v1, v2])) # = 1.00
|
||||
velocity = pos(2.0, Val{:diff})
|
||||
@test isapprox(velocity, (2.0-1.125)/0.5) # = 1.75
|
||||
end
|
||||
=#
|
||||
|
||||
function test_time_derivative_gradient_interpolation_of_field()
|
||||
# in unit square, u(X) = t*[X[1]*(X[2]+1), X[1]*(4*X[2]-1)]
|
||||
# => u_i,j = t*[X[2]+1 X[1]; 4*X[2]-1 4*X[1]]
|
||||
# => d(u_i,j)/dt = [X[2]+1 X[1]; 4*X[2]-1 4*X[1]]
|
||||
X = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [1.0, 0.0],
|
||||
3 => [1.0, 1.0],
|
||||
4 => [0.0, 1.0])
|
||||
u1 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [0.5, -0.5],
|
||||
3 => [1.0, 1.5],
|
||||
4 => [0.0, 0.0])
|
||||
u2 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [1.5, -1.5],
|
||||
3 => [3.0, 4.5],
|
||||
4 => [0.0, 0.0])
|
||||
element = Element(TestElement, [1, 2, 3, 4])
|
||||
update!(element, "geometry", X)
|
||||
update!(element, "displacement", 0.5 => u1)
|
||||
update!(element, "displacement", 1.5 => u2)
|
||||
|
||||
xi = [0.0, 0.0]
|
||||
time = 1.2
|
||||
diffgradu = element("displacement", xi, time, Val{:diff}, Val{:Grad})
|
||||
diffgradu_expected(X, t) = [X[2]+1 X[1]; 4*X[2]-1 4*X[1]]
|
||||
@test diffgradu == diffgradu_expected([0.5, 0.5], 1.2)
|
||||
end
|
||||
|
||||
@testset "some continuum mechanics interpolations" begin
|
||||
X = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [1.0, 0.0],
|
||||
3 => [1.0, 1.0],
|
||||
4 => [0.0, 1.0])
|
||||
u1 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [0.0, 0.0],
|
||||
3 => [0.0, 0.0],
|
||||
4 => [0.0, 0.0])
|
||||
u2 = Dict{Int64, Vector{Float64}}(
|
||||
1 => [0.0, 0.0],
|
||||
2 => [0.0, 0.0],
|
||||
3 => [1/4, 0.0],
|
||||
4 => [0.0, 0.0])
|
||||
element = Element(Quad4, [1, 2, 3, 4])
|
||||
update!(element, "geometry", X)
|
||||
update!(element, "displacement", 0.0 => u1)
|
||||
update!(element, "displacement", 1.0 => u2)
|
||||
|
||||
# from my old home works
|
||||
X = element("geometry", [0.0, 0.0], 1.0)
|
||||
u = element("displacement", [0.0, 0.0], 1.0)
|
||||
x = X + u
|
||||
x_expected = [9/16, 1/2]
|
||||
gradu = element("displacement", [0.0, 0.0], 1.0, Val{:Grad})
|
||||
epsilon = 1/2*(gradu + gradu')
|
||||
rotation = 1/2*(gradu - gradu')
|
||||
k = 0.25
|
||||
epsilon_expected = [
|
||||
X[2]*k 1/2*X[1]*k
|
||||
1/2*X[1]*k 0]
|
||||
rotation_expected = [
|
||||
0 k/2*X[1]
|
||||
-k/2*X[1] 0]
|
||||
F = I + gradu
|
||||
F_expected = [
|
||||
X[2]*k+1 X[1]*k
|
||||
0 1]
|
||||
C = F'*F
|
||||
C_expected = [
|
||||
(X[2]*k+1)^2 (X[2]*k+1)*X[1]*k
|
||||
(X[2]*k+1)*X[1]*k X[1]^2*k^2+1]
|
||||
E = 1/2*(F'*F - I)
|
||||
E_expected = [
|
||||
1/2*(X[2]*k + 1)^2-1/2 1/2*(X[2]*k+1)*X[1]*k
|
||||
1/2*(X[2]*k + 1)*X[1]*k 1/2*X[1]^2*k^2]
|
||||
U = 1/sqrt(trace(C) + 2*sqrt(det(C)))*(C + sqrt(det(C))*I)
|
||||
# U_expected = [1.24235 0.13804; 0.13804 1.02149]
|
||||
|
||||
@test isapprox(x, x_expected)
|
||||
@test isapprox(epsilon, epsilon_expected)
|
||||
@test isapprox(rotation, rotation_expected)
|
||||
@test isapprox(F, F_expected)
|
||||
@test isapprox(C, C_expected)
|
||||
@test isapprox(E, E_expected)
|
||||
# TODO: Fix test
|
||||
# @test isapprox(U, U_expected)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# 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.Testing
|
||||
importall Base
|
||||
import JuliaFEM: get_basis, get_dbasis, get_integration_points
|
||||
|
||||
type MyQuad4 <: AbstractElement
|
||||
end
|
||||
|
||||
function get_basis(element::Element{MyQuad4}, ip, time)
|
||||
1/4*[(1-ip[1])*(1-ip[2]) (1+ip[1])*(1-ip[2]) (1+ip[1])*(1+ip[2]) (1-ip[1])*(1+ip[2])]
|
||||
end
|
||||
|
||||
function get_dbasis(element::Element{MyQuad4}, ip, time)
|
||||
1/4*[-(1-ip[2]) (1-ip[2]) (1+ip[2]) -(1+ip[2])
|
||||
-(1-ip[1]) -(1+ip[1]) (1+ip[1]) (1-ip[1])]
|
||||
end
|
||||
|
||||
function get_integration_points(element::MyQuad4)
|
||||
[
|
||||
(1.0, 1.0/sqrt(3.0)*[-1, -1]),
|
||||
(1.0, 1.0/sqrt(3.0)*[ 1, -1]),
|
||||
(1.0, 1.0/sqrt(3.0)*[ 1, 1]),
|
||||
(1.0, 1.0/sqrt(3.0)*[-1, 1])
|
||||
]
|
||||
end
|
||||
|
||||
function length(element::Element{MyQuad4})
|
||||
return 4
|
||||
end
|
||||
|
||||
function size(element::Element{MyQuad4})
|
||||
return (2, 4)
|
||||
end
|
||||
|
||||
@testset "test new element" begin
|
||||
el = Element(MyQuad4, Int[])
|
||||
el["geometry"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]]
|
||||
el["displacement"] = Vector{Float64}[[0.0,0.0], [0.0,0.0], [1.0,0.0], [0.0,0.0]]
|
||||
@test isapprox(el("geometry", [0.0, 0.0], 0.0), [0.5, 0.5])
|
||||
@test isapprox(el("displacement", [0.0, 0.0], 0.0), [0.25, 0.0])
|
||||
el["temperature thermal conductivity"] = 6.0
|
||||
dim = length(el)
|
||||
K = zeros(dim, dim)
|
||||
A = 0.0
|
||||
time = 0.0
|
||||
for ip in get_integration_points(el)
|
||||
dN = el(ip, time, Val{:Grad})
|
||||
detJ = el(ip, time, Val{:detJ})
|
||||
w = ip.weight*detJ
|
||||
c = el("temperature thermal conductivity", ip, time)
|
||||
K += w*c*dN'*dN
|
||||
A += w
|
||||
end
|
||||
@test isapprox(A, 1.0)
|
||||
K_expected = [
|
||||
4.0 -1.0 -2.0 -1.0
|
||||
-1.0 4.0 -1.0 -2.0
|
||||
-2.0 -1.0 4.0 -1.0
|
||||
-1.0 -2.0 -1.0 4.0]
|
||||
@test isapprox(K, K_expected)
|
||||
end
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# 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.Testing
|
||||
|
||||
@testset "NSeg interpolate" begin
|
||||
element = Element(NSeg, [1, 2])
|
||||
@test element([0.0], 0.0) == [0.5 0.5]
|
||||
@test size(element) == (1, 2)
|
||||
@test is_nurbs(element)
|
||||
element2 = Element(Seg2, [1, 2])
|
||||
@test !is_nurbs(element2)
|
||||
end
|
||||
|
||||
@testset "NSurf interpolate" begin
|
||||
element = Element(NSurf, [1, 2, 3, 4])
|
||||
@test element([0.0, 0.0], 0.0) == [0.25 0.25 0.25 0.25]
|
||||
@test size(element) == (2, 4)
|
||||
@test is_nurbs(element)
|
||||
end
|
||||
|
||||
@testset "NSolid interpolate" begin
|
||||
element = Element(NSolid, [1, 2, 3, 4, 5, 6, 7, 8])
|
||||
@test element([0.0, 0.0, 0.0], 0.0) == [0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125]
|
||||
@test size(element) == (3, 8)
|
||||
@test is_nurbs(element)
|
||||
end
|
||||
@@ -1,89 +0,0 @@
|
||||
# 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.Testing
|
||||
|
||||
ALL_ELEMENTS = [
|
||||
Seg2, Seg3,
|
||||
Tri3, Tri6, Tri7,
|
||||
Quad4, Quad8, Quad9,
|
||||
Tet4, Tet10,
|
||||
Wedge6,
|
||||
Hex8, Hex20, Hex27
|
||||
]
|
||||
|
||||
info("basic data for elements implemented so far:")
|
||||
for element_type in [Poi1; ALL_ELEMENTS]
|
||||
element = Element(element_type, Int[])
|
||||
element_length = length(element)
|
||||
element_size = size(element)
|
||||
element_description = description(element)
|
||||
info("Element $element_type, description = $element_description, length = $element_length, size = $element_size")
|
||||
end
|
||||
|
||||
|
||||
ALL_ELEMENTS_NODES = [
|
||||
[1,2], [1,2,3],
|
||||
[1,2,3], [1,2,3,4,5,6], [1,2,3,4,5,6,7],
|
||||
[1,2,3,4], [1,2,3,4,5,6,7,8], [1,2,3,4,5,6,7,8,9],
|
||||
[1,2,3,4], [1,2,3,4,5,6,7,8,9,10],
|
||||
[1,2,3,4,5,6],
|
||||
[1,2,3,4,5,6,7,8],
|
||||
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20],
|
||||
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20,
|
||||
21,22,23,24,25,26,27]
|
||||
]
|
||||
|
||||
@testset "Evaluating basis" begin
|
||||
for (T, nod) in zip(ALL_ELEMENTS,ALL_ELEMENTS_NODES)
|
||||
el = Element(T,nod)
|
||||
nnodes = length(el)
|
||||
for (i, X) in enumerate(get_reference_coordinates(T))
|
||||
Ni = vec(el(X))
|
||||
expected = zeros(nnodes)
|
||||
expected[i] = 1.0
|
||||
@test isapprox(Ni, expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function get_volume{T<:AbstractElement}(::Type{T},nodes)
|
||||
X = get_reference_coordinates(T)
|
||||
element = Element(T,nodes)
|
||||
update!(element, "geometry", X)
|
||||
V = 0.0
|
||||
for ip in get_integration_points(element)
|
||||
V += ip.weight*element(ip, 0.0, Val{:detJ})
|
||||
end
|
||||
return V
|
||||
end
|
||||
|
||||
RESULTS = [2.0, 2.0, 0.5, 0.5, 0.5, 2.0^2, 2.0^2,
|
||||
2.0^2, 1/6, 1/6, 1.0, 2.0^3, 2.0^3, 2.0^3,]
|
||||
|
||||
@testset "Calculate reference element length/area/volume" begin
|
||||
for (T, nod, res) in zip(ALL_ELEMENTS,ALL_ELEMENTS_NODES,
|
||||
RESULTS)
|
||||
@test isapprox(get_volume(T,nod), res)
|
||||
end
|
||||
end
|
||||
|
||||
SIZES = [(1,2), (1,3), (2,3), (2,6), (2,7), (2,4),
|
||||
(2,8), (2,9), (3,4), (3,10), (3,6), (3,8),
|
||||
(3,20), (3,27)]
|
||||
|
||||
@testset "element size" begin
|
||||
for (T, nod, res) in zip(ALL_ELEMENTS,ALL_ELEMENTS_NODES, SIZES)
|
||||
@test size(Element(T,nod)) == res
|
||||
end
|
||||
end
|
||||
|
||||
@testset "element length" begin
|
||||
for i in 1:length(ALL_ELEMENTS)
|
||||
typ = ALL_ELEMENTS[i]
|
||||
vec = ALL_ELEMENTS_NODES[i]
|
||||
el = Element(typ,vec)
|
||||
@test length(el) == length(vec)
|
||||
end
|
||||
end
|
||||
@@ -41,7 +41,7 @@ using JuliaFEM.Testing
|
||||
|
||||
# Postprocess.
|
||||
# Interpolate temperature field along boundary of Γ₁ at time t=1.0
|
||||
xi = [0.0, -1.0]
|
||||
xi = (0.0, )
|
||||
X = el2("geometry", xi, 1.0)
|
||||
T = el2("temperature", xi, 1.0)
|
||||
info("Temperature at point X = $X is T = $T")
|
||||
|
||||
Reference in New Issue
Block a user