2015-08-24 01:14:03 +03:00
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
2015-11-27 10:10:00 +02:00
abstract AbstractElement
2015-08-31 20:15:28 +03:00
2016-05-20 04:39:51 +03:00
type Element { E <: AbstractElement }
2016-05-25 02:44:29 +03:00
id :: Int
2016-05-20 04:39:51 +03:00
connectivity :: Vector { Int }
2016-05-25 22:33:47 +03:00
integration_points :: Vector { IP }
2016-05-20 04:39:51 +03:00
fields :: Dict { ASCIIString , Field }
properties :: E
end
2016-05-27 17:45:12 +03:00
function Element { E <: AbstractElement } ( :: Type { E } , connectivity = [ ] , integration_points = [ ] , id = - 1 , fields = Dict ( ) , properties ... )
2016-05-25 22:33:47 +03:00
variant = E ( properties ... )
2016-05-27 17:45:12 +03:00
element = Element { E } ( id , connectivity , integration_points , fields , variant )
return element
2016-05-20 04:39:51 +03:00
end
function getindex ( element :: Element , field_name :: ASCIIString )
2016-06-27 16:11:33 +03:00
return element . fields [ field_name ]
end
function setindex! ( element :: Element , data :: Field , field_name :: ASCIIString )
element . fields [ field_name ] = data
2016-05-20 04:39:51 +03:00
end
function setindex! ( element :: Element , data , field_name :: ASCIIString )
element . fields [ field_name ] = Field ( data )
end
2016-07-01 02:55:56 +03:00
function call ( element :: Element , field_name :: ASCIIString )
return element [ field_name ]
end
2016-05-27 17:45:12 +03:00
function call ( element :: Element , field_name :: ASCIIString , time )
2016-05-24 19:05:25 +03:00
return element [ field_name ] ( time )
end
2016-07-01 02:55:56 +03:00
function last ( element :: Element , field_name :: ASCIIString )
return last ( element [ field_name ] )
end
2016-07-03 05:01:18 +03:00
function call ( element :: Element , ip , time = 0.0 )
2016-06-27 16:11:33 +03:00
return get_basis ( element , ip , time )
2016-05-20 04:39:51 +03:00
end
2016-05-25 22:33:47 +03:00
function call ( element :: Element , ip , time , :: Type { Val { :Jacobian } } )
2016-05-20 04:39:51 +03:00
X = element [ " geometry " ] ( time )
2016-05-25 22:33:47 +03:00
dN = get_dbasis ( element , ip , time )
2016-05-20 04:39:51 +03:00
J = sum ( [ kron ( dN [ : , i ] , X [ i ] ' ) for i = 1 : length ( X ) ] )
return J
end
2016-05-25 22:33:47 +03:00
function call ( element :: Element , ip , time , :: Type { Val { :detJ } } )
J = element ( ip , time , Val { :Jacobian } )
2016-05-22 17:00:01 +03:00
n , m = size ( J )
if n == m # volume element
return det ( J )
end
JT = transpose ( J )
if size ( JT , 2 ) == 1 # boundary of 2d problem, || ∂X/∂ξ ||
return norm ( JT )
else # manifold on 3d problem, || ∂X/∂ξ₁ × ∂X/∂ξ₂ ||
return norm ( cross ( JT [ : , 1 ] , JT [ : , 2 ] ) )
end
end
2016-05-25 22:33:47 +03:00
function call ( element :: Element , ip , time , :: Type { Val { :Grad } } )
J = element ( ip , time , Val { :Jacobian } )
return inv ( J ) * get_dbasis ( element , ip , time )
2016-05-20 04:39:51 +03:00
end
2016-05-25 22:33:47 +03:00
function call ( element :: Element , field_name :: ASCIIString , ip , time , :: Type { Val { :Grad } } )
2016-06-27 16:11:33 +03:00
return element ( ip , time , Val { :Grad } ) * element [ field_name ] ( time )
2016-05-25 22:33:47 +03:00
end
2016-07-03 05:01:18 +03:00
function call ( element :: Element , field :: Field , time )
return field ( time )
end
function call ( element :: Element , field :: DCTI , time )
return field . data
end
2016-05-27 17:45:12 +03:00
function call ( element :: Element , field_name :: ASCIIString , time )
2016-07-03 05:01:18 +03:00
field = element [ field_name ]
return call ( element , field , time )
2016-05-27 17:45:12 +03:00
end
2016-06-27 16:11:33 +03:00
function call ( element :: Element , field_name :: ASCIIString , ip , time :: Float64 )
field = element [ field_name ]
return call ( element , field , ip , time )
end
function call ( element :: Element , field :: DCTI , ip , time :: Float64 )
return field . data
end
2016-07-01 02:55:56 +03:00
function call ( element :: Element , field :: DCTV , ip , time :: Float64 )
return field ( time ) . data
end
2016-06-27 16:11:33 +03:00
function call ( element :: Element , field :: CVTV , ip , time :: Float64 )
return field ( ip , time )
end
function call ( element :: Element , field :: Field , ip , time :: Float64 )
field_ = field ( time )
2016-05-25 22:33:47 +03:00
basis = element ( ip , time )
n = length ( element )
2016-06-27 16:11:33 +03:00
m = length ( field_ )
2016-07-01 02:55:56 +03:00
if n != m
error ( " Error when trying to interpolate field $field at coords $ip and time $time : element length is $n and field length is $m , f = Nᵢfᵢ makes no sense! " )
end
2016-06-27 16:11:33 +03:00
return sum ( [ field_ [ i ] * basis [ i ] for i = 1 : n ] )
end
2016-05-20 04:39:51 +03:00
2016-05-22 02:34:38 +03:00
function size ( element :: Element , dim :: Int )
2016-06-27 16:11:33 +03:00
return size ( element ) [ dim ]
2016-05-22 02:34:38 +03:00
end
2016-05-20 04:39:51 +03:00
""" Update element field based on a dictionary of nodal data and connectivity information.
Examples
--------
julia> data = Dict(1 => [0.0, 0.0], 2 => [1.0, 2.0])
julia> element = Seg2([1, 2])
julia> update!(element, " geometry " , data)
As a result element now have time invariant (variable) vector field " geometry " with data ([0.0, 0.0], [1.0, 2.0]).
"""
function update! ( element :: Element , field_name :: ASCIIString , data :: Dict )
element [ field_name ] = [ data [ i ] for i in get_connectivity ( element ) ]
end
2016-06-27 16:11:33 +03:00
function update! { K , V } ( element :: Element , field_name :: ASCIIString , data :: Pair { Float64 , Dict { K , V } } )
time , field_data = data
element_data = V [ field_data [ i ] for i in get_connectivity ( element ) ]
update! ( element , field_name , time => element_data )
end
2016-07-01 02:55:56 +03:00
function update! ( element :: Element , field_name :: ASCIIString , datas :: Union { Real , Vector , Pair { Float64 , Union { Float64 , Real , Vector { Any } } } } ... )
2016-06-08 23:42:36 +03:00
for data in datas
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
2016-06-27 16:11:33 +03:00
else
if length ( data ) != length ( element )
update! ( element , field_name , DCTI ( data ) )
else
element [ field_name ] = data
end
end
end
end
2016-07-01 02:55:56 +03:00
function update! ( element :: Element , field_name :: ASCIIString , datas :: Pair ... )
for data in datas
update! ( element , field_name , data )
end
end
2016-06-27 16:11:33 +03:00
function update! ( element :: Element , field_name :: ASCIIString , data :: Pair { Float64 , Vector { Any } } )
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
element [ field_name ] = data
end
end
function update! ( element :: Element , field_name :: ASCIIString , data :: Pair { Float64 , Vector { Int64 } } )
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
element [ field_name ] = data
end
end
function update! ( element :: Element , field_name :: ASCIIString , data :: Pair { Float64 , Vector { Vector { Float64 } } } )
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
element [ field_name ] = data
end
end
function update! ( element :: Element , field_name :: ASCIIString , data :: Pair { Float64 , Float64 } )
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
element [ field_name ] = data
end
end
function update! ( element :: Element , field_name :: ASCIIString , data :: Union { Float64 , Vector } )
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
if length ( data ) != length ( element )
update! ( element , field_name , DCTI ( data ) )
2016-06-08 23:42:36 +03:00
else
element [ field_name ] = data
end
2016-06-02 22:58:54 +03:00
end
2016-05-20 04:39:51 +03:00
end
2016-06-17 02:10:17 +03:00
function update! ( element :: Element , datas :: Pair ... )
for ( field_name , data ) in datas
if haskey ( element , field_name )
update! ( element [ field_name ] , data )
else
element [ field_name ] = data
end
end
end
2016-06-27 16:11:33 +03:00
function update! ( element :: Element , field_name :: ASCIIString , data :: Function )
element [ field_name ] = data
end
function update! ( element :: Element , field_name :: ASCIIString , field :: Field )
element [ field_name ] = field
end
2016-05-22 02:34:38 +03:00
function update! ( elements :: Vector , field_name :: ASCIIString , data )
for element in elements
update! ( element , field_name , data )
end
end
2016-07-03 05:01:18 +03:00
#=
2016-07-01 02:55:56 +03:00
d b a s i s _ c a c h e = F o r w a r d D i f f . j a c o b i a n
2016-05-22 00:22:17 +03:00
" " " E v a l u a t e p a r t i a l d e r i v a t i v e s o f b a s i s f u n c t i o n s u s i n g F o r w a r d D i f f . " " "
2016-05-30 18:30:02 +03:00
f u n c t i o n g e t _ d b a s i s ( e l e m e n t : : E l e m e n t , i p , t i m e )
x i = i s a ( i p , I P ) ? i p . c o o r d s : i p
2016-05-22 00:22:17 +03:00
b a s i s ( x i ) = v e c ( g e t _ b a s i s ( e l e m e n t , x i , t i m e ) )
2016-07-01 02:55:56 +03:00
r e t u r n F o r w a r d D i f f . j a c o b i a n ( b a s i s , x i ) '
2016-05-22 00:22:17 +03:00
e n d
2016-07-03 05:01:18 +03:00
=#
2016-05-20 04:39:51 +03:00
2016-05-22 00:22:17 +03:00
""" Check existence of field. """
function haskey ( element :: Element , field_name )
haskey ( element . fields , field_name )
end
2016-05-20 04:39:51 +03:00
2016-05-22 02:34:38 +03:00
function get_connectivity ( element :: Element )
return element . connectivity
end
2016-05-25 22:33:47 +03:00
function get_integration_points ( element :: Element )
2016-05-27 17:45:12 +03:00
# first time initialize default integration points
if length ( element . integration_points ) == 0
ips = get_integration_points ( element . properties )
element . integration_points = [ IP ( i , w , xi ) for ( i , ( w , xi ) ) in enumerate ( ips ) ]
end
2016-05-25 22:33:47 +03:00
return element . integration_points
end
""" This is a special case, temporarily change order
of integration scheme mainly for mass matrix.
"""
function get_integration_points ( element :: Element , change_order :: Int )
order = get_integration_order ( element . properties )
order += change_order
2016-06-01 20:43:25 +03:00
ips = get_integration_points ( element . properties , order )
2016-05-25 22:33:47 +03:00
return [ IP ( i , w , xi ) for ( i , ( w , xi ) ) in enumerate ( ips ) ]
end
2016-05-22 02:34:38 +03:00
function get_gdofs ( element :: Element )
return get_gdofs ( element , 1 )
end
""" Return dual basis transformation matrix Ae. """
function get_dualbasis ( element :: Element , time )
nnodes = length ( element )
De = zeros ( nnodes , nnodes )
Me = zeros ( nnodes , nnodes )
2016-05-25 22:33:47 +03:00
for ip in get_integration_points ( element )
detJ = element ( ip , time , Val { :detJ } )
w = ip . weight * detJ
N = element ( ip , time )
De += w * diagm ( vec ( N ) )
Me += w * N ' * N
2016-05-22 02:34:38 +03:00
end
return De , Me , De * inv ( Me )
end
2016-05-20 04:39:51 +03:00
#=
2015-12-31 12:35:05 +02:00
t y p e E l e m e n t { E }
2015-11-27 10:10:00 +02:00
c o n n e c t i v i t y : : V e c t o r { I n t }
f i e l d s : : D i c t { A S C I I S t r i n g , F i e l d }
2016-02-05 11:32:09 +02:00
# m a t r i c e s t o c o n s t r u c t d u a l b a s i s
D : : M a t r i x { F l o a t 6 4 }
M : : M a t r i x { F l o a t 6 4 }
A : : M a t r i x { F l o a t 6 4 }
2015-11-27 10:10:00 +02:00
e n d
2015-12-14 02:09:33 +02:00
f u n c t i o n B a s e . s i z e { E } ( : : E l e m e n t { E } )
r e t u r n s i z e ( E )
e n d
2015-12-23 17:39:53 +02:00
f u n c t i o n B a s e . s i z e { E } ( : : E l e m e n t { E } , i : : I n t 6 4 )
r e t u r n s i z e ( E ) [ i ]
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c o n v e r t { E } ( : : T y p e { E l e m e n t { E } } , c o n n e c t i v i t y : : V e c t o r { I n t } )
2016-02-05 11:32:09 +02:00
r e t u r n E l e m e n t { E } ( c o n n e c t i v i t y , D i c t ( ) , M a t r i x ( ) , M a t r i x ( ) , M a t r i x ( ) )
2015-11-27 10:10:00 +02:00
e n d
2015-12-05 10:58:01 +02:00
f u n c t i o n g e t _ i n t e g r a t i o n _ p o i n t s { E } ( e l e m e n t : : E l e m e n t { E } , a r g s . . . )
r e t u r n g e t _ i n t e g r a t i o n _ p o i n t s ( E , a r g s . . . )
2015-11-27 10:10:00 +02:00
e n d
2015-08-24 01:14:03 +03:00
2015-11-30 16:04:13 +02:00
f u n c t i o n u p d a t e _ g a u s s _ f i e l d s ! ( e l e m e n t : : E l e m e n t , d a t a : : V e c t o r { I n t e g r a t i o n P o i n t } , t i m e : : R e a l )
i f h a s k e y ( e l e m e n t , " i n t e g r a t i o n p o i n t s " )
# p u s h o r u p d a t e
i f ! i s a p p r o x ( l a s t ( e l e m e n t [ " i n t e g r a t i o n p o i n t s " ] ) . t i m e , t i m e )
p u s h ! ( e l e m e n t [ " i n t e g r a t i o n p o i n t s " ] , t i m e = > d a t a )
e l s e
l a s t ( e l e m e n t [ " i n t e g r a t i o n p o i n t s " ] ) . d a t a = d a t a
e n d
e l s e
# c r e a t e
e l e m e n t [ " i n t e g r a t i o n p o i n t s " ] = F i e l d ( t i m e = > d a t a )
e n d
e n d
2015-10-28 04:29:14 +02:00
" " " G e t F i e l d S e t f r o m e l e m e n t . " " "
f u n c t i o n B a s e . g e t i n d e x ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e )
2015-11-11 00:52:16 +02:00
r e t u r n e l e m e n t . f i e l d s [ f i e l d _ n a m e ]
2015-10-28 04:29:14 +02:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n B a s e . l e n g t h { E } ( e l e m e n t : : E l e m e n t { E } )
s i z e ( E ) [ 2 ]
e n d
2015-11-23 03:17:15 +02:00
2015-11-11 00:52:16 +02:00
" " " A d d n e w F i e l d t o e l e m e n t .
2015-10-28 04:29:14 +02:00
E x a m p l e s
- - - - - - - -
2015-11-11 00:52:16 +02:00
> > > e l e m e n t [ " t e m p e r a t u r e " ] = [ 1 , 2 , 3 , 4 ]
> > > e l e m e n t [ " t e m p e r a t u r e " ] = ( 0 . 0 , [ 0 , 0 , 0 , 0 ] ) , ( 1 . 0 , [ 1 , 2 , 3 , 4 ] )
> > > e l e m e n t [ " t e m p e r a t u r e " ] = ( 0 . 0 = > [ 0 , 0 , 0 , 0 ] , 1 . 0 = > [ 1 , 2 , 3 , 4 ] )
2015-10-28 04:29:14 +02:00
" " "
2015-11-21 18:23:41 +02:00
f u n c t i o n B a s e . s e t i n d e x ! ( e l e m e n t : : E l e m e n t , d a t a , n a m e : : A S C I I S t r i n g )
e l e m e n t . f i e l d s [ n a m e ] = F i e l d ( d a t a )
2015-10-28 04:29:14 +02:00
e n d
2015-11-23 03:17:15 +02:00
f u n c t i o n B a s e . s e t i n d e x ! ( e l e m e n t : : E l e m e n t , f i e l d : : F i e l d , n a m e : : A S C I I S t r i n g )
e l e m e n t . f i e l d s [ n a m e ] = f i e l d
e n d
2015-11-21 18:23:41 +02:00
f u n c t i o n B a s e . s e t i n d e x ! ( e l e m e n t : : E l e m e n t , d a t a : : T u p l e , n a m e : : A S C I I S t r i n g )
e l e m e n t . f i e l d s [ n a m e ] = F i e l d ( d a t a . . . )
2015-11-11 00:52:16 +02:00
e n d
2015-09-14 23:20:33 +03:00
2015-11-23 03:17:15 +02:00
t y p e a l i a s V e c O r I P U n i o n { V e c t o r , I n t e g r a t i o n P o i n t }
2015-12-04 07:27:40 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , t i m e : : R e a l , v a r i a t i o n = n o t h i n g )
r e t u r n i s a ( v a r i a t i o n , V o i d ) ? e l e m e n t [ f i e l d _ n a m e ] ( t i m e ) : v a r i a t i o n
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , x i : : V e c O r I P , t i m e : : N u m b e r , v a r i a t i o n = n o t h i n g )
2015-12-04 07:27:40 +02:00
f i e l d = e l e m e n t ( f i e l d _ n a m e , t i m e , v a r i a t i o n )
# f i e l d = i s a ( v a r i a t i o n , V o i d ) ? e l e m e n t [ f i e l d _ n a m e ] ( t i m e ) : v a r i a t i o n
2015-11-27 10:10:00 +02:00
b a s i s = g e t _ b a s i s ( e l e m e n t )
r e t u r n b a s i s ( f i e l d , x i )
2015-11-23 03:17:15 +02:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , x i : : V e c O r I P , t i m e : : N u m b e r , : : T y p e { V a l { : g r a d } } , v a r i a t i o n = n o t h i n g )
2015-12-04 07:27:40 +02:00
# f i e l d = i s a ( v a r i a t i o n , V o i d ) ? e l e m e n t [ f i e l d _ n a m e ] ( t i m e ) : v a r i a t i o n
f i e l d = e l e m e n t ( f i e l d _ n a m e , t i m e , v a r i a t i o n )
2015-11-27 10:10:00 +02:00
b a s i s = g e t _ b a s i s ( e l e m e n t )
g e o m = e l e m e n t [ " g e o m e t r y " ] ( t i m e )
r e t u r n b a s i s ( g e o m , f i e l d , x i , V a l { : g r a d } )
2015-11-23 03:17:15 +02:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , x i : : V e c O r I P )
2015-11-30 16:04:13 +02:00
f i e l d = e l e m e n t [ f i e l d _ n a m e ]
b a s i s = g e t _ b a s i s ( e l e m e n t )
r e t u r n b a s i s ( e l e m e n t [ f i e l d _ n a m e ] , x i )
2015-11-23 03:17:15 +02:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , x i : : V e c O r I P , : : T y p e { V a l { : g r a d } } )
2015-11-30 16:04:13 +02:00
f i e l d = e l e m e n t [ f i e l d _ n a m e ]
g e o m = e l e m e n t [ " g e o m e t r y " ]
b a s i s = g e t _ b a s i s ( e l e m e n t )
r e t u r n b a s i s ( g e o m , f i e l d , x i , V a l { : g r a d } )
2015-11-23 03:17:15 +02:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g , t i m e : : N u m b e r )
2015-11-23 03:17:15 +02:00
r e t u r n e l e m e n t [ f i e l d _ n a m e ] ( t i m e )
e n d
2015-11-30 18:49:45 +02:00
2015-11-27 10:10:00 +02:00
f u n c t i o n g e t _ b a s i s { E } ( e l e m e n t : : E l e m e n t { E } , i p : : I n t e g r a t i o n P o i n t )
r e t u r n g e t _ b a s i s ( E , i p . x i )
2015-11-23 03:17:15 +02:00
e n d
2015-11-30 16:04:13 +02:00
f u n c t i o n g e t _ b a s i s { E } ( : : T y p e { E l e m e n t { E } } , x i : : V e c t o r { F l o a t 6 4 } )
r e t u r n g e t _ b a s i s ( E , x i )
e n d
2016-02-25 10:44:55 +02:00
f u n c t i o n g e t _ b a s i s { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c t o r )
2015-11-27 15:06:55 +02:00
r e t u r n g e t _ b a s i s ( E , x i )
e n d
f u n c t i o n c a l l { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c O r I P , t i m e : : F l o a t 6 4 = 0 . 0 )
2015-11-27 10:10:00 +02:00
r e t u r n g e t _ b a s i s ( e l e m e n t , x i )
2015-11-23 03:17:15 +02:00
e n d
2015-11-11 00:52:16 +02:00
2016-02-23 11:32:53 +02:00
" " " G i v e n a l i s t o f e l e m e n t a a n d n o d e s , f i n d a s u b s e t o f e l e m e n t s
c o n t a i n i n g n o d e s .
" " "
f u n c t i o n f i n d _ e l e m e n t s ( e l e m e n t s , n o d e s )
s = S e t { E l e m e n t } ( )
f o r e l e m e n t i n e l e m e n t s
c o n n = g e t _ c o n n e c t i v i t y ( e l e m e n t )
f o r j i n n o d e s
i f j i n c o n n
p u s h ! ( s , e l e m e n t )
b r e a k
e n d
e n d
e n d
r e t u r n c o l l e c t ( s )
e n d
f u n c t i o n g e t _ d b a s i s { E } ( e l e m e n t : : E l e m e n t { E } , i p : : I n t e g r a t i o n P o i n t )
r e t u r n g e t _ d b a s i s ( E , i p . x i )
e n d
f u n c t i o n g e t _ b a s i s { E , T < : R e a l } ( e l e m e n t : : E l e m e n t { E } , x i : : T )
r e t u r n g e t _ b a s i s ( E , x i )
e n d
2016-02-05 11:32:09 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , x i : : V e c O r I P , t i m e : : R e a l , : : T y p e { V a l { : d u a l b a s i s } } )
D e , M e , A e = g e t _ d u a l b a s i s ( e l e m e n t , t i m e )
2016-02-03 20:39:03 +02:00
N = g e t _ b a s i s ( e l e m e n t , x i )
2016-02-05 11:32:09 +02:00
P h i = A e * N '
2016-02-03 20:39:03 +02:00
r e t u r n P h i '
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n g e t _ b a s i s { E } ( e l e m e n t : : E l e m e n t { E } )
b a s i s = C V T I (
( x i : : V e c t o r ) - > g e t _ b a s i s ( E , x i ) ,
( x i : : V e c t o r ) - > g e t _ d b a s i s ( E , x i ) )
r e t u r n b a s i s
2015-10-26 05:40:41 +02:00
e n d
2015-11-30 16:04:13 +02:00
f u n c t i o n c a l l { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c O r I P , : : T y p e { V a l { : g r a d } } )
b a s i s = g e t _ b a s i s ( e l e m e n t )
g e o m = e l e m e n t [ " g e o m e t r y " ]
r e t u r n b a s i s ( g e o m , x i , V a l { : g r a d } )
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c O r I P , t i m e : : F l o a t 6 4 , : : T y p e { V a l { : g r a d } } )
b a s i s = g e t _ b a s i s ( e l e m e n t )
2015-11-30 16:04:13 +02:00
r e t u r n b a s i s ( e l e m e n t [ " g e o m e t r y " ] ( t i m e ) , x i , V a l { : g r a d } )
2015-08-24 01:14:03 +03:00
e n d
2015-11-27 10:10:00 +02:00
f u n c t i o n c a l l ( e l e m e n t : : E l e m e n t , f i e l d _ n a m e : : A S C I I S t r i n g )
r e t u r n e l e m e n t [ f i e l d _ n a m e ]
2015-08-24 01:14:03 +03:00
e n d
2015-12-13 13:47:45 +02:00
" " " R e t u r n t h e j a c o b i a n o f e l e m e n t . " " "
f u n c t i o n g e t _ j a c o b i a n { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c t o r { F l o a t 6 4 } , t i m e : : R e a l )
2015-11-27 10:10:00 +02:00
X = e l e m e n t ( " g e o m e t r y " , t i m e )
2015-12-13 13:47:45 +02:00
d N = g e t _ d b a s i s ( E , x i )
2015-12-04 07:27:40 +02:00
J = s u m ( [ k r o n ( d N [ : , i ] , X [ i ] ' ) f o r i = 1 : l e n g t h ( X ) ] )
2015-12-13 13:47:45 +02:00
r e t u r n J
e n d
f u n c t i o n g e t _ j a c o b i a n { E } ( e l e m e n t : : E l e m e n t { E } , i p : : I n t e g r a t i o n P o i n t , t i m e : : R e a l )
r e t u r n g e t _ j a c o b i a n ( e l e m e n t , i p . x i , t i m e )
e n d
2016-02-13 01:12:24 +02:00
" " " R e t u r n J a c o b i a n o f e l e m e n t i n d e f o r m e d s t a t e . " " "
f u n c t i o n g e t _ j a c o b i a n { E } ( e l e m e n t : : E l e m e n t { E } , x i : : V e c t o r { F l o a t 6 4 } , t i m e : : R e a l , : : T y p e { V a l { : d e f o r m e d } } )
x = e l e m e n t ( " g e o m e t r y " , t i m e )
i f h a s k e y ( e l e m e n t , " d i s p l a c e m e n t " )
x + = e l e m e n t ( " d i s p l a c e m e n t " , t i m e )
2015-12-14 02:09:33 +02:00
e n d
2016-02-13 01:12:24 +02:00
d N = g e t _ d b a s i s ( E , x i )
j = s u m ( [ k r o n ( d N [ : , i ] , x [ i ] ' ) f o r i = 1 : l e n g t h ( x ) ] )
r e t u r n j
2015-12-13 13:47:45 +02:00
e n d
2016-02-13 01:12:24 +02:00
f u n c t i o n g e t _ j a c o b i a n { E } ( e l e m e n t : : E l e m e n t { E } , i p : : I n t e g r a t i o n P o i n t , t i m e : : R e a l , : : T y p e { V a l { : d e f o r m e d } } )
r e t u r n g e t _ j a c o b i a n ( e l e m e n t , i p . x i , t i m e , V a l { : d e f o r m e d } )
2015-10-26 05:40:41 +02:00
e n d
2015-11-23 03:17:15 +02:00
2015-12-13 13:47:45 +02:00
2015-09-14 23:20:33 +03:00
2015-12-12 10:08:20 +02:00
" " " C a l c u l a t e l o c a l n o r m a l - t a n g e n t i a l c o o r d i n a t e s f o r e l e m e n t . " " "
f u n c t i o n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! { E } ( e l e m e n t : : E l e m e n t { E } , t i m e : : R e a l )
n t c o o r d s = M a t r i x [ ]
2016-02-03 20:39:03 +02:00
n o r m a l s = V e c t o r { F l o a t 6 4 } [ ]
2015-12-12 10:08:20 +02:00
r e f c o o r d s = g e t _ r e f e r e n c e _ e l e m e n t _ c o o r d i n a t e s ( E )
x = e l e m e n t ( " g e o m e t r y " , t i m e )
f o r x i i n r e f c o o r d s
d N = g e t _ d b a s i s ( E , x i ) * x
2015-12-20 21:17:47 +02:00
n , m = s i z e ( d N )
@ a s s e r t n ! = m # i f n = = m - > t h i s i s n o t m a n i f o l d
i f m = = 1 # p l a n e c a s e
t a n g e n t = d N / n o r m ( d N )
n o r m a l = [ - t a n g e n t [ 2 ] t a n g e n t [ 1 ] ] '
2016-02-03 20:39:03 +02:00
p u s h ! ( n o r m a l s , v e c ( n o r m a l ) )
2015-12-20 21:17:47 +02:00
p u s h ! ( n t c o o r d s , [ n o r m a l t a n g e n t ] )
e l s e i f m = = 2
n o r m a l = c r o s s ( d N [ : , 1 ] , d N [ : , 2 ] )
n o r m a l / = n o r m ( n o r m a l )
u 1 = n o r m a l
j = i n d m a x ( a b s ( u 1 ) )
v 2 = z e r o s ( 3 )
v 2 [ m o d ( j , 3 ) + 1 ] = 1 . 0
u 2 = v 2 - d o t ( u 1 , v 2 ) / d o t ( v 2 , v 2 ) * v 2
u 3 = c r o s s ( u 1 , u 2 )
t a n g e n t 1 = u 2 / n o r m ( u 2 )
t a n g e n t 2 = u 3 / n o r m ( u 3 )
p u s h ! ( n t c o o r d s , [ n o r m a l t a n g e n t 1 t a n g e n t 2 ] )
2016-02-03 20:39:03 +02:00
p u s h ! ( n o r m a l s , v e c ( n o r m a l ) )
2015-12-20 21:17:47 +02:00
e l s e
e r r o r ( " c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( ) : n = $ n , m = $ m " )
e n d
2015-12-12 10:08:20 +02:00
e n d
e l e m e n t [ " n o r m a l - t a n g e n t i a l c o o r d i n a t e s " ] = n t c o o r d s
2016-02-03 20:39:03 +02:00
e l e m e n t [ " n o r m a l s " ] = n o r m a l s
2015-12-12 10:08:20 +02:00
e n d
2016-02-03 20:39:03 +02:00
2016-02-05 22:26:07 +02:00
" " " R e t u r n l i s t o f n o d e s / c o n n e c t i v i t y p o i n t s f r o m a s e t o f e l e m e n t s .
" " "
f u n c t i o n g e t _ n o d e s ( e l e m e n t s : : V e c t o r )
n o d e s = S e t { I n t 6 4 } ( )
f o r e l e m e n t i n e l e m e n t s
p u s h ! ( n o d e s , g e t _ c o n n e c t i v i t y ( e l e m e n t ) . . . )
e n d
n o d e s = s o r t ( c o l l e c t ( n o d e s ) )
r e t u r n n o d e s
e n d
2016-02-16 17:40:11 +02:00
" " " C a l c u l a t e n o r m a l - t a n g e n t i a l c o o r d i n a t e s f o r a s e t o f e l e m e n t s .
2016-02-03 20:39:03 +02:00
N o t e s
- - - - -
A v e r a g e n o r m a l s s o t h a t n o r m a l s a r e u n i q u e i n n o d e s .
" " "
2016-02-05 22:26:07 +02:00
2016-02-13 01:12:24 +02:00
f u n c t i o n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( e l e m e n t s : : V e c t o r , t i m e : : R e a l , c o n f i g u r a t i o n : : S y m b o l = : d e f o r m e d )
2016-02-05 22:26:07 +02:00
i f s i z e ( e l e m e n t s [ 1 ] , 1 ) = = 1
2016-02-13 01:12:24 +02:00
r e t u r n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( e l e m e n t s , t i m e , V a l { 2 } , c o n f i g u r a t i o n )
2016-02-05 22:26:07 +02:00
e l s e
2016-02-13 01:12:24 +02:00
r e t u r n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( e l e m e n t s , t i m e , V a l { 3 } , c o n f i g u r a t i o n )
2016-02-05 22:26:07 +02:00
e n d
e n d
" " " C a l c u l a t e n o r m a l - t a n g e n t i a l c o o r d i n a t e s f o r 2 d c a s e .
N o t e s
- - - - -
n = ( e ₃ × ∂ X / ∂ ξ ) / | | e ₃ × ∂ X / ∂ ξ | | a n d e ₃ = [ 0 0 1 ]
" " "
2016-02-13 01:12:24 +02:00
f u n c t i o n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( e l e m e n t s : : V e c t o r , t i m e : : R e a l , : : T y p e { V a l { 2 } } , c o n f i g u r a t i o n : : S y m b o l )
2016-02-05 22:26:07 +02:00
n o d e s = g e t _ n o d e s ( e l e m e n t s )
n = z e r o s ( 2 , m a x i m u m ( n o d e s ) )
Q = [ 0 - 1 ; 1 0 ]
2015-12-20 21:17:47 +02:00
f o r e l e m e n t i n e l e m e n t s
2016-02-05 22:26:07 +02:00
g d o f s = g e t _ g d o f s ( e l e m e n t , 1 )
f o r i p i n g e t _ i n t e g r a t i o n _ p o i n t s ( e l e m e n t , V a l { 3 } )
2016-02-13 01:12:24 +02:00
i f c o n f i g u r a t i o n = = : d e f o r m e d
J = g e t _ j a c o b i a n ( e l e m e n t , i p , t i m e , V a l { : d e f o r m e d } )
e l s e
J = g e t _ j a c o b i a n ( e l e m e n t , i p , t i m e )
e n d
2016-02-05 22:26:07 +02:00
N = e l e m e n t ( i p , t i m e )
n [ : , g d o f s ] + = i p . w e i g h t * Q * J ' * N
e n d
2015-12-20 21:17:47 +02:00
e n d
2016-02-03 20:39:03 +02:00
t = z e r o s ( n )
2016-02-05 22:26:07 +02:00
f o r i = 1 : s i z e ( n , 2 )
n [ : , i ] = n [ : , i ] / n o r m ( n [ : , i ] )
t [ : , i ] = [ - n [ 2 , i ] , n [ 1 , i ] ]
e n d
f o r e l e m e n t i n e l e m e n t s
n o d e _ i d s = g e t _ c o n n e c t i v i t y ( e l e m e n t )
2016-02-13 01:12:24 +02:00
Q = M a t r i x { F l o a t 6 4 } [ [ n [ : , i ] t [ : , i ] ] f o r i i n n o d e _ i d s ]
e l e m e n t [ " n o r m a l - t a n g e n t i a l c o o r d i n a t e s " ] = ( t i m e = > Q )
2016-02-16 17:40:11 +02:00
e l e m e n t [ " n o r m a l s " ] = ( t i m e = > V e c t o r { F l o a t 6 4 } [ n [ : , i ] f o r i i n n o d e _ i d s ] )
2016-02-05 22:26:07 +02:00
e n d
e n d
" " " C a l c u l a t e n o r m a l - t a n g e n t i a l c o o r d i n a t e s f o r 3 d c a s e .
" " "
f u n c t i o n c a l c u l a t e _ n o r m a l _ t a n g e n t i a l _ c o o r d i n a t e s ! ( e l e m e n t s : : V e c t o r , t i m e : : R e a l , : : T y p e { V a l { 3 } } )
n o d e s = g e t _ n o d e s ( e l e m e n t s )
n = z e r o s ( 3 , m a x i m u m ( n o d e s ) )
f o r e l e m e n t i n e l e m e n t s
g d o f s = g e t _ g d o f s ( e l e m e n t , 1 )
f o r i p i n g e t _ i n t e g r a t i o n _ p o i n t s ( e l e m e n t , V a l { 3 } )
2016-02-13 01:12:24 +02:00
J = t r a n s p o s e ( g e t _ j a c o b i a n ( e l e m e n t , i p , t i m e , V a l { : d e f o r m e d } ) )
2016-02-05 22:26:07 +02:00
N = e l e m e n t ( i p , t i m e )
c = r e s h a p e ( c r o s s ( J [ : , 1 ] , J [ : , 2 ] ) , 3 , 1 )
n [ : , g d o f s ] + = i p . w e i g h t * c * N
e n d
e n d
t 1 = z e r o s ( n )
t 2 = z e r o s ( n )
f o r i = 1 : s i z e ( n , 2 )
i i n n o d e s | | c o n t i n u e
n [ : , i ] = n [ : , i ] / n o r m ( n [ : , i ] )
u 1 = n [ : , i ]
j = i n d m a x ( a b s ( n [ : , i ] ) )
v 2 = z e r o s ( 3 )
v 2 [ m o d ( j , 3 ) + 1 ] = 1 . 0
u 2 = v 2 - d o t ( u 1 , v 2 ) / d o t ( v 2 , v 2 ) * v 2
u 3 = c r o s s ( u 1 , u 2 )
t 1 [ : , i ] = u 2 / n o r m ( u 2 )
t 2 [ : , i ] = u 3 / n o r m ( u 3 )
2016-02-03 20:39:03 +02:00
e n d
f o r e l e m e n t i n e l e m e n t s
n o d e _ i d s = g e t _ c o n n e c t i v i t y ( e l e m e n t )
2016-02-05 22:26:07 +02:00
Q = M a t r i x { F l o a t 6 4 } [ [ n [ : , i ] t 1 [ : , i ] t 2 [ : , i ] ] f o r i i n n o d e _ i d s ]
2016-02-13 01:12:24 +02:00
e l e m e n t [ " n o r m a l - t a n g e n t i a l c o o r d i n a t e s " ] = ( t i m e = > Q )
2016-02-16 17:40:11 +02:00
e l e m e n t [ " n o r m a l s " ] = ( t i m e = > V e c t o r { F l o a t 6 4 } [ n [ : , i ] f o r i i n n o d e _ i d s ] )
2016-02-03 20:39:03 +02:00
e n d
2015-12-20 21:17:47 +02:00
e n d
2015-12-12 10:08:20 +02:00
2016-01-01 15:00:18 +02:00
" " " U p d a t e v a l u e s f o r s e v e r a l e l e m e n t s a t o n c e . " " "
# F I X M E : w i t h o r w i t h o u t { T } ?
2016-02-10 22:21:30 +02:00
f u n c t i o n u p d a t e ! { T } ( e l e m e n t s : : V e c t o r { E l e m e n t { T } } , f i e l d _ n a m e : : A S C I I S t r i n g , d a t a . . . )
2016-01-01 15:00:18 +02:00
f o r e l e m e n t i n e l e m e n t s
2016-02-10 22:21:30 +02:00
u p d a t e ! ( e l e m e n t , f i e l d _ n a m e , d a t a . . . )
2016-01-01 15:00:18 +02:00
e n d
e n d
2016-05-20 04:39:51 +03:00
=#