Skip to content

Fix cast of vector-valued function to array of scalar-valued functions #12

Description

@akoshakji

In commit 92c9615, the factory for a field where the gradient is a vector and the cast of a vector-valued function to an array of scalar-valued functions were removed. This is because the test in tests/fields was producing undefined behavior when a scalar field was instantiated by passing the gradient as a vector:

auto Df = mito::math::function([](const vector_t<2> & x) -> vector_t<2> {
    return { -sin(x[0] * x[1]) * x[1], -sin(x[0] * x[1]) * x[0] };
});

auto f_cosine = mito::math::field(f, Df);  // this generates undefined behavior

as opposed to

auto Dfx = mito::math::function([](const vector_t<2> & x) -> real { return -sin(x[0] * x[1]) * x[1]; });
auto Dfy = mito::math::function([](const vector_t<2> & x) -> real { return -sin(x[0] * x[1]) * x[0]; });

auto f_cosine = mito::math::field(f, { Dfx, Dfy });

which works as expected.

Most probably the issue resides in the cast of Function<X, Y> with Y a vector of dimension N to an std::array<function_t<X, scalar_t>, N>. The problematic cast is here below:

template <size_t N>
constexpr operator std::array<function_t<X, scalar_t>, N>() const requires(Y::size == N)
{
    auto _components = [this]<size_t... I>(std::index_sequence<I...>)
    {
        return std::array<function_t<X, scalar_t>, N>({ operator[](I)... });
    };
    return _components(std::make_index_sequence<N> {});
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions