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

Add an optional zone(s) argument to integrate functions

parent 39ecc278
No related branches found
No related tags found
1 merge request!138Fix a g++-9 warning
......@@ -91,6 +91,27 @@ SchemeModule::SchemeModule()
));
this->_addBuiltinFunction("integrate",
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 IQuadratureDescriptor>,
std::shared_ptr<const IDiscreteFunctionDescriptor>,
const std::vector<FunctionSymbolId>&)>>(
[](std::shared_ptr<const IMesh> mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& integration_zone_list,
std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
const std::vector<FunctionSymbolId>& function_id_list)
-> std::shared_ptr<const IDiscreteFunction> {
return DiscreteFunctionVectorIntegrator{mesh, integration_zone_list,
quadrature_descriptor,
discrete_function_descriptor, function_id_list}
.integrate();
}
));
this
->_addBuiltinFunction("integrate",
std::make_shared<BuiltinFunctionEmbedder<
......@@ -110,6 +131,20 @@ SchemeModule::SchemeModule()
));
this->_addBuiltinFunction(
"integrate",
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 IQuadratureDescriptor>, const FunctionSymbolId&)>>(
[](std::shared_ptr<const IMesh> mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& integration_zone_list,
std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
const FunctionSymbolId& function_id) -> std::shared_ptr<const IDiscreteFunction> {
return DiscreteFunctionIntegrator{mesh, integration_zone_list, quadrature_descriptor, function_id}.integrate();
}
));
this->_addBuiltinFunction("integrate",
std::make_shared<BuiltinFunctionEmbedder<
std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IMesh>,
......@@ -136,6 +171,24 @@ 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<
......@@ -159,24 +212,6 @@ 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>,
......
#include <scheme/DiscreteFunctionIntegrator.hpp>
#include <language/utils/IntegrateCellValue.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>
DiscreteFunctionIntegrator::_integrate() const
DiscreteFunctionIntegrator::_integrateOnZoneList() const
{
static_assert(std::is_convertible_v<DataType, ValueType>);
Assert(m_zone_list.size() > 0, "no zone list provided");
using MeshType = Mesh<Connectivity<Dimension>>;
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(m_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<DataType> array =
IntegrateCellValue<DataType(TinyVector<Dimension>)>::template integrate<MeshType>(m_function_id,
*m_quadrature_descriptor, *p_mesh,
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>
DiscreteFunctionIntegrator::_integrateGlobally() const
{
Assert(m_zone_list.size() == 0, "invalid call when zones are defined");
using MeshType = Mesh<Connectivity<Dimension>>;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(m_mesh);
......@@ -33,6 +95,17 @@ DiscreteFunctionIntegrator::_integrate() const
}
}
template <size_t Dimension, typename DataType, typename ValueType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionIntegrator::_integrate() const
{
if (m_zone_list.size() == 0) {
return this->_integrateGlobally<Dimension, DataType, ValueType>();
} else {
return this->_integrateOnZoneList<Dimension, DataType, ValueType>();
}
}
template <size_t Dimension>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionIntegrator::_integrate() const
......
......@@ -4,6 +4,7 @@
#include <analysis/IQuadratureDescriptor.hpp>
#include <language/utils/FunctionSymbolId.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <scheme/IDiscreteFunction.hpp>
#include <memory>
......@@ -12,9 +13,16 @@ class DiscreteFunctionIntegrator
{
private:
std::shared_ptr<const IMesh> m_mesh;
const std::vector<std::shared_ptr<const IZoneDescriptor>> m_zone_list;
std::shared_ptr<const IQuadratureDescriptor> m_quadrature_descriptor;
const FunctionSymbolId m_function_id;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _integrateOnZoneList() const;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _integrateGlobally() const;
template <size_t Dimension, typename DataType, typename ValueType = DataType>
std::shared_ptr<IDiscreteFunction> _integrate() const;
......@@ -30,6 +38,13 @@ class DiscreteFunctionIntegrator
: m_mesh{mesh}, m_quadrature_descriptor{quadrature_descriptor}, m_function_id{function_id}
{}
DiscreteFunctionIntegrator(const std::shared_ptr<const IMesh>& mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& zone_list,
const std::shared_ptr<const IQuadratureDescriptor>& quadrature_descriptor,
const FunctionSymbolId& function_id)
: m_mesh{mesh}, m_zone_list{zone_list}, m_quadrature_descriptor{quadrature_descriptor}, m_function_id{function_id}
{}
DiscreteFunctionIntegrator(const DiscreteFunctionIntegrator&) = delete;
DiscreteFunctionIntegrator(DiscreteFunctionIntegrator&&) = delete;
......
#include <scheme/DiscreteFunctionVectorIntegrator.hpp>
#include <language/utils/IntegrateCellArray.hpp>
#include <mesh/MeshCellZone.hpp>
#include <scheme/DiscreteFunctionP0Vector.hpp>
#include <utils/Exceptions.hpp>
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorIntegrator::_integrate() const
DiscreteFunctionVectorIntegrator::_integrateOnZoneList() const
{
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);
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 =
IntegrateCellArray<DataType(TinyVector<Dimension>)>::template integrate(m_function_id_list,
*m_quadrature_descriptor, *p_mesh,
zone_cell_list);
CellArray<DataType> cell_array{p_mesh->connectivity(), m_function_id_list.size()};
if constexpr (is_tiny_vector_v<DataType> or is_tiny_matrix_v<DataType>) {
cell_array.fill(zero);
} else {
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>
DiscreteFunctionVectorIntegrator::_integrateGlobally() const
{
Assert(m_zone_list.size() == 0, "invalid call when zones are defined");
std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(m_mesh);
return std::make_shared<
......@@ -17,6 +79,17 @@ DiscreteFunctionVectorIntegrator::_integrate() const
*m_quadrature_descriptor, *mesh));
}
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorIntegrator::_integrate() const
{
if (m_zone_list.size() == 0) {
return this->_integrateGlobally<Dimension, DataType>();
} else {
return this->_integrateOnZoneList<Dimension, DataType>();
}
}
template <size_t Dimension>
std::shared_ptr<IDiscreteFunction>
DiscreteFunctionVectorIntegrator::_integrate() const
......
......@@ -4,6 +4,7 @@
#include <analysis/IQuadratureDescriptor.hpp>
#include <language/utils/FunctionSymbolId.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/IZoneDescriptor.hpp>
#include <scheme/IDiscreteFunction.hpp>
#include <scheme/IDiscreteFunctionDescriptor.hpp>
......@@ -14,10 +15,17 @@ class DiscreteFunctionVectorIntegrator
{
private:
std::shared_ptr<const IMesh> m_mesh;
const std::vector<std::shared_ptr<const IZoneDescriptor>> m_zone_list;
std::shared_ptr<const IQuadratureDescriptor> m_quadrature_descriptor;
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> _integrateOnZoneList() const;
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction> _integrateGlobally() const;
template <size_t Dimension, typename DataType>
std::shared_ptr<IDiscreteFunction> _integrate() const;
......@@ -38,6 +46,19 @@ class DiscreteFunctionVectorIntegrator
m_function_id_list{function_id_list}
{}
DiscreteFunctionVectorIntegrator(
const std::shared_ptr<const IMesh>& mesh,
const std::vector<std::shared_ptr<const IZoneDescriptor>>& zone_list,
const std::shared_ptr<const IQuadratureDescriptor>& quadrature_descriptor,
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_quadrature_descriptor(quadrature_descriptor),
m_discrete_function_descriptor{discrete_function_descriptor},
m_function_id_list{function_id_list}
{}
DiscreteFunctionVectorIntegrator(const DiscreteFunctionVectorIntegrator&) = delete;
DiscreteFunctionVectorIntegrator(DiscreteFunctionVectorIntegrator&&) = delete;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment