[BUG]: dof_transformation_right_fn mis-slices data for mixed elements with block_size > 1
- Dominant language
- C++
- Stars
- 1.2k
- Forks
- 261
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 65
Description
### Summarize the issue
This is a bug found by Claude AI - which may or may not be accurate. I don't know if this is correct or not, but just pasting here as an issue, in case anyone can look into it.
File: `cpp/dolfinx/fem/FiniteElement.h`
Function: `FiniteElement::dof_transformation_right_fn` (mixed-element branch)
### Summary
In the mixed-element branch of dof_transformation_right_fn, each sub-element's DOF-transformation function is called with a data span that is not correctly restricted to that sub-element's own columns when block_size > 1. This silently produces incorrect data for any mixed (heterogeneous) element where a sub-element needs a DOF transformation and the transformation is applied from the right with more than one row of data — the situation that arises during bilinear-form matrix assembly.
### Current code
```
cpp// cpp/dolfinx/fem/FiniteElement.h
else if (!_sub_elements.empty())
{
if (!_reference_value_shape) // Mixed element
{
std::vector, std::span, std::int32_t, int)>>
sub_element_fns;
for (std::size_t i = 0; i < _sub_elements.size(); ++i)
{
sub_element_fns.push_back(
_sub_elements[i]->template dof_transformation_right_fn(ttype));
}
return [this, sub_element_fns](std::span data,
std::span cell_info,
std::int32_t cell, int block_size)
{
std::size_t offset = 0;
for (std::size_t e = 0; e < sub_element_fns.size(); ++e)
{
sub_element_fns[e](data.subspan(offset, data.size() - offset),
cell_info, cell, block_size);
offset += _sub_elements[e]->space_dimension();
}
};
}
...
```
### Root cause
block_size here is a row count, not a component count. This is confirmed by the call site in assemble_matrix_impl.h:
```
cpp// cpp/dolfinx/fem/assemble_matrix_impl.h
P0(Ae, cell_info0, cell0, ndim1); // left-apply, ndim1 rows
P1T(Ae, cell_info1, cell1, ndim0); // right-apply, ndim0 rows
```
data is therefore a row-major buffer of shape (block_size rows) x (total dofs). For sub-element e, occupying dof-columns [offset, offset + dim_e), the correct data for that sub-element is a strided slice — the same column range repeated in every row — not a single contiguous run.
### How to reproduce the bug
N/A
### Minimal Example (Python)
```Python
```
### Output (Python)
```bash
```
### Version
main branch
### DOLFINx git commit
_No response_
### Installation
_No response_
### Additional information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.