[draft] A draft for local assembler interfaces.
Merge request reports
Activity
added discussion label
- dune/assembler/localassemblerinterface.hh 0 → 100644
8 namespace Dune::Assembler { 9 10 // The following are not meant to be base-classes, but just to illustrate 11 // the interfaces, because a mock class is easier to grasp. 12 13 // I would propose that the following are independent concepts. 14 // A local assembler can satisfy several of those concepts. 15 // The global assembler does a concept check and calls the 16 // necessary methods only. 17 18 // Local assemblers on element 19 20 class LocalElementOperatorAssembler 21 { 22 void bindTestLocalView(const TestLocalView&); 23 void bindTrialLocalView(const TrialLocalView&); If we have two separate methods for binding the local-views, it gets a bit harder to check whether both are identical (e.g. refer to the same object). Do we want to specify an order in which the
bindxxx
are called? (I would say: no)Maybe it is better to have a
bindLocalViews
function that gets all local-views in a defined order as arguments, or even a tuple / named struct with all local-views. (Then the order is determined by names)
- dune/assembler/localassemblerinterface.hh 0 → 100644
7 8 namespace Dune::Assembler { 9 10 // The following are not meant to be base-classes, but just to illustrate 11 // the interfaces, because a mock class is easier to grasp. 12 13 // I would propose that the following are independent concepts. 14 // A local assembler can satisfy several of those concepts. 15 // The global assembler does a concept check and calls the 16 // necessary methods only. 17 18 // Local assemblers on element 19 20 class LocalElementOperatorAssembler 21 { 22 void bindTestLocalView(const TestLocalView&); - dune/assembler/localassemblerinterface.hh 0 → 100644
12 13 // I would propose that the following are independent concepts. 14 // A local assembler can satisfy several of those concepts. 15 // The global assembler does a concept check and calls the 16 // necessary methods only. 17 18 // Local assemblers on element 19 20 class LocalElementOperatorAssembler 21 { 22 void bindTestLocalView(const TestLocalView&); 23 void bindTrialLocalView(const TrialLocalView&); 24 25 void bindElement(const Element&); 26 27 void assembleElementOperator(LocalMatrix&); As mentioned earlier, I would separate the question of caching from the local assembler interface. At this level I would say, that the local assembler is responsible for managing its own cache.
But one may implement a special local assembler that provides a cache and has it's own higher level interface for local assemblers based on function evaluations.
- dune/assembler/localassemblerinterface.hh 0 → 100644
86 // Local assemblers on skeleton intersection 87 88 class LocalSkeletonOperatorAssembler 89 { 90 void bindTestLocalView(const TestLocalView&); 91 void bindTrialLocalView(const TrialLocalView&); 92 void bindOutsideTestLocalView(const OutsideTestLocalView&); 93 void bindOutsideTrialLocalView(const OutsideTrialLocalView&); 94 95 void bindElement(const Element&); 96 void bindOutsideElement(const Element&); 97 void bindIntersection(const Intersection&); 98 99 // We need to discuss, if we want to support one-sided, 100 // two-sided or both. 101 void assembleSkeletonOperator(LocalMatrix&); This depends on what the assembler should do. But I would say, that it's never a single element matrix. It's should be one of the following
- A 2x2 block matrix for a two-sided coupling.
- A 1x2 matrix for a one-sided coupling. This would be the first row of the above.
- Only the two off-diagonal blocks of the two-sided coupling (ignoring intra-element coupling)
- Only one off-diagonal blocks of the one-sided coupling (ignoring intra-element coupling).
While we only have a single, non-blocked (rectangular) matrix in the latter case, it's not an element-matrix, because it contains the coupling between two elements.
- dune/assembler/localassemblerinterface.hh 0 → 100644
78 void bindElement(const Element&); 79 void bindIntersection(const Intersection&); 80 81 void assembleBoundary(LocalMatrix&, LocalVector&); 82 }; 83 84 85 86 // Local assemblers on skeleton intersection 87 88 class LocalSkeletonOperatorAssembler 89 { 90 void bindTestLocalView(const TestLocalView&); 91 void bindTrialLocalView(const TrialLocalView&); 92 void bindOutsideTestLocalView(const OutsideTestLocalView&); 93 void bindOutsideTrialLocalView(const OutsideTrialLocalView&); Also here, all 4 local-views could be identical. How to recognize this situation? Is the local-assembler responsible for this optimization or can be pass this info somehow to the local-assembler. In AMDiS I have introduced a
LocalViewPair
that binds the local-views only once to an element. But this is not enough here, since the local-view are used by the assembler and not vice versa.In fufem we used the following approach:
The global assembler always passes two (for the skeleton 4) local views. But if test- and trial-basis are the same, it uses the same one for both roles. When the local assembler creates caches on
bind*LocalView()
it can detect this and only use a single cache.
- dune/assembler/localassemblerinterface.hh 0 → 100644
10 // The following are not meant to be base-classes, but just to illustrate 11 // the interfaces, because a mock class is easier to grasp. 12 13 // I would propose that the following are independent concepts. 14 // A local assembler can satisfy several of those concepts. 15 // The global assembler does a concept check and calls the 16 // necessary methods only. 17 18 // Local assemblers on element 19 20 class LocalElementOperatorAssembler 21 { 22 void bindTestLocalView(const TestLocalView&); 23 void bindTrialLocalView(const TrialLocalView&); 24 25 void bindElement(const Element&); IMO the whole design is based on the assumption that the global assembler must bind the
LocalView
. This way e.g. the check if we need to bind one or two (Galerkin or Petrov-Galerkin) is centralized. This is also central for easy composability of several local assemblers.Also the local assembler might not even use the local view, e.g. if it does a plain copy of a precomputed local matrix (for structured grids). Then it would be strange to require that the local assembler binds it, because the global one needs a bound
LocalView
later on to access the global indices.
mentioned in merge request !2 (closed)