Commit 57881afd authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#1718 PiecewiseConstantByDomain Parameter: the check about shapes is now properly implemented.

parent 77bfc06e
/*!
//
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Mon, 18 May 2015 14:55:40 +0200
//
// \ingroup ParametersGroup
// \addtogroup ParametersGroup
// \{
*/
#ifndef MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HPP_
#define MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HPP_
#include "Utilities/MatrixOrVector.hpp"
#include "Parameters/Internal/Traits.hpp"
#include "Parameters/Policy/PiecewiseConstantByDomain/Exceptions/PiecewiseConstantByDomain.hpp" // IWYU pragma: export
namespace MoReFEM::Internal::ParameterNS::PiecewiseConstantByDomainNS
{
/*!
* \brief Check the values associated to all the \a Domain all share the same shapes.
*
* Obviously this make sense only for \a Type::vector and \a Type::matrix cases; in \a Type::scalar nothing is done.
* If the shapes aren't the same, an exception is thrown (namely
* \a ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalVectorShape or
* \a ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalMatrixShape).
*
* \param[in] storage The data given in input at \a Parameter construction used to fill the values \a Parameter takes in the different \a Domain s
* (key is the unique identifier of \a Domain).
* \param[in] parameter_name Name of the \a Parameter for which the issue arose (as given in its constructor).
* \copydoc doxygen_hide_invoking_file_and_line
*/
template<Type TypeT>
void CheckShapeConsistency(const std::map<std::size_t, typename Traits<TypeT>::decayed_return_type>& storage,
std::string_view parameter_name,
const char* invoking_file,
int invoking_line);
} // namespace MoReFEM::Internal::ParameterNS::PiecewiseConstantByDomainNS
/// @} // addtogroup ParametersGroup
#include "Parameters/Policy/PiecewiseConstantByDomain/Internal/Helper.hxx" // IWYU pragma: export
#endif // MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HPP_
/*!
//
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Mon, 18 May 2015 14:55:40 +0200
//
// \ingroup ParametersGroup
// \addtogroup ParametersGroup
// \{
*/
#ifndef MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HXX_
#define MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HXX_
// IWYU pragma: private, include "Parameters/Policy/PiecewiseConstantByDomain/Internal/Helper.hpp"
#include "Parameters/Policy/PiecewiseConstantByDomain/Exceptions/PiecewiseConstantByDomain.hpp" // IWYU pragma: export
namespace MoReFEM::Internal::ParameterNS::PiecewiseConstantByDomainNS
{
template<Type TypeT>
void CheckShapeConsistency(const std::map<std::size_t, typename Traits<TypeT>::decayed_return_type>& storage,
std::string_view parameter_name,
const char* invoking_file,
int invoking_line)
{
if (storage.empty()) // weird case, but not the place to handle it.
return;
if constexpr(TypeT == Type::scalar)
;
else if constexpr(TypeT == Type::vector)
{
using ::MoReFEM::ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalVectorShape;
const auto& first_shape = storage.cbegin()->second.shape();
if (!std::all_of(storage.cbegin(),
storage.cend(),
[&first_shape](const auto& item)
{
const auto& [domain_id, vector] = item;
return vector.shape() == first_shape;
}))
throw InconsistentLocalVectorShape(storage,
parameter_name,
invoking_file,
invoking_line);
}
else if constexpr(TypeT == Type::matrix)
{
using ::MoReFEM::ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalMatrixShape;
const auto& first_shape = storage.cbegin()->second.shape();
if (!std::all_of(storage.cbegin(),
storage.cend(),
[&first_shape](const auto& item)
{
const auto& [domain_id, matrix] = item;
return matrix.shape() == first_shape;
}))
throw InconsistentLocalMatrixShape(storage,
parameter_name,
invoking_file,
invoking_line);
}
else
{
assert(false && "Case not foreseen. If a new type is added in the enum please add it in the "
"cases handled above.");
exit(EXIT_FAILURE);
}
}
} // namespace MoReFEM::Internal::ParameterNS::PiecewiseConstantByDomainNS
/// @} // addtogroup ParametersGroup
#include "Parameters/Policy/PiecewiseConstantByDomain/Internal/Helper.hxx" // IWYU pragma: export
#endif // MOREFEM_x_PARAMETERS_x_POLICY_x_PIECEWISE_CONSTANT_BY_DOMAIN_x_INTERNAL_x_HELPER_HXX_
### ===================================================================================
### This file is generated automatically by Scripts/generate_cmake_source_list.py.
### Do not edit it manually!
### Convention is that:
### - When a CMake file is manually managed, it is named canonically CMakeLists.txt.
###. - When it is generated automatically, it is named SourceList.cmake.
### ===================================================================================
target_sources(${MOREFEM_PARAM}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/Helper.hpp
${CMAKE_CURRENT_LIST_DIR}/Helper.hxx
${CMAKE_CURRENT_LIST_DIR}/SourceList.cmake
)
......@@ -4,7 +4,7 @@
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Mon, 18 May 2015 14:55:40 +0200
// Copyright (c) Inria. All rights reserved.
/Users/sebastien/Codes/MoReFEM/CoreLibrary// Copyright (c) Inria. All rights reserved.
//
// \ingroup ParametersGroup
// \addtogroup ParametersGroup
......@@ -167,8 +167,8 @@ namespace MoReFEM
*/
mapping_geom_elt_domain_type mapping_geom_elt_domain_;
};
} // namespace Policy
......
......@@ -21,6 +21,8 @@
#include "Utilities/Containers/UnorderedMap.hpp"
#include "Parameters/Policy/PiecewiseConstantByDomain/Internal/Helper.hpp"
namespace MoReFEM::ParameterNS::Policy
{
......@@ -34,6 +36,10 @@ namespace MoReFEM::ParameterNS::Policy
{
auto& mapping_geom_elt_domain = GetNonCstMapGeomEltDomain();
mapping_geom_elt_domain.max_load_factor(Utilities::DefaultMaxLoadFactor());
Internal::ParameterNS::PiecewiseConstantByDomainNS::CheckShapeConsistency<TypeT>(value,
name,
__FILE__, __LINE__);
decltype(auto) mesh = domain.GetMesh();
......
......@@ -16,3 +16,4 @@ target_sources(${MOREFEM_PARAM}
)
include(${CMAKE_CURRENT_LIST_DIR}/Exceptions/SourceList.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/Internal/SourceList.cmake)
......@@ -72,7 +72,7 @@ BOOST_FIXTURE_TEST_CASE(scalar, fixture_type)
>;
// clang-format on
parameter_type param1("parameter1", full_domain, 500.);
parameter_type param1("scalar_parameter", full_domain, 500.);
BOOST_CHECK_PREDICATE(NumericNS::AreEqual<double>, (param1.GetConstantValue())(500.)(epsilon));
......@@ -125,7 +125,7 @@ BOOST_FIXTURE_TEST_CASE(vector, fixture_type)
BOOST_REQUIRE_EQUAL(shape.size(), 1ul);
parameter_type param1("parameter1", full_domain, constant_value);
parameter_type param1("vector_parameter", full_domain, constant_value);
{
decltype(auto) read_constant_value = param1.GetConstantValue();
......@@ -181,7 +181,7 @@ BOOST_FIXTURE_TEST_CASE(matrix, fixture_type)
LocalMatrix constant_value { { 1., -0.5, 2., 4.21 }, { 2., -1.24, 0.54, 1.47 } };
parameter_type param1("parameter1", full_domain, constant_value);
parameter_type param1("matrix_parameter", full_domain, constant_value);
const auto shape = constant_value.shape();
......
......@@ -143,7 +143,7 @@ BOOST_FIXTURE_TEST_CASE(inconsistent_shape_for_vectors, fixture_type)
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad3), LocalVector { 1.2, 4. } }
};
BOOST_CHECK_THROW(std::make_unique<parameter_type>("param",
BOOST_CHECK_THROW(std::make_unique<parameter_type>("vector_with_inconsistent_shapes",
full_domain,
value_by_domain),
ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalVectorShape);
......@@ -176,10 +176,10 @@ BOOST_FIXTURE_TEST_CASE(inconsistent_shape_for_matrices, fixture_type)
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad3), LocalMatrix { { 1.2, 4. }, { -4., -1.2 } } }
};
BOOST_CHECK_THROW(std::make_unique<parameter_type>("param",
BOOST_CHECK_THROW(std::make_unique<parameter_type>("matrix_with_inconsistent_shapes",
full_domain,
value_by_domain),
ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalVectorShape);
ExceptionNS::ParameterNS::PiecewiseConstantByDomainNS::InconsistentLocalMatrixShape);
}
......@@ -209,7 +209,7 @@ BOOST_FIXTURE_TEST_CASE(scalar, fixture_type)
};
parameter_type param1("parameter1", full_domain, value_by_domain);
parameter_type param1("scalar_parameter", full_domain, value_by_domain);
decltype(auto) mesh_manager = Internal::MeshNS::MeshManager::GetInstance(__FILE__, __LINE__);
decltype(auto) mesh = mesh_manager.GetMesh(EnumUnderlyingType(MeshIndex::mesh));
......@@ -274,13 +274,13 @@ BOOST_FIXTURE_TEST_CASE(vector, fixture_type)
std::map<std::size_t, LocalVector> value_by_domain
{
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad1), LocalVector { 1., -0.5, 2., 4.21 } },
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad1), LocalVector { 1., -0.5, 4.21 } },
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad2), LocalVector { 10., 2., 5. } },
{ EnumUnderlyingType(TestNS::HardcodedConstructionNS::DomainIndex::quad3), LocalVector { -1., -7.5, 2. } }
};
parameter_type param1("parameter1", full_domain, value_by_domain);
parameter_type param1("vector_parameter", full_domain, value_by_domain);
decltype(auto) mesh_manager = Internal::MeshNS::MeshManager::GetInstance(__FILE__, __LINE__);
decltype(auto) mesh = mesh_manager.GetMesh(EnumUnderlyingType(MeshIndex::mesh));
......@@ -350,7 +350,7 @@ BOOST_FIXTURE_TEST_CASE(matrix, fixture_type)
};
parameter_type param1("parameter1", full_domain, value_by_domain);
parameter_type param1("matrix_parameter", full_domain, value_by_domain);
decltype(auto) mesh_manager = Internal::MeshNS::MeshManager::GetInstance(__FILE__, __LINE__);
decltype(auto) mesh = mesh_manager.GetMesh(EnumUnderlyingType(MeshIndex::mesh));
......
......@@ -28,7 +28,6 @@ namespace MoReFEM
//! Convenient alias for the type used most of the time in MoReFEM for local matrices.
using LocalMatrix = xt::xtensor<double, 2, xt::layout_type::row_major>;
//! Convenient enum class.
enum class IsMatrixOrVector { vector, matrix };
......
......@@ -14,5 +14,6 @@ target_sources(${MOREFEM_UTILITIES}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/Numeric.hpp
${CMAKE_CURRENT_LIST_DIR}/SourceList.cmake
)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment