Local
Tutorial
Reference
Download
Global
GiNaC
Swiginac
Python
SWIG
Simula Research Laboratory
# SyFi - Symbolic Finite Elements ## News Release 0.3.4: Bug fix in the degrees of freedom for the Raviart-Thomas and Nedelec elements. Release 0.3.3: Mainly a bug fix. A few examples described in the Para06 proceeding and talk are 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