Fields(场)
在JuliaFEM中,从项目一开始,我们脑海中就有一个清晰的概念:“一切都是场”。也就是说,任何事物都可以在时间和空间上发生变化。我们认为这个常数只是场不随时间、空间变化的一种特殊情况。场可以在空间方向上变化或不变,同理,在时间方向上可以是时间变量或时间不变。从这个思考中,我们可以认为存在四种(离散)场:
四种离散场
- discrete(离散), constant(空间常量), time invariant(时间不变) (DCTI)
- discrete(离散), variable(空间变量), time invariant (时间不变)(DVTI)
- discrete(离散), constant(空间常量), time variant(时间变量) (DCTV)
- discrete(离散), variable(空间变量), time variant(时间变量) (DVTV)
各离散场在JuliaFEM中的构造函数的参数类型分别为:
- DCTI,参数为一确定常数,如:DCTI(1)。
- DVTI,参数为一元祖(Tuple),元祖的长度与形函数的数量相匹配这样才能保证空间方向上差值可行,如:DVTI(1, 2, 3)。
- DCTV,参数为多组Pair,Pair的第一个参数为时刻(基本类型),第二个参数为对应的数值(基本类型),如:DCTV(0.0 => 5, 1.0 => 10)
- DVTV,参数为多组Pair,Pair的第一个参数为时刻(基本类型),第二个参数为对应的空间数值(Tuple类型),如:DVTV(0.0 => (1, 2), 1.0 => (2, 3))
在上面的例子中,所有定义的字段都是标量字段。定义向量场或张量场也是如此。唯一的区别是,现在我们定义了向量和张量,而不是单个标量值。它们在空间和时间方向上的变化与标量场的变化相同。下面是定义上述向量场的例子:
a = DCTI([1.0, 2.0])
b = DVTI(([1.0, 2.0], [2.0, 3.0]))
c = DCTV(0.0 => [1.0, 2.0], 1.0 => [2.0, 3.0])
d = DVTV(0.0 => ([1.0, 2.0], [2.0, 3.0]), 1.0 => ([2.0, 3.0], [3.0, 4.0]))
四种连续场
然后我们有连续的场,它们定义在整个域中,或者至少不是逐点地。按照已经用过的缩写,我们还有四个
字段:
- continuous(连续), constant(空间常量), time invariant(时间不变) (CCTI)
- continuous(连续), variable(空间变量), time invariant(时间不变) (CVTI)
- continuous(连续), constant(空间常量), time variant(时间变量) (CCTV)
- continuous,(连续) variable(空间变量), time variant (时间变量)(CVTV)
连续场在定义解析边界条件时可能有用,JuliaFEM仅仅给出了 CVTV的构造方法,参数为一个函数,比如CVTV((xi,t) -> xi*t)。
字典格式定义
通常离散场的变量都是单元素的数值,比如1-10。然而,有时候我们想用概念更清晰的索引来定义。例如,如果有一个三角形元素连接节点1、1000和100000,则仍然希望使用’ getindex '自然地访问该字段。我想要获取节点的位移,不是通过节点坐标而是通过简单的节点编号。这种情况下我们用字典比元祖更方便。在JuliaFEM中用字典格式定义了两种字段分别为DVTId,DVTVd(后面带d表示字典格式);
三个节点的编号分别为 1,1000,100000,三个节点的坐标为[0.0,0.0],[1.0,0.0],[1.0,1.0]。 DVTId可定义为如下:
X = Dict(1=>[0.0,0.0], 1000=>[1.0,0.0], 100000=>[1.0,1.0])
G = DVTId(X)
G[1], G[1000], G[100000]
#注意第一个参数为Int64
DVTVd可定义为如下:
Y = Dict(1=>[1.0,1.0], 1000=>[2.0,1.0], 100000=>[2.0,2.0])
F = DVTVd(0.0 => X, 1.0 => Y)
interpolate(F,0.5)[100000]
new_field函数
new_field函数会根据函数参数的类型自动构造字段,默认共有7种字段,DCTI, DCTV, DVTI, DVTV, CVTV, DVTId,
DVTVd。field(x)函数会自动调用new_field。
f1 = field(1) # return DCTI(1)
f2 = field(1, 2) # return DVTI(1,2)
f3 = field(0.0 => 1) # return DCTV(0.0 => 5)
f4 = field(0.0 => (1, 2), 1.0 => (2, 3)) # return DVTV(0.0 => (1, 2), 1.0 => (2, 3))
f5 = field((xi,t) -> xi[1]*t) # return CVTV((xi,t) -> xi*t)
f6 = field(1 => 1, 2 => 2) # return DVTId(1 => 1, 2 => 2) Pair第一个参数为Int64,所以不是DCTV
f7 = field(0.0 => (1=>1, 10=>2), 1.0 => (1=>2,10=>3)) # return DVTVd(0.0 => (1=>1, 10=>2), 1.0 => (1=>2,10=>3))
当然也可以自定义字段,自定义字段需要完成以下三个函数:new_field,update_field!,interpolate_field。