#include <scheme/DiscreteFunctionUtils.hpp> #include <mesh/Connectivity.hpp> #include <mesh/IMesh.hpp> #include <mesh/Mesh.hpp> #include <scheme/DiscreteFunctionP0.hpp> #include <scheme/DiscreteFunctionVariant.hpp> #include <utils/Stringify.hpp> std::shared_ptr<const IMesh> getCommonMesh(const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) { std::shared_ptr<const IMesh> i_mesh; bool is_same_mesh = true; for (const auto& discrete_function_variant : discrete_function_variant_list) { std::visit( [&](auto&& discrete_function) { if (not i_mesh.use_count()) { i_mesh = discrete_function.mesh(); } else { if (i_mesh != discrete_function.mesh()) { is_same_mesh = false; } } }, discrete_function_variant->discreteFunction()); } if (not is_same_mesh) { i_mesh.reset(); } return i_mesh; } bool hasSameMesh(const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) { std::shared_ptr<const IMesh> i_mesh; bool is_same_mesh = true; for (const auto& discrete_function_variant : discrete_function_variant_list) { std::visit( [&](auto&& discrete_function) { if (not i_mesh.use_count()) { i_mesh = discrete_function.mesh(); } else { if (i_mesh != discrete_function.mesh()) { is_same_mesh = false; } } }, discrete_function_variant->discreteFunction()); } return is_same_mesh; } template <size_t Dimension, typename DataType> std::shared_ptr<const IDiscreteFunction> shallowCopy(const std::shared_ptr<const Mesh<Connectivity<Dimension>>>& mesh, const std::shared_ptr<const DiscreteFunctionP0<Dimension, DataType>>& discrete_function) { Assert(mesh->shared_connectivity() == dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*discrete_function->mesh()).shared_connectivity(), "connectivities should be the same"); return std::make_shared<DiscreteFunctionP0<Dimension, DataType>>(mesh, discrete_function->cellValues()); } template <typename MeshType, typename DiscreteFunctionT> std::shared_ptr<const DiscreteFunctionVariant> shallowCopy(const std::shared_ptr<const MeshType>& mesh, const DiscreteFunctionT& f) { const std::shared_ptr function_mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh()); if (mesh->shared_connectivity() != function_mesh->shared_connectivity()) { throw NormalError("cannot shallow copy when connectivity changes"); } if constexpr (std::is_same_v<MeshType, typename DiscreteFunctionT::MeshType>) { if constexpr (is_discrete_function_P0_v<DiscreteFunctionT>) { return std::make_shared<DiscreteFunctionVariant>(DiscreteFunctionT(mesh, f.cellValues())); } else if constexpr (is_discrete_function_P0_vector_v<DiscreteFunctionT>) { return std::make_shared<DiscreteFunctionVariant>(DiscreteFunctionT(mesh, f.cellArrays())); } else { throw UnexpectedError("invalid discrete function type"); } } else { throw UnexpectedError("invalid mesh types"); } } std::shared_ptr<const DiscreteFunctionVariant> shallowCopy(const std::shared_ptr<const IMesh>& mesh, const std::shared_ptr<const DiscreteFunctionVariant>& discrete_function_variant) { return std::visit( [&](auto&& f) { if (mesh == f.mesh()) { return discrete_function_variant; } else if (mesh->dimension() != f.mesh()->dimension()) { throw NormalError("incompatible mesh dimensions"); } switch (mesh->dimension()) { case 1: { return shallowCopy(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), f); } case 2: { return shallowCopy(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), f); } case 3: { return shallowCopy(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), f); } // LCOV_EXCL_START default: { throw UnexpectedError("invalid mesh dimension"); } // LCOV_EXCL_STOP } }, discrete_function_variant->discreteFunction()); }