| 493 | //----------------------------------------------------------------------------- |
| 494 | template <std::floating_point T> |
| 495 | std::pair<std::vector<T>, std::array<std::size_t, 2>> |
| 496 | FiniteElement<T>::create_interpolation_operator(const FiniteElement& from) const |
| 497 | { |
| 498 | assert(_element); |
| 499 | assert(from._element); |
| 500 | if (_element->map_type() != from._element->map_type()) |
| 501 | { |
| 502 | throw std::runtime_error("Interpolation between elements with different " |
| 503 | "maps is not supported."); |
| 504 | } |
| 505 | |
| 506 | if (_bs == 1 or from._bs == 1) |
| 507 | { |
| 508 | // If one of the elements has bs=1, Basix can figure out the size of |
| 509 | // the matrix |
| 510 | return basix::compute_interpolation_operator<T>(*from._element, *_element); |
| 511 | } |
| 512 | else if (_bs > 1 and from._bs == _bs) |
| 513 | { |
| 514 | // If bs != 1 for at least one element, then bs0 == bs1 for this |
| 515 | // case |
| 516 | const auto [data, dshape] |
| 517 | = basix::compute_interpolation_operator<T>(*from._element, *_element); |
| 518 | std::array<std::size_t, 2> shape = {dshape[0] * _bs, dshape[1] * _bs}; |
| 519 | std::vector<T> out(shape[0] * shape[1]); |
| 520 | |
| 521 | // NOTE: Alternatively this operation could be implemented during |
| 522 | // matvec with the original matrix. |
| 523 | for (std::size_t i = 0; i < dshape[0]; ++i) |
| 524 | for (std::size_t j = 0; j < dshape[1]; ++j) |
| 525 | for (int k = 0; k < _bs; ++k) |
| 526 | out[shape[1] * (i * _bs + k) + (j * _bs + k)] |
| 527 | = data[dshape[1] * i + j]; |
| 528 | |
| 529 | return {std::move(out), shape}; |
| 530 | } |
| 531 | else |
| 532 | { |
| 533 | throw std::runtime_error( |
| 534 | "Interpolation for element combination is not supported."); |
| 535 | } |
| 536 | } |
| 537 | //----------------------------------------------------------------------------- |
| 538 | template <std::floating_point T> |
| 539 | bool FiniteElement<T>::needs_dof_transformations() const noexcept |
no test coverage detected