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

Add dot product for DiscreteFunctionP0 of R^d values

parent 363a98af
No related branches found
No related tags found
1 merge request!90Add access to cells' volume of a mesh in the script file
......@@ -147,4 +147,54 @@ MathFunctionRegisterForVh::MathFunctionRegisterForVh(SchemeModule& scheme_module
std::shared_ptr<const IDiscreteFunction>)>>(
[](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<
std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
std::shared_ptr<const IDiscreteFunction>)>>(
[](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<1>)>>(
[](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<1> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<2>)>>(
[](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<2> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<3>&)>>(
[](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<3>& b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(const TinyVector<1>, std::shared_ptr<const IDiscreteFunction>)>>(
[](const TinyVector<1> a, std::shared_ptr<const IDiscreteFunction> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(const TinyVector<2>, std::shared_ptr<const IDiscreteFunction>)>>(
[](const TinyVector<2> a, std::shared_ptr<const IDiscreteFunction> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
scheme_module
._addBuiltinFunction("dot",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IDiscreteFunction>(const TinyVector<3>&, std::shared_ptr<const IDiscreteFunction>)>>(
[](const TinyVector<3>& a, std::shared_ptr<const IDiscreteFunction> b)
-> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
}
......@@ -27,7 +27,7 @@
} \
} \
} else { \
throw UnexpectedError("invalid operand type " + operand_type_name(ARG)); \
throw NormalError("invalid operand type " + operand_type_name(ARG)); \
}
std::shared_ptr<const IDiscreteFunction>
......@@ -82,7 +82,7 @@ std::shared_ptr<const IDiscreteFunction>
atan2(const std::shared_ptr<const IDiscreteFunction>& f, const std::shared_ptr<const IDiscreteFunction>& g)
{
if ((f->dataType() == ASTNodeDataType::double_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType() == ASTNodeDataType::double_t and g->descriptor().type() == DiscreteFunctionType::P0)) {
(g->dataType() == ASTNodeDataType::double_t and g->descriptor().type() == DiscreteFunctionType::P0)) {
std::shared_ptr mesh = getCommonMesh({f, g});
if (mesh.use_count() == 0) {
......@@ -111,7 +111,7 @@ atan2(const std::shared_ptr<const IDiscreteFunction>& f, const std::shared_ptr<c
}
} else {
std::stringstream os;
os << "incompatible operand types " << operand_type_name(f) << " and " << operand_type_name(g);
os << "incompatible operands type " << operand_type_name(f) << " and " << operand_type_name(g);
throw NormalError(os.str());
}
}
......@@ -138,7 +138,9 @@ atan2(const double a, const std::shared_ptr<const IDiscreteFunction>& f)
}
}
} else {
throw UnexpectedError("invalid operand type " + operand_type_name(f));
std::stringstream os;
os << "incompatible operands type " << operand_type_name(a) << " and " << operand_type_name(f);
throw NormalError(os.str());
}
}
......@@ -164,7 +166,9 @@ atan2(const std::shared_ptr<const IDiscreteFunction>& f, const double a)
}
}
} else {
throw UnexpectedError("invalid operand type " + operand_type_name(f));
std::stringstream os;
os << "incompatible operands type " << operand_type_name(f) << " and " << operand_type_name(a);
throw NormalError(os.str());
}
}
......@@ -220,7 +224,7 @@ std::shared_ptr<const IDiscreteFunction>
pow(const std::shared_ptr<const IDiscreteFunction>& f, const std::shared_ptr<const IDiscreteFunction>& g)
{
if ((f->dataType() == ASTNodeDataType::double_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType() == ASTNodeDataType::double_t and g->descriptor().type() == DiscreteFunctionType::P0)) {
(g->dataType() == ASTNodeDataType::double_t and g->descriptor().type() == DiscreteFunctionType::P0)) {
std::shared_ptr mesh = getCommonMesh({f, g});
if (mesh.use_count() == 0) {
......@@ -276,7 +280,9 @@ pow(const double a, const std::shared_ptr<const IDiscreteFunction>& f)
}
}
} else {
throw UnexpectedError("invalid operand type " + operand_type_name(f));
std::stringstream os;
os << "incompatible operand types " << operand_type_name(a) << " and " << operand_type_name(f);
throw NormalError(os.str());
}
}
......@@ -302,6 +308,174 @@ pow(const std::shared_ptr<const IDiscreteFunction>& f, const double a)
}
}
} else {
throw UnexpectedError("invalid operand type " + operand_type_name(f));
std::stringstream os;
os << "incompatible operand types " << operand_type_name(f) << " and " << operand_type_name(a);
throw NormalError(os.str());
}
}
template <size_t Dimension>
std::shared_ptr<const IDiscreteFunction>
dot(const std::shared_ptr<const IDiscreteFunction>& f, const std::shared_ptr<const IDiscreteFunction>& g)
{
Assert((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(g->dataType() == ASTNodeDataType::vector_t and g->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == g->dataType().dimension()));
using DiscreteFunctionResultType = DiscreteFunctionP0<Dimension, double>;
switch (f->dataType().dimension()) {
case 1: {
using Rd = TinyVector<1>;
using DiscreteFunctionType = DiscreteFunctionP0<Dimension, Rd>;
return std::make_shared<const DiscreteFunctionResultType>(
dot(dynamic_cast<const DiscreteFunctionType&>(*f), dynamic_cast<const DiscreteFunctionType&>(*g)));
}
case 2: {
using Rd = TinyVector<2>;
using DiscreteFunctionType = DiscreteFunctionP0<Dimension, Rd>;
return std::make_shared<const DiscreteFunctionResultType>(
dot(dynamic_cast<const DiscreteFunctionType&>(*f), dynamic_cast<const DiscreteFunctionType&>(*g)));
}
case 3: {
using Rd = TinyVector<3>;
using DiscreteFunctionType = DiscreteFunctionP0<Dimension, Rd>;
return std::make_shared<const DiscreteFunctionResultType>(
dot(dynamic_cast<const DiscreteFunctionType&>(*f), dynamic_cast<const DiscreteFunctionType&>(*g)));
}
default: {
throw UnexpectedError("invalid data dimension " + operand_type_name(f));
}
}
}
std::shared_ptr<const IDiscreteFunction>
dot(const std::shared_ptr<const IDiscreteFunction>& f, const std::shared_ptr<const IDiscreteFunction>& g)
{
if ((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(g->dataType() == ASTNodeDataType::vector_t and g->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == g->dataType().dimension())) {
std::shared_ptr mesh = getCommonMesh({f, g});
if (mesh.use_count() == 0) {
throw NormalError("operands are defined on different meshes");
}
switch (mesh->dimension()) {
case 1: {
return dot<1>(f, g);
}
case 2: {
return dot<2>(f, g);
}
case 3: {
return dot<3>(f, g);
}
default: {
throw UnexpectedError("invalid mesh dimension");
}
}
} else {
std::stringstream os;
os << "incompatible operand types " << operand_type_name(f) << " and " << operand_type_name(g);
throw NormalError(os.str());
}
}
template <size_t Dimension, size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction>
dot(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<VectorDimension>& a)
{
Assert((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == a.dimension()));
using DiscreteFunctionResultType = DiscreteFunctionP0<Dimension, double>;
using DiscreteFunctionType = DiscreteFunctionP0<Dimension, TinyVector<VectorDimension>>;
return std::make_shared<const DiscreteFunctionResultType>(dot(dynamic_cast<const DiscreteFunctionType&>(*f), a));
}
template <size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction>
dot(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<VectorDimension>& a)
{
if ((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == a.dimension())) {
switch (f->mesh()->dimension()) {
case 1: {
return dot<1, VectorDimension>(f, a);
}
case 2: {
return dot<2, VectorDimension>(f, a);
}
case 3: {
return dot<3, VectorDimension>(f, a);
}
default: {
throw UnexpectedError("invalid mesh dimension");
}
}
} else {
std::stringstream os;
os << "incompatible operand types " << operand_type_name(f) << " and " << operand_type_name(a);
throw NormalError(os.str());
}
}
template <size_t Dimension, size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction>
dot(const TinyVector<VectorDimension>& a, const std::shared_ptr<const IDiscreteFunction>& f)
{
Assert((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == a.dimension()));
using DiscreteFunctionResultType = DiscreteFunctionP0<Dimension, double>;
using DiscreteFunctionType = DiscreteFunctionP0<Dimension, TinyVector<VectorDimension>>;
return std::make_shared<const DiscreteFunctionResultType>(dot(a, dynamic_cast<const DiscreteFunctionType&>(*f)));
}
template <size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction>
dot(const TinyVector<VectorDimension>& a, const std::shared_ptr<const IDiscreteFunction>& f)
{
if ((f->dataType() == ASTNodeDataType::vector_t and f->descriptor().type() == DiscreteFunctionType::P0) and
(f->dataType().dimension() == a.dimension())) {
switch (f->mesh()->dimension()) {
case 1: {
return dot<1, VectorDimension>(a, f);
}
case 2: {
return dot<2, VectorDimension>(a, f);
}
case 3: {
return dot<3, VectorDimension>(a, f);
}
default: {
throw UnexpectedError("invalid mesh dimension");
}
}
} else {
std::stringstream os;
os << "incompatible operand types " << operand_type_name(a) << " and " << operand_type_name(f);
throw NormalError(os.str());
}
}
template std::shared_ptr<const IDiscreteFunction> dot(const std::shared_ptr<const IDiscreteFunction>&,
const TinyVector<1>&);
template std::shared_ptr<const IDiscreteFunction> dot(const std::shared_ptr<const IDiscreteFunction>&,
const TinyVector<2>&);
template std::shared_ptr<const IDiscreteFunction> dot(const std::shared_ptr<const IDiscreteFunction>&,
const TinyVector<3>&);
template std::shared_ptr<const IDiscreteFunction> dot(const TinyVector<1>&,
const std::shared_ptr<const IDiscreteFunction>&);
template std::shared_ptr<const IDiscreteFunction> dot(const TinyVector<2>&,
const std::shared_ptr<const IDiscreteFunction>&);
template std::shared_ptr<const IDiscreteFunction> dot(const TinyVector<3>&,
const std::shared_ptr<const IDiscreteFunction>&);
......@@ -54,4 +54,15 @@ std::shared_ptr<const IDiscreteFunction> pow(const double, const std::shared_ptr
std::shared_ptr<const IDiscreteFunction> pow(const std::shared_ptr<const IDiscreteFunction>&, const double);
std::shared_ptr<const IDiscreteFunction> dot(const std::shared_ptr<const IDiscreteFunction>&,
const std::shared_ptr<const IDiscreteFunction>&);
template <size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction> dot(const std::shared_ptr<const IDiscreteFunction>&,
const TinyVector<VectorDimension>&);
template <size_t VectorDimension>
std::shared_ptr<const IDiscreteFunction> dot(const TinyVector<VectorDimension>&,
const std::shared_ptr<const IDiscreteFunction>&);
#endif // EMBEDDED_I_DISCRETE_FUNCTION_MATH_FUNCTIONS_HPP
......@@ -523,6 +523,42 @@ class DiscreteFunctionP0 : public IDiscreteFunction
return result;
}
PUGS_INLINE friend DiscreteFunctionP0<Dimension, double>
dot(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
{
static_assert(is_tiny_vector_v<DataType>);
Assert(f.m_cell_values.isBuilt() and g.m_cell_values.isBuilt());
DiscreteFunctionP0<Dimension, double> result{f.m_mesh};
parallel_for(
f.m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { result[cell_id] = dot(f[cell_id], g[cell_id]); });
return result;
}
PUGS_INLINE friend DiscreteFunctionP0<Dimension, double>
dot(const DiscreteFunctionP0& f, const DataType& a)
{
static_assert(is_tiny_vector_v<DataType>);
Assert(f.m_cell_values.isBuilt());
DiscreteFunctionP0<Dimension, double> result{f.m_mesh};
parallel_for(
f.m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { result[cell_id] = dot(f[cell_id], a); });
return result;
}
PUGS_INLINE friend DiscreteFunctionP0<Dimension, double>
dot(const DataType& a, const DiscreteFunctionP0& f)
{
static_assert(is_tiny_vector_v<DataType>);
Assert(f.m_cell_values.isBuilt());
DiscreteFunctionP0<Dimension, double> result{f.m_mesh};
parallel_for(
f.m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { result[cell_id] = dot(a, f[cell_id]); });
return result;
}
DiscreteFunctionP0(const std::shared_ptr<const MeshType>& mesh) : m_mesh{mesh}, m_cell_values{mesh->connectivity()} {}
DiscreteFunctionP0(const std::shared_ptr<const MeshType>& mesh, const CellValue<DataType>& cell_value)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment