Adding to my last reply.

If my mesh looked like
type FEMesh
    node::Vector{Node}
    elements_1::Vector{LinTrig}
    elements_2::Vector{LinQuad}
end

than it would also be OK because I could first call the function with 
elements_1, and then elements_2 and both times the compiler would know what 
concrete type I am sending in.

Now, what I don't want to do is to hand write my FEMesh-type every time I 
need a certain combination of elements. 


On Saturday, March 14, 2015 at 10:55:35 PM UTC+1, Kristoffer Carlsson wrote:
>
> Ok, I will give a minimum working example.
>
> Consider this:
>
> abstract FElement
>
>
> type LinTrig <: FElement
>     v1::Int
> end
>
>
> type LinQuad <: FElement
>     v1::Int
>     v2::Int
> end
>
>
> type Node
>     c::Float64
> end
>
>
> type FEMesh
>     node::Vector{Node}
>     elements::Vector{FElement}
> end
>
>
> function assembleK(mesh::FEMesh)
>     for element in mesh.elements
>         println(element.v1)
>     end
> end
>
> Now, running @code_warntype gives
>
> @code_warntype(assembleK(mesh))
>
> Variables:
>   mesh::FEMesh
>   #s2::Int64
>   element::FElement
>
> Body:
>   begin  # none, line 2:
>       GenSym(0) = 
> (top(getfield))(mesh::FEMesh,:elements)::Array{FElement,1}
>       #s2 = 1
>       GenSym(2) = #s2::Int64
>       GenSym(4) = (top(arraylen))(GenSym(0))::Int64
>       unless 
> (top(box))(Bool,(top(not_int))((top(slt_int))(GenSym(4),GenSym(2))::Bool)) 
> goto 1
>       2: 
>       GenSym(10) = (top(arrayref))(GenSym(0),#s2::Int64)::FElement
>       GenSym(11) = (top(box))(Int64,(top(add_int))(#s2::Int64,1))
>       element = GenSym(10)
>       #s2 = GenSym(11) # line 3:
>       println((top(getfield))(element::FElement,:v1)::Any)::Any
>       3: 
>       GenSym(6) = #s2::Int64
>       GenSym(8) = (top(arraylen))(GenSym(0))::Int64
>       unless 
> (top(box))(Bool,(top(not_int))((top(box))(Bool,(top(not_int))((top(slt_int))(GenSym(8),GenSym(6))::Bool))))
>  
> goto 2
>       1: 
>       0: 
>       return
>   end::Void
>
>
> So I have a type instability that will cause a lot of allocations and slow 
> the code down. If I instead stick to one element type and instead define 
> mesh to contain a vector of the concrete type like this
>
> type FEMesh
>     node::Vector{Node}
>     elements::Vector{LinTrig}
> end
>
> then I don't have an instability any more and my code runs much faster.
>
> My questions is basically how I would easiest remove the instability 
> without "hard coding" the type the elements will have.
>
>
> On Saturday, March 14, 2015 at 10:35:04 PM UTC+1, Sisyphuss wrote:
>>
>> Hello Kristoffer, I don't quite understand what you are doing. But by 
>> judging from the title of your post, I'd like to share with you my opinion, 
>> and I hope it would be helpful.
>>
>> The (multiple) dispatch used by Julia is a dynamic one, that is, the 
>> dispatch is preformed at run time instead of compiling time (or "code write 
>> time" as you mentioned). So you shouldn't have any worry about that, as 
>> long as your callee function can handle different concrete types. If it is 
>> not the case or it can't be achieved in a simple way, it is advised to 
>> write separate functions (a.k.a. generic function) for different concrete 
>> types.
>>
>>  
>>
>> On Saturday, March 14, 2015 at 9:28:48 PM UTC+1, Kristoffer Carlsson 
>> wrote:
>>>
>>> Hello,
>>>
>>> I am writing some code for Finite Elements in Julia. As usual, I have a 
>>> mesh with elements and nodes. However, I do not want to restrict myself to 
>>> only using one type of element per mesh and therefore I have a hierarchy of 
>>> element types along the lines of:
>>>
>>> abstract FElement
>>>
>>> type LinTrig <:FElement end
>>>
>>> type LinQuad <: FElement end
>>>
>>> etc
>>>
>>> My mesh then consists of a Vector of FElements.
>>>
>>> Since I have a Vector of an abstract type I get a performance hit when 
>>> I, for example, assemble the global stiffness matrix. The compiler does not 
>>> know what type of element it will find and have to check it in each 
>>> iteration. For simple material models the overhead from the type checking 
>>> is 10 times larger than calculating the elements stiffness matrix 
>>> contribution.
>>>
>>> Now, when I am writing the code for the assembler I can't know what 
>>> elements that the mesh will contain. However, *at the actual call* to 
>>> the assembly function I know what element types I have in the mesh and that 
>>> these will never change. I should then be able to give the compiler that 
>>> information and have it generate efficient code.
>>>
>>> I mean, I can do this manually. Just check for the element types, 
>>> generate one vector of elements for each element type and call the assembly 
>>> function for each separate vector of elements. All of these types will be 
>>> known.
>>>
>>> Is this possible to do somehow?
>>>
>>> I hope I made sense.
>>>
>>> Best regards,
>>> Kristoffer Carlsson
>>>
>>

Reply via email to