data structures, new testing concept

This commit is contained in:
Jukka Aho
2015-11-01 18:44:50 +02:00
parent 42d81bc86d
commit b985ebf50c
17 changed files with 875 additions and 847 deletions
+37 -3
View File
@@ -5,11 +5,13 @@
using JuliaFEM
using FactCheck
using Logging
@Logging.configure(level=DEBUG)
using JuliaFEM.Test
#using FactCheck
#using Logging
#@Logging.configure(level=DEBUG)
#=
facts("Testing if somebody used print, println(), @sprint in src directory") do
# TODO: make better reqular expression. Currently it will match all print words
lines_with_print = Dict()
@@ -77,6 +79,7 @@ facts("Looking the [src,test] folders *.jl files header information") do
@fact files_no_license => isempty out_str
end
#=
test_files = readdir(Pkg.dir("JuliaFEM")*"/test")
for test_file in test_files
Logging.info("checking is $test_file is real test file")
@@ -85,6 +88,7 @@ for test_file in test_files
include(test_file)
end
end
=#
# Keep this at the end of this file (include statements above this)
@Logging.configure(level=DEBUG)
@@ -92,3 +96,33 @@ end
for dic in FactCheck.getstats()
@debug(dic[1], ": ",dic[2])
end
=#
### NEW STYLE OF TESTING
using JuliaFEM.Test
function run_tests()
for test_file in readdir(Pkg.dir("JuliaFEM")*"/test")
info("checking is $test_file is real test file")
if (startswith(test_file, "test_")) & (endswith(test_file, ".jl"))
run_test(test_file)
end
end
passed, failed, errors, critical = print_test_statistics()
# at the very end throw error if something is failed
if failed + errors critical != 0
error("Some tests has failed. Fix them. Now.")
exit(1)
else
info("""All tests has passed \o/ .""")
exit(0)
end
end
run_tests()
+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
module BasisTests
using JuliaFEM.Test
using JuliaFEM: get_basis, grad, FieldSet, Field, Quad4
"""basic continuum interpolations"""
function test_basic_interpolations()
element = Quad4([1, 2, 3, 4])
element["geometry"] = Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]
element["temperature"] = ([0.0, 0.0, 0.0, 0.0], [1.0, 2.0, 3.0, 4.0])
element["displacement"] = (
Vector[[0.0, 0.0], [0.0, 0.0], [0.00, 0.0], [0.0, 0.0]],
Vector[[0.0, 0.0], [0.0, 0.0], [0.25, 0.0], [0.0, 0.0]])
# from my old home works
basis = get_basis(element)
dbasis = grad(basis)
@test isapprox(basis("geometry", [0.0, 0.0], 1.0) + basis("displacement", [0.0, 0.0], 1.0), [9/16, 1/2])
gradu = dbasis("displacement", [0.0, 0.0], 1.0)
epsilon = 1/2*(gradu + gradu')
rotation = 1/2*(gradu - gradu')
X = basis("geometry", [0.0, 0.0], 1.0)
k = 0.25
epsilon_wanted = [X[2]*k 1/2*X[1]*k; 1/2*X[1]*k 0]
rotation_wanted = [0 k/2*X[1]; -k/2*X[1] 0]
@test isapprox(epsilon, epsilon_wanted)
@test isapprox(rotation, rotation_wanted)
F = I + gradu
@test isapprox(F, [X[2]*k+1 X[1]*k; 0 1])
C = F'*F
@test isapprox(C, [(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)
@test isapprox(E, [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)
@test isapprox(U, [1.24235 0.13804; 0.13804 1.02149])
end
function test_interpolation_in_temporal_basis()
info("testing interpolation on temporal basis")
temporalbasis = TemporalBasis((t) -> [1-t, t], (t) -> [-1, 1])
@test temporalbasis(0.2) == [0.8, 0.2]
i1 = Increment([0.0])
i2 = Increment([1.0])
i3 = Increment([2.0])
t1 = TimeStep(0.0, Increment[i1])
t2 = TimeStep(2.0, Increment[i2])
t3 = TimeStep(4.0, Increment[i3])
field = Field(TimeStep[t1, t2, t3])
@test call(field, temporalbasis, -Inf) == [0.0]
@test call(field, temporalbasis, 0.0) == [0.0]
@test call(field, temporalbasis, 1.0) == [0.5]
@test call(field, temporalbasis, 2.0) == [1.0]
@test call(field, temporalbasis, 3.0) == [1.5]
@test call(field, temporalbasis, 4.0) == [2.0]
@test call(field, temporalbasis, +Inf) == [2.0]
@test call(field, temporalbasis, +Inf, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, -Inf, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 0.0, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 0.5, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 1.0, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 1.5, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 2.0, Val{:derivative}) == [0.5]
fs = FieldSet()
t = collect(linspace(0, 2, 5))
x = 1/2*t.^2
x2 = tuple(collect(zip(t, x))...)
# => ((0.0,0.0),(0.5,0.125),(1.0,0.5),(1.5,1.125),(2.0,2.0))
fs["particle"] = x2
position = call(fs["particle"], temporalbasis, 1.0)[1]
@test isapprox(position, 0.50)
velocity = call(fs["particle"], temporalbasis, 2.0, Val{:derivative})[1]
@test isapprox(velocity, (2.0-1.125)/0.5) # = 1.75
velocity = call(fs["particle"], temporalbasis, 1.0, Val{:derivative})[1]
v1 = (0.500 - 0.125)/0.5
v2 = (1.125 - 0.500)/0.5
info("v1 = $v1, v2 = $v2")
info(mean([v1, v2]))
@test isapprox(velocity, mean([v1, v2])) # = 1.00
# FIXME, returns wrong type.
@test isa(position, Increment) == true
@test isa(velocity, Increment) == true
end
function test_interpolation_in_spatial_basis()
info("testing interpolation on spatial basis")
basis(xi) = 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])]'
dbasis(xi) = 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])]
spatialbasis = SpatialBasis(basis, dbasis)
@test spatialbasis.basis([0.0, 0.0]) == 1/4*[1 1 1 1]
fs = FieldSet()
fs["geometry"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]]
fs["displacement"] = (0.0, zeros(2, 4)), (1.0, Vector[[0.0, 0.0], [0.0, 0.0], [0.25, 0.0], [0.0, 0.0]])
X = call(last(fs["geometry"]), spatialbasis, [0.0, 0.0])
u = call(last(fs["displacement"]), spatialbasis, [0.0, 0.0])
x = X+u
@test X 1/2*[1, 1]
@test x [9/16, 1/2]
gradu = call(last(fs["displacement"]), spatialbasis, [0.0, 0.0], last(fs["geometry"]), Val{:gradient})
@test gradu [0.125 0.125; 0.0 0.0]
end
end
+5 -4
View File
@@ -1,13 +1,13 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
module ElasticityTests
using Base.Test
using JuliaFEM.Test
using JuliaFEM: Quad4, Field, FieldSet, CPS4, get_basis, solve!, PlaneStressElasticityProblem
function run()
function test_elasticity_one_element()
element = Quad4([1, 2, 3, 4])
element["geometry"] = Vector[[0.0, 0.0], [10.0, 0.0], [10.0, 1.0], [0.0, 1.0]]
element["youngs modulus"] = 500.0
@@ -24,4 +24,5 @@ function run()
@test disp -8.77303119819776
end
run()
end
+20 -21
View File
@@ -1,18 +1,22 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
using FactCheck
using JuliaFEM: Element, Basis, Field, FieldSet, FunctionSpace
module ElementTests
using JuliaFEM.Test
using JuliaFEM: Element, Basis, Field, FieldSet, FunctionSpace, test_element
""" Prototype element
This should always pass test_element if everything is ok.
"""
type MockElement <: Element
connectivity :: Array{Int, 1}
connectivity :: Vector{Int}
basis :: Basis
fields :: Dict{ASCIIString, FieldSet}
fields :: FieldSet
end
function MockElement(connectivity)
h(xi) = 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])]
@@ -24,33 +28,26 @@ function MockElement(connectivity)
basis = Basis(h, dh)
MockElement(connectivity, basis, Dict())
end
Base.size(element::Type{MockElement}) = (2, 4)
using JuliaFEM: test_element
facts("test test_element against mock element") do
"""test test_element against mock element"""
function test_mockelement()
test_element(MockElement)
end
facts("test adding fieldsets and fields to element") do
""" test adding fieldsets and fields to element"""
function test_add_fields_to_element()
el = MockElement([1, 2, 3, 4])
fieldset = JuliaFEM.FieldSet("geometry")
field1 = JuliaFEM.Field(0.0, [0.0, 0.0, 0.0, 0.0])
push!(fieldset, field1)
field2 = JuliaFEM.Field(1.0, [1.0, 1.0, 1.0, 1.0])
push!(fieldset, field2)
el["geometry"] = fieldset
fields = el["geometry"]
@fact length(fields) --> 2
@fact fields[1] --> field1
@fact fields[2] --> field2
el["geometry"] = [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]
field = el["geometry"]
@test length(field) == 2 # two time steps
end
#=
facts("interpolation of fields in some function space") do
element = MockElement([1, 2, 3, 4])
el = MockElement([1, 2, 3, 4])
fieldset1 = FieldSet("geometry", [Field(0.0, Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])])
fieldset2 = FieldSet("constant scalar field", [Field(0.0, 1.0)])
fieldset3 = FieldSet("scalar field", [Field(0.0, [1.0, 2.0, 3.0, 4.0])])
@@ -79,4 +76,6 @@ facts("interpolation of fields in some function space") do
@fact v("vector field 3", xi, t) --> 1/4*[1+2+3+4, 5+6+7+8, 9+10+11+12]
@fact v("tensor field 1", xi, t) --> 1/4*[1+2+3+4 5+6+7+8; 9+10+11+12 13+14+15+16]
end
=#
end
+237 -178
View File
@@ -2,115 +2,222 @@
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
module TypesTests
module FieldTests
using JuliaFEM: Increment, TimeStep, AbstractField, DefaultDiscreteField, FieldSet
using JuliaFEM: Increment, TimeStep, Field, DefaultDiscreteField, FieldSet
using JuliaFEM: TemporalBasis, SpatialBasis, ContinuousField, DiscreteField
using JuliaFEM: Field
using JuliaFEM: DefaultContinuousField
using JuliaFEM.Test
using Base.Test
""" testing Increment """
function test_increment()
info("testing Increment")
# testing Increment
# constant increment
I3 = Increment(1)
@test isa(I3, Increment)
@test length(I3) == 1
# FIXME: i don't like 1-length arrays
@test I3 == [1]
# two increments with vector data
I1 = Increment([1, 2, 3])
I2 = Increment([2, 3, 4])
@test dot(I1, I2) == 20
@test dot([1,2,3], I2) == 20
@test dot(I1, [2,3,4]) == 20
@test length(I1) == 3
@test length(I2) == 3
# basic math
@test 1/2*(I1+I2) == [1.5, 2.5, 3.5]
@test I1 + 1 == [2, 3, 4]
@test I1 - 1 == [0, 1, 2]
@test I1*3 == [3, 6, 9]
@test I1+I2 == [3, 5, 7]
# dot product
@test dot(I1, I2) == 20
@test dot([1,2,3], I2) == 20
@test dot(I1, [2,3,4]) == 20
@test dot([1, 2], Increment[I1, I2])
# similarity
f = zeros(Increment, 2, 4)
@test length(f) == 4
g = similar(f, ones(8))
@test typeof(f) == typeof(g)
@test length(f) == length(g)
# promotion of increment
@test typeof(I1+1) == typeof(I1)
@test typeof(I1-1) == typeof(I1)
@test typeof(I1*3) == typeof(I1)
# vec
@test vec(g) == ones(8)
# promotion
# FIXME: how to do promotion so that modified increment is still increment?
@test isa(I1+1, Increment)
@test isa(I1-1, Increment)
@test isa(3*I1, Increment)
@test isa(1/2*I1, Increment)
@test isa(I1+I2, Increment)
@test isa(I1-I2, Increment)
# FIXME
#@test typeof(I1) == typeof(I1+I2)
#@test typeof(I1/2) == typeof(I1)
#@test typeof(1/2*S1) == typeof(I1)
end
test_increment()
""" testing TimeStep """
function test_timestep()
info("testing TimeStep")
info("test_timestep(): create empty timestep")
ts = TimeStep()
@test length(ts) == 0
@test ts.time == 0.0
info("create timestep with two increments")
i1 = Increment([1, 2, 3])
i2 = Increment([2, 3, 4])
i3 = Increment([2, 3, 4])
i4 = Increment([3, 4, 5])
t1 = TimeStep(1.0, Increment[i1, i2])
t2 = TimeStep(2.0, Increment[i3, i4])
@test length(t1) == length(t2) == 2
t3 = TimeStep(3.0, i1+1)
increments = Increment[i1, i2]
ts = TimeStep(1.0, increments)
@test length(ts) == 2
info("create timestep with scalar value")
ts = TimeStep(1)
@test length(ts) == 1
@test ts.time == 0.0
@test isa(ts[1], Increment)
@test ts[1] == [1]
info("create timestep compactly for time t=0.0")
ts = TimeStep([1, 2, 3])
@test length(ts) == 1
@test ts.time == 0.0
@test isa(ts[1], Increment)
@test ts[1] == [1, 2, 3]
info("create timestep compactly, add three increments compactly for time t=0.0")
ts = TimeStep(1, 2, 3)
@test length(ts) == 3
@test ts.time == 0.0
@test isa(ts[1], Increment)
info("create timestep compactly, add two increments compactly for time t=0.0")
ts = TimeStep([1, 2, 3], [2, 3, 4])
@test length(ts) == 2
@test ts.time == 0.0
@test isa(ts[1], Increment)
@test ts[1] == [1, 2, 3]
@test ts[2] == [2, 3, 4]
info("create standard timesteps")
info(TimeStep(0.5, Increment([1, 2])))
@test TimeStep(0.5, [1, 2]).time == 0.5
@test TimeStep(0.5, [1, 2]) == [1, 2]
@test TimeStep(0.5, 1).time == 0.5
@test TimeStep(0.5, 1) == [1]
end
test_timestep()
function test_watta_fak()
# TODO: this test will fail if Increment is typealiased to Vector
fs = FieldSet()
fs["discrete field"] = [1, 2, 3, 4]
T0 = last(fs["discrete field"])
info("last discrete field: $T0, ", typeof(T0))
T1 = T0 + 1
info("adding 1 to discrete field: $T1, ", typeof(T1))
ts = TimeStep(1.0, T1)
info("creating time step: $ts, ", typeof(ts))
push!(fs["discrete field"], ts)
info("last discrete field = ", last(fs["discrete field"]))
info("fieldset: $fs")
@test last(fs["discrete field"]) == [2, 3, 4, 5]
end
test_watta_fak()
""" testing DefaultDiscreteField """
function test_default_discrete_field()
info("testing DefaultDiscreteField")
info("test_default_discrete_field(): the traditional way")
i1 = Increment([1, 2, 3])
i2 = Increment([2, 3, 4])
t1 = TimeStep(1.0, Increment[i1, i2])
i3 = Increment([2, 3, 4])
i4 = Increment([3, 4, 5])
t1 = TimeStep(1.0, Increment[i1, i2])
t2 = TimeStep(2.0, Increment[i3, i4])
timesteps = TimeStep[t1, t2]
f1 = DefaultDiscreteField(timesteps)
@test length(f1) == 2
@test isa(f1, AbstractField) == true
end
test_default_discrete_field()
@test isa(f1, Field)
@test f1[1][1] == [1, 2, 3]
@test f1[1][2] == [2, 3, 4]
@test f1[2][1] == [2, 3, 4]
@test f1[2][2] == [3, 4, 5]
@test f1[1].time == 1.0
@test f1[2].time == 2.0
info("test_default_discrete_field(): quick way, this creates one timestep with vector value")
f1 = DefaultDiscreteField([1, 2, 3])
info("f1 = $f1")
@test isa(f1[1], TimeStep)
@test isa(f1[1][1], Increment)
@test f1[1][1] == [1, 2, 3]
@test f1[1].time == 0.0
info("test_default_discrete_field(): quick way, two timesteps with constant value")
f1 = DefaultDiscreteField(1, 2)
@test length(f1) == 2
@test isa(f1[1], TimeStep)
@test isa(f1[2], TimeStep)
@test isa(f1[1][1], Increment)
@test isa(f1[2][1], Increment)
@test f1[1][1] == [1]
@test f1[2][1] == [2]
@test f1[1].time == 0.0
@test f1[2].time == 1.0
info("test_default_discrete_field(): quick way, one timestep with scalar value")
f1 = DefaultDiscreteField(1)
@test length(f1) == 1
@test isa(f1[1], TimeStep)
@test isa(f1[1][1], Increment)
@test f1[1][1] == [1]
@test f1[1].time == 0.0
info("test_default_discrete_field(): quick way, two timesteps with vector value")
f1 = DefaultDiscreteField([1, 2, 3], [3, 4, 5])
@test length(f1) == 2
@test isa(f1[1], TimeStep)
@test isa(f1[2], TimeStep)
@test isa(f1[1][1], Increment)
@test isa(f1[2][1], Increment)
@test f1[1][1] == [1, 2, 3]
@test f1[2][1] == [3, 4, 5]
@test f1[1].time == 0.0
@test f1[2].time == 1.0
info("test_default_discrete_field(): quick way, set time vector also")
f1 = DefaultDiscreteField( (0.5, [1, 2, 3]), (1.0, [3, 4, 5]) )
@test isa(f1[1], TimeStep)
@test isa(f1[2], TimeStep)
@test isa(f1[1][1], Increment)
@test isa(f1[2][1], Increment)
@test f1[1][1] == [1, 2, 3]
@test f1[2][1] == [3, 4, 5]
@test f1[1].time == 0.5
@test f1[2].time == 1.0
end
""" testing DefaultContinuousField """
function test_default_continuous_field()
function myfield(xi::Vector, time::Float64)
time/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
f = DefaultContinuousField(myfield)
@test f([0.0, 0.0], 1.0) == [0.25 0.25 0.25 0.25]
end
""" testing FieldSet """
function test_fieldset()
i1 = Increment([1, 2, 3])
i2 = Increment([2, 3, 4])
i3 = Increment([2, 3, 4])
i4 = Increment([3, 4, 5])
t1 = TimeStep(1.0, Increment[i1, i2])
t2 = TimeStep(2.0, Increment[i3, i4])
timesteps = TimeStep[t1, t2]
f1 = DefaultDiscreteField(timesteps)
info("testing adding discrete field to FieldSet")
info("test_fieldset(): testing adding discrete field to FieldSet")
fs = FieldSet()
fs["temperature"] = f1
fs["temperature"] = DefaultDiscreteField([1, 2, 3])
@test length(fs) == 1
info("testing adding discrete fields quickly")
# the easy way
info("test_fieldset(): testing adding discrete fields quickly")
fs2 = FieldSet()
fs2["temperature"] = [1, 2, 3, 4]
@test fs2["temperature"][end][end] == [1, 2, 3, 4]
@test last(fs2["temperature"]) == [1, 2, 3, 4]
info("test_fieldset(): testing adding all kind of discrete fields")
fs2 = FieldSet()
fs2["constant scalar field"] = 1
fs2["scalar field"] = [1, 2, 3, 4]
@@ -120,45 +227,61 @@ function test_fieldset()
timestep = fs2["vector field"][end]
@test timestep.time == 0.0
info("testing adding timesteps")
# add another timestep
info("test_fieldset(): testing adding timesteps")
fs = FieldSet()
fs["temperature"] = [1, 2, 3, 4]
T0 = last(fs["temperature"]) # last increment of last field
info("last temperature = $T0")
T1 = T0 + 1
@test typeof(T0) == typeof(T1)
info("last temperature T0 = $T0")
T1 = Increment(T0 + 1)
info("typeof T1 = $(typeof(T1))")
timestep = TimeStep(1.0, Increment[T1]) # new list of increments for timestep
push!(fs["temperature"], timestep)
T2 = last(fs["temperature"])
info("last temperature = $T2")
info("last temperature T2 = $T2")
@test last(fs["temperature"]) == [2, 3, 4, 5]
# or more easily
info("test_fieldset(): testing adding timesteps compactly")
timestep = TimeStep(2.0, T1)
push!(fs["temperature"], timestep)
@test length(fs["temperature"].timesteps) == 3
info("test adding several time steps at once")
info("test_fieldset(): test adding several time steps at once without time vector")
fs3 = FieldSet()
fs3["time series 1"] = (0.0, [1, 2, 3, 4]), (0.5, [2, 3, 4, 5]), (1.0, [1, 1, 1, 1])
@test fs3["time series 1"][end].time == 1.0
fs3["time series 2"] = [1, 2, 3, 4], [2, 3, 4, 5], [1, 1, 1, 1]
@test fs3["time series 2"][end].time == 2.0
end
test_fieldset()
fs3["time series 2"] = [1, 2, 3, 4], [2, 3, 4, 5]
info(fs3)
@test fs3["time series 2"][1].time == 0.0
@test fs3["time series 2"][2].time == 1.0
@test fs3["time series 2"][1][end] == [1, 2, 3, 4]
@test fs3["time series 2"][2][end] == [2, 3, 4, 5]
info("test_fieldset(): test adding several time steps at once with time vector")
fs3 = FieldSet()
fs3["time series 1"] = (0.0, [1, 2, 3, 4]), (0.5, [2, 3, 4, 5])
@test fs3["time series 1"][1].time == 0.0
@test fs3["time series 1"][2].time == 0.5
@test fs3["time series 1"][1][end] == [1, 2, 3, 4]
@test fs3["time series 1"][2][end] == [2, 3, 4, 5]
info("test_fieldset(): adding continuous field")
fs = FieldSet()
fs["continuous field"] = (xi, t) -> xi[1]*xi[2]*t
@test fs["continuous field"]([1.0, 2.0], 3.0) == 6.0
type MyFunnyContinuousField <: ContinuousField
basis :: Function
discretefield :: DiscreteField
end
function Base.call(field::MyFunnyContinuousField, xi::Vector, time::Number=1.0)
data = last(field.discretefield) # get the last timestep last increment
type MyContinuousField <: ContinuousField
basis :: Function
discrete_field :: DiscreteField
end
function Base.call(field::MyContinuousField, xi::Vector, time::Number=1.0)
data = last(field.discrete_field) # get the last timestep last increment
info("data = $data, typeof data = $(typeof(data))")
basis = time*field.basis(xi) # evaluate basis at point ξ.
sum([basis[i]*data[i] for i=1:length(data)]) # sum results
end
""" testing ContinuousField """
function test_continuous_field()
info("testing continuous field")
fs = FieldSet()
fs["discrete field"] = [1, 2, 3, 4]
basis(xi) = 1/4*[
@@ -166,7 +289,7 @@ function test_continuous_field()
(1+xi[1])*(1-xi[2]),
(1+xi[1])*(1+xi[2]),
(1-xi[1])*(1+xi[2])]
fs["continuous field"] = MyFunnyContinuousField(basis, fs["discrete field"])
fs["continuous field"] = MyContinuousField(basis, fs["discrete field"])
@test fs["continuous field"]([0.0, 0.0], 1.0) == 1/4*(1+2+3+4)
T0 = last(fs["discrete field"])
T1 = T0 + 1.0
@@ -174,21 +297,20 @@ function test_continuous_field()
push!(fs["discrete field"], TimeStep(1.0, T0+1.0))
@test fs["continuous field"]([0.0, 0.0], 1.0) == 1/4*(2+3+4+5)
end
test_continuous_field()
type MyFunnyDiscreteField <: DiscreteField
type MyDiscreteField <: DiscreteField
discrete_points :: Vector
continuousfield :: ContinuousField
continuous_field :: ContinuousField
end
Base.length(field::MyFunnyDiscreteField) = length(field.discrete_points)
Base.endof(field::MyFunnyDiscreteField) = endof(field.discrete_points)
Base.last(field::MyFunnyDiscreteField) = Float64[field[i] for i=1:length(field)]
function Base.getindex(field::MyFunnyDiscreteField, idx::Int64)
field.continuousfield(field.discrete_points[idx])
Base.length(field::MyDiscreteField) = length(field.discrete_points)
Base.endof(field::MyDiscreteField) = endof(field.discrete_points)
Base.last(field::MyDiscreteField) = Float64[field[i] for i=1:length(field)]
function Base.getindex(field::MyDiscreteField, idx::Int64)
field.continuous_field(field.discrete_points[idx])
end
""" testing DiscreteField """
function test_discrete_field()
info("testing discrete field")
fs = FieldSet()
fs["discrete field"] = [1, 2, 3, 4]
basis(xi) = 1/4*[
@@ -196,98 +318,35 @@ function test_discrete_field()
(1+xi[1])*(1-xi[2]),
(1+xi[1])*(1+xi[2]),
(1-xi[1])*(1+xi[2])]
fs["continuous field"] = MyFunnyContinuousField(basis, fs["discrete field"])
fs["continuous field"] = MyContinuousField(basis, fs["discrete field"])
discrete_points = 1.0/sqrt(3.0)*Vector[[-1, -1], [1, -1], [1, 1], [-1, 1]]
fs["discrete field 2"] = MyFunnyDiscreteField(discrete_points, fs["continuous field"])
fs["discrete field 2"] = MyDiscreteField(discrete_points, fs["continuous field"])
@test last(fs["discrete field 2"]) [
1.7559830641437073,
2.0893163974770410,
2.9106836025229590,
3.2440169358562922]
end
test_discrete_field()
function test_interpolation_in_temporal_basis()
info("testing interpolation on temporal basis")
temporalbasis = TemporalBasis((t) -> [1-t, t], (t) -> [-1, 1])
@test temporalbasis(0.2) == [0.8, 0.2]
i1 = Increment([0.0])
i2 = Increment([1.0])
i3 = Increment([2.0])
t1 = TimeStep(0.0, Increment[i1])
t2 = TimeStep(2.0, Increment[i2])
t3 = TimeStep(4.0, Increment[i3])
field = Field(TimeStep[t1, t2, t3])
@test call(field, temporalbasis, -Inf) == [0.0]
@test call(field, temporalbasis, 0.0) == [0.0]
@test call(field, temporalbasis, 1.0) == [0.5]
@test call(field, temporalbasis, 2.0) == [1.0]
@test call(field, temporalbasis, 3.0) == [1.5]
@test call(field, temporalbasis, 4.0) == [2.0]
@test call(field, temporalbasis, +Inf) == [2.0]
@test call(field, temporalbasis, +Inf, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, -Inf, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 0.0, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 0.5, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 1.0, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 1.5, Val{:derivative}) == [0.5]
@test call(field, temporalbasis, 2.0, Val{:derivative}) == [0.5]
fs = FieldSet()
t = collect(linspace(0, 2, 5))
x = 1/2*t.^2
x2 = tuple(collect(zip(t, x))...)
# => ((0.0,0.0),(0.5,0.125),(1.0,0.5),(1.5,1.125),(2.0,2.0))
fs["particle"] = x2
position = call(fs["particle"], temporalbasis, 1.0)[1]
@test position 0.50
velocity = call(fs["particle"], temporalbasis, 2.0, Val{:derivative})[1]
@test velocity (2.0-1.125)/0.5 # = 1.75
velocity = call(fs["particle"], temporalbasis, 1.0, Val{:derivative})[1]
v1 = (0.500 - 0.125)/0.5
v2 = (1.125 - 0.500)/0.5
info("v1 = $v1, v2 = $v2")
info(mean([v1, v2]))
@test velocity mean([v1, v2]) # = 1.00
# FIXME, returns wrong type.
#=
@test isa(position, Increment) == true
@test isa(velocity, Increment) == true
=#
function test_field_conversion()
i1 = Increment([1, 2, 3])
i2 = Increment([2, 3, 4])
t1 = TimeStep(1.0, Increment[i1, i2])
i3 = Increment([2, 3, 4])
i4 = Increment([3, 4, 5])
t2 = TimeStep(2.0, Increment[i3, i4])
timesteps = TimeStep[t1, t2]
info("timesteps = $timesteps")
f1 = Field(timesteps)
info("field = $f1")
@test length(f1) == 2
@test isa(f1, Field)
@test f1[1][1] == [1, 2, 3]
@test f1[1][2] == [2, 3, 4]
@test f1[2][1] == [2, 3, 4]
@test f1[2][2] == [3, 4, 5]
@test f1[1].time == 1.0
@test f1[2].time == 2.0
end
test_interpolation_in_temporal_basis()
function test_interpolation_in_spatial_basis()
info("testing interpolation on spatial basis")
basis(xi) = 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])]'
dbasis(xi) = 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])]
spatialbasis = SpatialBasis(basis, dbasis)
@test spatialbasis.basis([0.0, 0.0]) == 1/4*[1 1 1 1]
fs = FieldSet()
fs["geometry"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]]
fs["displacement"] = (0.0, zeros(2, 4)), (1.0, Vector[[0.0, 0.0], [0.0, 0.0], [0.25, 0.0], [0.0, 0.0]])
X = call(last(fs["geometry"]), spatialbasis, [0.0, 0.0])
u = call(last(fs["displacement"]), spatialbasis, [0.0, 0.0])
x = X+u
@test X 1/2*[1, 1]
@test x [9/16, 1/2]
gradu = call(last(fs["displacement"]), spatialbasis, [0.0, 0.0], last(fs["geometry"]), Val{:gradient})
@test gradu [0.125 0.125; 0.0 0.0]
end
test_interpolation_in_spatial_basis()
println("test_fields.jl: all test passing.")
end
+8 -3
View File
@@ -1,11 +1,14 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
module GlobalAssemblyTests
using JuliaFEM.Test
using JuliaFEM: Quad4, Seg2, FieldSet, Field, PlaneHeatProblem
using JuliaFEM: initialize_global_assembly, calculate_global_assembly!
using FactCheck
facts("assemble a simple two element problem and solve") do
"""assemble a simple two element problem and solve"""
function test_asssembly()
el1 = Quad4([1, 2, 3, 4])
el1["geometry"] = Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]
el1["temperature thermal conductivity"] = 6.0
@@ -28,5 +31,7 @@ facts("assemble a simple two element problem and solve") do
A = lufact(global_assembly.stiffness_matrix[free_dofs, free_dofs])
b = full(global_assembly.force_vector)[free_dofs]
u = A \ b
@fact u --> roughly([101.0, 101.0])
@test isapprox(u, roughly([101.0, 101.0]))
end
end
+13 -5
View File
@@ -3,10 +3,17 @@
# unit tests for heat equations
using FactCheck
using JuliaFEM: Seg2, Quad4, Field, FieldSet, DC2D4, initialize_local_assembly, calculate_local_assembly!, DC2D2
module HeatTests # always wrap tests to module ending with "Tests"
facts("tests on [0x1]x[0x1] domain") do
using JuliaFEM.Test # always use JuliaFEM.Test, not Base.Test
using JuliaFEM: Seg2, Quad4, Field, FieldSet, DC2D4,
initialize_local_assembly, calculate_local_assembly!,
DC2D2
"tests on [0x1]x[0x1] domain"
function test_one_element() # always start test function with name test_
# volume element
element = Quad4([1, 2, 3, 4])
@@ -29,7 +36,7 @@ facts("tests on [0x1]x[0x1] domain") do
fdofs = [1, 2]
A = la.stiffness_matrix
b = la.force_vector
@fact A[fdofs, fdofs] \ b[fdofs] --> roughly([1.0, 1.0])
@test isapprox(A[fdofs, fdofs] \ b[fdofs], [1.0, 1.0])
# Set constant flux g=6 on boundary. Accurate solution is
# u(x,y) = x which equals T=1 on boundary.
@@ -37,7 +44,8 @@ facts("tests on [0x1]x[0x1] domain") do
calculate_local_assembly!(la, boundary_equation, "temperature")
b = la.force_vector
@fact A[fdofs, fdofs] \ b[fdofs] --> roughly([1.0, 1.0])
@test isapprox(A[fdofs, fdofs] \ b[fdofs], [1.0, 1.0]) # always use @test to test things.
end
end
-39
View File
@@ -1,39 +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: get_basis, grad, FieldSet, Field, Quad4
using FactCheck
facts("basic continuum interpolations") do
element = Quad4([1, 2, 3, 4])
element["geometry"] = Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]
element["temperature"] = ([0.0, 0.0, 0.0, 0.0], [1.0, 2.0, 3.0, 4.0])
element["displacement"] = (
Vector[[0.0, 0.0], [0.0, 0.0], [0.00, 0.0], [0.0, 0.0]],
Vector[[0.0, 0.0], [0.0, 0.0], [0.25, 0.0], [0.0, 0.0]])
# from my old home works
basis = get_basis(element)
dbasis = grad(basis)
@fact basis("geometry", [0.0, 0.0], 1.0) + basis("displacement", [0.0, 0.0], 1.0) --> [9/16, 1/2]
gradu = dbasis("displacement", [0.0, 0.0], 1.0)
epsilon = 1/2*(gradu + gradu')
rotation = 1/2*(gradu - gradu')
X = basis("geometry", [0.0, 0.0], 1.0)
k = 0.25
epsilon_wanted = [X[2]*k 1/2*X[1]*k; 1/2*X[1]*k 0]
rotation_wanted = [0 k/2*X[1]; -k/2*X[1] 0]
@fact epsilon --> roughly(epsilon_wanted)
@fact rotation --> roughly(rotation_wanted)
F = I + gradu
@fact F --> [X[2]*k+1 X[1]*k; 0 1]
C = F'*F
@fact C --> [(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)
@fact E --> [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)
#@fact U --> roughly([1.24235 0.13804; 0.13804 1.02149])
end
+10 -2
View File
@@ -1,10 +1,15 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
using JuliaFEM: interpolate
module MathTests
using JuliaFEM.Test
using FactCheck
function test_math()
@test 1+1 == 2
end
#using JuliaFEM: interpolate
#=
facts("test interpolation of different field variables") do
N(xi) = [
(1-xi[1])*(1-xi[2])/4
@@ -31,3 +36,6 @@ facts("test interpolation of different field variables") do
@fact interpolate(F5, dNdξ, [0.0, 0.0]) --> [5.0 0.0; 0.0 0.5]
@fact interpolate(F6, N, [0.0, 0.0]) --> 36
end
=#
end