mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-20 20:22:03 +00:00
data structures, new testing concept
This commit is contained in:
@@ -8,12 +8,13 @@
|
||||
"\n",
|
||||
"**Author(s)**: Jukka Aho\n",
|
||||
"\n",
|
||||
"**Abstract**: Description of basis data structures. In this notebook the concepts of `Increment`, `TimeStep`, `Field`, `FieldSet`, `SpatialBasis`, `TemporalBasis` are intoduced. With combining these atomic structures one is able to form finite elements and interpolate it's fields in time and spatial domain.\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",
|
||||
"- `Increment` is the most atomic structure. It's a vector-like object with 1 dimension. Each element in `Increment` can be scalar, vector or tensor (2 or 4 order). It's easy to extend `Increment` to have other data types too.\n",
|
||||
"- `TimeStep` is container for increments in certain time $t$.\n",
|
||||
"- `Field` is container for timesteps for a single field.\n",
|
||||
"- `DefaultDiscreteField` is container for timesteps for a single field.\n",
|
||||
"- `FieldSet` is container for all fields.\n",
|
||||
"- `DefaultContinuousField` can have continuous field variables.\n",
|
||||
"\n",
|
||||
"## Revision history\n",
|
||||
"\n",
|
||||
@@ -86,8 +87,8 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 1 entry:\n",
|
||||
" \"temperature\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.Inc…"
|
||||
"Dict{ASCIIString,JuliaFEM.Field} with 1 entry:\n",
|
||||
" \"temperature\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(1.0,JuliaFE…"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
@@ -96,7 +97,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using JuliaFEM: Increment, TimeStep, Field, FieldSet\n",
|
||||
"using JuliaFEM: Increment, TimeStep, Field, FieldSet, DefaultDiscreteField\n",
|
||||
"\n",
|
||||
"fs = FieldSet()\n",
|
||||
"i1 = Increment([1, 2, 3])\n",
|
||||
@@ -105,7 +106,7 @@
|
||||
"i3 = Increment([2, 3, 4])\n",
|
||||
"i4 = Increment([3, 4, 5])\n",
|
||||
"t2 = TimeStep(2.0, Increment[i3, i4])\n",
|
||||
"f1 = Field(TimeStep[t1, t2])\n",
|
||||
"f1 = DefaultDiscreteField(TimeStep[t1, t2])\n",
|
||||
"fs[\"temperature\"] = f1\n",
|
||||
"fs"
|
||||
]
|
||||
@@ -127,7 +128,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"([3,4,5],JuliaFEM.Increment{Int64})"
|
||||
"3-element JuliaFEM.Increment{Int64}:\n",
|
||||
" 3\n",
|
||||
" 4\n",
|
||||
" 5"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
@@ -136,8 +140,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"increment = fs[\"temperature\"][end][end]\n",
|
||||
"increment, typeof(increment)"
|
||||
"fs[\"temperature\"][2][2]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -188,12 +191,12 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 5 entries:\n",
|
||||
" \"fourth order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"constant scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"vector field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"second order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…"
|
||||
"Dict{ASCIIString,JuliaFEM.Field} with 5 entries:\n",
|
||||
" \"fourth order tensor fi… => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(…\n",
|
||||
" \"constant scalar field\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(…\n",
|
||||
" \"vector field\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(…\n",
|
||||
" \"scalar field\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(…\n",
|
||||
" \"second order tensor fi… => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(…"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
@@ -228,10 +231,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 3 entries:\n",
|
||||
" \"density\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.Inc…\n",
|
||||
" \"geometry\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.Inc…\n",
|
||||
" \"temperature\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.Inc…"
|
||||
"Dict{ASCIIString,JuliaFEM.Field} with 3 entries:\n",
|
||||
" \"density\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaFE…\n",
|
||||
" \"geometry\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaFE…\n",
|
||||
" \"temperature\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaFE…"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
@@ -287,26 +290,20 @@
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 6 entries:\n",
|
||||
" \"fourth order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"constant scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"vector field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"time series\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"second order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO: time on last timestep: 1.0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fs2[\"time series\"] = (0.0, [1, 2, 3, 4]), (0.5, [2, 3, 4, 5]), (1.0, [1, 1, 1, 1])\n",
|
||||
"fs2[\"time series\"][end].time\n",
|
||||
"fs2"
|
||||
"t0 = TimeStep(0.0, Increment([1, 2, 3, 4]))\n",
|
||||
"t1 = TimeStep(0.5, Increment([2, 3, 4, 5]))\n",
|
||||
"t2 = TimeStep(1.0, Increment([1, 1, 1, 1]))\n",
|
||||
"fs2[\"time series\"] = [t0, t1, t2]\n",
|
||||
"\n",
|
||||
"info(\"time on last timestep: $(fs2[\"time series\"][end].time)\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -324,21 +321,16 @@
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 7 entries:\n",
|
||||
" \"fourth order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"constant scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"vector field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"scalar field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"time series\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"time series 2\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…\n",
|
||||
" \"second order tensor fi… => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[J…"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"ename": "LoadError",
|
||||
"evalue": "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",
|
||||
"output_type": "error",
|
||||
"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 call at essentials.jl:56",
|
||||
" in setindex! at dict.jl:641"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
@@ -363,9 +355,9 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2-element Array{JuliaFEM.TimeStep{T},1}:\n",
|
||||
" JuliaFEM.Increment[[1,2,3,4]]\n",
|
||||
" JuliaFEM.Increment[[2,3,4,5]]"
|
||||
"2-element Array{JuliaFEM.TimeStep,1}:\n",
|
||||
" JuliaFEM.TimeStep(0.0,JuliaFEM.Increment[[1,2,3,4]])\n",
|
||||
" JuliaFEM.TimeStep(1.0,JuliaFEM.Increment[[2,3,4,5]])"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
@@ -375,7 +367,7 @@
|
||||
],
|
||||
"source": [
|
||||
"T0 = first(fs[\"temperature\"]) # pick first timestep (or to be spesific, last increment of first timestep)\n",
|
||||
"T1 = T0 + 1 # create new increment from old one\n",
|
||||
"T1 = Increment(T0 + 1) # create new increment from old one\n",
|
||||
"timestep = TimeStep(1.0, T1) # create new timestep at t=1.0\n",
|
||||
"push!(fs[\"temperature\"], timestep) # push to field"
|
||||
]
|
||||
@@ -533,7 +525,7 @@
|
||||
"source": [
|
||||
"### Creating continuous and discrete fields\n",
|
||||
"\n",
|
||||
"In the last section the concept of fields was demonstrated. The `Field` is actually just a typealias for a `DefaultDiscreteField` and `DefaultDiscreteField` is subtype of `DiscreteField` which is subtype of `AbstractField`:"
|
||||
"In previous section the concept of discrete fields was demonstrated. `DefaultDiscreteField` is subtype of `DiscreteField` which is subtype of `Field`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -555,8 +547,8 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using JuliaFEM: AbstractField, DiscreteField\n",
|
||||
"Field <: DiscreteField <: AbstractField"
|
||||
"using JuliaFEM: DefaultDiscreteField, DiscreteField, Field\n",
|
||||
"DefaultDiscreteField <: DiscreteField <: Field"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -574,7 +566,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using JuliaFEM: FieldSet, ContinuousField"
|
||||
"using JuliaFEM: FieldSet, DefaultContinuousField, ContinuousField"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -587,7 +579,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"MyFunnyField()"
|
||||
"MyContinuousField()"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
@@ -596,12 +588,12 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"type MyFunnyField <: ContinuousField\n",
|
||||
"type MyContinuousField <: ContinuousField\n",
|
||||
"end\n",
|
||||
"function Base.call(f::MyFunnyField, xi::Vector, time::Number)\n",
|
||||
"function Base.call(f::MyContinuousField, xi::Vector, time::Number)\n",
|
||||
" 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])]\n",
|
||||
"end\n",
|
||||
"f = MyFunnyField()"
|
||||
"f = MyContinuousField()"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -637,8 +629,8 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 1 entry:\n",
|
||||
" \"basis\" => MyFunnyField()"
|
||||
"Dict{ASCIIString,JuliaFEM.Field} with 1 entry:\n",
|
||||
" \"basis\" => MyContinuousField()"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
@@ -648,7 +640,7 @@
|
||||
],
|
||||
"source": [
|
||||
"fs = FieldSet()\n",
|
||||
"fs[\"basis\"] = MyFunnyField()\n",
|
||||
"fs[\"basis\"] = MyContinuousField()\n",
|
||||
"fs"
|
||||
]
|
||||
},
|
||||
@@ -679,7 +671,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Naturally we can pass another fields or even fieldsets to continuous field to make fields depend from each other. Here's another example, where `ContinuousField` takes another field and operates it with some function."
|
||||
"Again we have a shortcut to quickly define continuous fields:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -692,7 +684,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"call (generic function with 1246 methods)"
|
||||
"6.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 21,
|
||||
@@ -701,11 +693,41 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"type MyFunnyContinuousField <: ContinuousField\n",
|
||||
"fs[\"continuous field\"] = (xi, t) -> xi[1]*xi[2]*t\n",
|
||||
"fs[\"continuous field\"]([1.0, 2.0], 3.0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Naturally we can pass another fields or even fieldsets to continuous field to make fields depend from each other. Here's another example, where `ContinuousField` takes another field and operates it with some function."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"call (generic function with 1259 methods)"
|
||||
]
|
||||
},
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"type MyContinuousField2 <: ContinuousField\n",
|
||||
" basis :: Function\n",
|
||||
" discrete_field :: DiscreteField\n",
|
||||
"end\n",
|
||||
"function Base.call(field::MyFunnyContinuousField, xi::Vector, time::Number=1.0)\n",
|
||||
"function Base.call(field::MyContinuousField2, xi::Vector, time::Number=1.0)\n",
|
||||
" data = last(field.discrete_field) # get the last timestep last increment\n",
|
||||
" basis = field.basis(xi) # evaluate basis at point ξ.\n",
|
||||
" sum([basis[i]*data[i] for i=1:length(data)]) # sum results\n",
|
||||
@@ -721,7 +743,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 23,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -729,10 +751,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"MyFunnyContinuousField(basis,JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.Increment[[1,2,3,4]]]))"
|
||||
"MyContinuousField2(basis,JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,JuliaFEM.Increment[[1,2,3,4]])]))"
|
||||
]
|
||||
},
|
||||
"execution_count": 22,
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -745,7 +767,7 @@
|
||||
" (1+xi[1])*(1-xi[2]),\n",
|
||||
" (1+xi[1])*(1+xi[2]),\n",
|
||||
" (1-xi[1])*(1+xi[2])]\n",
|
||||
"fs[\"continuous field\"] = MyFunnyContinuousField(basis, fs[\"discrete field\"])"
|
||||
"fs[\"continuous field\"] = MyContinuousField2(basis, fs[\"discrete field\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -757,7 +779,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"execution_count": 24,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -768,7 +790,7 @@
|
||||
"(2.5,[1,2,3,4])"
|
||||
]
|
||||
},
|
||||
"execution_count": 23,
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -786,7 +808,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"execution_count": 25,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -794,19 +816,19 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 2 entries:\n",
|
||||
" \"continuous field\" => MyFunnyContinuousField(basis,JuliaFEM.DefaultDiscreteFi…\n",
|
||||
" \"discrete field\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFE…"
|
||||
"Dict{ASCIIString,JuliaFEM.Field} with 2 entries:\n",
|
||||
" \"continuous field\" => MyContinuousField2(basis,JuliaFEM.DefaultDiscreteField(…\n",
|
||||
" \"discrete field\" => JuliaFEM.DefaultDiscreteField([JuliaFEM.TimeStep(0.0,Ju…"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"T0 = last(fs[\"discrete field\"])\n",
|
||||
"push!(fs[\"discrete field\"], TimeStep(1.0, T0 + 1.0)) # push to field\n",
|
||||
"push!(fs[\"discrete field\"], TimeStep(1.0, Increment(T0 + 1.0))) # push to field\n",
|
||||
"fs"
|
||||
]
|
||||
},
|
||||
@@ -819,7 +841,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"execution_count": 26,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -827,10 +849,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(3.5,[2,3,4,5])"
|
||||
"(3.5,[2.0,3.0,4.0,5.0])"
|
||||
]
|
||||
},
|
||||
"execution_count": 25,
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -848,7 +870,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"execution_count": 27,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -859,7 +881,7 @@
|
||||
"(2.5,3.5)"
|
||||
]
|
||||
},
|
||||
"execution_count": 26,
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -877,7 +899,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"execution_count": 28,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -888,28 +910,28 @@
|
||||
"getindex (generic function with 126 methods)"
|
||||
]
|
||||
},
|
||||
"execution_count": 27,
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using JuliaFEM: DiscreteField\n",
|
||||
"type MyFunnyDiscreteField <: DiscreteField\n",
|
||||
"type MyDiscreteField <: DiscreteField\n",
|
||||
" discrete_points :: Vector\n",
|
||||
" continuous_field :: ContinuousField\n",
|
||||
"end\n",
|
||||
"Base.length(field::MyFunnyDiscreteField) = length(field.discrete_points)\n",
|
||||
"Base.endof(field::MyFunnyDiscreteField) = endof(field.discrete_points)\n",
|
||||
"Base.last(field::MyFunnyDiscreteField) = Float64[field[i] for i=1:length(field)]\n",
|
||||
"function Base.getindex(field::MyFunnyDiscreteField, idx::Int64)\n",
|
||||
"Base.length(field::MyDiscreteField) = length(field.discrete_points)\n",
|
||||
"Base.endof(field::MyDiscreteField) = endof(field.discrete_points)\n",
|
||||
"Base.last(field::MyDiscreteField) = Float64[field[i] for i=1:length(field)]\n",
|
||||
"function Base.getindex(field::MyDiscreteField, idx::Int64)\n",
|
||||
" field.continuous_field(field.discrete_points[idx])\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"execution_count": 29,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -924,14 +946,14 @@
|
||||
" 4.24402"
|
||||
]
|
||||
},
|
||||
"execution_count": 28,
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"discrete_points = 1.0/sqrt(3.0)*Vector[[-1, -1], [1, -1], [1, 1], [-1, 1]]\n",
|
||||
"fs[\"discrete field 2\"] = MyFunnyDiscreteField(discrete_points, fs[\"continuous field\"])\n",
|
||||
"fs[\"discrete field 2\"] = MyDiscreteField(discrete_points, fs[\"continuous field\"])\n",
|
||||
"last(fs[\"discrete field 2\"])"
|
||||
]
|
||||
},
|
||||
@@ -952,7 +974,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"execution_count": 30,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -963,7 +985,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"execution_count": 31,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -976,7 +998,7 @@
|
||||
" 0.2"
|
||||
]
|
||||
},
|
||||
"execution_count": 30,
|
||||
"execution_count": 31,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -996,7 +1018,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"execution_count": 32,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1008,7 +1030,7 @@
|
||||
" 0.25 0.25 0.25 0.25"
|
||||
]
|
||||
},
|
||||
"execution_count": 31,
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1028,7 +1050,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"execution_count": 33,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1039,7 +1061,7 @@
|
||||
"([0.0,0.5,1.0,1.5,2.0],[0.0,0.125,0.5,1.125,2.0])"
|
||||
]
|
||||
},
|
||||
"execution_count": 32,
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1051,28 +1073,6 @@
|
||||
"t, x"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((0.0,0.0),(0.5,0.125),(1.0,0.5),(1.5,1.125),(2.0,2.0))"
|
||||
]
|
||||
},
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x2 = tuple(collect(zip(t, x))...)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
@@ -1093,7 +1093,14 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fs[\"particle position\"] = x2\n",
|
||||
"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)"
|
||||
]
|
||||
@@ -1105,6 +1112,29 @@
|
||||
"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": 35,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1-element Array{Float64,1}:\n",
|
||||
" 1.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"call(fs[\"particle position\"], temporalbasis, 1.0, Val{:derivative})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@@ -1123,7 +1153,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"execution_count": 36,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1131,12 +1161,12 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dict{ASCIIString,JuliaFEM.AbstractField} with 2 entries:\n",
|
||||
" \"geometry\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.In…\n",
|
||||
" \"displacement\" => JuliaFEM.DefaultDiscreteField(JuliaFEM.TimeStep[JuliaFEM.In…"
|
||||
"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": 35,
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1144,13 +1174,15 @@
|
||||
"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",
|
||||
"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]])\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": 36,
|
||||
"execution_count": 37,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1163,7 +1195,7 @@
|
||||
" 0.5 "
|
||||
]
|
||||
},
|
||||
"execution_count": 36,
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1185,7 +1217,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"execution_count": 38,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1198,7 +1230,7 @@
|
||||
" 0.0 0.0 "
|
||||
]
|
||||
},
|
||||
"execution_count": 37,
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1220,7 +1252,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"execution_count": 39,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -1231,7 +1263,7 @@
|
||||
"FiniteElement"
|
||||
]
|
||||
},
|
||||
"execution_count": 38,
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -1263,17 +1295,17 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"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[39], in expression starting on line 2",
|
||||
"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[39], in expression starting on line 2",
|
||||
"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",
|
||||
""
|
||||
]
|
||||
}
|
||||
@@ -1295,6 +1327,15 @@
|
||||
"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": {
|
||||
|
||||
@@ -47,30 +47,6 @@
|
||||
"- variational form, \"principle of minimum potential energy\": there exists some functional or \"potential function\" $\\Pi$ we are minimizing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Logger(root,DEBUG,Base.PipeEndpoint(open, 0 bytes waiting),root)"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using Logging\n",
|
||||
"using FactCheck\n",
|
||||
"Logging.configure(level=DEBUG)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@@ -89,13 +65,13 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 69,
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using JuliaFEM: Element, Field, FieldSet, Basis"
|
||||
"using JuliaFEM: Element, Basis, FieldSet"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -107,7 +83,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -116,7 +92,7 @@
|
||||
"type MyQuad4 <: Element\n",
|
||||
" connectivity :: Array{Int, 1}\n",
|
||||
" basis :: Basis\n",
|
||||
" fields :: Dict{ASCIIString, FieldSet}\n",
|
||||
" fields :: FieldSet\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
@@ -129,7 +105,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -140,7 +116,7 @@
|
||||
"MyQuad4"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -165,7 +141,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -173,10 +149,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"size (generic function with 74 methods)"
|
||||
"size (generic function with 81 methods)"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -192,6 +168,68 @@
|
||||
"Here comes one important thing. We always define our \"things\" so that the first index is dimension, like $(x, y, z)$ or $(\\xi_1, \\xi_2, \\xi_3)$ and second index is basis function number / node id or something similar to that. To motivate this, consider the following example:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2x4 Array{Int64,2}:\n",
|
||||
" 1 3 5 7\n",
|
||||
" 2 4 6 8"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x = [1 2; 3 4; 5 6; 7 8]'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here, if we consider $x$ as of some field e.g. geometry, our coordinates of first node is $(1, 2)$, second is $(3, 4)$ and so on. Typically on vector field problems the global assembly is something like $(u_1, v_1, u_2, v_2, \\ldots, )$. If fields are defined this way we can easily flatten matrix to vector and back:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"8-element Array{Int64,1}:\n",
|
||||
" 1\n",
|
||||
" 2\n",
|
||||
" 3\n",
|
||||
" 4\n",
|
||||
" 5\n",
|
||||
" 6\n",
|
||||
" 7\n",
|
||||
" 8"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"dim = size(x)\n",
|
||||
"x2 = vec(x)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
@@ -212,68 +250,6 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x = [1 2; 3 4; 5 6; 7 8]'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here, if we consider $x$ as of some field e.g. geometry, our coordinates of first node is $(1, 2)$, second is $(3, 4)$ and so on. Typically on vector field problems the global assembly is something like $(u_1, v_1, u_2, v_2, \\ldots, )$. If fields are defined this way we can easily flatten matrix to vector and back:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"8-element Array{Int64,1}:\n",
|
||||
" 1\n",
|
||||
" 2\n",
|
||||
" 3\n",
|
||||
" 4\n",
|
||||
" 5\n",
|
||||
" 6\n",
|
||||
" 7\n",
|
||||
" 8"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"dim = size(x)\n",
|
||||
"x2 = vec(x)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2x4 Array{Int64,2}:\n",
|
||||
" 1 3 5 7\n",
|
||||
" 2 4 6 8"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"reshape(x2, dim)"
|
||||
]
|
||||
@@ -287,7 +263,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -317,7 +293,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -326,15 +302,22 @@
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"28-Oct 04:26:43:INFO:root:Testing element MyQuad4\n",
|
||||
"28-Oct 04:26:43:INFO:root:element dimension: 2 x 4\n",
|
||||
"28-Oct 04:26:43:INFO:root:Initializing element\n",
|
||||
"28-Oct 04:26:43:INFO:root:basis at [0.0,0.0]: [0.25 0.25 0.25 0.25]\n",
|
||||
"28-Oct 04:26:43:INFO:root:field val at [0.0,0.0]: 2.5\n",
|
||||
"28-Oct 04:26:43:INFO:root:derivative of basis at [0.0,0.0]: [-0.5 0.5 0.5 -0.5\n",
|
||||
" -0.5 -0.5 0.5 0.5]\n",
|
||||
"28-Oct 04:26:43:INFO:root:field val at [0.0,0.0]: [0.0 2.0]\n",
|
||||
"28-Oct 04:26:43:INFO:root:Element MyQuad4 passed tests.\n"
|
||||
"INFO: Testing element MyQuad4\n",
|
||||
"INFO: element dimension: 2 x 4\n",
|
||||
"INFO: Initializing element\n",
|
||||
"INFO: basis at [0.0,0.0]: [0.25 0.25 0.25 0.25]\n",
|
||||
"INFO: field val at [0.0,0.0]: 0.0\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "LoadError",
|
||||
"evalue": "LoadError: MethodError: `inv` has no method matching inv(::Array{Float64,1})\nwhile loading In[9], in expression starting on line 2",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"LoadError: MethodError: `inv` has no method matching inv(::Array{Float64,1})\nwhile loading In[9], in expression starting on line 2",
|
||||
"",
|
||||
" in call at /home/jukka/.julia/v0.4/JuliaFEM/src/elements.jl:147",
|
||||
" in test_element at /home/jukka/.julia/v0.4/JuliaFEM/src/elements.jl:57"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1291,6 +1274,7 @@
|
||||
" u = basis(\"displacement\", ip, time, variation)\n",
|
||||
" ∇u = dbasis(\"displacement\", ip, time, variation)\n",
|
||||
" F = I + ∇u\n",
|
||||
" # F = F_e*F_p\n",
|
||||
" b = basis(\"displacement volume load\", ip, time)\n",
|
||||
" E = 1/2*(F'*F - I)\n",
|
||||
" S = λ*trace(E)*I + 2*μ*E\n",
|
||||
|
||||
Reference in New Issue
Block a user