Skip to content

Add methods to skip entities and intersections

What does this MR do?

Implements a way to completely skip bind and assembly of entities and intersection. When the assembly includes local function spaces that are empty (e.g. in a multidomain setting), their binding still takes places and may take an important part of the assembly time. The engines already envisaged such implementation for entities (i.e. assembleCell()) but the local operator never exposed any interface for it. Here I extend the local assembler interface to also ask for the intersection assembly and add an interface to the local operator as well as the switch to make it backwards compatible.

I am not specially bound to the flag/function names, so if you have better ideas, feel free to propose them.

What about combined operators?

If some operators want to skip an entity/intersection but others don't, then the combined operator should do not skip the whole assemble if at least one of the local operators want to do the assembly. However, it is expected to still skip all the calls to local methods (e.g. alpha_volume). For instance:


struct MyCombinedOperator {
  
  // ...

  std::tuple<LOP0,LOP1> _lops;

  enum { doSkipEntity = true };

  template<class EG>
  bool skip_entity(const EG& eg) const
  {
    return std::get<0>(_lops).skip_entity(eg) and std::get<1>(_lops).skip_entity(eg);
  }

  template<typename EG, typename LFSU, typename X, typename LFSV, typename R>
  void alpha_volume(const EG& eg, const LFSU& lfsu, const X& x, const LFSV& lfsv, R& r) const
  {
    if (std::get<0>(_lops).skip_entity(eg))
      std::get<0>(_lops).alpha_volume(eg,lfsu,x,lfsv,r);
    if (std::get<1>(_lops).skip_entity(eg))
      std::get<1>(_lops).alpha_volume(eg,lfsu,x,lfsv,r);
  }
};

This could be automated by adding a predicate on the CombinedOperator class, however, it is not possible to evaluate the skip_* methods on all local functions because pattern_* methods do not receive entity information. Thus, until this is fixed, only one choice is possible: only allow the same results of the skip methods.

struct MyCombinedOperator {
  
  // ...

  template<typename EG>
  bool skip_entity
  ( const EG& eg) const
  {
    // check that all operators return the same
    if (std::get<0>(_lops).skip_entity(eg) ^ std::get<1>(_lops).skip_entity(eg))
      DUNE_THROW(RangeError, "MyCombinedOperator is not allowed to have different skip_entity results");
    return std::get<0>(_lops).skip_entity(eg);
  }
};

Is this MR ready to be reviewed?

Yes. The feature is implemented and the pipeline seems to be passing good.

Edited by Santiago Ospina De Los Ríos

Merge request reports