有限元形函数及JuliaFEM中的实现方式

形函数

形函数也称插值函数,是构造单元内某点坐标、位移与单元顶点坐标或位移关系的函数。构造时需先假定单元的位移模式,一般用多项式表达,如三节点三角形单元采用 1+u+v,四节点四边形单元用1+u+v+u*v。插值函数是节点坐标与位移模式多项式的函数。

位移模式

我们以三角形单元为例说明形函数的构造方法:
在这里插入图片描述

1.三角形单元的位移模式为1+u+v;
2. 三个顶点的坐标分别为 ( x i , y i ) , ( x j , y j ) , ( x m , y m ) (x_{i},y_{i}),(x_{j},y_{j}),(x_{m},y_{m}) (xiyi),(xjyj),(xmym),对应局部坐标系下的坐标为(0,0),(1,0),(0,1);
3. 单元内任意点的位移可通过下式表达:
(1) u = α 1 + α 2 x + α 3 y v = α 4 + α 5 x + α 6 y u=\alpha_{1}+ \alpha_{2} x+\alpha_{3}y\newline v=\alpha_{4}+ \alpha_{5} x+\alpha_{6}y \tag{1} u=α1+α2x+α3yv=α4+α5x+α6y(1)
4.将节点坐标带入(1)式,可得顶点处的位移为:
u i = α 1 + α 2 x i + α 3 y i u j = α 1 + α 2 x j + α 3 y j u m = α 1 + α 2 x m + α 3 y m v i = α 4 + α 5 x i + α 6 y i v j = α 4 + α 5 x j + α 6 y j v m = α 4 + α 5 x m + α 6 y m u_{i}=\alpha_{1}+ \alpha_{2} x_{i}+\alpha_{3}y_{i}\newline u_{j}=\alpha_{1}+ \alpha_{2} x_{j}+\alpha_{3}y_{j}\newline u_{m}=\alpha_{1}+ \alpha_{2} x_{m}+\alpha_{3}y_{m}\newline v_{i}=\alpha_{4}+ \alpha_{5} x_{i}+\alpha_{6}y_{i}\newline v_{j}=\alpha_{4}+ \alpha_{5} x_{j}+\alpha_{6}y_{j}\newline v_{m}=\alpha_{4}+ \alpha_{5} x_{m}+\alpha_{6}y_{m}\newline ui=α1+α2xi+α3yiuj=α1+α2xj+α3yjum=α1+α2xm+α3ymvi=α4+α5xi+α6yivj=α4+α5xj+α6yjvm=α4+α5xm+α6ym
即:
(2) { u i u j u m } = [ 1 x i y i 1 x j y j 1 x m y m ] ∗ { α 1 α 2 α 3 } \left\{\begin{matrix} u_{i}\\ u_{j} \\ u_{m} \\ \end{matrix}\right\} = \left[ \begin{matrix} 1&x_{i}&y_{i}\\ 1&x_{j}&y_{j}\\ 1&x_{m}&y_{m} \\ \end{matrix} \right] * \left\{\begin{matrix} \alpha_{1}\\ \alpha_{2} \\ \alpha_{3} \\ \end{matrix}\right\}\tag{2} uiujum=111xixjxmyiyjymα1α2α3(2)
令:
[ T ] = [ 1 x i y i 1 x j y j 1 x m y m ] \left[ \begin{matrix} T \end{matrix} \right] = \left[ \begin{matrix} 1&x_{i}&y_{i}\\ 1&x_{j}&y_{j}\\ 1&x_{m}&y_{m} \\ \end{matrix} \right] [T]=111xixjxmyiyjym

JuliaFEM中[T]矩阵的实现

[T]中“列”为位移模式中多项式在i,j,m处的数值。JuliaFEM中包FEMBasis中的vandermonde.jl主要用于实现[T]矩阵。


'''
vandermonde_matrix(polynomial, coordinates)
Given some polynomial and coordinates points (1-3 dimensions), create a Vandermonde
matrix.
# Example
To genererate a Vandermonde matrix for a reference quadrangle `[-1.0, 1.0]^2` for
polynomial `p(u,v) = 1 + u + v + u*v`, one writes:

polynomial = :(1 + u + v + u*v)
coordinates = ((-1.0,-1.0), (1.0,-1.0), (1.0,1.0), (-1.0,1.0))
V = vandermonde_matrix(polynomial, coordinates)
# output
[
1.0 -1.0 -1.0  1.0
1.0  1.0 -1.0 -1.0
1.0  1.0  1.0  1.0
1.0 -1.0  1.0 -1.0
]
'''
function vandermonde_matrix(polynomial::Expr, coordinates::NTuple{N, NTuple{D, T}}) where {N, D, T<:Number}
    A = zeros(N, N)
    first(polynomial.args) == :+ || error("Use only summation between terms of polynomial")
    args = polynomial.args[2:end]
    for i in 1:N
        X = coordinates[i]
        if D == 1
            data = (:u => X[1],)
        elseif D == 2
            data = (:u => X[1], :v => X[2])
        elseif D == 3
            data = (:u => X[1], :v => X[2], :w => X[3])
        end
        for (j, term) in enumerate(args)
            A[i,j] = subs(term, data)
        end
    end
    return A
