diff --git a/bindings/python/src/State.cxx b/bindings/python/src/State.cxx
index 314857f3f..b3c6b1283 100644
--- a/bindings/python/src/State.cxx
+++ b/bindings/python/src/State.cxx
@@ -43,8 +43,8 @@ static pybind11::object State_getExternalStateVariables(
} // end of State_getExternalStateVariables
static void State_setMaterialProperty(mgis::behaviour::State& s,
- const std::string& n,
- const mgis::real v) {
+ const std::string& n,
+ const mgis::real v) {
mgis::behaviour::setMaterialProperty(s, n, v);
} // end of State_setMaterialProperty
diff --git a/docs/web/CMakeLists.txt b/docs/web/CMakeLists.txt
index acb5cfdfc..958b66a26 100644
--- a/docs/web/CMakeLists.txt
+++ b/docs/web/CMakeLists.txt
@@ -86,6 +86,8 @@ if(MGIS_HAVE_PANDOC)
mgis_pandoc_generate_html_page(release-notes-3.0.2 "--toc" "--toc-depth=3")
mgis_pandoc_generate_html_page(release-notes-3.0.3 "--toc" "--toc-depth=3")
mgis_pandoc_generate_html_page(release-notes-3.1 "--toc" "--toc-depth=3")
+ mgis_pandoc_generate_html_page(release-notes-3.1.1 "--toc" "--toc-depth=3")
+ mgis_pandoc_generate_html_page(release-notes-3.2 "--toc" "--toc-depth=3")
mgis_pandoc_generate_html_page(orthotropic-behaviours "--toc" "--toc-depth=3")
mgis_pandoc_generate_html_page(behaviour-integration-failure-analysis "--toc" "--toc-depth=3")
mgis_pandoc_generate_html_page(functions "--toc" "--toc-depth=3")
diff --git a/docs/web/mgis-template.html b/docs/web/mgis-template.html
index 3a069345e..477b559d4 100644
--- a/docs/web/mgis-template.html
+++ b/docs/web/mgis-template.html
@@ -127,6 +127,11 @@
Version 3.1.x
+ Version 3.2.x
+
diff --git a/docs/web/release-notes-3.1.1.md b/docs/web/release-notes-3.1.1.md
new file mode 100644
index 000000000..b6942b6d3
--- /dev/null
+++ b/docs/web/release-notes-3.1.1.md
@@ -0,0 +1,28 @@
+---
+title: MFrontGenericInterfaceSupport Version 3.1.1
+author: Thomas Helfer
+date: 2026
+lang: en-EN
+numbersections: true
+documentclass: article
+from: markdown+tex_math_single_backslash
+geometry:
+ - margin=2cm
+papersize: a4
+link-citations: true
+colorlinks: true
+figPrefixTemplate: "$$i$$"
+tabPrefixTemplate: "$$i$$"
+secPrefixTemplate: "$$i$$"
+eqnPrefixTemplate: "($$i$$)"
+bibliography: bibliography.bib
+---
+
+The page describes the new functionalities of Version 3.1.1 of the
+`MFrontGenericInterfaceSupport` project.
+
+# Issues fixed
+
+## Issue 197: [MGIS/Function] Fix `CoalescedMemoryAccessCompositeTensorsView` for scalar values
+
+For more details, see
diff --git a/docs/web/release-notes-3.2.md b/docs/web/release-notes-3.2.md
new file mode 100644
index 000000000..383e674dc
--- /dev/null
+++ b/docs/web/release-notes-3.2.md
@@ -0,0 +1,90 @@
+---
+title: MFrontGenericInterfaceSupport Version 3.2
+author: Thomas Helfer
+date: 2026
+lang: en-EN
+numbersections: true
+documentclass: article
+from: markdown+tex_math_single_backslash
+geometry:
+ - margin=2cm
+papersize: a4
+link-citations: true
+colorlinks: true
+figPrefixTemplate: "$$i$$"
+tabPrefixTemplate: "$$i$$"
+secPrefixTemplate: "$$i$$"
+eqnPrefixTemplate: "($$i$$)"
+bibliography: bibliography.bib
+---
+
+This version is meant to be used with `TFEL` Version 5.2.
+
+# New features of the `MGIS/Function` library
+
+## Functions using a strided memory access
+
+The following classes have been introduced:
+
+- `StridedCoalescedMemoryAccessTensorView`
+- `StridedCoalescedMemoryAccessCompositeTensorsView`
+
+### `StridedCoalescedMemoryAccessTensorView`
+
+`StridedCoalescedMemoryAccessTensorView` is a tensorial function view
+which stores its components in non interleaved manner using the
+following scheme:
+
+~~~~
+| <------- Component 1 ---------> |....| <----- Component Nc ---------> |
++-------++-------++------++-------+----+-------++------++------++-------+
+| Elt 1 || Elt 2 || .... || Elt N |....| Elt 1 ||Elt 2 || .... || Elt N |
++-------++-------++------++-------+----+-------++------++------++-------+
+~~~~
+
+#### Example of usage
+
+~~~~{.cxx}
+constexpr auto ne = size_type{2};
+auto space = BasicLinearSpace{ne};
+std::array values = {1, 10, 2, 20, 3, 30, 4, 40};
+const auto f = StridedCoalescedMemoryAccessTensorView<
+ BasicLinearSpace, tfel::math::stensor<2, real>, false>{space, values};
+const auto e1 = f(0);
+// e1 = {1, 2, 3, 4}
+const auto e2 = f(1);
+// e2 = {10, 20, 30, 40}
+~~~~
+
+## `StridedCoalescedMemoryAccessCompositeTensorsView`
+
+`StridedCoalescedMemoryAccessCompositeTensorsView` allows retrieving
+scalar or tensorial objects which are stored in a non interleaved
+manner.
+
+#### Example of usage
+
+~~~~{.cxx}
+using CompositeFunctionView =
+ StridedCoalescedMemoryAccessCompositeTensorsView;
+constexpr auto ne = size_type{2};
+auto space = BasicLinearSpace{ne};
+std::array values = {1, 10, 2, 20, 3, 30, 4, 40};
+const auto f = CompositeFunctionView{space, values};
+const auto e1 = f.get<0, tfel::math::stensor<2, real>>(0);
+// e1 = {1, 2, 3, 4}
+const auto e2 = f.get<0, tfel::math::stensor<2, real>>(1);
+// e2 = {10, 20, 30, 40}
+~~~~
+
+# Acknowledgements
+
+The authors are grateful to the many contributors to the `TFEL/MFront`
+project. This research was conducted in the framework of the PLEIADES
+project, which was supported financially by the CEA (Commissariat à
+l’Énergie Atomique et aux Énergies Alternatives), EDF (Électricité de
+France) and Framatome. Work on `MGIS/Function` was performed as part of
+the EURATOM OperaHPC Project co-funded by the European Union.
+
+# Issues fixed
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 58c3405aa..a946b6b78 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -97,4 +97,10 @@ if(enable-mgis-function)
mgis_header(MGIS/Function/Tensors CoalescedMemoryAccessTensorView.ixx)
mgis_header(MGIS/Function/Tensors CoalescedMemoryAccessCompositeTensorsView.hxx)
mgis_header(MGIS/Function/Tensors CoalescedMemoryAccessCompositeTensorsView.ixx)
+ mgis_header(MGIS/Function StridedCoalescedMemoryAccessFunctionViewBase.hxx)
+ mgis_header(MGIS/Function StridedCoalescedMemoryAccessFunctionViewBase.ixx)
+ mgis_header(MGIS/Function/Tensors StridedCoalescedMemoryAccessTensorView.hxx)
+ mgis_header(MGIS/Function/Tensors StridedCoalescedMemoryAccessTensorView.ixx)
+ mgis_header(MGIS/Function/Tensors StridedCoalescedMemoryAccessCompositeTensorsView.hxx)
+ mgis_header(MGIS/Function/Tensors StridedCoalescedMemoryAccessCompositeTensorsView.ixx)
endif(enable-mgis-function)
diff --git a/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx b/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx
new file mode 100644
index 000000000..f31e5c271
--- /dev/null
+++ b/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx
@@ -0,0 +1,123 @@
+/*!
+ * \file MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx
+ * \brief
+ * \author Thomas Helfer
+ * \date 17/01/2026
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX
+#define LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX
+
+#include
+#include
+#include "MGIS/Config.hxx"
+#include "MGIS/Contract.hxx"
+#include "MGIS/Function/SpaceConcept.hxx"
+#include "MGIS/Function/FunctionConcept.hxx"
+#include "MGIS/Function/Function.hxx"
+#include "MGIS/Function/Evaluator.hxx"
+
+namespace mgis::function {
+
+ /*!
+ * \brief a class meant to describe a function, each component of which is
+ * stored contiguously in non interleaved manner using the following scheme:
+ *
+ * ~~~~
+ * | <------- Component 1 ---------> |....| <----- Component Nc ---------> |
+ * +-------++-------++------++-------+----+-------++------++------++-------+
+ * | Elt 1 || Elt 2 || .... || Elt N |....| Elt 1 ||Elt 2 || .... || Elt N |
+ * +-------++-------++------++-------+----+-------++------++------++-------+
+ * ~~~~
+ */
+ template
+ requires(N > 0) struct StridedCoalescedMemoryAccessFunctionViewBase
+ : private PreconditionsChecker<
+ StridedCoalescedMemoryAccessFunctionViewBase> {
+ /*!
+ * \brief check that the preconditions to build the view are met
+ * \param[in] eh: error handler.
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ [[nodiscard]] static constexpr bool checkPreconditions(
+ AbstractErrorHandler&,
+ const Space& space,
+ std::span) requires(!is_mutable);
+ /*!
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase(
+ const Space&, std::span) requires(!is_mutable);
+ /*!
+ * \brief check that the preconditions to build the view are met
+ * \param[in] eh: error handler.
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ [[nodiscard]] static constexpr bool checkPreconditions(
+ AbstractErrorHandler&, const Space&, std::span);
+ /*!
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase(const Space&,
+ std::span);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] o: offset associated with the integration point
+ */
+ [[nodiscard]] constexpr std::array getValues(const size_type) const
+ requires(LinearElementSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] e: element index
+ * \param[in] i: quadrature point index
+ */
+ [[nodiscard]] constexpr std::array getValues(const size_type,
+ const size_type) const
+ requires(LinearQuadratureSpaceConcept);
+ //! \return the underlying quadrature space
+ [[nodiscard]] constexpr const Space& getSpace() const noexcept;
+
+ protected:
+ /*!
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ template
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase(
+ const PreconditionsCheck&,
+ const Space&,
+ std::span) requires(!is_mutable);
+ /*!
+ * \param[in] space: space
+ * \param[in] values: values
+ */
+ template
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase(
+ const PreconditionsCheck&,
+ const Space&,
+ std::span);
+ //! \brief underlying discretization space
+ const Space space;
+ //! \brief pointer to the first component
+ const std::conditional_t data_pointer;
+ };
+
+} // namespace mgis::function
+
+#include "MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.ixx"
+
+#endif /* LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX \
+ */
diff --git a/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.ixx b/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.ixx
new file mode 100644
index 000000000..57537ab15
--- /dev/null
+++ b/include/MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.ixx
@@ -0,0 +1,148 @@
+/*!
+ * \file MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.ixx
+ * \brief
+ * \author Thomas Helfer
+ * \date 17/01/2026
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX
+#define LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX
+
+namespace mgis::function {
+
+ template
+ requires(N > 0) //
+ constexpr bool StridedCoalescedMemoryAccessFunctionViewBase<
+ Space,
+ N,
+ is_mutable>::checkPreconditions(AbstractErrorHandler& eh,
+ const Space& s,
+ std::span values) //
+ requires(!is_mutable) {
+ const auto ne = getSpaceSize(s);
+ if (values.size() != N * ne) {
+ return eh.registerErrorMessage("invalid number of values");
+ }
+ return true;
+ } // end of checkPreconditions
+
+ template
+ requires(N > 0) //
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase::
+ StridedCoalescedMemoryAccessFunctionViewBase(
+ const Space& s,
+ std::span values) requires(!is_mutable)
+ : StridedCoalescedMemoryAccessFunctionViewBase(
+ preconditions_check, s, values) {
+ } // end of StridedCoalescedMemoryAccessFunctionViewBase
+
+ template
+ requires(N > 0) //
+ template
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase::
+ StridedCoalescedMemoryAccessFunctionViewBase(
+ const PreconditionsCheck& pcheck,
+ const Space& s,
+ std::span values) requires(!is_mutable)
+ : PreconditionsChecker(
+ pcheck, s, values),
+ space(s),
+ data_pointer(values.data()) {
+ } // end of StridedCoalescedMemoryAccessFunctionViewBase
+
+ template
+ requires(N > 0) //
+ constexpr bool StridedCoalescedMemoryAccessFunctionViewBase<
+ Space,
+ N,
+ is_mutable>::checkPreconditions(AbstractErrorHandler& eh,
+ const Space& s,
+ std::span values) {
+ const auto ne = getSpaceSize(s);
+ if (values.size() != N * ne) {
+ return eh.registerErrorMessage("invalid number of values");
+ }
+ return true;
+ } // end of checkPreconditions
+
+ template
+ requires(N > 0) //
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase::
+ StridedCoalescedMemoryAccessFunctionViewBase(const Space& s,
+ std::span values)
+ : StridedCoalescedMemoryAccessFunctionViewBase(
+ preconditions_check, s, values) {
+ } // end of StridedCoalescedMemoryAccessFunctionViewBase
+
+ template
+ requires(N > 0) //
+ template
+ constexpr StridedCoalescedMemoryAccessFunctionViewBase::
+ StridedCoalescedMemoryAccessFunctionViewBase(
+ const PreconditionsCheck& pcheck,
+ const Space& s,
+ std::span values)
+ : PreconditionsChecker(
+ pcheck, s, values),
+ space(s),
+ data_pointer(values.data()) {
+ } // end of StridedCoalescedMemoryAccessFunctionViewBase
+
+ template
+ requires(N > 0) //
+ constexpr const Space& StridedCoalescedMemoryAccessFunctionViewBase<
+ Space,
+ N,
+ is_mutable>::getSpace() const noexcept {
+ return this->space;
+ } // end of getSpace
+
+ template
+ requires(N > 0) //
+ constexpr std::array //
+ StridedCoalescedMemoryAccessFunctionViewBase::
+ getValues(const size_type i) const
+ requires(LinearElementSpaceConcept) {
+ return [ this, i ](std::index_sequence)
+ ->std::array {
+ const auto ne = getSpaceSize(this->space);
+ return {this->data_pointer[i + ne * Is]...};
+ }
+ (std::make_index_sequence());
+ } // end of getValues
+
+ template
+ requires(N > 0) //
+ constexpr std::array //
+ StridedCoalescedMemoryAccessFunctionViewBase::
+ getValues(const size_type e,
+ const size_type q) const //
+ requires(LinearQuadratureSpaceConcept) {
+ return [ this, e, q ](std::index_sequence)
+ ->std::array {
+ const auto ne = getSpaceSize(this->space);
+ const auto o = getQuadraturePointOffset(this->space, e, q);
+ return {this->data_pointer[o + ne * Is]...};
+ }
+ (std::make_index_sequence());
+ } // end of getValues
+
+} // end of namespace mgis::function
+
+#endif /* LIB_MGIS_FUNCTION_STRIDEDCOALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX \
+ */
diff --git a/include/MGIS/Function/Tensors.hxx b/include/MGIS/Function/Tensors.hxx
index a6ea8e06d..67edd201b 100644
--- a/include/MGIS/Function/Tensors.hxx
+++ b/include/MGIS/Function/Tensors.hxx
@@ -25,6 +25,8 @@
#include "MGIS/Function/Tensors/TensorModifier.hxx"
#include "MGIS/Function/Tensors/CoalescedMemoryAccessTensorView.hxx"
#include "MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.hxx"
+#include "MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.hxx"
+#include "MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx"
namespace mgis::function::internals {
diff --git a/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.hxx b/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.hxx
index 86af2c0f2..9f8ceaa6e 100644
--- a/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.hxx
+++ b/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.hxx
@@ -28,12 +28,25 @@
namespace mgis::function {
- /*!
- * \brief a tensor which is true if the type is equal to real or matches the
- * TensorConcept
- */
- template
- concept ScalarOrTensorConcept = std::same_as || TensorConcept;
+ template
+ struct CoalescedMemoryAccessCompositeTensorsViewMutableValue {
+ using type = tfel::math::CoalescedView;
+ };
+
+ template <>
+ struct CoalescedMemoryAccessCompositeTensorsViewMutableValue {
+ using type = real&;
+ };
+
+ template
+ struct CoalescedMemoryAccessCompositeTensorsViewConstValue {
+ using type = tfel::math::CoalescedView;
+ };
+
+ template <>
+ struct CoalescedMemoryAccessCompositeTensorsViewConstValue {
+ using type = const real&;
+ };
/*!
* \brief a coalescence view which acts as a tensorial function
@@ -49,15 +62,13 @@ namespace mgis::function {
//
template
using MutableValues =
- std::conditional_t,
- real&,
- tfel::math::CoalescedView>;
+ typename CoalescedMemoryAccessCompositeTensorsViewMutableValue<
+ ValueType>::type;
//
template
using ConstValues =
- std::conditional_t,
- const real&,
- tfel::math::CoalescedView>;
+ typename CoalescedMemoryAccessCompositeTensorsViewConstValue<
+ ValueType>::type;
// inheriting constructor
using CoalescedMemoryAccessFunctionViewBase::
CoalescedMemoryAccessFunctionViewBase;
@@ -69,8 +80,7 @@ namespace mgis::function {
[[nodiscard]] constexpr MutableValues
get(const size_type) requires(
(begin + internals::CompileTimeSize::value <= N) &&
- is_mutable && LinearElementSpaceConcept &&
- (!hasElementWorkspace));
+ is_mutable && LinearElementSpaceConcept);
/*!
* \return the data associated with an integration point
* \param[in] e: element index
@@ -80,8 +90,7 @@ namespace mgis::function {
[[nodiscard]] constexpr MutableValues
get(const size_type, const size_type) requires(
(begin + internals::CompileTimeSize::value <= N) &&
- is_mutable && LinearQuadratureSpaceConcept &&
- (!hasCellWorkspace));
+ is_mutable && LinearQuadratureSpaceConcept);
/*!
* \return the data associated with an integration point
* \param[in] o: offset associated with the integration point
@@ -90,8 +99,7 @@ namespace mgis::function {
[[nodiscard]] constexpr ConstValues get(
const size_type) const //
requires((begin + internals::CompileTimeSize::value <= N) &&
- LinearElementSpaceConcept &&
- (!hasElementWorkspace));
+ LinearElementSpaceConcept);
/*!
* \return the data associated with an integration point
* \param[in] e: element index
@@ -101,8 +109,7 @@ namespace mgis::function {
[[nodiscard]] constexpr ConstValues get(const size_type,
const size_type) const
requires((begin + internals::CompileTimeSize::value <= N) &&
- LinearQuadratureSpaceConcept &&
- (!hasCellWorkspace));
+ LinearQuadratureSpaceConcept);
}; // end of CoalescedMemoryAccessCompositeTensorsView
diff --git a/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.ixx b/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.ixx
index f754ed7d1..a861f5cf8 100644
--- a/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.ixx
+++ b/include/MGIS/Function/Tensors/CoalescedMemoryAccessCompositeTensorsView.ixx
@@ -22,16 +22,16 @@ namespace mgis::function {
template
constexpr
typename CoalescedMemoryAccessCompositeTensorsView::
- template MutableValues CoalescedMemoryAccessCompositeTensorsView<
- Space,
- N,
- is_mutable>::get(const size_type i) //
+ template MutableValues //
+ CoalescedMemoryAccessCompositeTensorsView::get(const size_type
+ i) //
requires((begin + internals::CompileTimeSize::value <= N) &&
- is_mutable && LinearElementSpaceConcept &&
- (!hasElementWorkspace)) {
+ is_mutable && LinearElementSpaceConcept) {
if constexpr (std::same_as) {
const auto ptr = this->template getValuePointer(i);
- return *(ptr[0]);
+ return ptr[0];
} else {
return tfel::math::CoalescedView(
this->template getValuesPointers<
@@ -44,17 +44,15 @@ namespace mgis::function {
template
constexpr
typename CoalescedMemoryAccessCompositeTensorsView::
- template MutableValues CoalescedMemoryAccessCompositeTensorsView<
- Space,
- N,
- is_mutable>::get(const size_type e,
- const size_type q) //
+ template MutableValues //
+ CoalescedMemoryAccessCompositeTensorsView::get(
+ const size_type e,
+ const size_type q) //
requires((begin + internals::CompileTimeSize::value <= N) &&
- is_mutable && LinearQuadratureSpaceConcept &&
- (!hasCellWorkspace)) {
+ is_mutable && LinearQuadratureSpaceConcept) {
if constexpr (std::same_as) {
const auto ptr = this->template getValuePointer(e, q);
- return *(ptr[0]);
+ return ptr[0];
} else {
return tfel::math::CoalescedView(
this->template getValuesPointers<
@@ -67,16 +65,16 @@ namespace mgis::function {
template
constexpr
typename CoalescedMemoryAccessCompositeTensorsView::
- template ConstValues CoalescedMemoryAccessCompositeTensorsView<
- Space,
- N,
- is_mutable>::get(const size_type i) const //
+ template ConstValues //
+ CoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::get(const size_type i) const //
requires((begin + internals::CompileTimeSize::value <= N) &&
- LinearElementSpaceConcept &&
- (!hasElementWorkspace)) {
+ LinearElementSpaceConcept) {
if constexpr (std::same_as) {
const auto ptr = this->template getValuePointer(i);
- return *(ptr[0]);
+ return ptr[0];
} else {
return tfel::math::CoalescedView(
this->template getValuesPointers<
@@ -89,17 +87,15 @@ namespace mgis::function {
template
constexpr
typename CoalescedMemoryAccessCompositeTensorsView::
- template ConstValues CoalescedMemoryAccessCompositeTensorsView<
- Space,
- N,
- is_mutable>::get(const size_type e,
- const size_type q) const //
+ template ConstValues //
+ CoalescedMemoryAccessCompositeTensorsView::get(
+ const size_type e,
+ const size_type q) const //
requires((begin + internals::CompileTimeSize::value <= N) &&
- LinearQuadratureSpaceConcept &&
- (!hasCellWorkspace)) {
+ LinearQuadratureSpaceConcept) {
if constexpr (std::same_as) {
const auto ptr = this->template getValuePointer(e, q);
- return *(ptr[0]);
+ return ptr[0];
} else {
return tfel::math::CoalescedView(
this->template getValuesPointers<
diff --git a/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx
new file mode 100644
index 000000000..afaf7f8c5
--- /dev/null
+++ b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx
@@ -0,0 +1,122 @@
+/*!
+ * \file
+ * MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx
+ * \brief
+ * \author Thomas Helfer
+ * \date 27/10/2025
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef MGIS_HAVE_TFEL
+#error "TFEL is required to use strided coalesced memory access tensor views"
+#endif /* MGIS_HAVE_TFEL */
+
+#ifndef LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_HXX
+#define LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_HXX
+
+#include
+#include
+#include
+#include "TFEL/Math/Array/StridedCoalescedView.hxx"
+#include "MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx"
+#include "MGIS/Function/Tensors/TensorConcept.hxx"
+
+namespace mgis::function {
+
+ template
+ struct StridedCoalescedMemoryAccessCompositeTensorsViewMutableValue {
+ using type = tfel::math::StridedCoalescedView;
+ };
+
+ template <>
+ struct StridedCoalescedMemoryAccessCompositeTensorsViewMutableValue {
+ using type = real&;
+ };
+
+ template
+ struct StridedCoalescedMemoryAccessCompositeTensorsViewConstValue {
+ using type = tfel::math::StridedCoalescedView;
+ };
+
+ template <>
+ struct StridedCoalescedMemoryAccessCompositeTensorsViewConstValue {
+ using type = const real&;
+ };
+
+ /*!
+ * \brief a strided coalescence view which acts as a tensorial function
+ *
+ * \tparam Space: functional space
+ * \tparam N: number of components
+ * \tparam is_mutable: boolean stating if the view can return mutable values.
+ */
+ template
+ requires(N > 0) //
+ struct StridedCoalescedMemoryAccessCompositeTensorsView
+ : StridedCoalescedMemoryAccessFunctionViewBase {
+ //
+ template
+ using MutableValues =
+ typename StridedCoalescedMemoryAccessCompositeTensorsViewMutableValue<
+ ValueType>::type;
+ //
+ template
+ using ConstValues =
+ typename StridedCoalescedMemoryAccessCompositeTensorsViewConstValue<
+ ValueType>::type;
+ // inheriting constructor
+ using StridedCoalescedMemoryAccessFunctionViewBase::
+ StridedCoalescedMemoryAccessFunctionViewBase;
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] o: offset associated with the integration point
+ */
+ template
+ [[nodiscard]] constexpr MutableValues
+ get(const size_type) requires(
+ (begin + internals::CompileTimeSize::value <= N) &&
+ is_mutable && LinearElementSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] e: element index
+ * \param[in] i: quadrature point index
+ */
+ template
+ [[nodiscard]] constexpr MutableValues
+ get(const size_type, const size_type) requires(
+ (begin + internals::CompileTimeSize::value <= N) &&
+ is_mutable && LinearQuadratureSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] o: offset associated with the integration point
+ */
+ template
+ [[nodiscard]] constexpr ConstValues get(
+ const size_type) const //
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ LinearElementSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] e: element index
+ * \param[in] i: quadrature point index
+ */
+ template
+ [[nodiscard]] constexpr ConstValues get(const size_type,
+ const size_type) const
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ LinearQuadratureSpaceConcept);
+
+ }; // end of StridedCoalescedMemoryAccessCompositeTensorsView
+
+} // namespace mgis::function
+
+#include "MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.ixx"
+
+#endif /* LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_HXX \
+ */
diff --git a/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.ixx b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.ixx
new file mode 100644
index 000000000..0a1733fa5
--- /dev/null
+++ b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.ixx
@@ -0,0 +1,112 @@
+/*!
+ * \file
+ * MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.ixx
+ * \brief
+ * \author Thomas Helfer
+ * \date 27/10/2025
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_IXX
+#define LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_IXX
+
+namespace mgis::function {
+
+ template
+ requires(N > 0) //
+ template
+ constexpr typename StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::template MutableValues //
+ StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::get(const size_type i) //
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ is_mutable && LinearElementSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ if constexpr (std::same_as) {
+ return this->data_pointer[begin * ne + i];
+ } else {
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + begin * ne + i, ne);
+ }
+ } // end of get
+
+ template
+ requires(N > 0) //
+ template
+ constexpr typename StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::template MutableValues //
+ StridedCoalescedMemoryAccessCompositeTensorsView::
+ get(const size_type e,
+ const size_type q) //
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ is_mutable && LinearQuadratureSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ const auto o = getQuadraturePointOffset(this->space, e, q);
+ if constexpr (std::same_as) {
+ return this->data_pointer[begin * ne + o];
+ } else {
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + begin * ne + o, ne);
+ }
+ } // end of get
+
+ template
+ requires(N > 0) //
+ template
+ constexpr typename StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::template ConstValues //
+ StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::get(const size_type i) const //
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ LinearElementSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ if constexpr (std::same_as) {
+ return this->data_pointer[begin * ne + i];
+ } else {
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + begin * ne + i, ne);
+ }
+ } // end of get
+
+ template
+ requires(N > 0) //
+ template
+ constexpr typename StridedCoalescedMemoryAccessCompositeTensorsView<
+ Space,
+ N,
+ is_mutable>::template ConstValues //
+ StridedCoalescedMemoryAccessCompositeTensorsView::
+ get(const size_type e,
+ const size_type q) const //
+ requires((begin + internals::CompileTimeSize::value <= N) &&
+ LinearQuadratureSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ const auto o = getQuadraturePointOffset(this->space, e, q);
+ if constexpr (std::same_as) {
+ return this->data_pointer[begin * ne + o];
+ } else {
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + begin * ne + o, ne);
+ }
+ } // end of get
+
+} // namespace mgis::function
+
+#endif /* LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSCOMPOSITETENSORSVIEW_IXX \
+ */
diff --git a/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.hxx b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.hxx
new file mode 100644
index 000000000..f420f2da1
--- /dev/null
+++ b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.hxx
@@ -0,0 +1,89 @@
+/*!
+ * \file MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.hxx
+ * \brief
+ * \author Thomas Helfer
+ * \date 27/10/2025
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef MGIS_HAVE_TFEL
+#error "TFEL is required to use coalesced memory access tensor views"
+#endif /* MGIS_HAVE_TFEL */
+
+#ifndef LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_HXX
+#define LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_HXX
+
+#include "TFEL/Math/Array/StridedCoalescedView.hxx"
+#include "MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx"
+#include "MGIS/Function/Tensors/TensorConcept.hxx"
+
+namespace mgis::function {
+
+ /*!
+ * \brief a coalescence view which acts as a tensorial function
+ *
+ * \tparam Space: functional space
+ * \tparam TensorType: tensorial object mapped
+ * \tparam is_mutable: boolean stating if the view can return mutable values.
+ */
+ template
+ struct StridedCoalescedMemoryAccessTensorView
+ : StridedCoalescedMemoryAccessFunctionViewBase<
+ Space,
+ internals::CompileTimeSize::value,
+ is_mutable> {
+ //
+ using MutableValues = tfel::math::StridedCoalescedView;
+ //
+ using ConstValues = tfel::math::StridedCoalescedView;
+
+ // inheriting constructor
+ using StridedCoalescedMemoryAccessFunctionViewBase<
+ Space,
+ internals::CompileTimeSize::value,
+ is_mutable>::StridedCoalescedMemoryAccessFunctionViewBase;
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] o: offset associated with the integration point
+ */
+ [[nodiscard]] constexpr MutableValues operator()(const size_type) requires(
+ is_mutable&& LinearElementSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] e: element index
+ * \param[in] i: quadrature point index
+ */
+ [[nodiscard]] constexpr MutableValues
+ operator()(const size_type, const size_type) requires(
+ is_mutable&& LinearQuadratureSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] o: offset associated with the integration point
+ */
+ [[nodiscard]] constexpr ConstValues operator()(const size_type) const
+ requires(LinearElementSpaceConcept);
+ /*!
+ * \return the data associated with an integration point
+ * \param[in] e: element index
+ * \param[in] i: quadrature point index
+ */
+ [[nodiscard]] constexpr ConstValues operator()(const size_type,
+ const size_type) const
+ requires(LinearQuadratureSpaceConcept);
+
+ }; // end of StridedCoalescedMemoryAccessTensorView
+
+} // namespace mgis::function
+
+#include "MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.ixx"
+
+#endif /* LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_HXX \
+ */
diff --git a/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.ixx b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.ixx
new file mode 100644
index 000000000..7c233a41e
--- /dev/null
+++ b/include/MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.ixx
@@ -0,0 +1,86 @@
+/*!
+ * \file MGIS/Function/Tensors/StridedCoalescedMemoryAccessTensorView.ixx
+ * \brief
+ * \author Thomas Helfer
+ * \date 17/01/2026
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#ifndef LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_IXX
+#define LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_IXX
+
+namespace mgis::function {
+
+ template
+ constexpr
+ typename StridedCoalescedMemoryAccessTensorView::MutableValues
+ StridedCoalescedMemoryAccessTensorView::
+ operator()(const size_type i) requires(
+ is_mutable&& LinearElementSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ return tfel::math::StridedCoalescedView(this->data_pointer + i,
+ ne);
+ } // end of operator()
+
+ template
+ constexpr
+ typename StridedCoalescedMemoryAccessTensorView::MutableValues
+ StridedCoalescedMemoryAccessTensorView::
+ operator()(const size_type e,
+ const size_type q) //
+ requires(is_mutable&& LinearQuadratureSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ const auto o = getQuadraturePointOffset(this->space, e, q);
+ return tfel::math::StridedCoalescedView(this->data_pointer + o,
+ ne);
+ } // end of operator()
+
+ template
+ constexpr
+ typename StridedCoalescedMemoryAccessTensorView::ConstValues
+ StridedCoalescedMemoryAccessTensorView::
+ operator()(const size_type i) const //
+ requires(LinearElementSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + i, ne);
+ } // end of operator()
+
+ template
+ constexpr
+ typename StridedCoalescedMemoryAccessTensorView::ConstValues
+ StridedCoalescedMemoryAccessTensorView::
+ operator()(const size_type e, const size_type q) const //
+ requires(LinearQuadratureSpaceConcept) {
+ const auto ne = getSpaceSize(this->space);
+ const auto o = getQuadraturePointOffset(this->space, e, q);
+ return tfel::math::StridedCoalescedView(
+ this->data_pointer + o, ne);
+ } // end of operator()
+
+} // namespace mgis::function
+
+#endif /* LIB_MGIS_FUNCTION_TENSORS_STRIDEDCOALESCEDMEMORYACCESSTENSORVIEW_IXX \
+ */
diff --git a/include/MGIS/Function/Tensors/TensorConcept.hxx b/include/MGIS/Function/Tensors/TensorConcept.hxx
index 8dbd64d1a..e1cc9a950 100644
--- a/include/MGIS/Function/Tensors/TensorConcept.hxx
+++ b/include/MGIS/Function/Tensors/TensorConcept.hxx
@@ -145,6 +145,13 @@ namespace mgis::function {
template
concept TensorConcept = internals::IsTensor::value;
+ /*!
+ * \brief a tensor which is true if the type is equal to real or matches the
+ * TensorConcept
+ */
+ template
+ concept ScalarOrTensorConcept = std::same_as || TensorConcept;
+
} // end of namespace mgis::function
#endif /* LIB_MGIS_FUNCTION_TENSORCONCEPT_HXX */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 066c6d3f5..e2f0c5134 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -40,6 +40,7 @@ if(enable-mgis-function)
Evaluator.cxx
UniformEvaluator.cxx
CoalescedMemoryAccessFunctionView.cxx
+ StridedCoalescedMemoryAccessFunctionView.cxx
MaterialFunctionManager.cxx)
if(MGIS_HAVE_TFEL)
list(APPEND MFrontGenericInterface_SOURCES
diff --git a/src/StridedCoalescedMemoryAccessFunctionView.cxx b/src/StridedCoalescedMemoryAccessFunctionView.cxx
new file mode 100644
index 000000000..cebe1670a
--- /dev/null
+++ b/src/StridedCoalescedMemoryAccessFunctionView.cxx
@@ -0,0 +1,18 @@
+/*!
+ * \file StridedCoalescedMemoryAccessFunctionView.cxx
+ * \brief
+ * \author Thomas Helfer
+ * \date 17/01/2026
+ * \copyright (C) Copyright Thomas Helfer 2018.
+ * Use, modification and distribution are subject
+ * to one of the following licences:
+ * - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
+ * file LGPL-3.0.txt)
+ * - CECILL-C, Version 1.0 (See accompanying files
+ * CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
+ */
+
+#include "MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx"
+#ifdef MGIS_HAVE_TFEL
+#include "MGIS/Function/Tensors/StridedCoalescedMemoryAccessCompositeTensorsView.hxx"
+#endif /* MGIS_HAVE_TFEL */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4e099397b..db6a8a709 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -545,6 +545,29 @@ if((CMAKE_HOST_WIN32) AND (NOT MSYS))
PROPERTY ENVIRONMENT "PATH=$\;${MGIS_PATH_STRING}")
endif((CMAKE_HOST_WIN32) AND (NOT MSYS))
+add_executable(StridedCoalescedMemoryAccessFunctionViewTest
+ EXCLUDE_FROM_ALL
+ StridedCoalescedMemoryAccessFunctionViewTest.cxx)
+target_link_libraries(StridedCoalescedMemoryAccessFunctionViewTest
+ PRIVATE MFrontGenericInterface tfel::TFELTests)
+add_test(NAME StridedCoalescedMemoryAccessFunctionViewTest
+ COMMAND StridedCoalescedMemoryAccessFunctionViewTest)
+add_dependencies(check StridedCoalescedMemoryAccessFunctionViewTest)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.2.0)
+ target_compile_definitions(StridedCoalescedMemoryAccessFunctionViewTest
+ PRIVATE MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS)
+ endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.2.0)
+endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+if(CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
+ target_compile_definitions(StridedCoalescedMemoryAccessFunctionViewTest
+ PRIVATE MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS)
+endif()
+if((CMAKE_HOST_WIN32) AND (NOT MSYS))
+ set_property(TEST StridedCoalescedMemoryAccessFunctionViewTest
+ PROPERTY ENVIRONMENT "PATH=$\;${MGIS_PATH_STRING}")
+endif((CMAKE_HOST_WIN32) AND (NOT MSYS))
+
add_executable(MechanicalEvaluatorsTest
EXCLUDE_FROM_ALL
MechanicalEvaluatorsTest.cxx)
diff --git a/tests/CoalescedMemoryAccessFunctionViewTest.cxx b/tests/CoalescedMemoryAccessFunctionViewTest.cxx
index e1eb986fd..ead15f533 100644
--- a/tests/CoalescedMemoryAccessFunctionViewTest.cxx
+++ b/tests/CoalescedMemoryAccessFunctionViewTest.cxx
@@ -88,6 +88,9 @@ struct CoalescedMemoryAccessTensorViewTest final
std::array values = {1, 10, 2, 20, 3, 30, 4, 40};
const auto oscalar_functions =
splitArrayIntoScalarFunctionViews<4>(ctx, space, values);
+ if (!oscalar_functions.has_value()) {
+ raise("splitArrayIntoScalarFunctionViews failed");
+ }
const auto f =
CoalescedMemoryAccessTensorView, false>{
@@ -113,6 +116,7 @@ struct CoalescedMemoryAccessCompositeTensorsViewTest final
this->test2();
this->test3();
this->test4();
+ this->test5();
return this->result;
}
@@ -186,7 +190,8 @@ struct CoalescedMemoryAccessCompositeTensorsViewTest final
auto ctx = Context{};
TFEL_TESTS_ASSERT(
!CompositeView::checkPreconditions(ctx, space, out_values));
- TFEL_TESTS_CHECK_EQUAL(ctx.getRawErrorMessage(), "invalid number of values");
+ TFEL_TESTS_CHECK_EQUAL(ctx.getRawErrorMessage(),
+ "invalid number of values");
if constexpr (config::contract_violation_policy ==
config::ContractViolationPolicy::RAISE) {
bool has_thrown = false;
@@ -255,6 +260,28 @@ struct CoalescedMemoryAccessCompositeTensorsViewTest final
TFEL_TESTS_STATIC_ASSERT(local_abs(r[11]) < seps);
#endif /* MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS */
} // end of test4
+ void test5() {
+#ifndef MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS
+ using namespace mgis;
+ using namespace mgis::function;
+ using ImmutableCompositeView =
+ CoalescedMemoryAccessCompositeTensorsView;
+ auto local_abs = [](const mgis::real r) { return r > 0 ? r : -r; };
+ constexpr auto r = []() -> std::array {
+ auto ctx = ContractViolationHandler{};
+ auto space = BasicLinearSpace{2};
+ const auto values = std::array{2, 3, -1, 4};
+ const auto view = ImmutableCompositeView{space, values};
+ return std::array{view.get<0, real>(0), view.get<1, real>(0),
+ view.get<0, real>(1), view.get<1, real>(1)};
+ }();
+ constexpr auto eps = real{1e-14};
+ TFEL_TESTS_STATIC_ASSERT(local_abs(r[0] - 2) < eps);
+ TFEL_TESTS_STATIC_ASSERT(local_abs(r[1] + 1) < eps);
+ TFEL_TESTS_STATIC_ASSERT(local_abs(r[2] - 3) < eps);
+ TFEL_TESTS_STATIC_ASSERT(local_abs(r[3] - 4) < eps);
+#endif /* MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS */
+ } // end of test5
};
TFEL_TESTS_GENERATE_PROXY(CoalescedMemoryAccessFunctionViewBaseTest,
diff --git a/tests/StridedCoalescedMemoryAccessFunctionViewTest.cxx b/tests/StridedCoalescedMemoryAccessFunctionViewTest.cxx
new file mode 100644
index 000000000..2cef3db15
--- /dev/null
+++ b/tests/StridedCoalescedMemoryAccessFunctionViewTest.cxx
@@ -0,0 +1,294 @@
+/*!
+ * \file tests/StridedCoalescedMemoryAccessFunctionViewTest.cxx
+ * \brief
+ * \author Thomas Helfer
+ * \date 26/10/2025
+ */
+
+#include
+#include
+#include
+#include
+#include "TFEL/Tests/TestCase.hxx"
+#include "TFEL/Tests/TestProxy.hxx"
+#include "TFEL/Tests/TestManager.hxx"
+#include "TFEL/Material/Lame.hxx"
+#include "MGIS/Function/SharedSpace.hxx"
+#include "MGIS/Function/BasicLinearSpace.hxx"
+#include "MGIS/Function/BasicLinearQuadratureSpace.hxx"
+#include "MGIS/Function/StridedCoalescedMemoryAccessFunctionViewBase.hxx"
+#include "MGIS/Function/Tensors.hxx"
+
+namespace mgis::function {} // end of namespace mgis::function
+
+struct StridedCoalescedMemoryAccessFunctionViewBaseTest final
+ : public tfel::tests::TestCase {
+ StridedCoalescedMemoryAccessFunctionViewBaseTest()
+ : tfel::tests::TestCase(
+ "MGIS/Function",
+ "StridedCoalescedMemoryAccessFunctionViewBaseTests") {
+ } // end of StridedCoalescedMemoryAccessFunctionViewBaseTest
+ tfel::tests::TestResult execute() override {
+ this->test1();
+ return this->result;
+ }
+
+ private:
+ void test1() {
+#ifndef MGIS_DISABLE_CONSTEXPR_FUNCTION_TESTS
+ using namespace mgis;
+ using namespace mgis::function;
+ auto local_abs = [](const mgis::real r) { return r > 0 ? r : -r; };
+ constexpr auto r =
+ []() -> std::tuple, std::array> {
+ auto space = BasicLinearSpace{2};
+ auto values = std::vector{5, 12, -2, 3};
+ auto coalesced_view =
+ StridedCoalescedMemoryAccessFunctionViewBase