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

Add an optional zone(s) argument to interpolate functions

The values are set to 0 in cells that are not in the zone(s)
parent 53b1798c
No related branches found
No related tags found
1 merge request!138Fix a g++-9 warning
......@@ -11,6 +11,7 @@
#include <language/utils/TypeDescriptor.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/IBoundaryDescriptor.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
......@@ -158,6 +159,55 @@ SchemeModule::SchemeModule()
));
this->_addBuiltinFunction("interpolate",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(std::shared_ptr<const IMesh>,
const std::vector<std::shared_ptr<const IZoneDescriptor>>&,
std::shared_ptr<const IDiscreteFunctionDescriptor>,
const std::vector<FunctionSymbolId>&)>>(
[](std::shared_ptr<const IMesh> mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& interpolation_zone_list,
std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
const std::vector<FunctionSymbolId>& function_id_list)
-> std::shared_ptr<const IDiscreteFunction> {
return DiscreteFunctionVectorInterpoler{mesh, interpolation_zone_list,
discrete_function_descriptor, function_id_list}
.interpolate();
}
));
this->_addBuiltinFunction("interpolate",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(std::shared_ptr<const IMesh>,
const std::vector<std::shared_ptr<const IZoneDescriptor>>&,
std::shared_ptr<const IDiscreteFunctionDescriptor>,
const FunctionSymbolId&)>>(
[](std::shared_ptr<const IMesh> mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& interpolation_zone_list,
std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
const FunctionSymbolId& function_id) -> std::shared_ptr<const IDiscreteFunction> {
switch (discrete_function_descriptor->type()) {
case DiscreteFunctionType::P0: {
return DiscreteFunctionInterpoler{mesh, interpolation_zone_list,
discrete_function_descriptor, function_id}
.interpolate();
}
case DiscreteFunctionType::P0Vector: {
return DiscreteFunctionVectorInterpoler{mesh,
interpolation_zone_list,
discrete_function_descriptor,
{function_id}}
.interpolate();
}
default: {
throw NormalError("invalid function descriptor type");
}
}
}
));
this->_addBuiltinFunction("randomizeMesh",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IMesh>(std::shared_ptr<const IMesh>,
......
#include <scheme/DiscreteFunctionInterpoler.hpp>
#include <language/utils/InterpolateItemValue.hpp>
#include <mesh/MeshCellZone.hpp>
#include <scheme/DiscreteFunctionP0.hpp>
#include <utils/Exceptions.hpp>
template <size_t Dimension, typename DataType, typename ValueType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionInterpoler::_interpolate() const
DiscreteFunctionInterpoler::_interpolateOnZoneList() const
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
static_assert(std::is_convertible_v<DataType, ValueType>);
Assert(m_zone_list.size() > 0, "no zone list provided");
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
using MeshDataType = MeshData<Dimension>;
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
CellValue<bool> is_in_zone{p_mesh->connectivity()};
is_in_zone.fill(false);
size_t number_of_cells = 0;
for (const auto& zone : m_zone_list) {
auto mesh_cell_zone = getMeshCellZone(*p_mesh, *zone);
const auto& cell_list = mesh_cell_zone.cellList();
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
const CellId cell_id = cell_list[i_cell];
if (is_in_zone[cell_id]) {
std::ostringstream os;
os << "cell " << cell_id << " (number " << p_mesh->connectivity().cellNumber()[cell_id]
<< ") is present multiple times in zone list";
throw NormalError(os.str());
}
++number_of_cells;
is_in_zone[cell_id] = true;
}
}
Array<CellId> zone_cell_list{number_of_cells};
{
size_t i_cell = 0;
for (CellId cell_id = 0; cell_id < p_mesh->numberOfCells(); ++cell_id) {
if (is_in_zone[cell_id]) {
zone_cell_list[i_cell++] = cell_id;
}
}
}
Array<const DataType> array =
InterpolateItemValue<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id,
mesh_data.xj(),
zone_cell_list);
CellValue<ValueType> cell_value{p_mesh->connectivity()};
if constexpr (is_tiny_vector_v<ValueType> or is_tiny_matrix_v<ValueType>) {
cell_value.fill(zero);
} else {
cell_value.fill(0);
}
parallel_for(
zone_cell_list.size(), PUGS_LAMBDA(const size_t i_cell) { cell_value[zone_cell_list[i_cell]] = array[i_cell]; });
return std::make_shared<DiscreteFunctionP0<Dimension, ValueType>>(p_mesh, cell_value);
}
template <size_t Dimension, typename DataType, typename ValueType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionInterpoler::_interpolateGlobally() const
{
Assert(m_zone_list.size() == 0, "invalid call when zones are defined");
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
using MeshDataType = MeshData<Dimension>;
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
if constexpr (std::is_same_v<DataType, ValueType>) {
return std::make_shared<
DiscreteFunctionP0<Dimension, ValueType>>(mesh,
DiscreteFunctionP0<Dimension, ValueType>>(p_mesh,
InterpolateItemValue<DataType(TinyVector<Dimension>)>::
template interpolate<ItemType::cell>(m_function_id, mesh_data.xj()));
} else {
......@@ -24,12 +86,23 @@ DiscreteFunctionInterpoler::_interpolate() const
InterpolateItemValue<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id,
mesh_data.xj());
CellValue<ValueType> cell_value{mesh->connectivity()};
CellValue<ValueType> cell_value{p_mesh->connectivity()};
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { cell_value[cell_id] = cell_data[cell_id]; });
p_mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { cell_value[cell_id] = cell_data[cell_id]; });
return std::make_shared<DiscreteFunctionP0<Dimension, ValueType>>(mesh, cell_value);
return std::make_shared<DiscreteFunctionP0<Dimension, ValueType>>(p_mesh, cell_value);
}
}
template <size_t Dimension, typename DataType, typename ValueType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionInterpoler::_interpolate() const
{
if (m_zone_list.size() == 0) {
return this->_interpolateGlobally<Dimension, DataType, ValueType>();
} else {
return this->_interpolateOnZoneList<Dimension, DataType, ValueType>();
}
}
......
......@@ -3,6 +3,7 @@
#include <language/utils/FunctionSymbolId.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <scheme/IDiscreteFunction.hpp>
#include <scheme/IDiscreteFunctionDescriptor.hpp>
......@@ -12,9 +13,16 @@ class DiscreteFunctionInterpoler
{
private:
std::shared_ptr<const IMesh> m_mesh;
const std::vector<std::shared_ptr<const IZoneDescriptor>> m_zone_list;
std::shared_ptr<const IDiscreteFunctionDescriptor> m_discrete_function_descriptor;
const FunctionSymbolId m_function_id;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _interpolateOnZoneList() const;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _interpolateGlobally() const;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _interpolate() const;
......@@ -30,6 +38,16 @@ class DiscreteFunctionInterpoler
: m_mesh{mesh}, m_discrete_function_descriptor{discrete_function_descriptor}, m_function_id{function_id}
{}
DiscreteFunctionInterpoler(const std::shared_ptr<const IMesh>& mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& zone_list,
const std::shared_ptr<const IDiscreteFunctionDescriptor>& discrete_function_descriptor,
const FunctionSymbolId& function_id)
: m_mesh{mesh},
m_zone_list{zone_list},
m_discrete_function_descriptor{discrete_function_descriptor},
m_function_id{function_id}
{}
DiscreteFunctionInterpoler(const DiscreteFunctionInterpoler&) = delete;
DiscreteFunctionInterpoler(DiscreteFunctionInterpoler&&) = delete;
......
#include <scheme/DiscreteFunctionVectorInterpoler.hpp>
#include <language/utils/InterpolateItemArray.hpp>
#include <mesh/MeshCellZone.hpp>
#include <scheme/DiscreteFunctionP0Vector.hpp>
#include <utils/Exceptions.hpp>
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorInterpoler::_interpolate() const
DiscreteFunctionVectorInterpoler::_interpolateOnZoneList() const
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
Assert(m_zone_list.size() > 0, "no zone list provided");
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
using MeshDataType = MeshData<Dimension>;
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
CellValue<bool> is_in_zone{p_mesh->connectivity()};
is_in_zone.fill(false);
size_t number_of_cells = 0;
for (const auto& zone : m_zone_list) {
auto mesh_cell_zone = getMeshCellZone(*p_mesh, *zone);
const auto& cell_list = mesh_cell_zone.cellList();
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
const CellId cell_id = cell_list[i_cell];
if (is_in_zone[cell_id]) {
std::ostringstream os;
os << "cell " << cell_id << " (number " << p_mesh->connectivity().cellNumber()[cell_id]
<< ") is present multiple times in zone list";
throw NormalError(os.str());
}
++number_of_cells;
is_in_zone[cell_id] = true;
}
}
Array<CellId> zone_cell_list{number_of_cells};
{
size_t i_cell = 0;
for (CellId cell_id = 0; cell_id < p_mesh->numberOfCells(); ++cell_id) {
if (is_in_zone[cell_id]) {
zone_cell_list[i_cell++] = cell_id;
}
}
}
Table<const DataType> table =
InterpolateItemArray<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id_list,
mesh_data.xj(),
zone_cell_list);
CellArray<DataType> cell_array{p_mesh->connectivity(), m_function_id_list.size()};
cell_array.fill(0);
parallel_for(
zone_cell_list.size(), PUGS_LAMBDA(const size_t i_cell) {
for (size_t i = 0; i < table.numberOfColumns(); ++i) {
cell_array[zone_cell_list[i_cell]][i] = table(i_cell, i);
}
});
return std::make_shared<DiscreteFunctionP0Vector<Dimension, DataType>>(p_mesh, cell_array);
}
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorInterpoler::_interpolateGlobally() const
{
Assert(m_zone_list.size() == 0, "invalid call when zones are defined");
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
using MeshDataType = MeshData<Dimension>;
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*p_mesh);
return std::make_shared<
DiscreteFunctionP0Vector<Dimension, DataType>>(mesh, InterpolateItemArray<DataType(TinyVector<Dimension>)>::
DiscreteFunctionP0Vector<Dimension, DataType>>(p_mesh, InterpolateItemArray<DataType(TinyVector<Dimension>)>::
template interpolate<ItemType::cell>(m_function_id_list,
mesh_data.xj()));
}
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorInterpoler::_interpolate() const
{
if (m_zone_list.size() == 0) {
return this->_interpolateGlobally<Dimension, DataType>();
} else {
return this->_interpolateOnZoneList<Dimension, DataType>();
}
}
template <size_t Dimension>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorInterpoler::_interpolate() const
......
......@@ -3,6 +3,7 @@
#include <language/utils/FunctionSymbolId.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <scheme/IDiscreteFunction.hpp>
#include <scheme/IDiscreteFunctionDescriptor.hpp>
......@@ -13,9 +14,16 @@ class DiscreteFunctionVectorInterpoler
{
private:
std::shared_ptr<const IMesh> m_mesh;
const std::vector<std::shared_ptr<const IZoneDescriptor>> m_zone_list;
std::shared_ptr<const IDiscreteFunctionDescriptor> m_discrete_function_descriptor;
const std::vector<FunctionSymbolId> m_function_id_list;
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction> _interpolateOnZoneList() const;
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction> _interpolateGlobally() const;
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction> _interpolate() const;
......@@ -32,6 +40,17 @@ class DiscreteFunctionVectorInterpoler
: m_mesh{mesh}, m_discrete_function_descriptor{discrete_function_descriptor}, m_function_id_list{function_id_list}
{}
DiscreteFunctionVectorInterpoler(
const std::shared_ptr<const IMesh>& mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& zone_list,
const std::shared_ptr<const IDiscreteFunctionDescriptor>& discrete_function_descriptor,
const std::vector<FunctionSymbolId>& function_id_list)
: m_mesh{mesh},
m_zone_list{zone_list},
m_discrete_function_descriptor{discrete_function_descriptor},
m_function_id_list{function_id_list}
{}
DiscreteFunctionVectorInterpoler(const DiscreteFunctionVectorInterpoler&) = delete;
DiscreteFunctionVectorInterpoler(DiscreteFunctionVectorInterpoler&&) = delete;
......
......@@ -158,9 +158,11 @@ add_executable (mpi_unit_tests
mpi_test_main.cpp
test_Connectivity.cpp
test_DiscreteFunctionInterpoler.cpp
test_DiscreteFunctionInterpolerByZone.cpp
test_DiscreteFunctionP0.cpp
test_DiscreteFunctionP0Vector.cpp
test_DiscreteFunctionVectorInterpoler.cpp
test_DiscreteFunctionVectorInterpolerByZone.cpp
test_EmbeddedIDiscreteFunctionMathFunctions.cpp
test_EmbeddedIDiscreteFunctionOperators.cpp
test_InterpolateItemArray.cpp
......
This diff is collapsed.
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