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

Improve binary operators handling for DiscreteFunctionP0

- code is more generic
- handles properly mixture of const/non-const data types
parent c6efb5f0
No related branches found
No related tags found
1 merge request!89Add missing compatibility check when affecting lists to R^d or R^dxd
......@@ -50,6 +50,11 @@ class DiscreteFunctionP0 : public IDiscreteFunction
return m_discrete_function_descriptor;
}
operator DiscreteFunctionP0<Dimension, const DataType>() const
{
return DiscreteFunctionP0<Dimension, const DataType>(m_mesh, m_cell_values);
}
PUGS_INLINE
void
fill(const DataType& data) const noexcept
......@@ -65,72 +70,154 @@ class DiscreteFunctionP0 : public IDiscreteFunction
return m_cell_values[cell_id];
}
friend DiscreteFunctionP0
operator+(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
template <typename DataType2T>
PUGS_INLINE DiscreteFunctionP0<Dimension, decltype(DataType{} + DataType2T{})>
operator+(const DiscreteFunctionP0<Dimension, DataType2T>& g) const
{
const DiscreteFunctionP0& f = *this;
Assert(f.mesh() == g.mesh(), "functions are nor defined on the same mesh");
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0 sum(mesh);
DiscreteFunctionP0<Dimension, decltype(DataType{} + DataType2T{})> sum(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { sum[cell_id] = f[cell_id] + g[cell_id]; });
return sum;
}
friend DiscreteFunctionP0
operator-(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
template <typename LHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(LHSDataType{} + DataType{})>
operator+(const LHSDataType& a, const DiscreteFunctionP0& g)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(g.mesh());
using ProductDataType = decltype(LHSDataType{} + DataType{});
DiscreteFunctionP0<Dimension, ProductDataType> sum(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { sum[cell_id] = a + g[cell_id]; });
return sum;
}
template <typename RHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(DataType{} + RHSDataType{})>
operator+(const DiscreteFunctionP0& f, const RHSDataType& b)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
using ProductDataType = decltype(DataType{} + RHSDataType{});
DiscreteFunctionP0<Dimension, ProductDataType> sum(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { sum[cell_id] = f[cell_id] + b; });
return sum;
}
template <typename DataType2T>
PUGS_INLINE DiscreteFunctionP0<Dimension, decltype(DataType{} - DataType2T{})>
operator-(const DiscreteFunctionP0<Dimension, DataType2T>& g) const
{
const DiscreteFunctionP0& f = *this;
Assert(f.mesh() == g.mesh(), "functions are nor defined on the same mesh");
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0 difference(mesh);
DiscreteFunctionP0<Dimension, decltype(DataType{} - DataType2T{})> difference(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { difference[cell_id] = f[cell_id] - g[cell_id]; });
return difference;
}
friend DiscreteFunctionP0
operator*(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
template <typename LHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(LHSDataType{} - DataType{})>
operator-(const LHSDataType& a, const DiscreteFunctionP0& g)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(g.mesh());
using ProductDataType = decltype(LHSDataType{} - DataType{});
DiscreteFunctionP0<Dimension, ProductDataType> difference(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { difference[cell_id] = a - g[cell_id]; });
return difference;
}
template <typename RHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(DataType{} - RHSDataType{})>
operator-(const DiscreteFunctionP0& f, const RHSDataType& b)
{
Assert(f.mesh() == g.mesh(), "functions are nor defined on the same mesh");
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0 product(mesh);
using ProductDataType = decltype(DataType{} - RHSDataType{});
DiscreteFunctionP0<Dimension, ProductDataType> difference(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * g[cell_id]; });
return product;
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { difference[cell_id] = f[cell_id] - b; });
return difference;
}
template <typename DataType2T>
friend DiscreteFunctionP0<Dimension, decltype(DataType2T{} * DataType{})>
operator*(const DiscreteFunctionP0<Dimension, DataType2T>& f, const DiscreteFunctionP0& g)
PUGS_INLINE DiscreteFunctionP0<Dimension, decltype(DataType{} * DataType2T{})>
operator*(const DiscreteFunctionP0<Dimension, DataType2T>& g) const
{
const DiscreteFunctionP0& f = *this;
Assert(f.mesh() == g.mesh(), "functions are nor defined on the same mesh");
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, decltype(DataType2T{} * DataType{})> product(mesh);
DiscreteFunctionP0<Dimension, decltype(DataType{} * DataType2T{})> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * g[cell_id]; });
return product;
}
friend DiscreteFunctionP0
operator*(const double& a, const DiscreteFunctionP0& f)
template <typename LHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(LHSDataType{} * DataType{})>
operator*(const LHSDataType& a, const DiscreteFunctionP0& f)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0 product(mesh);
using ProductDataType = decltype(LHSDataType{} * DataType{});
DiscreteFunctionP0<Dimension, ProductDataType> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = a * f[cell_id]; });
return product;
}
friend DiscreteFunctionP0
operator/(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
template <typename RHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(DataType{} * RHSDataType{})>
operator*(const DiscreteFunctionP0& f, const RHSDataType& b)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
using ProductDataType = decltype(DataType{} * RHSDataType{});
DiscreteFunctionP0<Dimension, ProductDataType> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * b; });
return product;
}
template <typename DataType2T>
PUGS_INLINE DiscreteFunctionP0<Dimension, decltype(DataType{} / DataType2T{})>
operator/(const DiscreteFunctionP0<Dimension, DataType2T>& g) const
{
const DiscreteFunctionP0& f = *this;
Assert(f.mesh() == g.mesh(), "functions are nor defined on the same mesh");
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0 ratio(mesh);
DiscreteFunctionP0<Dimension, decltype(DataType{} / DataType2T{})> ratio(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { ratio[cell_id] = f[cell_id] / g[cell_id]; });
return ratio;
}
template <typename LHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(LHSDataType{} / DataType{})>
operator/(const LHSDataType& a, const DiscreteFunctionP0& f)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
using ProductDataType = decltype(LHSDataType{} / DataType{});
DiscreteFunctionP0<Dimension, ProductDataType> ratio(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { ratio[cell_id] = a / f[cell_id]; });
return ratio;
}
template <typename RHSDataType>
PUGS_INLINE friend DiscreteFunctionP0<Dimension, decltype(DataType{} / RHSDataType{})>
operator/(const DiscreteFunctionP0& f, const RHSDataType& b)
{
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
using ProductDataType = decltype(DataType{} / RHSDataType{});
DiscreteFunctionP0<Dimension, ProductDataType> ratio(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { ratio[cell_id] = f[cell_id] / b; });
return ratio;
}
DiscreteFunctionP0(const std::shared_ptr<const MeshType>& mesh, const FunctionSymbolId& function_id) : m_mesh(mesh)
{
using MeshDataType = MeshData<Dimension>;
......@@ -155,64 +242,4 @@ class DiscreteFunctionP0 : public IDiscreteFunction
~DiscreteFunctionP0() = default;
};
template <size_t Dimension, size_t ValueDimension>
DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>>
operator*(const TinyMatrix<ValueDimension>& A, const DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>>& f)
{
using MeshType = typename DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>>::MeshType;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = A * f[cell_id]; });
return product;
}
template <size_t Dimension, size_t ValueDimension>
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>
operator*(const TinyMatrix<ValueDimension>& A, const DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>& f)
{
using MeshType = typename DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>::MeshType;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = A * f[cell_id]; });
return product;
}
template <size_t Dimension, size_t ValueDimension>
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>
operator*(const DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>& f, const TinyMatrix<ValueDimension>& A)
{
using MeshType = typename DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>::MeshType;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * A; });
return product;
}
template <size_t Dimension, size_t ValueDimension>
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>
operator*(const DiscreteFunctionP0<Dimension, double>& f, const TinyMatrix<ValueDimension>& A)
{
using MeshType = typename DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>>::MeshType;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, TinyMatrix<ValueDimension>> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * A; });
return product;
}
template <size_t Dimension, size_t ValueDimension>
DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>>
operator*(const DiscreteFunctionP0<Dimension, double>& f, const TinyVector<ValueDimension>& A)
{
using MeshType = typename DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>>::MeshType;
std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(f.mesh());
DiscreteFunctionP0<Dimension, TinyVector<ValueDimension>> product(mesh);
parallel_for(
mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { product[cell_id] = f[cell_id] * A; });
return product;
}
#endif // DISCRETE_FUNCTION_P0_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment