data structures (almost) working

This commit is contained in:
Jukka Aho
2015-11-02 23:29:52 +02:00
parent e39d9796b0
commit 1e9d33c0f0
3 changed files with 183 additions and 239 deletions
+117 -204
View File
@@ -6,7 +6,7 @@
"source": [
"# Data structures\n",
"\n",
"**Author(s)**: Jukka Aho\n",
"Author(s): Jukka Aho\n",
"\n",
"**Abstract**: Description of basis data structures. In this notebook the concepts of `Increment`, `TimeStep`, `DiscreteField`, `ContinuousField`, `FieldSet`, `SpatialBasis` and `TemporalBasis` are intoduced. By combining these atomic structures one is able to form finite elements and interpolate it's fields in time and spatial domain.\n",
"\n",
@@ -53,6 +53,8 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating discrete fields\n",
"\n",
"Here's the strategy in short: each non-linear iteration is `Increment`, what is a vector-like object containing data. Elements of `Increment` can be scalars, vectors or tensors. `Increment` belongs to `TimeStep`. `TimeStep` contains one or more increments. Then we have `Field` which contains all timesteps. And finally we have `FieldSet` which contains all fields.\n",
"\n",
" FieldSet -> Field -> TimeStep -> Increment -> data\n",
@@ -65,16 +67,7 @@
" FieldSet -> \"temperature\" -> 1.0 -> 1 -> [3,4,5,6]\n",
" 2 -> [5,6,7,8]\n",
"\n",
"and so on."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating discrete fields\n",
"\n",
"Here we create a `FieldSet` containing one field `temperature` which contains two `TimeStep`s, two `Increment`s in both of them."
"and so on. Here we create a `FieldSet` containing one field `temperature` which contains two `TimeStep`s, two `Increment`s in both of them."
]
},
{
@@ -178,7 +171,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This way we can easily (discrete) create scalar, vector and tensor fields."
"This way we can easily create discrete scalar, vector and tensor fields."
]
},
{
@@ -327,14 +320,14 @@
"traceback": [
"LoadError: MethodError: `convert` has no method matching convert(::Type{Float64}, ::Array{Int64,1})\nThis may have arisen from a call to the constructor Float64(...),\nsince type constructors fall back to convert methods.\nClosest candidates are:\n call{T}(::Type{T}, ::Any)\n convert(::Type{Float64}, !Matched::Int8)\n convert(::Type{Float64}, !Matched::Int16)\n ...\nwhile loading In[8], in expression starting on line 1",
"",
" in convert at /home/jukka/.julia/v0.4/JuliaFEM/src/fields.jl:205",
" in convert at /home/jukka/.julia/v0.4/JuliaFEM/src/fields.jl:233",
" in call at essentials.jl:56",
" in setindex! at dict.jl:641"
]
}
],
"source": [
"fs2[\"time series 2\"] = [1, 2, 3, 4], [2, 3, 4, 5], [1, 1, 1, 1]\n",
"fs2[\"time series 2\"] = [1, 2], [2, 3], [3, 4]\n",
"fs2"
]
},
@@ -342,7 +335,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"To add another field, with different time."
"Adding another field, with different time."
]
},
{
@@ -714,7 +707,7 @@
{
"data": {
"text/plain": [
"call (generic function with 1259 methods)"
"call (generic function with 1275 methods)"
]
},
"execution_count": 22,
@@ -738,7 +731,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we create two fields, one is discrete and another is continuous which takes discrete field as parametes"
"Now we create two fields, one is discrete and another is continuous which takes discrete field as parameter:"
]
},
{
@@ -803,7 +796,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Add another discrete field:"
"Next we add another discrete field and see that continuous field which is \"connected\" to discrete fields updates accordingly:"
]
},
{
@@ -865,7 +858,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"What we did is that we actually interpolated discrete field using continuous functions. We evaluated discrete field using bilinear basis at midpoint of \"element\":"
"What we just did is that we actually interpolated discrete field using continuous functions. We evaluated discrete field using bilinear basis at midpoint of \"element\":"
]
},
{
@@ -967,9 +960,11 @@
"\n",
"In earlier the concepts of `DiscreteField` and `ContinuousField` were introduced, so that now we can define discrete set of values and continuous functions. It has also been shown how fields can depend from each other such a way that we interpolate continuous field from discrete field and vice versa. \n",
"\n",
"This motivates us to create continuous fields which are interpolated from discrete values with some proper basis. By thinking this way interpolation is nothing more than just an application of the earlier results already shown. \n",
"This motivates us to create continuous fields which are interpolated from discrete fields using some polynomial basis. By thinking this way interpolation is nothing more than just an application of the earlier results already shown.\n",
"\n",
"Interpolation of fields works of course both in time and spatial dimension. Here's a simple example showing the main concept:"
"Some fields has special meaning in JuliaFEM. Typically one needs to define at least discrete field `geometry` and continuous field `basis` so that basic interpolation is working on element. \n",
"\n",
"Interpolation of fields works of course both in time and spatial dimension. Here's a simple example showing the main concept."
]
},
{
@@ -980,7 +975,14 @@
},
"outputs": [],
"source": [
"using JuliaFEM: TemporalBasis, SpatialBasis"
"using JuliaFEM: Basis"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Yep, it's just continuous field:"
]
},
{
@@ -993,9 +995,7 @@
{
"data": {
"text/plain": [
"2-element Array{Float64,1}:\n",
" 0.8\n",
" 0.2"
"true"
]
},
"execution_count": 31,
@@ -1004,16 +1004,14 @@
}
],
"source": [
"# first unanonymous function is the actual basis and second one is derivative with respect to time\n",
"temporalbasis = TemporalBasis((t) -> [1-t, t], (t) -> [-1, 1])\n",
"\n",
"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])]\n",
"dbasis(xi) = 1/4*[\n",
" -(1-xi[2]) (1-xi[2]) (1+xi[2]) -(1+xi[2])\n",
" -(1-xi[1]) -(1+xi[1]) (1+xi[1]) (1-xi[1])]\n",
"spatialbasis = SpatialBasis(basis, dbasis)\n",
"\n",
"temporalbasis(0.2)"
"Basis <: ContinuousField"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Basis + DiscreteField = Interpolation:"
]
},
{
@@ -1026,8 +1024,7 @@
{
"data": {
"text/plain": [
"1x4 Array{Float64,2}:\n",
" 0.25 0.25 0.25 0.25"
"JuliaFEM.ElementBasis(basis,dbasis)"
]
},
"execution_count": 32,
@@ -1036,16 +1033,12 @@
}
],
"source": [
"spatialbasis([0.0, 0.0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Interpolation in time domain\n",
"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])]\n",
"dbasis(xi) = 1/4*[\n",
" -(1-xi[2]) (1-xi[2]) (1+xi[2]) -(1+xi[2])\n",
" -(1-xi[1]) -(1+xi[1]) (1+xi[1]) (1-xi[1])]\n",
"\n",
"To interpolate in time domain, call `DefaultDiscreteField` with `TemporalBasis` and time. Result is a `Increment` interpolated to that time. Here we interpolate the position of particle moving $x = \\frac{1}{2}t^2$ at time $t=1.0$."
"N = Basis(basis, dbasis)"
]
},
{
@@ -1058,7 +1051,8 @@
{
"data": {
"text/plain": [
"([0.0,0.5,1.0,1.5,2.0],[0.0,0.125,0.5,1.125,2.0])"
"1x4 Array{Float64,2}:\n",
" 0.25 0.25 0.25 0.25"
]
},
"execution_count": 33,
@@ -1067,10 +1061,16 @@
}
],
"source": [
"fs = FieldSet()\n",
"t = collect(linspace(0, 2, 5))\n",
"x = 1/2*t.^2\n",
"t, x"
"N([0.0, 0.0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Interpolation in time domain\n",
"\n",
"To interpolate in time domain, call `DiscreteField` given time. Result is a `Increment` interpolated to that time. Here we interpolate the position of particle moving $x = \\frac{1}{2}t^2$ at time $t=1.0$."
]
},
{
@@ -1083,8 +1083,7 @@
{
"data": {
"text/plain": [
"1-element Array{Float64,1}:\n",
" 0.5"
"(linspace(0.0,2.0,5),[0.0,0.125,0.5,1.125,2.0])"
]
},
"execution_count": 34,
@@ -1093,23 +1092,9 @@
}
],
"source": [
"timesteps = TimeStep[]\n",
"for (ti, xi) in zip(t, x)\n",
" increment = Increment(xi)\n",
" push!(timesteps, TimeStep(ti, increment))\n",
"end\n",
"\n",
"#fs[\"particle position\"] = t, 1/2*t.^2\n",
"fs[\"particle position\"] = timesteps\n",
"temporalbasis = TemporalBasis((t) -> [1-t, t], (t) -> [-1, 1])\n",
"call(fs[\"particle position\"], temporalbasis, 1.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It's also possible to take time derivatives. To do so, call `Field` with `TemporalBasis`, time, and additional argument `Val{:derivative}`. Again, same example:"
"t = linspace(0, 2, 5)\n",
"x = 1/2*t.^2\n",
"t, x"
]
},
{
@@ -1122,8 +1107,8 @@
{
"data": {
"text/plain": [
"1-element Array{Float64,1}:\n",
" 1.0"
"1-element JuliaFEM.Increment{Float64}:\n",
" 0.5"
]
},
"execution_count": 35,
@@ -1132,7 +1117,45 @@
}
],
"source": [
"call(fs[\"particle position\"], temporalbasis, 1.0, Val{:derivative})"
"timesteps = TimeStep[]\n",
"for (ti, xi) in zip(t, x)\n",
" increment = Increment(xi)\n",
" push!(timesteps, TimeStep(ti, increment))\n",
"end\n",
"\n",
"#fs[\"particle position\"] = t, 1/2*t.^2\n",
"pos = Field(timesteps)\n",
"pos(1.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It's also possible to take time derivatives. To do so, call `Field` with `TemporalBasis`, time, and additional argument `Val{:derivative}`. Again, same example:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"1-element Array{Float64,1}:\n",
" 1.0"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pos(1.0, Val{:derivative})"
]
},
{
@@ -1151,68 +1174,20 @@
"Let's have a $\\left[0,1\\right]\\times\\left[0,1\\right] \\in \\mathbb{R}^2$ domain and $u_5 = 0.25$ displacement in upper right corner pointint to the $x_1$ direction. We seek for a center point of this at time $t=1.0$."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"Dict{ASCIIString,JuliaFEM.Field} with 2 entries:\n",
" \"geometry\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaF…\n",
" \"displacement\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaF…"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fs = FieldSet()\n",
"fs[\"geometry\"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]]\n",
"u0 = TimeStep(0.0, Increment(zeros(2, 4)))\n",
"u1 = TimeStep(1.0, Increment(Vector[[0.0, 0.0], [0.0, 0.0], [0.25, 0.0], [0.0, 0.0]]))\n",
"fs[\"displacement\"] = [u0, u1]\n",
"fs"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"2-element Array{Float64,1}:\n",
" 0.5625\n",
" 0.5 "
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"X = call(last(fs[\"geometry\"]), spatialbasis, [0.0, 0.0])\n",
"u = call(last(fs[\"displacement\"]), spatialbasis, [0.0, 0.0])\n",
"x = X+u\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It's also possible to take gradient of field. To calculate gradient, call `Increment` with `SpatialBasis` and coordinate $\\boldsymbol\\xi$. Also, give another `Increment` to calculate Jacobian, typically geometry, \n",
"and add additional argument `Val{:gradient}'."
"geometry = Field(Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]])\n",
"displacement = Field(\n",
" (0.0, Vector[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]),\n",
" (1.0, Vector[[0.0, 0.0], [0.0, 0.0], [1/4, 0.0], [0.0, 0.0]]))\n",
"X = Basis(basis, dbasis, geometry)\n",
"u = Basis(basis, dbasis, displacement);"
]
},
{
@@ -1225,9 +1200,9 @@
{
"data": {
"text/plain": [
"2x2 Array{Float64,2}:\n",
" 0.125 0.125\n",
" 0.0 0.0 "
"2-element Array{Float64,1}:\n",
" 0.5625\n",
" 0.5 "
]
},
"execution_count": 38,
@@ -1236,18 +1211,15 @@
}
],
"source": [
"gradu = call(last(fs[\"displacement\"]), spatialbasis, [0.0, 0.0], last(fs[\"geometry\"]), Val{:gradient})"
"x2(xi, t) = X(xi, t) + u(xi, t)\n",
"x2([0.0, 0.0], 1.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we have:\n",
"- `FieldSet` which defines discrete values in time and space\n",
"- Interpolants `TemporalBasis` and `SpatialBasis` which defines how discrete fields values are interpolated to get continuous fields.\n",
"\n",
"Let's plug these in one new composite type and call it to *Finite Element*:"
"Calculating gradient of vector field, i.e, $u_{i,j}$:"
]
},
{
@@ -1260,7 +1232,9 @@
{
"data": {
"text/plain": [
"FiniteElement"
"2x2 Array{Float64,2}:\n",
" 0.125 0.125\n",
" 0.0 0.0 "
]
},
"execution_count": 39,
@@ -1269,73 +1243,12 @@
}
],
"source": [
"abstract AbstractElement\n",
"\n",
"type FiniteElement <: AbstractElement\n",
" connectivity :: Array{Int, 1}\n",
" basis :: SpatialBasis\n",
" time :: TemporalBasis\n",
" fields :: Dict{ASCIIString, FieldSet}\n",
"end\n",
"\n",
"function FiniteElement(connectivity)\n",
" f(t) = [1-t, t]\n",
" df(t) = [-1, 1]\n",
" temporal_basis = TemporalBasis(f, df)\n",
"\n",
" 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])]\n",
" dh(xi) = 1/4*[\n",
" -(1-xi[2]) (1-xi[2]) (1+xi[2]) -(1+xi[2])\n",
" -(1-xi[1]) -(1+xi[1]) (1+xi[1]) (1-xi[1])]\n",
" spatial_basis = SpatialBasis(h, dh)\n",
"\n",
" return FiniteElement(connectivity, spatial_basis, temporal_basis, Dict())\n",
"end"
"# this needs some redesign.\n",
"N = FEM.Basis(basis, dbasis)\n",
"dN = FEM.ElementGradientBasis(N, geometry)\n",
"gradu = FEM.ElementFieldGradientBasis(dN, displacement)\n",
"gradu([0.0, 0.0], 1.0)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "LoadError",
"evalue": "LoadError: MethodError: `setindex!` has no method matching setindex!(::FiniteElement, ::Array{Array{Float64,1},1}, ::ASCIIString)\nwhile loading In[40], in expression starting on line 2",
"output_type": "error",
"traceback": [
"LoadError: MethodError: `setindex!` has no method matching setindex!(::FiniteElement, ::Array{Array{Float64,1},1}, ::ASCIIString)\nwhile loading In[40], in expression starting on line 2",
""
]
}
],
"source": [
"fe = FiniteElement([1, 2, 3, 4])\n",
"fe[\"geometry\"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]]\n",
"fe[\"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]])\n",
"\n",
"basis = get_basis(fe)\n",
"basis(\"geometry\", [0.0, 0.0])\n",
"\n",
"dbasis = grad(basis)\n",
"dbasis(\"displacement\", [0.0, 0.0], 0.5)\n",
"dbasis(\"displacement\", [0.0, 0.0], 1.0)\n",
"\n",
"u = fe[\"displacement\"]\n",
"strain = 1/2(grad(u) + grad(u)')\n",
"strain_rate = diff(strain)\n",
"strain_rate([0.0, 0.0], 1.0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
+1 -1
View File
@@ -205,7 +205,7 @@ function Base.call(field::DiscreteField, time::Number,
t2 = field[j]
J = abs(t2.time - t1.time)
t = (time-t1.time)/J
result = 1/J*((1-t)*t1[end] + t*t2[end])
result = 1/J*(-1*t1[end] + 1*t2[end])
return Increment(result)
end
+65 -34
View File
@@ -7,6 +7,7 @@ using JuliaFEM.Test
using JuliaFEM
using JuliaFEM: Basis, ElementGradientBasis, ElementFieldGradientBasis, Field
using JuliaFEM: Increment, TimeStep
function get_basis()
@@ -53,6 +54,9 @@ function test_linear_time_extrapolation_of_field()
T(X,t) = t*(1 + X[1] + 3*X[2] - 2*X[1]*X[2])
@test b([0.0, 0.0], -1.0) == T([0.5, 0.5], -1.0)
@test b([0.0, 0.0], 3.0) == T([0.5, 0.5], 3.0)
# when going to \pm infinity, return the last one.
@test b([0.0, 0.0], -Inf) == T([0.5, 0.5], 0.0)
@test b([0.0, 0.0], +Inf) == T([0.5, 0.5], 1.0)
end
function test_constant_time_extrapolation_of_field()
@@ -144,14 +148,14 @@ function test_time_derivative_gradient_interpolation_of_field()
(0.0, Vector[[0.0, 0.0], [0.0, 0.0], [0.00, 0.0], [0.0, 0.0]]),
(1.0, Vector[[0.0, 0.0], [0.0, 0.5], [0.25, 1.0], [0.0, 0.0]]))
basis, dbasis = get_basis()
N = Basis(basis, dbasis)
# wanted
#u = Basis(basis, dbasis, displacement)
#u = get_basis(element, "displacement")
#L = grad(diff(u))
#D = 1/2*(L + L')
#@text isapprox(D([0.0, 0.0], 1.0), ...)
#@test isapprox(D([0.0, 0.0], 1.0), ...)
basis, dbasis = get_basis()
N = Basis(basis, dbasis)
xi = [0.0, 0.0]
time = 1.0
grad = ElementGradientBasis(N, geometry)(xi, time)
@@ -199,47 +203,74 @@ end
=#
function test_interpolation_in_temporal_basis()
i1 = Increment([0.0])
i2 = Increment([1.0])
i3 = Increment([2.0])
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))
info("field(1.0) = $(field(1.0))")
@test field(-Inf) == [0.0]
@test field( 0.0) == [0.0]
@test field( 1.0) == [0.5]
@test field( 2.0) == [1.0]
@test field( 3.0) == [1.5]
@test field( 4.0) == [2.0]
@test field(+Inf) == [2.0]
end
function test_derivative_interpolation_in_temporal_basis_in_constant_velocity()
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 field(+Inf, Val{:derivative}) == [0.5]
@test field(-Inf, Val{:derivative}) == [0.5]
@test field( 0.0, Val{:derivative}) == [0.5]
@test field( 0.5, Val{:derivative}) == [0.5]
@test field( 1.0, Val{:derivative}) == [0.5]
@test field( 1.5, Val{:derivative}) == [0.5]
@test field( 2.0, Val{:derivative}) == [0.5]
end
function test_derivative_interpolation_in_temporal_basis_in_variable_velocity()
t = linspace(0, 2, 5)
x = 1/2*t.^2
x2 = tuple(collect(zip(t, x))...)
timesteps = TimeStep[]
for (ti, xi) in zip(t, x)
increment = Increment(xi)
push!(timesteps, TimeStep(ti, increment))
end
# => ((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]
pos = Field(timesteps)
velocity = pos(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
velocity = pos(2.0, Val{:derivative})[1]
@test isapprox(velocity, (2.0-1.125)/0.5) # = 1.75
end
function test_derivative_interpolation_in_temporal_basis_in_variable_velocity_check_type()
t = linspace(0, 2, 5)
x = 1/2*t.^2
timesteps = TimeStep[]
for (ti, xi) in zip(t, x)
increment = Increment(xi)
push!(timesteps, TimeStep(ti, increment))
end
# => ((0.0,0.0),(0.5,0.125),(1.0,0.5),(1.5,1.125),(2.0,2.0))
pos = Field(timesteps)
velocity = pos(1.0, Val{:derivative})
# after interpolation, we are expecting to have same type where we started
@test isa(velocity, Increment) == true
end