SyFi - Symbolic Finite Elements
News
Release 0.3.3:
Mainly a bug fix. A few examples described in the
Para06 proceeding
is also included.
Release 0.3:
The Hermite and Nedelec elements have been added. Legendre polynomials are implemented.
Examples demonstrating code generation and the use of Diffpack, Dolfin, PyCC,
and Trilinos have been made.
Release 0.2:
Added Bernstein polynomials. The Crouzeix-Raviart, Raviart-Thomas, and Taylor-Hood elements are implemented.
Python support is added. Element matrices are computed for the Stokes problem and the mixed Poisson problem.
Also, the Jacobian of a nonlinear convection diffusion problem is computed based on symbolic differentiation.
Release 0.1:
Lagrangian elements and element matrices for Poisson problem are implemented.
Appetizer
The finite element method (FEM) package SyFi
is a C++ library built on top of
the symbolic math library GiNaC.
The name SyFi stands for Symbolic Finite Elements.
The package provides polygonal domains, polynomial spaces,
and degrees of freedom as symbolic expressions that are easily
manipulated. This makes it easy to define finite elements.
The following example shows the computation of the
element matrix for the Poisson problem in C++,
void compute_element_matrix(Polygon& T, int order) {
std::map<std::pair<int,int>, ex> A; // matrix of expression
std::pair<int,int> index; // index in matrix
LagrangeFE fe; // Lagrangian element of any order
fe.set(order); // set the order
fe.set(T); // set the polygon
fe.compute_basis_functions(); // compute the basis functions
for (int i=0; i< fe.nbf() ; i++) {
index.first = i;
for (int j=0; j< fe.nbf() ; j++) {
index.second = j;
ex nabla = inner(grad(fe.N(i)), grad(fe.N(j))); // compute the integrands
ex Aij = T.integrate(nabla); // compute the weak form
A[index] = Aij; // update element matrix
}
}
}
The following example demonstrates the computation of the
Jacobian matrix for the nonlinear
convection-diffusion equation in case of a power-law fluid:
polygon = ReferenceTriangle()
fe = VectorCrouzeixRaviart(polygon,1)
fe.compute_basis_functions()
# create sum u_i N_i
u, ujs = sum("u", fe)
n = symbol("n")
for i in range(0,fe.nbf()):
# nonlinear power-law diffusion term
mu = inner(grad(u), grad(u))
fi_diffusion = pow(mu,n)*inner(grad(u), grad(fe.N(i)))
# nonlinear convection term
uxgradu = (u.transpose()*grad(u)).evalm()
fi_convection = inner(uxgradu, fe.N(i), True)
fi = fi_diffusion + fi_convection
Fi = polygon.integrate(fi)
for j in range(0,fe.nbf()):
# differentiate to get the Jacobian
uj = ujs.op(j)
Jij = diff(Fi, uj)
# print out expression as C code
print "J[%d,%d]=%s\n"%(i,j, Jij.evalf().printc())
Requirement
SyFi relies on the symbolic math library GiNaC
Kent-Andre Mardal
|