← Back to team overview

ffc team mailing list archive

FFC code generation for inline coefficient evaluation (i.e. coefficients defined as expressions in UFL)

 

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Profiling DOLFIN assembly shows that for forms with many coefficients or
computationally expensive expressions assigned to coefficients, a great
deal of the whole assembly is spent in expression evaluation.

An idea I wanted to investigate was giving an expresssion in UFL and
have FFC generate corresponding code to evaluate it inline during tensor
tabulation. That should have the potential of eliminating some of the
overhead.

However, currently that is only possible within very limited bounds. FFC
does not yet support UFL conditionals, which essentially limits possible
expressions to depend on coordinates only and be the same over the whole
domain (which is not very useful for most form coefficients, e.g. source
terms).

This brings me to my questions:
1) Do you see a reasonable chance for speeding up assembly in the way
described?
2) Is my assessement correct? Or do I miss some capabilities of FFC that
support my use case?
3) Since UFL basically support arbitrary python syntax, would it be
reasonable to support translation for user-defined Expressions given in
python (either overloading eval in a class defived from Expression or
passing C++ code to the SWIG constructor of Expression)? FFC would
generate code to evaluate these Expressions inline during tensor
tabulation. That would of course require the Expression to be stateless
and have not input other than the coordinates. But at least it would
provide much more flexibility and also consistency with the DOLFIN
interface in general
(sidenote: it is possible to specify Expressions in this way in UFL, but
they are treated just like Coefficients by FFC)

Illustration example (UFL file):
  from dolfin import Expression

  code_expr = """
  class Source : public Expression
  {
  public:
    void eval(Array<double>& values, const Array<double>& x) const
    {
      values[0] = ((x[0]-0.25)*(x[0]-0.25)+(x[1]-0.5)*(x[1]-0.5) <
0.025) ? 1.0 : 0.0;
    }
  };
  """

  scalar = FiniteElement("Lagrange", triangle, 1)

  v  = TestFunction(scalar)
  u  = TrialFunction(scalar)
  u0 = Coefficient(scalar)
  f = Expressions(code_expr)

  c = 0.05
  k = 0.1
  alpha = 1.0

  a = v*u*dx + k*alpha*u*v*dx + k*c*dot(grad(v), grad(u))*dx
  L = v*u0*dx + k*v*f*dx

Florian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (MingW32)

iEYEARECAAYFAkxJf58ACgkQ8Z6llsctAxYHqACgtzcgezJn1VrCFp9N7UcE40kq
9/oAoLJPMhaosQvthrOy0dGAgOkNiYh5
=KB3/
-----END PGP SIGNATURE-----

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Follow ups