end

代码中subs()主要实现用数值代替表达式中的变量进行计算;

'''
subs(expression, data)
Given expression and pair(s) of `symbol => value` data, substitute to expression.
# Examples
Let us have polynomial `1 + u + v + u*v^2`, and substitute u=1 and v=2:

expression = :(1 + u + v + u*v^2)
data = (:u => 1.0, :v => 2.0)
subs(expression, data)
8.0
'''
function subs(p::Expr, data::NTuple{N,Pair{Symbol, T}}) where {N, T}
    for di in data
        p = subs(p, di)
    end
    return simplify(p)
end

上述三角形单元生产的[T]矩阵为:

julia> p= :(1+u+v)
:(1 + u + v) 
julia> X=(
(0.0, 0.0), # i
(1.0, 0.0), # j
(0.0, 1.0), # m
)
((0.0, 0.0), (1.0, 0.0), (0.0, 1.0)) 
julia> V=vandermonde_matrix(p,X)
3×3 Array{Float64,2}: 
1.0  0.0  0.0 
1.0  1.0  0.0 
1.0  0.0  1.0 

形函数定义

将(2)进行推导可得:
(3) { α 1 α 2 α 3 } = [ T ] − 1 ∗ { u i u j u m } \left\{ \begin{matrix} \alpha_{1}\\ \alpha_{2} \\ \alpha_{3} \\ \end{matrix} \right\}= \left[ \begin{matrix} T \end{matrix} \right] ^{-1} * \left\{\begin{matrix} u_{i}\\ u_{j} \\ u_{m} \\ \end{matrix}\right\} \tag{3} α1α2α3=[T]1uiujum(3)
将(3)式带入(1)式可得:
(4) u = [ 1 u v ] ∗ [ T ] − 1 ∗ { u i u j u m } u= \left[ \begin{matrix} 1&amp;u&amp;v \end{matrix} \right] * \left[ \begin{matrix} T \end{matrix} \right] ^{-1} * \left\{\begin{matrix} u_{i}\\ u_{j} \\ u_{m} \\ \end{matrix}\right\} \tag{4} u=[1uv][T]1uiujum(4)
定义形函数: [ N ] = [ 1 u v ] ∗ [ T ] − 1 \left[ \begin{matrix} N \end{matrix} \right]=\left[ \begin{matrix} 1&amp;u&amp;v \end{matrix} \right] * \left[ \begin{matrix} T \end{matrix} \right] ^{-1} [N]=[1uv][T]1
这里的坐标为局部坐标,由 [ T ] ∗ [ T ] − 1 = [ E ] \left[ \begin{matrix} T \end{matrix} \right]* \left[ \begin{matrix} T \end{matrix} \right] ^{-1} = \left[ \begin{matrix} E \end{matrix} \right] [T][T]1=[E]
那么 [ T ] ∗ [ X 1 ] = [ 1 0 0 ] \left[ \begin{matrix} T \end{matrix} \right]*[X1]= \left[ \begin{matrix} 1\\ 0\\ 0 \end{matrix} \right] [T][X1]=100这里的X1为[T]^{-1}的第一列,同理 [ T ] ∗ [ X 2 ] = [ 0 1 0 ] 这 里 的 X 2 为 [ T ] − 1 的 第 二 列 。 \left[ \begin{matrix} T \end{matrix} \right]*[X2]= \left[ \begin{matrix} 0\\ 1\\ 0 \end{matrix} \right]这里的X2为[T]^{-1}的第二列。 [T][X2]=010X2[T]1

Julia中形函数的实现

create_basis.jl中的calculate_interpolation_polynomials(p,v)函数用于计算形函数,参数p为位移模式多项式(p::Expr)如:(1+u+v),参数v即为上述的[T]矩阵。

function calculate_interpolation_polynomials(p, V)
    basis = []
    first(p.args) == :+ || error("Use only summation between terms of polynomial")
    args = p.args[2:end]
    N = size(V, 1)
    b = zeros(N)
    for i in 1:N
        fill!(b, 0.0)
        b[i] = 1.0
        #计算逆矩阵的单列
        solution = V \ b
        N = Expr(:call, :+)
        for (ai, bi) in zip(solution, args)
            isapprox(ai, 0.0) && continue
            #位移模式多项式如[1 u v]与逆矩阵的单列相乘并放入数组中
            push!(N.args, simplify( :( $ai * $bi ) ))
        end
        push!(basis, N)
    end
    return basis
end

Julia中形函数导数的实现

主要通过Calculus模块中differentiate(N,var)函数,N为形函数,var为[:u, :v, :w]

function calculate_interpolation_polynomial_derivatives(basis, D)
    vars = [:u, :v, :w]
    dbasis = []
    for N in basis
        partial_derivatives = []
        for j in 1:D
        #分别对u v w进行求导
            push!(partial_derivatives, simplify(differentiate(N, vars[j])))
        end
        push!(dbasis, partial_derivatives)
    end
    return dbasis
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值