Giter VIP home page Giter VIP logo

ffcx's Introduction

FFCx: The FEniCSx Form Compiler

FFCx CI Spack install Coverage Status

FFCx is a new version of the FEniCS Form Compiler. It is being actively developed and is compatible with DOLFINx.

FFCx is a compiler for finite element variational forms. From a high-level description of the form in the Unified Form Language (UFL), it generates efficient low-level C code that can be used to assemble the corresponding discrete operator (tensor). In particular, a bilinear form may be assembled into a matrix and a linear form may be assembled into a vector. FFCx may be used either from the command line (by invoking the ffcx command) or as a Python module (import ffcx).

FFCx is part of the FEniCS Project. For more information, visit https://www.fenicsproject.org

Installation

To install FFCx from PyPI:

$ pip install fenics-ffcx

To install FFCx from the source directory:

$ pip install .

Documentation

Documentation can be viewed at https://docs.fenicsproject.org/ffcx/main

Interface file installation only

FFCx provides the ufcx.h interface header for finite element kernels, used by DOLFINx. ufcx.h is installed by FFCx within the Python site packages, but it is sometimes helpful to install only the header file. This can be done using cmake:

$ cmake -B build-dir -S cmake/
$ cmake --build build-dir
$ cmake --install build-dir

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see https://www.gnu.org/licenses/.

ffcx's People

Contributors

anderslogg avatar aslakbergersen avatar aterrel avatar blechta avatar chrisrichardson avatar dham avatar francesco-ballarin avatar garth-wells avatar hplgit avatar igorbaratta avatar ivanyashchuk avatar jhale avatar johanhake avatar johannesring avatar jorgensd avatar jpdean avatar kent-and avatar lzlarryli avatar martinal avatar meg-simula avatar michalhabera avatar miklos1 avatar minrk avatar mliertzer avatar mscroggs avatar nate-sime avatar nschloe avatar smuething avatar tuomas2 avatar w1th0utnam3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ffcx's Issues

Make generated dofmap abstract

FFC presently generates a concrete dofmap which just needs the global number of mesh entities. It does, however, rely on a specific ordering of the mesh that is only defined for simplex meshes.

A solver using the generated code, e.g. DOLFIN, will typically create this dofmap and re-order it for memory locality, suitable for distributed parallel computation, to support dof blocks, and, in the case of meshes without the special ordering, for higher-order elements. Also, the solver needs to keep track of the FFC generated dofmaps to support extraction of sub-dofmaps.

The re-ordering code on the solver side is complicated. It would be simpler for FFC and the solver if FFC provided the core abstract data necessary for the solver to construct a concrete dofmap. As a start, the generated could specify:

  • Block size
  • Mesh entity (dim) to which each dof belongs, e.g. vertex, edge, facet, cell, whole (sub-)domain
  • Data to support extraction of sub-dofmaps

Generated code fails to compile when using conditionals in complex mode

Generated C code fails to compile in the complex mode when using conditionals.
This is due to the comparison of complex values which cannot be ordered.

UFL file example:

element = FiniteElement("Lagrange", interval, 1)
v = TestFunction(element)
f = Coefficient(element)
x = SpatialCoordinate(interval)
c = conditional(le(real(x[0]),  0.025), 1.0, 0.0)
L = c*inner(f, v) * dx

Excerpt of the generated integral code containing the error:

...
const ufc_scalar_t x_c0 = coordinate_dofs[0] * FE1_C0_Q2[0][iq][0] + coordinate_dofs[1] * FE1_C0_Q2[0][iq][1];
alignas(32) ufc_scalar_t sv2[4];
sv2[0] = creal(x_c0);
sv2[1] = creal(sv2[0]);
sv2[2] = (sv2[1] <= 0.025 ? 1.0 : 0.0) * w0;  // <=
...

warnings on form compilation

I am getting several warnings when compiling forms from dolfinx.

Below is the output when running dolfinx/python/demo/stokes-taylor-hood/demo_stokes-taylor-hood.py

libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2534:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2617:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2671:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2737:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c: In function ‘tabulate_tensor_integral_cell_otherwise_28b3c200ded93f24df4749a4d01805a62878ea3d’:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2949:15: warning: unused variable ‘FE8_C0_D10_Q3_dofmap’ [-Wunused-variable]
     const int FE8_C0_D10_Q3_dofmap[5] = { 6, 7, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2948:15: warning: unused variable ‘FE13_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE13_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~~
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2947:15: warning: unused variable ‘FE8_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE8_C0_D01_Q3_dofmap[5] = { 6, 8, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2947:15: warning: ‘FE8_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2948:15: warning: ‘FE13_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE13_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~~
libffcx_forms_11736d4fcd6f4c7d7fda49a599db40d5a6f106f4.c:2949:15: warning: ‘FE8_C0_D10_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE8_C0_D10_Q3_dofmap[5] = { 6, 7, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2534:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2617:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2671:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2737:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c: In function ‘tabulate_tensor_integral_cell_otherwise_88dcad742c4987f5db3d534023dc372e8d003462’:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2949:15: warning: unused variable ‘FE4_C0_D10_Q3_dofmap’ [-Wunused-variable]
     const int FE4_C0_D10_Q3_dofmap[5] = { 0, 1, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2948:15: warning: unused variable ‘FE9_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE9_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2947:15: warning: unused variable ‘FE4_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q3_dofmap[5] = { 0, 2, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2947:15: warning: ‘FE4_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2948:15: warning: ‘FE9_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE9_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_8c792bd8ee5ca4662907615f375231a3830f9f86.c:2949:15: warning: ‘FE4_C0_D10_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE4_C0_D10_Q3_dofmap[5] = { 0, 1, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2534:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2617:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2671:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2737:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c: In function ‘tabulate_tensor_integral_cell_otherwise_05ebde50c08aa524543ae80d6f60f715d05f8ebc’:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2949:15: warning: unused variable ‘FE4_C0_D10_Q3_dofmap’ [-Wunused-variable]
     const int FE4_C0_D10_Q3_dofmap[5] = { 0, 1, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2948:15: warning: unused variable ‘FE9_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE9_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2947:15: warning: unused variable ‘FE4_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q3_dofmap[5] = { 0, 2, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2947:15: warning: ‘FE4_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2948:15: warning: ‘FE9_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE9_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_6918ba168062b5b12715984fb74bfe8a4db77dbf.c:2949:15: warning: ‘FE4_C0_D10_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE4_C0_D10_Q3_dofmap[5] = { 0, 1, 3, 4, 5 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c:1353:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c:1419:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c: In function ‘tabulate_tensor_integral_cell_otherwise_a89ffd7fa64fbef2b1e48ccbb5922f5d8ad127e1’:
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c:1629:15: warning: unused variable ‘FE4_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_7fca636145db150089bd872c160eea3e79d0539d.c:1629:15: warning: ‘FE4_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2534:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2617:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2671:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2737:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c: In function ‘tabulate_tensor_integral_cell_otherwise_46a0022a2a4a29bed333e75533aa9ce1066223a1’:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2948:15: warning: unused variable ‘FE7_C0_D01_Q3_dofmap’ [-Wunused-variable]
     const int FE7_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2947:15: warning: unused variable ‘FE2_C0_Q3_dofmap’ [-Wunused-variable]
     const int FE2_C0_Q3_dofmap[6] = { 6, 7, 8, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~
At top level:
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2947:15: warning: ‘FE2_C0_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_aa4b3c2db1e22338f29792b4f20e37d454e5a833.c:2948:15: warning: ‘FE7_C0_D01_Q3_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE7_C0_D01_Q3_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c:1353:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c:1419:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c: In function ‘tabulate_tensor_integral_cell_otherwise_8c34aa9664a7a7322c85b0c3937d1ac6ee8212e1’:
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c:1629:15: warning: unused variable ‘FE4_C0_D01_Q1_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q1_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_dbac2d0e737e185e2e64a7564b2fa1015ee9ac58.c:1629:15: warning: ‘FE4_C0_D01_Q1_dofmap’ defined but not used [-Wunused-const-variable=]
(A) Norm of velocity coefficient vector: 17.435407162111872
(A) Norm of pressure coefficient vector: 311.4425381292949
(B) Norm of velocity coefficient vector: 17.435407193004238
(B) Norm of pressure coefficient vector: 311.4425379790811
(C) Norm of velocity coefficient vector: 17.435407174711123
(C) Norm of pressure coefficient vector: 311.4425379789682
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3369:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3435:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3503:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3586:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘create_dofmap_7f791dfd60e9f19bc1db3b8814f5fb665066603d’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3673:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c: In function ‘tabulate_tensor_integral_cell_otherwise_8cd58b3d9efced44aabfaf43246e21efbd3b6de9’:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3886:15: warning: unused variable ‘FE16_C2_Q6_dofmap’ [-Wunused-variable]
     const int FE16_C2_Q6_dofmap[3] = { 12, 13, 14 };
               ^~~~~~~~~~~~~~~~~
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3885:15: warning: unused variable ‘FE16_C0_D10_Q6_dofmap’ [-Wunused-variable]
     const int FE16_C0_D10_Q6_dofmap[5] = { 6, 7, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~~
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3884:15: warning: unused variable ‘FE4_C0_D01_Q6_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q6_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3883:15: warning: unused variable ‘FE16_C0_D01_Q6_dofmap’ [-Wunused-variable]
     const int FE16_C0_D01_Q6_dofmap[5] = { 6, 8, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~~
At top level:
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3883:15: warning: ‘FE16_C0_D01_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3884:15: warning: ‘FE4_C0_D01_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE4_C0_D01_Q6_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3885:15: warning: ‘FE16_C0_D10_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE16_C0_D10_Q6_dofmap[5] = { 6, 7, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~~~~~~
libffcx_forms_acc14651a3453b4668543df8072663bceec24af5.c:3886:15: warning: ‘FE16_C2_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE16_C2_Q6_dofmap[3] = { 12, 13, 14 };
               ^~~~~~~~~~~~~~~~~
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘create_dofmap_6cb3ad097fe4be1fae82f84f3c2b45e868a2ebde’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3369:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘create_dofmap_cd7a6bc181fadfbdceca0887c63423446f7d34bf’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3435:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘create_dofmap_5f40f9c775897ede8b4bf82993c85484363aafb7’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3503:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘create_dofmap_4c265f74c56b4aa11d9777c47c03e105bad5b0be’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3586:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘create_dofmap_7f791dfd60e9f19bc1db3b8814f5fb665066603d’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3673:29: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   dofmap->base_permutations = bp;
                             ^
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c: In function ‘tabulate_tensor_integral_cell_otherwise_57c82f8664b849190604db35b2df5d301f5ebff1’:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3884:15: warning: unused variable ‘FE4_C0_D01_Q6_dofmap’ [-Wunused-variable]
     const int FE4_C0_D01_Q6_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3883:15: warning: unused variable ‘FE7_C0_Q6_dofmap’ [-Wunused-variable]
     const int FE7_C0_Q6_dofmap[6] = { 6, 7, 8, 9, 10, 11 };
               ^~~~~~~~~~~~~~~~
At top level:
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3883:15: warning: ‘FE7_C0_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
libffcx_forms_408d57d0c1038d2e170a2b3e84c13090edccb92b.c:3884:15: warning: ‘FE4_C0_D01_Q6_dofmap’ defined but not used [-Wunused-const-variable=]
     const int FE4_C0_D01_Q6_dofmap[2] = { 3, 4 };
               ^~~~~~~~~~~~~~~~~~~~
(D) Norm of velocity coefficient vector: 17.43540717470972
(D) Norm of pressure coefficient vector: 311.59141819987246

The one for dofmap->base_permutations = bp; was probably introduced by #206.
I am not able to pinpoint the exact cause for the other two, but I can assure that none of them were happening three days ago, so it's possible that this is due to some of the modifications introduced in either #201 or #204.
Thanks

Remove ffc script

The ffc script can cause confusion with Python versions. Remove script and use python -m ffc foo.ufl.

ABI incompatibility with c++17 dolfinx?

Dear all,

I am currently compiling dolfinx on two machines (one Centos 7, the other Debian 10).
The two systems provide luckily the same version of the compiler (g++ 8.3.0). I compile dolfinx and dependencies with the same scripts on both machines.

On the Debian 10 one, I get several failures while testing, the first one being

======================================================== FAILURES ========================================================
____________________________________________ test_assembly_dS_domains[mode0] _____________________________________________

mode = GhostMode.none

    @parametrize_ghost_mode
    def test_assembly_dS_domains(mode):
        N = 10
        mesh = dolfin.UnitSquareMesh(dolfin.MPI.comm_world, N, N, ghost_mode=mode)
        one = dolfin.Constant(mesh, 1)
>       val = dolfin.fem.assemble_scalar(one * ufl.dS)

fem/test_assemble_domains.py:179: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_dolfin-2019.2.0.dev0-py3.7-linux-x86_64.egg/dolfin/fem/assemble.py:70: in assemble_scalar
    return cpp.fem.assemble_scalar(_create_cpp_form(M))
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_dolfin-2019.2.0.dev0-py3.7-linux-x86_64.egg/dolfin/fem/assemble.py:24: in _create_cpp_form
    return Form(form)._cpp_object
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_dolfin-2019.2.0.dev0-py3.7-linux-x86_64.egg/dolfin/fem/form.py:43: in __init__
    mpi_comm=mesh.mpi_comm())
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_dolfin-2019.2.0.dev0-py3.7-linux-x86_64.egg/dolfin/jit.py:51: in mpi_jit
    return local_jit(*args, **kwargs)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_dolfin-2019.2.0.dev0-py3.7-linux-x86_64.egg/dolfin/jit.py:116: in ffc_jit
    r = ffc.codegeneration.jit.compile_forms([ufl_object], parameters=p, cache_dir=cache_dir, **cffi_options)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/codegeneration/jit.py:175: in compile_forms
    cffi_extra_compile_args, cffi_verbose, cffi_debug)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/codegeneration/jit.py:256: in _compile_objects
    _, code_body = ffc.compiler.compile_ufl_objects(ufl_objects, prefix="JIT", parameters=parameters)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/compiler.py:117: in compile_ufl_objects
    analysis = analyze_ufl_objects(ufl_objects, parameters)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/analysis.py:63: in analyze_ufl_objects
    form_data = tuple(_analyze_form(form, parameters) for form in forms)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/analysis.py:63: in <genexpr>
    form_data = tuple(_analyze_form(form, parameters) for form in forms)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ffc-2019.2.0.dev0-py3.7.egg/ffc/analysis.py:200: in _analyze_form
    complex_mode=complex_mode)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/compute_form_data.py:332: in compute_form_data
    form = apply_restrictions(form)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/apply_restrictions.py:175: in apply_restrictions
    only_integral_type=integral_types)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/map_integrands.py:58: in map_integrand_dags
    form, only_integral_type)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/map_integrands.py:39: in map_integrands
    for itg in form.integrals()]
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/map_integrands.py:39: in <listcomp>
    for itg in form.integrals()]
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/map_integrands.py:46: in map_integrands
    return itg.reconstruct(function(itg.integrand()))
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/map_integrands.py:57: in <lambda>
    return map_integrands(lambda expr: map_expr_dag(function, expr, compress),
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/corealg/map_dag.py:37: in map_expr_dag
    result, = map_expr_dags(function, [expression], compress=compress)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/corealg/map_dag.py:84: in map_expr_dags
    r = handlers[v._ufl_typecode_](v)
$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/algorithms/apply_restrictions.py:78: in _missing_rule
    error("Missing rule for %s" % o._ufl_class_.__name__)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <ufl.log.Logger object at 0x7fd3eb7e34a8>, message = ('Missing rule for Constant',)

    def error(self, *message):
        "Write error message and raise an exception."
        self._log.error(*message)
>       raise self._exception_type(self._format_raw(*message))
E       ufl.log.UFLException: Missing rule for Constant

$HOME/fenicsx/2019-11-28-1eef790b8/petsc-2019-11-26-3055757620-3.12.2/lib/python3.7/site-packages/fenics_ufl-2019.2.0.dev0-py3.7.egg/ufl/log.py:172: UFLException
--------------------------------------------------- Captured log call ----------------------------------------------------
ERROR    UFL:log.py:171 Missing rule for Constant

I get similar failures later on in other tests, as well as when wrapping external classes with pybind11.

On the CentOS 7 machine everything runs fine instead.

After bisecting, I am reasonably sure that the issue was introduced when switching to C++17 in
FEniCS/dolfinx#641
but I am not fully able to debug any further due to limited knowledge of FFCX.

Is it possible that we need to enforce the std=c++17 flag on every FFCX compilation, as well as in the pybind11 layer of dolfinx?

tabulate_reference_dof_coordinates fails for some vector elements

Minimal failing example:

import numpy as np
import ffc.codegeneration.jit
import ufl

cell = ufl.triangle
element = ufl.FiniteElement("N1curl", cell, 2)  # Order 1 works
compiled_element, module = ffc.codegeneration.jit.compile_elements([element])

compiled_e = compiled_element[0][0]

tdim = compiled_e.topological_dimension
space_dim = compiled_e.space_dimension
X = np.zeros([space_dim, tdim])
X_ptr = module.ffi.cast("double *", module.ffi.from_buffer(X))
result = compiled_e.tabulate_reference_dof_coordinates(X_ptr)
assert result == 0

Memory leak in dofmap->base_permutations

The below will cause a memory leak:

dofmap->base_permutations = malloc(sizeof(int) * 30);

Can it now be a static array? See ufc_integral

There should be an variable giving the length of the array.

Inefficient code for "preintegrated" blocks of huge element tensors

Same issue as: https://bitbucket.org/fenics-project/ffc/issues/173/uflacs-preintegration-emits-inefficient
Still a problem in FFC-X as my hacky fix was not merged yet (#25)

UFL code to reproduce issue:

cell = tetrahedron
element = FiniteElement("Nedelec 1st kind H(curl)", cell, 3)

u = TrialFunction(element)
v = TestFunction(element)

a = (inner(curl(u), curl(v)) - Constant(cell, 1)*inner(u, v))*dx

The element tensor of a has size 45 x 45. UFLACS uses block_mode = "preintegrated" for the whole element tensor which leads to 45 x 45 assignments with roughly the same amount of terms per assignment. GCC compilation with -O2 does not terminate with a reasonable amount of memory (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85072) with this code.

My fix transformed block_mode = "preintegrated" blocks into loops if the preintegration tables exceeded a specific size. However, it looks like block_mode = "premultiplied" already generates code like this. E.g. forcing UFLACS to use block_mode = "premultiplied" by replacing this line:

block_mode = "preintegrated"

leads to code that looks much cleaner and GCC can compile. In this example it generates 51 static PM arrays with size 44x44 and assigns them to A in 9 loops like:

for (int i = 0; i < 44; ++i)
        for (int j = 0; j < 44; ++j)
            A[45 * DM0[i] + DM0[j]] += TM0 * PM44[0][i][j] + TM1 * PM45[0][i][j] + TM2 * PM46[0][i][j] + TM3 * PM47[0][i][j] + TM2 * PM46[0][j][i] + TM4 * PM48[0][i][j] + TM5 * PM49[0][i][j] + TM3 * PM47[0][j][i] + TM5 * PM49[0][j][i] + TM6 * PM50[0][i][j];

I also looked at the code generation for block_mode = "preintegrated" and there is a switch inline_tables. Forcing it to be false leads to the generation of several PI arrays similar to the arrays above. However this only changes the expressions in the 45x45 assignments to refer to these arrays instead of having the coefficients inlined directly into the assignments. The assignments are still unrolled completely and GCC fails to compile it.

Therefore I would suggest to use this mode premultiplied, if preintegrated were chosen but some table size exceeds some limit. However, I still have to find out what information is available at the line shown above which could be used to make the decision.

tabulate_tensor function using block_mode = "preintegrated": tabulate_tensor_preintegrated.txt
tabulate_tensor function using block_mode = "premultiplied": tabulate_tensor_premultiplied.txt

Add function to list subdofs

To support the new dofmap data structures a function is needed that provides the indices (local) for a subdofmap. I.e., if the parents dofs are 0, 1, 2, 3, 4, 5, the dofs for sub-dofmap 0 might be 0, 2, 4, and for sub-dofmap 1 they might be 1, 3, 5.

Possible signature is

int tabulate_submap(*dofs, int submap_index);

Replace DOLFIN C++ convenience wrappers with C factory functions

The generated DOLFIN C++ convenience wrappers (-l dolfin) are overkill now that the relevant DOLFIN constructors have long used shared pointers. They could be replaced by conveniently named (C) factory functions.

This will support the transition to the code being plain C rather than C++.

Limitations of num_coordinate_component_dofs

Currently there are several limitations in the num_coordinate_component_dofs, https://github.com/FEniCS/ffcx/blob/master/ffc/codegeneration/definitions.py#L16-L44.

  • Does not support higher order quadrilaterals (Fix in PR #156, this fix should work for arbitrary order quadrilateral elements).
  • Does not support any mesh with degree > 3.

Until recently, there was no support in dolfin for meshes with higher order than 2. Now that we have added order 3 triangles, extending this to arbitrary order is tempting.
Then, as the comment in num_coordinate_components_dofs we should get this info from FIAT through IR.

Compile cffi headers directly from ufc.h

JIT compilation with CFFI should not assume a copy of ufc.h, but extract it from the actual file.
e.g. some comment lines could be introduced in ufc.h to split on.

Implement support for FunctionSpace

Implementing the UFL concept of a FunctionSpace would map nicely onto implementations. It would also:

  • Provide a natural grouping of [element, dofmap, coordinate_map]
  • Simplify the attachment of a non-affine maps
  • Fix an issue around the generation of single elements, which at present does not generate a coordinate map.

Note: the new 'DOLFIN' wrappers (which now have no DOLFIN dependency) are effectively creating FunctionSpace structs that collect an element, dofmap and coordinate map (replacing the C++ wrappers).

Simplify form integral id handling

ufc_form integrals are unnecessarily complex, with, for example:

/// Create a new cell integral on sub domain subdomain_id 
ufc_cell_integral* (*create_cell_integral)(int subdomain_id);

/// Create a new cell integral on everywhere else
ufc_cell_integral* (*create_default_cell_integral)(void);

/// Upper bound on subdomain ids for cell integrals
int max_cell_subdomain_id;

where max_cell_subdomain_id could possible be very large.

More helpful would be:

/// Create a new cell integral on sub domain subdomain_id 
ufc_cell_integral* (*create_cell_integral)(int subdomain_id);

/// Number of subdomain ids for cell integrals, and array of ids
void ufc_cell_integral_ids (**ids, int& num_ids);

where the default integral could be -1.

Update tsfc intermediate representation of integral

The tsfc intermediate representation of integral (tsfcrepresentation.compute_integral_ir) is not in sync with uflacsrepresentation.compute_integral_ir and ffc.ir.representation.ir_integral (namedtuple).

This prevents the use of the tsfc representation.

Numpy non-tuple nd-indexing deprecation warning in UFLACS

Since Numpy 1.15.0 the following warning is raised in UFLACS:

FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

caused by

active[targets] = 1

Can be reproduced using NumPy 1.15.0 and ufl file:

el = FiniteElement("Lagrange", triangle, 1)
v = TestFunction(el)
u = TrialFunction(el)
a = inner(grad(u), grad(v)) * dx

Warning was introduced in NumPy here: numpy/numpy#9686

numpy/numpy#11411 suggests that if the warning is issued, it is always ok to replace to just transform the argument in a tuple but I'm not sure if the UFLACS code always causes this warning. Don't have the time at the moment to identify what inputs this UFLACS funtion receives.

Shorten generated function names

Generic function names a very long, with quite a few words plus a long hash. There function are not in general called by users, but are accessed via wrappers. The very long names:

  • Look untidy and can be hard to read
  • Some compilers might not accept the long names
    Function names that are not intended for direct use could be mainly hash string, with a code comment to make purpose clear.

compile_elements fails for quadrilateral "HDiv Trace" elements

Minimal failing example:

import ffc.codegeneration.jit
import ufl

cell = ufl.quadrilateral
element = ufl.FiniteElement("HDiv Trace", cell, 1)
compiled_element, module = ffc.codegeneration.jit.compile_elements([element])

The above fails at A = e.element.A in _evaluate_basis with AttributeError: 'HDivTrace' object has no attribute 'A'.

There appears to be a check

if isinstance(e, HDivTrace):
    return "Function not supported for Trace elements"

to prevent this occurring, but it obviously isn't working as intended.

Make kernels thread-safe

Because C kernels with local static arrays, kernels are no longer thread-safe. This creates issues especially with numba's parallel=True attempts.

We should consider trading threaded performance for non-threaded with static arrays.

The reason behind violation of thread-safety should be investigated more, as we have const static arrays.

Make UFC C-only (and not C++)

Making the generated code C-only will make optimisation and just-in-time compilation easier and faster. C code is faster to compile, doesn't do name mangling (which makes JIT easier and will allow of-the-shelf tools like Python CFFI to be used from DOLFIN and independently by users). It also opens the way for using OpenCL, etc.

The C++ classes should be replaced by structs, with function pointers and factory functions to emulate the object-oriented interface.

Outstanding tasks:

  • Replace ufc::finite_element with ufc_finite_element C struct
  • Replace ufc::coordinate_mapping with ufc::coordinate_mapping C struct
  • Replace ufc::dofmap with ufc_dofmap C struct
  • Replace ufc::form with ufc_form C struct
  • Replace ufc::integral with ufc_integral C struct

Some details:

  • Remove dynamic allocation of element in the ufc_finite_element function for mapping coordinates (was avoidable with C++)
  • Handle cases elegantly where a member function was called. Keep simple and just return an error code?

Max/min of geometric quantities

In complex mode, CellDiameter expands to maximum over cell edges lengths (this happens in UFL).
MaxValue has no handler in ufl_to_cnodes.py which is safe, because maximum of complex number is ambiguous.
Since geometry in FFCx/dolfinx is always real, we should support MaxValue and MinValue on geometric quantities.

Nonunique namespace for methods in multiple forms/elements/...

Few methods in generated C code do not have hashed prefix (unique name). When several forms are compiled with JIT cffi and python loads these shared libraries, mixing of the methods without unique names could happen (this is OS environment dependent).

It leads to silent behaviour, binary incompatibility and incorrect functions being called for tabulation, ...

The issue reported also FEniCS/dolfinx#341

Include 'prefix' (filename) in function hash when using FFC from the command line

When using FFC from the command line (rather than JIT), the file name, e.g. Poisson was included in the class names. Now that the command line and JIT follow a common code path and use hashes in in the classes name we need to add the filename to the hash when using FFC from the command line to avoid name clashes across more than one generated file.

Remove method ufc::finite_element::map_dofs

This function (it seems) interpolates f(x) into an FE space. It is often used magically, causing some user confusion.

It would be simpler and cleaner to just use point-wise eval of functions.

ffc "binary" installs with hardwired python3 path

The first line of ffc - the command line executable is:

#!/usr/bin/python3

which would be better as

#!/usr/bin/env python3

because the exact python3 maybe depend on your $PATH. Not sure how to change this, as it is done automatically by setuptools.

Make coordinate_dofs always 3D

tabulate_tensor expects the cell coordinate dofs in the same gdim as the cell is defined.
In the dolfin assembler, we need to clip the 3D geometry down to the gdim expected by ffc.

  • Change ffc to use 3D geometry only.

Update tabulate_tensor signature for form constants

Change signature for tabulate tensor to separate out FE coefficients and Constants, e.g.

tabulate_tensor(ufc_scalar_t *A, ufc_scalar_t *w, ufc_scalar_t *c, double *coords, int *entity_index, int *orient);

  • Change signature

  • Separate out constants from other coefficients in generated code

Generate list of sub-dof indices for dofmaps

It would be helpful to have a list of local dof indices (local to a cell) that correspond to a sub-dofmap. This would make extracting sub-maps simpler, and support different dof orderings in local element matrices/vectors.

Fixes for create_functionspace_foo

The functions with the new signature

ufc_function_space* create_functionspace_form_foo_L

should use if-else, and should return NULL and avoid malloc if the string identifier function_name is not found.

Redesign FE interpolation (and get it working again for multi-point dofs)

Original evaluate_dof(s) using ufc::function was replaced by tabulate_reference_dof_coordinates + map_dofs (transform_values since #32). This made it basically defunct for multiple points dofs. Examples

element = FiniteElement("Nedelec 1st kind H(curl)", triangle, 2)
element = FiniteElement("Nedelec 1st kind H(curl)", tetrahedron, 3)
element = FiniteElement("Nedelec 2nd kind H(curl)", triangle, 2)
element = FiniteElement("Nedelec 2nd kind H(curl)", tetrahedron, 2)

which since that do not support interpolation because dofs are multi-point.

Note that these examples in fact currently crash on a trivially fixable assertion when compiled.

How to reproduce:

cat - > e.ufl <<EOF
element = FiniteElement("Nedelec 1st kind H(curl)", triangle, 2)
EOF

python3 -mffc e.ufl

# observe that implementation of transform_values is junk, will not compile

Restructure cell orientation information passed into tabulate_tensor and transform_reference_basis_derivatives

Currently, edge_reflections, face_rotations and face_reflections are passed in, as well as quadrature_permutation in tabulate_tensor.

typedef void(ufc_tabulate_tensor)(
ufc_scalar_t* restrict A, const ufc_scalar_t* w, const ufc_scalar_t* c,
const double* restrict coordinate_dofs, const int* entity_local_index,
const uint8_t* restrict quadrature_permutation,
const bool* edge_reflections, const bool* face_reflections,
const uint8_t* face_rotations);

int (*transform_reference_basis_derivatives)(
double* restrict values, int order, int num_points,
const double* restrict reference_values, const double* restrict X,
const double* restrict J, const double* restrict detJ,
const double* restrict K, const bool* edge_reflections,
const bool* face_reflections, const uint8_t* face_rotations);

This information should be passed in a more tidy way, possibly as an array cell_ordering[dimension][rotation/reflection][entiity_index].

CellDiameter not defined for higher-order cells

When using P2 geometry, CellDiameter raises a warning in UFL followed by an error in ffc:

WARNING:UFL:Only know how to compute cell diameter of P1 or Q1 cell.

".../access.py", line 66, in get
    raise RuntimeError("Not handled: {}".format(type(e)))
RuntimeError: Not handled: <class 'ufl.geometry.CellDiameter'>

It is useful to have an estimate of the "cell diameter", even if it is not the actual length of an edge, but just the distance between vertices.

Should this be calculated in ffc, or ufl? Should it still be called CellDiameter?

Add bool function to tell if basis functions need push-forward

At the moment, all evaluated basis functions on a reference element need to be passed through ufc::finite_element::transform_reference_basis_derivatives in case a transform is needed, e.g. Piola transform.

For Lagrange elements this could be avoided.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.