Skip to content
Snippets Groups Projects
Commit e7129c30 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add ItemArray interpoler and plug it to the language

parent 05c9d061
Branches
Tags
1 merge request!166Feature/item array in pgs
......@@ -5,6 +5,7 @@
#include <language/utils/BinaryOperatorProcessorBuilder.hpp>
#include <language/utils/BuiltinFunctionEmbedder.hpp>
#include <language/utils/FunctionTable.hpp>
#include <language/utils/ItemArrayVariantFunctionInterpoler.hpp>
#include <language/utils/ItemValueVariantFunctionInterpoler.hpp>
#include <language/utils/OStream.hpp>
#include <language/utils/OperatorRepository.hpp>
......@@ -129,6 +130,17 @@ MeshModule::MeshModule()
));
this->_addBuiltinFunction(
"interpolate_array",
std::function(
[](std::shared_ptr<const IMesh> mesh, std::shared_ptr<const ItemType> item_type,
const std::vector<FunctionSymbolId>& function_id_list) -> std::shared_ptr<const ItemArrayVariant> {
return ItemArrayVariantFunctionInterpoler{mesh, *item_type, function_id_list}.interpolate();
}
));
this->_addBuiltinFunction("transform", std::function(
[](std::shared_ptr<const IMesh> p_mesh,
......
......@@ -28,6 +28,7 @@ add_library(PugsLanguageUtils
FunctionSymbolId.cpp
IncDecOperatorRegisterForN.cpp
IncDecOperatorRegisterForZ.cpp
ItemArrayVariantFunctionInterpoler.cpp
ItemValueVariantFunctionInterpoler.cpp
OFStream.cpp
OperatorRepository.cpp
......
#include <language/utils/ItemArrayVariantFunctionInterpoler.hpp>
#include <language/utils/InterpolateItemArray.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/ItemArrayVariant.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
#include <utils/Exceptions.hpp>
#include <memory>
template <size_t Dimension, typename DataType, typename ArrayType>
std::shared_ptr<ItemArrayVariant>
ItemArrayVariantFunctionInterpoler::_interpolate() const
{
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
using MeshDataType = MeshData<Dimension>;
switch (m_item_type) {
case ItemType::cell: {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
return std::make_shared<ItemArrayVariant>(
InterpolateItemArray<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id_list,
mesh_data.xj()));
}
case ItemType::face: {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
return std::make_shared<ItemArrayVariant>(
InterpolateItemArray<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::face>(m_function_id_list,
mesh_data.xl()));
}
case ItemType::edge: {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
return std::make_shared<ItemArrayVariant>(
InterpolateItemArray<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::edge>(m_function_id_list,
mesh_data.xe()));
}
case ItemType::node: {
return std::make_shared<ItemArrayVariant>(
InterpolateItemArray<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::node>(m_function_id_list,
p_mesh->xr()));
}
// LCOV_EXCL_START
default: {
throw UnexpectedError("invalid item type");
}
// LCOV_EXCL_STOP
}
}
template <size_t Dimension>
std::shared_ptr<ItemArrayVariant>
ItemArrayVariantFunctionInterpoler::_interpolate() const
{
const ASTNodeDataType data_type = [&] {
const auto& function0_descriptor = m_function_id_list[0].descriptor();
Assert(function0_descriptor.domainMappingNode().children[1]->m_data_type == ASTNodeDataType::typename_t);
ASTNodeDataType data_type = function0_descriptor.domainMappingNode().children[1]->m_data_type.contentType();
for (size_t i = 1; i < m_function_id_list.size(); ++i) {
const auto& function_descriptor = m_function_id_list[i].descriptor();
Assert(function_descriptor.domainMappingNode().children[1]->m_data_type == ASTNodeDataType::typename_t);
if (data_type != function_descriptor.domainMappingNode().children[1]->m_data_type.contentType()) {
throw NormalError("functions must have the same type");
}
}
return data_type;
}();
switch (data_type) {
case ASTNodeDataType::bool_t: {
return this->_interpolate<Dimension, bool>();
}
case ASTNodeDataType::unsigned_int_t: {
return this->_interpolate<Dimension, uint64_t>();
}
case ASTNodeDataType::int_t: {
return this->_interpolate<Dimension, int64_t>();
}
case ASTNodeDataType::double_t: {
return this->_interpolate<Dimension, double>();
}
case ASTNodeDataType::vector_t: {
switch (data_type.dimension()) {
case 1: {
return this->_interpolate<Dimension, TinyVector<1>>();
}
case 2: {
return this->_interpolate<Dimension, TinyVector<2>>();
}
case 3: {
return this->_interpolate<Dimension, TinyVector<3>>();
}
// LCOV_EXCL_START
default: {
std::ostringstream os;
os << "invalid vector dimension " << rang::fgB::red << data_type.dimension() << rang::style::reset;
throw UnexpectedError(os.str());
}
// LCOV_EXCL_STOP
}
}
case ASTNodeDataType::matrix_t: {
Assert(data_type.numberOfColumns() == data_type.numberOfRows(), "undefined matrix type");
switch (data_type.numberOfColumns()) {
case 1: {
return this->_interpolate<Dimension, TinyMatrix<1>>();
}
case 2: {
return this->_interpolate<Dimension, TinyMatrix<2>>();
}
case 3: {
return this->_interpolate<Dimension, TinyMatrix<3>>();
}
// LCOV_EXCL_START
default: {
std::ostringstream os;
os << "invalid vector dimension " << rang::fgB::red << data_type.dimension() << rang::style::reset;
throw UnexpectedError(os.str());
}
// LCOV_EXCL_STOP
}
}
// LCOV_EXCL_START
default: {
std::ostringstream os;
os << "invalid interpolation array type: " << rang::fgB::red << dataTypeName(data_type) << rang::style::reset;
throw UnexpectedError(os.str());
}
// LCOV_EXCL_STOP
}
}
std::shared_ptr<ItemArrayVariant>
ItemArrayVariantFunctionInterpoler::interpolate() const
{
switch (m_mesh->dimension()) {
case 1: {
return this->_interpolate<1>();
}
case 2: {
return this->_interpolate<2>();
}
case 3: {
return this->_interpolate<3>();
}
// LCOV_EXCL_START
default: {
throw UnexpectedError("invalid dimension");
}
// LCOV_EXCL_STOP
}
}
#ifndef ITEM_ARRAY_VARIANT_FUNCTION_INTERPOLER_HPP
#define ITEM_ARRAY_VARIANT_FUNCTION_INTERPOLER_HPP
#include <language/utils/FunctionSymbolId.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <mesh/ItemArrayVariant.hpp>
#include <mesh/ItemType.hpp>
class ItemArrayVariantFunctionInterpoler
{
private:
std::shared_ptr<const IMesh> m_mesh;
const ItemType m_item_type;
const std::vector<FunctionSymbolId> m_function_id_list;
template <size_t Dimension, typename DataType, typename ArrayType = DataType>
std::shared_ptr<ItemArrayVariant> _interpolate() const;
template <size_t Dimension>
std::shared_ptr<ItemArrayVariant> _interpolate() const;
public:
std::shared_ptr<ItemArrayVariant> interpolate() const;
ItemArrayVariantFunctionInterpoler(const std::shared_ptr<const IMesh>& mesh,
const ItemType& item_type,
const std::vector<FunctionSymbolId>& function_id_list)
: m_mesh{mesh}, m_item_type{item_type}, m_function_id_list{function_id_list}
{}
ItemArrayVariantFunctionInterpoler(const ItemArrayVariantFunctionInterpoler&) = delete;
ItemArrayVariantFunctionInterpoler(ItemArrayVariantFunctionInterpoler&&) = delete;
~ItemArrayVariantFunctionInterpoler() = default;
};
#endif // ITEM_ARRAY_VARIANT_FUNCTION_INTERPOLER_HPP
......@@ -60,13 +60,13 @@ ItemValueVariantFunctionInterpoler::_interpolate() const
switch (data_type) {
case ASTNodeDataType::bool_t: {
return this->_interpolate<Dimension, bool, double>();
return this->_interpolate<Dimension, bool>();
}
case ASTNodeDataType::unsigned_int_t: {
return this->_interpolate<Dimension, uint64_t, double>();
return this->_interpolate<Dimension, uint64_t>();
}
case ASTNodeDataType::int_t: {
return this->_interpolate<Dimension, int64_t, double>();
return this->_interpolate<Dimension, int64_t>();
}
case ASTNodeDataType::double_t: {
return this->_interpolate<Dimension, double>();
......
......@@ -179,6 +179,7 @@ add_executable (mpi_unit_tests
test_ItemArray.cpp
test_ItemArrayUtils.cpp
test_ItemArrayVariant.cpp
test_ItemArrayVariantFunctionInterpoler.cpp
test_ItemValue.cpp
test_ItemValueUtils.cpp
test_ItemValueVariant.cpp
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment