FEniCS / ffcx

Next generation FEniCS Form Compiler for finite element forms
https://fenicsproject.org
Other
145 stars 38 forks source link

Get rid of `switch` in C output #585

Closed chrisrichardson closed 1 year ago

chrisrichardson commented 1 year ago

UFCx provides some functions, e.g. tabulate_entity_dofs which are implemented in C using switch/case. There is no real need for this, and there are additional issues for prism/pyramid where the number of dofs per entity is variable. The switch/case syntax is messy and confusing, error prone.

I propose replacing the code with static data. Essentially, it is just a list of lists, and this can be encoded with two arrays:

e.g. for closure dofs on a prism, note different lengths for dim 2. Python:

entity_closure_dofs = [[[0], [1], [2], [3], [4], [5]], [[0, 1], [0, 2], [0, 3], [1, 2], [1, 4], [2, 5], 
    [3, 4], [3, 5], [4, 5]], [[0, 1, 2], [0, 1, 3, 4], [0, 2, 3, 5], [1, 2, 4, 5], [3, 4, 5]], [[0, 1, 2, 3, 4, 5]]]

C:

static const int entity_closure_dofs[] = {
  0,
  1,
  2,
  3,
  4,
  5,
  0,1,
  0,2,
  0,3,
  1,2,
  1,4,
  2,5,
  3,4,
  3,5,
  4,5,
  0,1,2,
  0,1,3,4,
  0,2,3,5,
  1,2,4,5,
  3,4,5,
  0,1,2,3,4,5};
static const entity_closure_dofs_offsets_0[] = {0,1,2,3,4,5,6};
static const entity_closure_dofs_offsets_1[] = {6,8,10,12,14,16,18,20,22,24};
static const entity_closure_dofs_offsets_2[] = {24,27,31,35,39,42};
static const entity_closure_dofs_offsets_3[] = {42,48};

In fact, these offsets could all be put into one array, assuming we know the topology already (I think we do).

chrisrichardson commented 1 year ago

Other use of switch/case and code in the ufcx interface can also be replaced with static data, e.g. for integrals and function space.

chrisrichardson commented 1 year ago
michalhabera commented 1 year ago

Agree. We had many "dynamic" allocations and dynamic factories in the old FFC, https://github.com/FEniCS/ffcx/pull/321