| 430 | /// each column block |
| 431 | template <dolfinx::scalar T> |
| 432 | std::array<std::vector<std::shared_ptr<const FunctionSpace<T>>>, 2> |
| 433 | common_function_spaces( |
| 434 | const std::vector< |
| 435 | std::vector<std::array<std::shared_ptr<const FunctionSpace<T>>, 2>>>& V) |
| 436 | { |
| 437 | assert(!V.empty()); |
| 438 | std::vector<std::shared_ptr<const FunctionSpace<T>>> spaces0(V.size(), |
| 439 | nullptr); |
| 440 | std::vector<std::shared_ptr<const FunctionSpace<T>>> spaces1(V.front().size(), |
| 441 | nullptr); |
| 442 | |
| 443 | // Loop over rows |
| 444 | for (std::size_t i = 0; i < V.size(); ++i) |
| 445 | { |
| 446 | // Loop over columns |
| 447 | for (std::size_t j = 0; j < V[i].size(); ++j) |
| 448 | { |
| 449 | auto& V0 = V[i][j][0]; |
| 450 | auto& V1 = V[i][j][1]; |
| 451 | if (V0 and V1) |
| 452 | { |
| 453 | if (!spaces0[i]) |
| 454 | spaces0[i] = V0; |
| 455 | else |
| 456 | { |
| 457 | if (spaces0[i] != V0) |
| 458 | throw std::runtime_error("Mismatched test space for row."); |
| 459 | } |
| 460 | |
| 461 | if (!spaces1[j]) |
| 462 | spaces1[j] = V1; |
| 463 | else |
| 464 | { |
| 465 | if (spaces1[j] != V1) |
| 466 | throw std::runtime_error("Mismatched trial space for column."); |
| 467 | } |
| 468 | } |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | // Check that there are no null entries |
| 473 | if (std::find(spaces0.begin(), spaces0.end(), nullptr) != spaces0.end()) |
| 474 | throw std::runtime_error("Could not deduce all block test spaces."); |
| 475 | if (std::find(spaces1.begin(), spaces1.end(), nullptr) != spaces1.end()) |
| 476 | throw std::runtime_error("Could not deduce all block trial spaces."); |
| 477 | |
| 478 | return {spaces0, spaces1}; |
| 479 | } |
| 480 | |
| 481 | /// Type deduction |
| 482 | template <typename U, typename V, typename W> |
no test coverage detected