getDP的核心算法在kernal文件夹下,在treatment_formulation.cpp中有对有限元方程的计算函数Cal_FemGlobalEquation:
void Cal_FemGlobalEquation(struct EquationTerm * EquationTerm_P,
struct DefineQuantity * DefineQuantity_P0,
struct QuantityStorage * QuantityStorage_P0)
dof{},花括号里的内容是指“未知量”的意思。见getDP官方解释:
在waveguide例子中formulation.pro中定义了三维有限元的方程:
Formulation {
{ Name eFormulation ; Type FemEquation ;
Quantity {
{ Name e ; Type Local ; NameOfSpace eSpace ; }
}
Equation {
Galerkin { [ (1/muR[]) * Dof{d e} , {d e} ] ;
In Domain ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ -k0^2 * epsR[] * Dof{e}, {e} ] ;
In Domain ; Integration I1 ; Jacobian Jac ; }
// Galerkin { [ Normal[] /\ ( (1/muR[]) * Dof{d e} ) , {e} ] ;
// In BndABC ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ -2*I[]*k0 * (1/muR[]) * Normal[] /\ ( Normal[] /\ eInc[] ) , {e} ] ;
In BndABC ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ I[]*k0 * (1/muR[]) * Normal[] /\ ( Normal[] /\ Dof{e} ) , {e} ] ;
In BndABC ; Integration I1 ; Jacobian Jac ; }
}
}
{ Name hFormulation ; Type FemEquation ;
Quantity {
{ Name h ; Type Local ; NameOfSpace hSpace ; }
}
Equation {
Galerkin { [ (1/epsR[]) * Dof{d h} , {d h} ] ;
In Domain ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ -k0^2 * muR[] * Dof{h} , {h} ] ;
In Domain ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ -2*I[]*k0 * (1/epsR[]) * Normal[] /\ ( Normal[] /\ hInc[] ) , {h} ] ;
In BndABC ; Integration I1 ; Jacobian Jac ; }
Galerkin { [ I[]*k0 * (1/epsR[]) * Normal[] /\ ( Normal[] /\ Dof{h} ) , {h} ] ;
In BndABC ; Integration I1 ; Jacobian Jac ; }
}
}
这里,/\代表叉积,从上面的代码可以看出,ONELAB直接将矢量波动方程搬上来了。结合《电磁场有限元方法》(金建铭)的三维有限元分析得出初步结论。ONELAB算有限元电磁场,会比专业软件慢,因为对公式进行针对性化简的过程,例如保留叉积就会增加很多计算量,而这个叉积实际上是不必要算的,见书5.3小节。