diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index abdfcb937..240c5c17d 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -28,7 +28,6 @@ install_header(TFEL/Metaprogramming/Forward TypeList.hxx) install_header(TFEL/Metaprogramming Implements.hxx) install_header(TFEL/Metaprogramming TypeList.hxx) install_header(TFEL/Metaprogramming TypeList.ixx) -install_header(TFEL/Metaprogramming IsConstCallable.hxx) install_header(TFEL/Metaprogramming GenerateTypeList.hxx) install_header(TFEL/Metaprogramming InvalidType.hxx) install_header(TFEL/Metaprogramming HasIterator.hxx) @@ -36,7 +35,6 @@ install_header(TFEL/Metaprogramming HasConstIterator.hxx) install_header(TFEL/Metaprogramming HasRandomAccessConstIterator.hxx) install_header(TFEL/Metaprogramming EmptyClass.hxx) install_header(TFEL/Metaprogramming HasRandomAccessIterator.hxx) -install_header(TFEL/Metaprogramming ResultOf.hxx) install_header(TFEL/Metaprogramming MakeIntegerRange.hxx) install_header(TFEL/TypeTraits/Promote Promote.ixx) diff --git a/include/TFEL/Config/TFELConfig.hxx b/include/TFEL/Config/TFELConfig.hxx index 577b0c96c..e45e98ed4 100644 --- a/include/TFEL/Config/TFELConfig.hxx +++ b/include/TFEL/Config/TFELConfig.hxx @@ -336,17 +336,17 @@ */ #define TFEL_CONSTEXPR constexpr -#if (defined __CUDACC__) || (defined __HIPPCC__) +#if (defined __CUDACC__) || (defined __HIPCC__) #ifndef TFEL_DEVICE #define TFEL_DEVICE __device__ #endif /* TFEL_DEVICE */ #ifndef TFEL_HOST #define TFEL_HOST __host__ #endif /* TFEL_HOST */ -#if (defined __CUDA_ARCH__) || (defined __HIP_ARCH__) +#if (defined __CUDA_ARCH__) || (defined __HIP_DEVICE_COMPILE__) #define TFEL_NO_REPORT_CONTRACT_VIOLATION 1 -#endif /* (defined __CUDA_ARCH__) || (defined __HIP_ARCH__) */ -#endif /* (defined __CUDACC__) || (defined __HIPPCC__) */ +#endif /* (defined __CUDA_ARCH__) || (defined __HIP_DEVICE_COMPILE__) */ +#endif /* (defined __CUDACC__) || (defined __HIPCC__) */ #if defined(__clang__) && defined(__CUDA__) && defined(__CUDA_ARCH__) #define TFEL_NO_REPORT_CONTRACT_VIOLATION 1 diff --git a/include/TFEL/FSAlgorithm/copy.hxx b/include/TFEL/FSAlgorithm/copy.hxx index fc982ceea..0112d89cf 100644 --- a/include/TFEL/FSAlgorithm/copy.hxx +++ b/include/TFEL/FSAlgorithm/copy.hxx @@ -14,8 +14,8 @@ #ifndef LIB_TFEL_FSALGORITHM_COPY_HXX #define LIB_TFEL_FSALGORITHM_COPY_HXX -#include "TFEL/Config/TFELConfig.hxx" #include +#include "TFEL/Config/TFELConfig.hxx" #include "TFEL/TypeTraits/IsRandomAccessIterator.hxx" namespace tfel::fsalgo { @@ -48,14 +48,14 @@ namespace tfel::fsalgo { * - InputIterator is a model of Input Iterator. * - OutputIterator is a model of Output Iterator. * - InputIterator's value type is convertible to a type in OutputIterator's - * set of value types. + * set of value types. * * \author Thomas Helfer * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE OutputIterator exe(InputIterator p, - OutputIterator q) { + TFEL_HOST_DEVICE constexpr static OutputIterator exe( + InputIterator p, OutputIterator q) noexcept { *q = *p; return copy::exe(++p, ++q); } @@ -77,8 +77,8 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE OutputIterator exe(InputIterator, - OutputIterator q) { + TFEL_HOST_DEVICE constexpr static OutputIterator exe( + InputIterator, OutputIterator q) noexcept { return q; } }; @@ -104,8 +104,8 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE OutputIterator exe(InputIterator p, - OutputIterator q) { + TFEL_HOST_DEVICE constexpr static OutputIterator exe( + InputIterator p, OutputIterator q) noexcept { *q = *p; return ++q; } @@ -142,11 +142,8 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE constexpr static auto exe(InputIterator p, + OutputIterator q) noexcept { q[0] = p[0]; q[1] = p[1]; return q + 2; @@ -157,11 +154,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<1u>::exe(++p, ++q); } @@ -180,8 +176,7 @@ namespace tfel::fsalgo { struct copy<3u> { /*! * This version of copy is used if iterators are Random Access. Test is - * based on the tfel::typetraits::IsRandomAccessIterator class. \see - * std::enable_if, tfel::typetraits::IsRandomAccessIterator + * based on the tfel::typetraits::IsRandomAccessIterator class. * * \param InputIterator iterator to the element to be copied * \param OutputIterator iterator to the place where this element will be @@ -199,11 +194,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -215,11 +209,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<2u>::exe(++p, ++q); } @@ -256,11 +249,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -273,11 +265,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<3u>::exe(++p, ++q); } @@ -314,11 +305,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -332,11 +322,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<4u>::exe(++p, ++q); } @@ -373,11 +362,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -392,11 +380,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<5u>::exe(++p, ++q); } @@ -433,11 +420,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -453,11 +439,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<6u>::exe(++p, ++q); } @@ -494,11 +479,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -515,11 +499,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<7u>::exe(++p, ++q); } @@ -556,11 +539,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + (tfel::typetraits::IsRandomAccessIterator::cond && + tfel::typetraits::IsRandomAccessIterator::cond)) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -578,11 +560,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<8u>::exe(++p, ++q); } @@ -619,11 +600,10 @@ namespace tfel::fsalgo { * \date 30 Jun 2006 */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< - tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond, - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( + tfel::typetraits::IsRandomAccessIterator::cond&& + tfel::typetraits::IsRandomAccessIterator::cond) { q[0] = p[0]; q[1] = p[1]; q[2] = p[2]; @@ -642,11 +622,10 @@ namespace tfel::fsalgo { * \see copy::exe for details */ template - static TFEL_FSALGORITHM_INLINE typename std::enable_if< + TFEL_HOST_DEVICE static constexpr auto + exe(InputIterator p, OutputIterator q) noexcept requires( !(tfel::typetraits::IsRandomAccessIterator::cond && - tfel::typetraits::IsRandomAccessIterator::cond), - OutputIterator>::type - exe(InputIterator p, OutputIterator q) { + tfel::typetraits::IsRandomAccessIterator::cond)) { *q = *p; return copy<9u>::exe(++p, ++q); } diff --git a/include/TFEL/Material/Barlat2004YieldCriterion.hxx b/include/TFEL/Material/Barlat2004YieldCriterion.hxx index 6bb713e9e..dcac993ca 100644 --- a/include/TFEL/Material/Barlat2004YieldCriterion.hxx +++ b/include/TFEL/Material/Barlat2004YieldCriterion.hxx @@ -22,35 +22,35 @@ namespace tfel::material { //! a simple alias - template + template using BarlatStressType = tfel::math::numeric_type; //! a simple alias - template + template using BarlatBaseType = tfel::typetraits::base_type>; //! a simple alias - template + template using BarlatLinearTransformationType = tfel::math::st2tost2(), BarlatBaseType>; //! a simple alias - template + template using BarlatInvertStressType = tfel::math::result_type, BarlatStressType, tfel::math::OpDiv>; //! a simple alias - template + template using BarlatStressNormalType = tfel::math::stensor(), BarlatBaseType>; //! a simple alias - template + template using BarlatStressEigenTensorType = tfel::math::stensor(), BarlatBaseType>; //! a simple alias - template + template using BarlatStressSecondDerivativeType = tfel::math::st2tost2(), BarlatInvertStressType>; @@ -58,7 +58,7 @@ namespace tfel::material { * \brief an helper structure used to simplify the code * \tparam StressStensor: type of the stress tensor */ - template + template struct BarlatStressAndDerivativesWithRespectToEigenvalues { //! Barlat stress BarlatStressType Phi; @@ -89,68 +89,69 @@ namespace tfel::material { tfel::math::tvector<9u, BarlatInvertStressType> d2Phi_dsvp1dsvp2; }; // end of struct BarlatStressAndDerivativesWithRespectToEigenvalues - /*! - * \tparam N: space dimension - * \tparam real: numerical type - * \return a linear transformation of the stresses - * \param[in] c12: coefficient of the linear transformation - * \param[in] c21: coefficient of the linear transformation - * \param[in] c13: coefficient of the linear transformation - * \param[in] c31: coefficient of the linear transformation - * \param[in] c23: coefficient of the linear transformation - * \param[in] c32: coefficient of the linear transformation - * \param[in] c44: coefficient of the linear transformation - * \param[in] c55: coefficient of the linear transformation - * \param[in] c66: coefficient of the linear transformation - * - * The linear transformation is defined as follows: - * \f[ - * \underline{L}= - * \frac{1}{3}\, - * \begin{pmatrix} - * 0 & -c_{12} & -c_{13} & 0 & 0 & 0 \\ - * -c_{21} & 0 & -c_{23} & 0 & 0 & 0 \\ - * -c_{31} & -c_{32} & 0 & 0 & 0 & 0 \\ - * 0 & 0 & 0 & c_{44} & 0 & 0 \\ - * 0 & 0 & 0 & 0 & c_{55} & 0 \\ - * 0 & 0 & 0 & 0 & 0 & c_{66} \\ - * \end{pmatrix} - * \, - * \cdot - * \, - * \begin{pmatrix} - * 2 & -1 & -1 & 0 & 0 & 0 \\ - * -1 & 2 & -1 & 0 & 0 & 0 \\ - * -1 & -1 & 2 & 0 & 0 & 0 \\ - * 0 & 0 & 0 & 1 & 0 & 0 \\ - * 0 & 0 & 0 & 0 & 1 & 0 \\ - * 0 & 0 & 0 & 0 & 0 & 1 \\ - * \end{pmatrix} - * \f] - * \note Barlat uses the following convention for storing - * symmetric tensors: - * \f[ - * \begin{pmatrix} - * xx & yy & zz & yz & zx & xy - * \end{pmatrix} - * \f] - * which is not consistent with the - * `TFEL`/`Cast3M`/`Abaqus`/`Ansys` conventions: - * \f[ - * \begin{pmatrix} - * xx & yy & zz & xy & xz & yz - * \end{pmatrix} - * \f] - * - * Therefore, if one wants to uses coeficients \f$c^{B}\f$ given - * by Barlat, one shall call this function as follows: - * - * \code{.cpp} - * const auto l1 = - * makeBarlatLinearTransformation<3>(cB_12,cB_21,cB_13,cB_31, - * cB_23,cB_32,cB_66,cBB_55,cBB_44); - * \endcode - */ + + /*! + * \tparam N: space dimension + * \tparam real: numerical type + * \return a linear transformation of the stresses + * \param[in] c12: coefficient of the linear transformation + * \param[in] c21: coefficient of the linear transformation + * \param[in] c13: coefficient of the linear transformation + * \param[in] c31: coefficient of the linear transformation + * \param[in] c23: coefficient of the linear transformation + * \param[in] c32: coefficient of the linear transformation + * \param[in] c44: coefficient of the linear transformation + * \param[in] c55: coefficient of the linear transformation + * \param[in] c66: coefficient of the linear transformation + * + * The linear transformation is defined as follows: + * \f[ + * \underline{L}= + * \frac{1}{3}\, + * \begin{pmatrix} + * 0 & -c_{12} & -c_{13} & 0 & 0 & 0 \\ + * -c_{21} & 0 & -c_{23} & 0 & 0 & 0 \\ + * -c_{31} & -c_{32} & 0 & 0 & 0 & 0 \\ + * 0 & 0 & 0 & c_{44} & 0 & 0 \\ + * 0 & 0 & 0 & 0 & c_{55} & 0 \\ + * 0 & 0 & 0 & 0 & 0 & c_{66} \\ + * \end{pmatrix} + * \, + * \cdot + * \, + * \begin{pmatrix} + * 2 & -1 & -1 & 0 & 0 & 0 \\ + * -1 & 2 & -1 & 0 & 0 & 0 \\ + * -1 & -1 & 2 & 0 & 0 & 0 \\ + * 0 & 0 & 0 & 1 & 0 & 0 \\ + * 0 & 0 & 0 & 0 & 1 & 0 \\ + * 0 & 0 & 0 & 0 & 0 & 1 \\ + * \end{pmatrix} + * \f] + * \note Barlat uses the following convention for storing + * symmetric tensors: + * \f[ + * \begin{pmatrix} + * xx & yy & zz & yz & zx & xy + * \end{pmatrix} + * \f] + * which is not consistent with the + * `TFEL`/`Cast3M`/`Abaqus`/`Ansys` conventions: + * \f[ + * \begin{pmatrix} + * xx & yy & zz & xy & xz & yz + * \end{pmatrix} + * \f] + * + * Therefore, if one wants to uses coeficients \f$c^{B}\f$ given + * by Barlat, one shall call this function as follows: + * + * \code{.cpp} + * const auto l1 = + * makeBarlatLinearTransformation<3>(cB_12,cB_21,cB_13,cB_31, + * cB_23,cB_32,cB_66,cBB_55,cBB_44); + * \endcode + */ template TFEL_HOST_DEVICE constexpr tfel::math::st2tost2 makeBarlatLinearTransformation(const real, @@ -161,7 +162,7 @@ namespace tfel::material { const real, const real, const real, - const real); + const real) noexcept; /*! * \tparam N: space dimension * \tparam real: numerical type @@ -195,7 +196,7 @@ namespace tfel::material { */ template TFEL_HOST_DEVICE constexpr tfel::math::st2tost2 - makeBarlatLinearTransformation(const tfel::math::fsarray<9u, real>&); + makeBarlatLinearTransformation(const tfel::math::fsarray<9u, real>&) noexcept; /*! * \tparam H: modelling hypothesis * \tparam c: orthotropic axis convention @@ -255,7 +256,7 @@ namespace tfel::material { const real, const real, const real, - const real); + const real) noexcept; /*! * \tparam H: modelling hypothesis * \tparam oac: orthotropic axis convention @@ -297,9 +298,10 @@ namespace tfel::material { template - TFEL_HOST_DEVICE constexpr tfel::math:: - st2tost2::value, real> - makeBarlatLinearTransformation(const tfel::math::fsarray<9u, real>&); + TFEL_HOST_DEVICE constexpr tfel::math::st2tost2< + ModellingHypothesisToSpaceDimension::value, + real> + makeBarlatLinearTransformation(const tfel::math::fsarray<9u, real>&) noexcept; /*! * \brief This function computes the Barlat yield stress. * The Barlat yield stress is defined by: @@ -389,7 +391,7 @@ namespace tfel::material { * \param[in] e: criterion used to check if the von Mises stress is null * \return the Barlat yield stress \f$\phi\left(\underline{\bf s}\right)\f$ */ - template @@ -412,7 +414,7 @@ namespace tfel::material { * \param[in] e: criterion used to check if the von Mises stress is null. * \see `computeBarlatStress` */ - template @@ -437,7 +439,8 @@ namespace tfel::material { * \param[in] a: Barlat exponent * \see `computeBarlatStress` */ - template + template TFEL_HOST_DEVICE BarlatStressAndDerivativesWithRespectToEigenvalues computeBarlatStressSecondDerivative( @@ -459,7 +462,7 @@ namespace tfel::material { * \param[in] e: criterion used to check if the stress are null * \see `computeBarlatStress` */ - template diff --git a/include/TFEL/Material/Barlat2004YieldCriterion.ixx b/include/TFEL/Material/Barlat2004YieldCriterion.ixx index db12a9cae..8cee220cd 100644 --- a/include/TFEL/Material/Barlat2004YieldCriterion.ixx +++ b/include/TFEL/Material/Barlat2004YieldCriterion.ixx @@ -17,180 +17,171 @@ #include "TFEL/Math/General/Abs.hxx" #include "TFEL/Material/OrthotropicStressLinearTransformation.hxx" -namespace tfel::material { +namespace tfel::material::internals { - namespace internals { + /*! + * \brief add the terms relative to the eigenvectors derivatives + * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress + * \param[in] dPhi_dvp: first derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] d2Phi_dvp2: second derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + TFEL_HOST_DEVICE constexpr void completeBaralatStressSecondDerivative( + tfel::material::BarlatStressSecondDerivativeType&, + const tfel::math::tvector<3u, + tfel::material::BarlatBaseType>&, + const tfel::math:: + tvector<6u, tfel::material::BarlatInvertStressType>&, + const tfel::math::tvector<3u, BarlatStressType>&, + const tfel::math::tmatrix<3u, 3u, BarlatBaseType>&, + const tfel::material::BarlatStressType) noexcept // + requires(tfel::math::getSpaceDimension() == 1u) { + } // end of completeBaralatStressSecondDerivative + /*! + * \brief add the terms relative to the eigenvectors derivatives + * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress + * \param[in] dPhi_dvp: first derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] d2Phi_dvp2: second derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + TFEL_HOST_DEVICE void completeBaralatStressSecondDerivative( + tfel::material::BarlatStressSecondDerivativeType& + d2Phi_ds2, + const tfel::math::tvector<3u, + tfel::material::BarlatBaseType>& + dPhi_dvp, + const tfel::math::tvector< + 6u, + tfel::material::BarlatInvertStressType>& d2Phi_dvp2, + const tfel::math::tvector<3u, BarlatStressType>& vp, + const tfel::math::tmatrix<3u, 3u, BarlatBaseType>& m, + const tfel::material::BarlatStressType e) // + requires(tfel::math::getSpaceDimension() == 2u) { + using namespace tfel::math; + using base = tfel::material::BarlatBaseType; + constexpr auto icste = Cste::isqrt2; + const tvector<3u, base> v0 = m.template column_view<0u>(); + const tvector<3u, base> v1 = m.template column_view<1u>(); + const stensor<2u, base> n01 = + stensor<2u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * + icste; + if (tfel::math::abs(vp[0] - vp[1]) < e) { + d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[1] - 2 * d2Phi_dvp2[3]) / 2) * + (n01 ^ n01); + } else { + d2Phi_ds2 += (dPhi_dvp[0] - dPhi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); + } + } // end of completeBaralatStressSecondDerivative + /*! + * \brief add the terms relative to the eigenvectors derivatives + * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress + * \param[in] dPhi_dvp: first derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] d2Phi_dvp2: second derivative of the Barlat + * equivalent stress with respect to the eigenvalues + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + TFEL_HOST_DEVICE void completeBaralatStressSecondDerivative( + tfel::material::BarlatStressSecondDerivativeType& + d2Phi_ds2, + const tfel::math::tvector<3u, + tfel::material::BarlatBaseType>& + dPhi_dvp, + const tfel::math::tvector< + 6u, + tfel::material::BarlatInvertStressType>& d2Phi_dvp2, + const tfel::math::tvector<3u, BarlatStressType>& vp, + const tfel::math::tmatrix<3u, 3u, BarlatBaseType>& m, + const tfel::material::BarlatStressType e) // + requires(tfel::math::getSpaceDimension() == 3u) { + using namespace tfel::math; + using base = tfel::material::BarlatBaseType; + constexpr auto cste = Cste::isqrt2; + const tvector<3u, base> v0 = m.template column_view<0u>(); + const tvector<3u, base> v1 = m.template column_view<1u>(); + const tvector<3u, base> v2 = m.template column_view<2u>(); + const stensor<3u, base> n01 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * + cste; + const stensor<3u, base> n02 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v2) * + cste; + const stensor<3u, base> n12 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v1, v2) * + cste; + if (tfel::math::abs(vp[0] - vp[1]) < e) { + d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[1] - 2 * d2Phi_dvp2[3]) / 2) * + (n01 ^ n01); + } else { + d2Phi_ds2 += (dPhi_dvp[0] - dPhi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); + } + if (tfel::math::abs(vp[0] - vp[2]) < e) { + d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[2] - 2 * d2Phi_dvp2[4]) / 2) * + (n02 ^ n02); + } else { + d2Phi_ds2 += (dPhi_dvp[0] - dPhi_dvp[2]) / (vp[0] - vp[2]) * (n02 ^ n02); + } + if (tfel::math::abs(vp[1] - vp[2]) < e) { + d2Phi_ds2 += ((d2Phi_dvp2[1] + d2Phi_dvp2[2] - 2 * d2Phi_dvp2[5]) / 2) * + (n12 ^ n12); + } else { + d2Phi_ds2 += (dPhi_dvp[1] - dPhi_dvp[2]) / (vp[1] - vp[2]) * (n12 ^ n12); + } + } // end of completeBaralatStressSecondDerivative - /*! - * \brief add the terms relative to the eigenvectors derivatives - * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress - * \param[in] dPhi_dvp: first derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] d2Phi_dvp2: second derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - TFEL_HOST_DEVICE typename std::enable_if< - tfel::math::getSpaceDimension() == 1u, - void>::type - completeBaralatStressSecondDerivative( - tfel::material::BarlatStressSecondDerivativeType&, - const tfel::math:: - tvector<3u, tfel::material::BarlatBaseType>&, - const tfel::math:: - tvector<6u, tfel::material::BarlatInvertStressType>&, - const tfel::math::tvector<3u, BarlatStressType>&, - const tfel::math::tmatrix<3u, 3u, BarlatBaseType>&, - const tfel::material::BarlatStressType) { - } // end of completeBaralatStressSecondDerivative - /*! - * \brief add the terms relative to the eigenvectors derivatives - * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress - * \param[in] dPhi_dvp: first derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] d2Phi_dvp2: second derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - TFEL_HOST_DEVICE typename std::enable_if< - tfel::math::getSpaceDimension() == 2u, - void>::type - completeBaralatStressSecondDerivative( - tfel::material::BarlatStressSecondDerivativeType& - d2Phi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::BarlatBaseType>& dPhi_dvp, - const tfel::math::tvector< - 6u, - tfel::material::BarlatInvertStressType>& d2Phi_dvp2, - const tfel::math::tvector<3u, BarlatStressType>& vp, - const tfel::math::tmatrix<3u, 3u, BarlatBaseType>& m, - const tfel::material::BarlatStressType e) { - using namespace tfel::math; - using base = tfel::material::BarlatBaseType; - constexpr auto icste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const stensor<2u, base> n01 = - stensor<2u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - icste; - if (tfel::math::abs(vp[0] - vp[1]) < e) { - d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[1] - 2 * d2Phi_dvp2[3]) / 2) * - (n01 ^ n01); - } else { - d2Phi_ds2 += - (dPhi_dvp[0] - dPhi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); - } - } // end of completeBaralatStressSecondDerivative - /*! - * \brief add the terms relative to the eigenvectors derivatives - * \param[out] d2Phi_ds2: second derivative of the Barlat equivalent stress - * \param[in] dPhi_dvp: first derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] d2Phi_dvp2: second derivative of the Barlat - * equivalent stress with respect to the eigenvalues - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - TFEL_HOST_DEVICE typename std::enable_if< - tfel::math::getSpaceDimension() == 3u, - void>::type - completeBaralatStressSecondDerivative( - tfel::material::BarlatStressSecondDerivativeType& - d2Phi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::BarlatBaseType>& dPhi_dvp, - const tfel::math::tvector< - 6u, - tfel::material::BarlatInvertStressType>& d2Phi_dvp2, - const tfel::math::tvector<3u, BarlatStressType>& vp, - const tfel::math::tmatrix<3u, 3u, BarlatBaseType>& m, - const tfel::material::BarlatStressType e) { - using namespace tfel::math; - using base = tfel::material::BarlatBaseType; - constexpr auto cste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const tvector<3u, base> v2 = m.template column_view<2u>(); - const stensor<3u, base> n01 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - cste; - const stensor<3u, base> n02 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v2) * - cste; - const stensor<3u, base> n12 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v1, v2) * - cste; - if (tfel::math::abs(vp[0] - vp[1]) < e) { - d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[1] - 2 * d2Phi_dvp2[3]) / 2) * - (n01 ^ n01); - } else { - d2Phi_ds2 += - (dPhi_dvp[0] - dPhi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); - } - if (tfel::math::abs(vp[0] - vp[2]) < e) { - d2Phi_ds2 += ((d2Phi_dvp2[0] + d2Phi_dvp2[2] - 2 * d2Phi_dvp2[4]) / 2) * - (n02 ^ n02); - } else { - d2Phi_ds2 += - (dPhi_dvp[0] - dPhi_dvp[2]) / (vp[0] - vp[2]) * (n02 ^ n02); - } - if (tfel::math::abs(vp[1] - vp[2]) < e) { - d2Phi_ds2 += ((d2Phi_dvp2[1] + d2Phi_dvp2[2] - 2 * d2Phi_dvp2[5]) / 2) * - (n12 ^ n12); - } else { - d2Phi_ds2 += - (dPhi_dvp[1] - dPhi_dvp[2]) / (vp[1] - vp[2]) * (n12 ^ n12); - } - } // end of completeBaralatStressSecondDerivative +} // end of namespace tfel::material::internals - } // end namespace internals +namespace tfel::material { template - constexpr tfel::math::st2tost2 makeBarlatLinearTransformation( - const real c12, - const real c21, - const real c13, - const real c31, - const real c23, - const real c32, - const real c44, - const real c55, - const real c66) { + TFEL_HOST_DEVICE constexpr tfel::math::st2tost2 + makeBarlatLinearTransformation(const real c12, + const real c21, + const real c13, + const real c31, + const real c23, + const real c32, + const real c44, + const real c55, + const real c66) noexcept { return makeOrthotropicStressLinearTransformation( c12, c21, c13, c31, c23, c32, c44, c55, c66); } // end of makeBarlatLinearTransformation template - constexpr tfel::math::st2tost2 makeBarlatLinearTransformation( - const tfel::math::fsarray<9u, real>& c) { + TFEL_HOST_DEVICE constexpr tfel::math::st2tost2 + makeBarlatLinearTransformation( + const tfel::math::fsarray<9u, real>& c) noexcept { return makeOrthotropicStressLinearTransformation(c); } // end of makeBarlatLinearTransformation template - constexpr tfel::math::st2tost2::value, - real> - makeBarlatLinearTransformation(const real c12, - const real c21, - const real c13, - const real c31, - const real c23, - const real c32, - const real c44, - const real c55, - const real c66) { + TFEL_HOST_DEVICE constexpr tfel::math:: + st2tost2::value, real> + makeBarlatLinearTransformation(const real c12, + const real c21, + const real c13, + const real c31, + const real c23, + const real c32, + const real c44, + const real c55, + const real c66) noexcept { return makeOrthotropicStressLinearTransformation( c12, c21, c13, c31, c23, c32, c44, c55, c66); } // end of makeBarlatLinearTransformation @@ -198,13 +189,14 @@ namespace tfel::material { template - constexpr tfel::math::st2tost2::value, - real> - makeBarlatLinearTransformation(const tfel::math::fsarray<9u, real>& c) { + TFEL_HOST_DEVICE constexpr tfel::math:: + st2tost2::value, real> + makeBarlatLinearTransformation( + const tfel::math::fsarray<9u, real>& c) noexcept { return makeOrthotropicStressLinearTransformation(c); } // end of makeBarlatLinearTransformation - template BarlatStressType computeBarlatStress( @@ -236,7 +228,7 @@ namespace tfel::material { 1 / real(a)); } // end of computeBarlatStress - template std::tuple, @@ -333,7 +325,8 @@ namespace tfel::material { return std::make_tuple(Phi, eval(dPhi_ds1 * l1 + dPhi_ds2 * l2)); } // end of computeBarlatStressNormal - template + template BarlatStressAndDerivativesWithRespectToEigenvalues computeBarlatStressSecondDerivative( const tfel::math::tvector<3u, BarlatStressType>& vp1, @@ -446,7 +439,7 @@ namespace tfel::material { return d; } // end of BarlatStressSecondDerivative - template std::tuple, diff --git a/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.hxx b/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.hxx deleted file mode 100644 index 89b7e5886..000000000 --- a/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.hxx +++ /dev/null @@ -1,130 +0,0 @@ -/*! - * \file include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.hxx - * \brief - * \author Thomas Helfer - * \date 15/11/2017 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence - * or the CECILL-A licence. A copy of thoses licences are delivered - * with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#ifndef LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_HXX -#define LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_HXX - -#include "TFEL/Math/stensor.hxx" -#include "TFEL/Math/st2tost2.hxx" - -namespace tfel::material { - - //! a simple alias - template - using CazacuStressType = tfel::math::numeric_type; - //! a simple alias - template - using CazacuBaseType = - tfel::typetraits::base_type>; - //! a simple alias - template - using CazacuInvertStressType = - tfel::math::result_type, - CazacuStressType, - tfel::math::OpDiv>; - //! a simple alias - template - using CazacuStressNormalType = - tfel::math::stensor(), - CazacuBaseType>; - //! a simple alias - template - using CazacuStressEigenTensorType = - tfel::math::stensor(), - CazacuBaseType>; - //! a simple alias - template - using CazacuStressSecondDerivativeType = - tfel::math::st2tost2(), - CazacuInvertStressType>; - /*! - * \brief compute the Cazacu 2006 yield stress defined as follows: - * \f[ - * \phi\left(\underline{\bf sig}\right) = - * \sqrt[a]{ - * \left(\left|S_{1}|-k\,S_{1}\right)^{a} - * \left(\left|S_{1}|-k\,S_{2}\right)^{a} - * \left(\left|S_{3}|-k\,S_{3}\right)^{a} - * } - * \f] - * where \f$S_{1}\f$, \f$S_{2}\f$, and \f$S_{3}\f$, are the - * eigenvalues of the deviatoric part of the stress tensor. - * - * \tparam StressStensor: type of the stress tensor - * \tparam CazacuExponentType: type of the hosford exponent - * (could be a numeric type or an integer type) - * \tparam es: eigen solver to be used - * \param[in] sig: stress tensor - * \param[in] a: Cazacu exponent - * \param[in] k: Cazacu coefficient - * \param[in] e: criterion used to check if the stress are null - */ - template - TFEL_HOST_DEVICE CazacuStressType - computeCazacu2006IsotropicStress(const StressStensor&, - const CazacuExponentType, - const CazacuBaseType, - const CazacuStressType); - /*! - * \brief compute the Cazacu yield stress and the its first derivative - * \tparam StressStensor: type of the stress tensor - * \tparam CazacuExponentType: type of the hosford exponent - * (could be a numeric type or an integer type) - * \tparam es: eigen solver to be used - * \param[in] sig: stress tensor - * \param[in] a: Cazacu exponent - * \param[in] k: Cazacu coefficient - * \param[in] e: criterion used to check if the stress are null - */ - template - TFEL_HOST_DEVICE std::tuple, - CazacuStressNormalType> - computeCazacu2006IsotropicStressNormal(const StressStensor&, - const CazacuExponentType, - const CazacuBaseType, - const CazacuStressType); - /*! - * \brief compute the Cazacu yield stress and its first and second derivatives - * \tparam StressStensor: type of the stress tensor - * \tparam CazacuExponentType: type of the hosford exponent - * (could be a numeric type or an integer type) - * \tparam es: eigen solver to be used - * \param[in] sig: stress tensor - * \param[in] a: Cazacu exponent - * \param[in] k: Cazacu coefficient - * \param[in] e: criterion used to check if the stress are null - */ - template - TFEL_HOST_DEVICE std::tuple, - CazacuStressNormalType, - CazacuStressSecondDerivativeType> - computeCazacu2006IsotropicStressSecondDerivative( - const StressStensor&, - const CazacuExponentType, - const CazacuBaseType, - const CazacuStressType); - -} // end of namespace tfel::material - -#include "TFEL/Material/Cazacu2006IsotropicYieldCriterion.ixx" - -#endif /* LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_HXX */ diff --git a/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.ixx b/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.ixx deleted file mode 100644 index 958db015b..000000000 --- a/include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.ixx +++ /dev/null @@ -1,350 +0,0 @@ -/*! - * \file include/TFEL/Material/Cazacu2006IsotropicYieldCriterion.ixx - * \brief - * \author Thomas Helfer - * \date 15/11/2017 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence - * or the CECILL-A licence. A copy of thoses licences are delivered - * with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#ifndef LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_IXX -#define LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_IXX - -#include -#include -#include -#include "TFEL/Math/General/Abs.hxx" - -namespace tfel::material { - - namespace internals { - - /*! - * \brief compute the second derivative of the Cazacu equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Cazacu equivalent stress - * \param[in] dPsi_dvp: first derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 1u, - void>::type - computeCazacu2006IsotropicStressSecondDerivative( - tfel::material::CazacuStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math:: - tvector<3u, tfel::material::CazacuBaseType>&, - const tfel::math::tvector< - 6u, - tfel::material::CazacuInvertStressType>& d2Psi_dvp2, - const tfel::material::CazacuStressEigenTensorType&, - const tfel::material::CazacuStressEigenTensorType&, - const tfel::material::CazacuStressEigenTensorType&, - const tfel::math::tvector<3u, CazacuStressType>&, - const tfel::math::tmatrix<3u, 3u, CazacuBaseType>&, - const tfel::material::CazacuStressType) { - d2Psi_ds2 = {d2Psi_dvp2[0], d2Psi_dvp2[3], d2Psi_dvp2[4], - d2Psi_dvp2[3], d2Psi_dvp2[1], d2Psi_dvp2[5], - d2Psi_dvp2[4], d2Psi_dvp2[5], d2Psi_dvp2[2]}; - } // end of computeCazacu2006IsotropicStressSecondDerivative - /*! - * \brief compute the second derivative of the Cazacu equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Cazacu equivalent stress - * \param[in] dPsi_dvp: first derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 2u, - void>::type - computeCazacu2006IsotropicStressSecondDerivative( - tfel::material::CazacuStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::CazacuBaseType>& dPsi_dvp, - const tfel::math::tvector< - 6u, - tfel::material::CazacuInvertStressType>& d2Psi_dvp2, - const tfel::material::CazacuStressEigenTensorType& n0, - const tfel::material::CazacuStressEigenTensorType& n1, - const tfel::material::CazacuStressEigenTensorType& n2, - const tfel::math::tvector<3u, CazacuStressType>& vp, - const tfel::math::tmatrix<3u, 3u, CazacuBaseType>& m, - const tfel::material::CazacuStressType e) { - using namespace tfel::math; - using base = tfel::material::CazacuBaseType; - constexpr auto icste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const stensor<2u, base> n01 = - stensor<2u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - icste; - d2Psi_ds2 = (d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[1] * (n1 ^ n1) + - d2Psi_dvp2[2] * (n2 ^ n2)); - if (tfel::math::abs(vp(0) - vp(1)) < e) { - d2Psi_ds2 += ((d2Psi_dvp2[0] + d2Psi_dvp2[1]) / 2) * (n01 ^ n01); - } else { - // 0 1 2 3 4 5 - // s1s1 s2s2 s3s3 s1s2 s1s3 s2s3 - d2Psi_ds2 += - (dPsi_dvp[0] - dPsi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); - } - } // end of computeCazacu2006IsotropicStressSecondDerivative - /*! - * \brief compute the second derivative of the Cazacu equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Cazacu equivalent stress - * \param[in] dPsi_dvp: first derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Cazacu - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 3u, - void>::type - computeCazacu2006IsotropicStressSecondDerivative( - tfel::material::CazacuStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::CazacuBaseType>& dPsi_dvp, - const tfel::math::tvector< - 3u, - tfel::material::CazacuInvertStressType>& d2Psi_dvp2, - const tfel::material::CazacuStressEigenTensorType& n0, - const tfel::material::CazacuStressEigenTensorType& n1, - const tfel::material::CazacuStressEigenTensorType& n2, - const tfel::math::tvector<3u, CazacuStressType>& vp, - const tfel::math::tmatrix<3u, 3u, CazacuBaseType>& m, - const tfel::material::CazacuStressType e) { - using namespace tfel::math; - using base = tfel::material::CazacuBaseType; - constexpr auto cste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const tvector<3u, base> v2 = m.template column_view<2u>(); - const stensor<3u, base> n01 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - cste; - const stensor<3u, base> n02 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v2) * - cste; - const stensor<3u, base> n12 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v1, v2) * - cste; - d2Psi_ds2 = d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[1] * (n1 ^ n1) + - d2Psi_dvp2[2] * (n2 ^ n2); - if ((tfel::math::abs(vp(0) - vp(1)) < e) && - (tfel::math::abs(vp(0) - vp(2)) < e)) { - d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[1]) / 2) * (n01 ^ n01) + - ((d2Psi_dvp2[0] + d2Psi_dvp2[2]) / 2) * (n02 ^ n02) + - ((d2Psi_dvp2[1] + d2Psi_dvp2[2]) / 2) * (n12 ^ n12)); - } else if (tfel::math::abs(vp(0) - vp(1)) < e) { - d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[1]) / 2) * (n01 ^ n01) + - dPsi_dvp[0] * (n02 ^ n02) / (vp[0] - vp[2]) + - dPsi_dvp[1] * (n12 ^ n12) / (vp[1] - vp[2]) + - dPsi_dvp[2] * ((n12 ^ n12) / (vp[2] - vp[1]) + - (n02 ^ n02) / (vp[2] - vp[0]))); - } else if (tfel::math::abs(vp(0) - vp(2)) < e) { - d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[2]) / 2) * (n02 ^ n02) + - dPsi_dvp[1] * ((n01 ^ n01) / (vp[1] - vp[0]) + - (n12 ^ n12) / (vp[1] - vp[2])) + - dPsi_dvp[0] * (n01 ^ n01) / (vp[0] - vp[1]) + - dPsi_dvp[2] * (n12 ^ n12) / (vp[2] - vp[1])); - } else if (tfel::math::abs(vp(1) - vp(2)) < e) { - d2Psi_ds2 += (((d2Psi_dvp2[1] + d2Psi_dvp2[2]) / 2) * (n12 ^ n12) + - dPsi_dvp[0] * ((n01 ^ n01) / (vp[0] - vp[1]) + - (n02 ^ n02) / (vp[0] - vp[2])) + - dPsi_dvp[1] * (n01 ^ n01) / (vp[1] - vp[0]) + - dPsi_dvp[2] * (n02 ^ n02) / (vp[2] - vp[0])); - } else { - d2Psi_ds2 += (dPsi_dvp[0] * ((n01 ^ n01) / (vp[0] - vp[1]) + - (n02 ^ n02) / (vp[0] - vp[2])) + - dPsi_dvp[1] * ((n01 ^ n01) / (vp[1] - vp[0]) + - (n12 ^ n12) / (vp[1] - vp[2])) + - dPsi_dvp[2] * ((n12 ^ n12) / (vp[2] - vp[1]) + - (n02 ^ n02) / (vp[2] - vp[0]))); - } - } // end of computeCazacu2006IsotropicStressSecondDerivative - - } // end of namespace internals - - template - CazacuStressType computeCazacu2006IsotropicStress( - const StressStensor& sig, - const CazacuExponentType a, - const CazacuBaseType k, - const CazacuStressType e) { - using real = CazacuBaseType; - const auto seq = sigmaeq(s); - if (seq < e) { - return seq * 0; - } - const auto iseq = 1 / seq; - const auto s = deviator(sig); - const auto vp = s.template computeEigenValues() * iseq; - return seq * - std::pow( - std::pow(tfel::math::abs(tfel::math::abs(vp[0]) - k * vp[0]), - a) + - std::pow(tfel::math::abs(tfel::math::abs(vp[1]) - k * vp[1]), - a) + - std::pow(tfel::math::abs(tfel::math::abs(vp[2]) - k * vp[2]), - a), - 1 / real(a)); - } // end of computeCazacu2006IsotropicYieldStress - - template - std::tuple, - CazacuStressNormalType> - computeCazacu2006IsotropicStressNormal( - const StressStensor& sig, - const CazacuExponentType a, - const CazacuBaseType k, - const CazacuStressType e) { - constexpr auto N = tfel::math::getSpaceDimension(); - using stress = CazacuStressType; - using real = CazacuBaseType; - using normal = CazacuStressNormalType; - // Von Mises stress used to normalise the stress eigenvalues - const auto s = deviator(sig); - const auto seq = sigmaeq(s); - if (seq < e) { - return std::make_tuple(stress{0}, normal{real{0}}); - } - const auto iseq = 1 / seq; - // no structured bindings yet - tfel::math::tvector<3u, stress> vp; - tfel::math::tmatrix<3u, 3u, real> m; - std::tie(vp, m) = s.template computeEigenVectors(); - const auto n = tfel::math::stensor::computeEigenTensors(m); - // eigenvalues are normalised by the Von Mises stress to avoid - // overflow - const auto rvp = vp * iseq; - const real r[3] = {tfel::math::abs(tfel::math::abs(rvp[0]) - k * rvp[0]), - tfel::math::abs(tfel::math::abs(rvp[1]) - k * rvp[1]), - tfel::math::abs(tfel::math::abs(rvp[2]) - k * rvp[2])}; - const real rPsi_am1[3] = {std::pow(r[0], a - 1), std::pow(r[1], a - 1), - std::pow(r[2], a - 1)}; - const real rPsi_a = - rPsi_am1[0] * r[0] + rPsi_am1[1] * r[1] + rPsi_am1[2] * r[2]; - // Cazacu equivalent stress - const real Psi = seq * std::pow(rPsi_a, 1 / real(a)); - - constexpr auto K = tfel::math::st2tost2::K(); - const auto dPsi_ds = ...; - return std::make_tuple(Psi, eval(dPsi_ds * K)); - } // end of computeCazacu2006IsotropicStressNormal - - template - std::tuple, - CazacuStressNormalType, - CazacuStressSecondDerivativeType> - computeCazacu2006IsotropicStressSecondDerivative( - const StressStensor& sig, - const CazacuExponentType a, - const CazacuBaseType k, - const CazacuStressType e) { - constexpr auto N = tfel::math::getSpaceDimension(); - using stress = CazacuStressType; - using real = CazacuBaseType; - using istress = tfel::math::result_type; - using normal = CazacuStressNormalType; - using second_derivative = CazacuStressSecondDerivativeType; - const auto s = deviator(sig); - // Von Mises stress used to normalise the stress eigenvalues - const auto seq = sigmaeq(s); - if (seq < e) { - return std::make_tuple(stress{0}, normal{real{0}}, - n second_derivative{istress{0}}); - } - const auto iseq = 1 / seq; - // no structured bindings yet - tfel::math::tvector<3u, stress> vp; - tfel::math::tmatrix<3u, 3u, real> m; - std::tie(vp, m) = s.template computeEigenVectors(); - const auto n = tfel::math::stensor::computeEigenTensors(m); - // eigenvalues are normalised by the Von Mises stress to avoid - // overflow - const auto rvp = vp * iseq; - const real Psi_a = - (std::pow(tfel::math::abs(tfel::math::abs(vp[0]) - k * vp[0]), a) + - std::pow(tfel::math::abs(tfel::math::abs(vp[1]) - k * vp[1]), a) + - std::pow(tfel::math::abs(tfel::math::abs(vp[2]) - k * vp[2]), a)); - // Cazacu equivalent stress - const real Psi = seq * std::pow(Psi_a, 1 / real(a)); - // For the derivatives, the stress eigenvalues are normalised by - // the Cazacu equivalent stress - const auto rvp2 = vp / Psi; - // first derivative of the Cazacu stress - // const tfel::math::tvector<3u,real> drvp2 = {rvp2[0]-rvp2[1], - // rvp2[0]-rvp2[2], - // rvp2[1]-rvp2[2]}; - // const tfel::math::tvector<3u,real> drvp2_am2 = - // {real(std::pow(tfel::math::abs(drvp2[0]),a-2)), - // real(std::pow(tfel::math::abs(drvp2[1]),a-2)), - // real(std::pow(tfel::math::abs(drvp2[2]),a-2))}; - // const tfel::math::tvector<3u,real> dPsi_dsvp = - // {( drvp2[0]*drvp2_am2[0]+drvp2[1]*drvp2_am2[1])/2, - // (-drvp2[0]*drvp2_am2[0]+drvp2[2]*drvp2_am2[2])/2, - // (-drvp2[1]*drvp2_am2[1]-drvp2[2]*drvp2_am2[2])/2}; - // const auto dPsi_ds = tfel::math::eval(dPsi_dsvp[0]*std::get<0>(n)+ - // dPsi_dsvp[1]*std::get<1>(n)+ - // dPsi_dsvp[2]*std::get<2>(n)); - // // second derivative - // const auto cste = (a-1)/Psi; - // const tfel::math::tvector<6u,istress> d2Psi_dsvp2 = - // {cste*( (drvp2_am2[0]+drvp2_am2[1])/2-dPsi_dsvp[0]*dPsi_dsvp[0]), // - // s1s1 cste*( - // (drvp2_am2[0]+drvp2_am2[2])/2-dPsi_dsvp[1]*dPsi_dsvp[1]), - // // s2s2 cste*( - // (drvp2_am2[1]+drvp2_am2[2])/2-dPsi_dsvp[2]*dPsi_dsvp[2]), // s3s3 - // cste*(-(drvp2_am2[0])/2-dPsi_dsvp[0]*dPsi_dsvp[1]), // s1s2 - // cste*(-(drvp2_am2[1])/2-dPsi_dsvp[0]*dPsi_dsvp[2]), // s1s3 - // cste*(-(drvp2_am2[2])/2-dPsi_dsvp[1]*dPsi_dsvp[2])}; // s2s3 - tfel::math::st2tost2 d2Psi_ds2; - internals::computeCazacu2006IsotropicStressSecondDerivative( - d2Psi_ds2, dPsi_dsvp, d2Psi_dsvp2, std::get<0>(n), std::get<1>(n), - std::get<2>(n), vp, m, e); - constexpr auto K = tfel::math::st2tost2::K(); - // K is symmetric, so we can write K*d2Psi_ds2*K rather than - // transpose(K)*d2Psi_ds2*K - return std::make_tuple(Psi, eval(dPsi_ds * K), eval(K * d2Psi_ds2 * K)); - } // end of computeCazacu2006IsotropicSecondDerivative - -} // end of namespace tfel::material - -#endif /* LIB_TFEL_MATERIAL_CAZACU2006ISOTROPICYIELDCRITERION_IXX */ diff --git a/include/TFEL/Material/Hosford1972YieldCriterion.hxx b/include/TFEL/Material/Hosford1972YieldCriterion.hxx index fb2bf5a78..cfe2f8cad 100644 --- a/include/TFEL/Material/Hosford1972YieldCriterion.hxx +++ b/include/TFEL/Material/Hosford1972YieldCriterion.hxx @@ -20,30 +20,30 @@ namespace tfel::material { //! a simple alias - template + template using HosfordStressType = tfel::math::numeric_type; //! a simple alias - template + template using HosfordBaseType = tfel::typetraits::base_type>; //! a simple alias - template + template using HosfordInvertStressType = tfel::math::result_type, HosfordStressType, tfel::math::OpDiv>; //! a simple alias - template + template using HosfordStressNormalType = tfel::math::stensor(), HosfordBaseType>; //! a simple alias - template + template using HosfordStressEigenTensorType = tfel::math::stensor(), HosfordBaseType>; //! a simple alias - template + template using HosfordStressSecondDerivativeType = tfel::math::st2tost2(), HosfordInvertStressType>; @@ -57,7 +57,7 @@ namespace tfel::material { * \param[in] a: Hosford exponent * \param[in] e: criterion used to check if the stress are null */ - template @@ -75,7 +75,7 @@ namespace tfel::material { * \param[in] a: Hosford exponent * \param[in] e: criterion used to check if the stress are null */ - template @@ -95,7 +95,7 @@ namespace tfel::material { * \param[in] a: Hosford exponent * \param[in] e: criterion used to check if the stress are null */ - template diff --git a/include/TFEL/Material/Hosford1972YieldCriterion.ixx b/include/TFEL/Material/Hosford1972YieldCriterion.ixx index 7e8c76a4d..1d96d52d3 100644 --- a/include/TFEL/Material/Hosford1972YieldCriterion.ixx +++ b/include/TFEL/Material/Hosford1972YieldCriterion.ixx @@ -19,204 +19,194 @@ #include #include "TFEL/Math/General/Abs.hxx" -namespace tfel::material { +namespace tfel::material::internals { - namespace internals { + /*! + * \brief compute the second derivative of the Hosford equivalent stress + * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent + * stress + * \param[in] dPsi_dvp: first derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] d2Psi_dvp2: second derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] n0: first eigen tensor + * \param[in] n1: second eigen tensor + * \param[in] n2: third eigen tensor + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + void computeHosfordStressSecondDerivative( + tfel::material::HosfordStressSecondDerivativeType& + d2Psi_ds2, + const tfel::math:: + tvector<3u, tfel::material::HosfordBaseType>&, + const tfel::math::tvector< + 6u, + tfel::material::HosfordInvertStressType>& d2Psi_dvp2, + const tfel::material::HosfordStressEigenTensorType&, + const tfel::material::HosfordStressEigenTensorType&, + const tfel::material::HosfordStressEigenTensorType&, + const tfel::math::tvector<3u, HosfordStressType>&, + const tfel::math::tmatrix<3u, 3u, HosfordBaseType>&, + const tfel::material::HosfordStressType) // + requires(tfel::math::getSpaceDimension() == 1u) { + d2Psi_ds2 = {d2Psi_dvp2[0], d2Psi_dvp2[3], d2Psi_dvp2[4], + d2Psi_dvp2[3], d2Psi_dvp2[1], d2Psi_dvp2[5], + d2Psi_dvp2[4], d2Psi_dvp2[5], d2Psi_dvp2[2]}; + } // end of computeHosfordStressSecondDerivative + /*! + * \brief compute the second derivative of the Hosford equivalent stress + * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent + * stress + * \param[in] dPsi_dvp: first derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] d2Psi_dvp2: second derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] n0: first eigen tensor + * \param[in] n1: second eigen tensor + * \param[in] n2: third eigen tensor + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + void computeHosfordStressSecondDerivative( + tfel::material::HosfordStressSecondDerivativeType& + d2Psi_ds2, + const tfel::math::tvector<3u, + tfel::material::HosfordBaseType>& + dPsi_dvp, + const tfel::math::tvector< + 6u, + tfel::material::HosfordInvertStressType>& d2Psi_dvp2, + const tfel::material::HosfordStressEigenTensorType& n0, + const tfel::material::HosfordStressEigenTensorType& n1, + const tfel::material::HosfordStressEigenTensorType& n2, + const tfel::math::tvector<3u, HosfordStressType>& vp, + const tfel::math::tmatrix<3u, 3u, HosfordBaseType>& m, + const tfel::material::HosfordStressType e) // + requires(tfel::math::getSpaceDimension() == 2u) { + using namespace tfel::math; + using base = tfel::material::HosfordBaseType; + constexpr auto icste = Cste::isqrt2; + const tvector<3u, base> v0 = m.template column_view<0u>(); + const tvector<3u, base> v1 = m.template column_view<1u>(); + const stensor<2u, base> n01 = + stensor<2u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * + icste; + d2Psi_ds2 = (d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[3] * (n0 ^ n1) + + d2Psi_dvp2[4] * (n0 ^ n2) + d2Psi_dvp2[1] * (n1 ^ n1) + + d2Psi_dvp2[3] * (n1 ^ n0) + d2Psi_dvp2[5] * (n1 ^ n2) + + d2Psi_dvp2[2] * (n2 ^ n2) + d2Psi_dvp2[4] * (n2 ^ n0) + + d2Psi_dvp2[5] * (n2 ^ n1)); + if (tfel::math::abs(vp(0) - vp(1)) < e) { + d2Psi_ds2 += ((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * + (n01 ^ n01); + } else { + // 0 1 2 3 4 5 + // s1s1 s2s2 s3s3 s1s2 s1s3 s2s3 + d2Psi_ds2 += (dPsi_dvp[0] - dPsi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); + } + } // end of computeHosfordStressSecondDerivative + /*! + * \brief compute the second derivative of the Hosford equivalent stress + * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent + * stress + * \param[in] dPsi_dvp: first derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] d2Psi_dvp2: second derivative of the Hosford + * equivalent stress with respect to the eigenvalue + * \param[in] n0: first eigen tensor + * \param[in] n1: second eigen tensor + * \param[in] n2: third eigen tensor + * \param[in] vp: eigen values + * \param[in] m: matrix for the eigen vectors + * \param[in] e: criterion used to check if two eigenvalues are equal + */ + template + void computeHosfordStressSecondDerivative( + tfel::material::HosfordStressSecondDerivativeType& + d2Psi_ds2, + const tfel::math::tvector<3u, + tfel::material::HosfordBaseType>& + dPsi_dvp, + const tfel::math::tvector< + 6u, + tfel::material::HosfordInvertStressType>& d2Psi_dvp2, + const tfel::material::HosfordStressEigenTensorType& n0, + const tfel::material::HosfordStressEigenTensorType& n1, + const tfel::material::HosfordStressEigenTensorType& n2, + const tfel::math::tvector<3u, HosfordStressType>& vp, + const tfel::math::tmatrix<3u, 3u, HosfordBaseType>& m, + const tfel::material::HosfordStressType e) // + requires(tfel::math::getSpaceDimension() == 3u) { + using namespace tfel::math; + using base = tfel::material::HosfordBaseType; + constexpr auto cste = Cste::isqrt2; + const tvector<3u, base> v0 = m.template column_view<0u>(); + const tvector<3u, base> v1 = m.template column_view<1u>(); + const tvector<3u, base> v2 = m.template column_view<2u>(); + const stensor<3u, base> n01 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * + cste; + const stensor<3u, base> n02 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v2) * + cste; + const stensor<3u, base> n12 = + stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v1, v2) * + cste; + d2Psi_ds2 = d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[3] * (n0 ^ n1) + + d2Psi_dvp2[4] * (n0 ^ n2) + d2Psi_dvp2[1] * (n1 ^ n1) + + d2Psi_dvp2[3] * (n1 ^ n0) + d2Psi_dvp2[5] * (n1 ^ n2) + + d2Psi_dvp2[2] * (n2 ^ n2) + d2Psi_dvp2[4] * (n2 ^ n0) + + d2Psi_dvp2[5] * (n2 ^ n1); + if ((tfel::math::abs(vp(0) - vp(1)) < e) && + (tfel::math::abs(vp(0) - vp(2)) < e)) { + d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * + (n01 ^ n01) + + ((d2Psi_dvp2[0] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[4]) / 2) * + (n02 ^ n02) + + ((d2Psi_dvp2[1] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[5]) / 2) * + (n12 ^ n12)); + } else if (tfel::math::abs(vp(0) - vp(1)) < e) { + d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * + (n01 ^ n01) + + dPsi_dvp[0] * (n02 ^ n02) / (vp[0] - vp[2]) + + dPsi_dvp[1] * (n12 ^ n12) / (vp[1] - vp[2]) + + dPsi_dvp[2] * ((n12 ^ n12) / (vp[2] - vp[1]) + + (n02 ^ n02) / (vp[2] - vp[0]))); + } else if (tfel::math::abs(vp(0) - vp(2)) < e) { + d2Psi_ds2 += (((d2Psi_dvp2[0] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[4]) / 2) * + (n02 ^ n02) + + dPsi_dvp[1] * ((n01 ^ n01) / (vp[1] - vp[0]) + + (n12 ^ n12) / (vp[1] - vp[2])) + + dPsi_dvp[0] * (n01 ^ n01) / (vp[0] - vp[1]) + + dPsi_dvp[2] * (n12 ^ n12) / (vp[2] - vp[1])); + } else if (tfel::math::abs(vp(1) - vp(2)) < e) { + d2Psi_ds2 += (((d2Psi_dvp2[1] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[5]) / 2) * + (n12 ^ n12) + + dPsi_dvp[0] * ((n01 ^ n01) / (vp[0] - vp[1]) + + (n02 ^ n02) / (vp[0] - vp[2])) + + dPsi_dvp[1] * (n01 ^ n01) / (vp[1] - vp[0]) + + dPsi_dvp[2] * (n02 ^ n02) / (vp[2] - vp[0])); + } else { + d2Psi_ds2 += + (dPsi_dvp[0] * + ((n01 ^ n01) / (vp[0] - vp[1]) + (n02 ^ n02) / (vp[0] - vp[2])) + + dPsi_dvp[1] * + ((n01 ^ n01) / (vp[1] - vp[0]) + (n12 ^ n12) / (vp[1] - vp[2])) + + dPsi_dvp[2] * + ((n12 ^ n12) / (vp[2] - vp[1]) + (n02 ^ n02) / (vp[2] - vp[0]))); + } + } // end of computeHosfordStressSecondDerivative - /*! - * \brief compute the second derivative of the Hosford equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent - * stress - * \param[in] dPsi_dvp: first derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 1u, - void>::type - computeHosfordStressSecondDerivative( - tfel::material::HosfordStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math:: - tvector<3u, tfel::material::HosfordBaseType>&, - const tfel::math::tvector< - 6u, - tfel::material::HosfordInvertStressType>& d2Psi_dvp2, - const tfel::material::HosfordStressEigenTensorType&, - const tfel::material::HosfordStressEigenTensorType&, - const tfel::material::HosfordStressEigenTensorType&, - const tfel::math::tvector<3u, HosfordStressType>&, - const tfel::math::tmatrix<3u, 3u, HosfordBaseType>&, - const tfel::material::HosfordStressType) { - d2Psi_ds2 = {d2Psi_dvp2[0], d2Psi_dvp2[3], d2Psi_dvp2[4], - d2Psi_dvp2[3], d2Psi_dvp2[1], d2Psi_dvp2[5], - d2Psi_dvp2[4], d2Psi_dvp2[5], d2Psi_dvp2[2]}; - } // end of computeHosfordStressSecondDerivative - /*! - * \brief compute the second derivative of the Hosford equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent - * stress - * \param[in] dPsi_dvp: first derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 2u, - void>::type - computeHosfordStressSecondDerivative( - tfel::material::HosfordStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::HosfordBaseType>& dPsi_dvp, - const tfel::math::tvector< - 6u, - tfel::material::HosfordInvertStressType>& d2Psi_dvp2, - const tfel::material::HosfordStressEigenTensorType& n0, - const tfel::material::HosfordStressEigenTensorType& n1, - const tfel::material::HosfordStressEigenTensorType& n2, - const tfel::math::tvector<3u, HosfordStressType>& vp, - const tfel::math::tmatrix<3u, 3u, HosfordBaseType>& m, - const tfel::material::HosfordStressType e) { - using namespace tfel::math; - using base = tfel::material::HosfordBaseType; - constexpr auto icste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const stensor<2u, base> n01 = - stensor<2u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - icste; - d2Psi_ds2 = (d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[3] * (n0 ^ n1) + - d2Psi_dvp2[4] * (n0 ^ n2) + d2Psi_dvp2[1] * (n1 ^ n1) + - d2Psi_dvp2[3] * (n1 ^ n0) + d2Psi_dvp2[5] * (n1 ^ n2) + - d2Psi_dvp2[2] * (n2 ^ n2) + d2Psi_dvp2[4] * (n2 ^ n0) + - d2Psi_dvp2[5] * (n2 ^ n1)); - if (tfel::math::abs(vp(0) - vp(1)) < e) { - d2Psi_ds2 += ((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * - (n01 ^ n01); - } else { - // 0 1 2 3 4 5 - // s1s1 s2s2 s3s3 s1s2 s1s3 s2s3 - d2Psi_ds2 += - (dPsi_dvp[0] - dPsi_dvp[1]) / (vp[0] - vp[1]) * (n01 ^ n01); - } - } // end of computeHosfordStressSecondDerivative - /*! - * \brief compute the second derivative of the Hosford equivalent stress - * \param[out] d2Psi_ds2: second derivative of the Hosford equivalent - * stress - * \param[in] dPsi_dvp: first derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] d2Psi_dvp2: second derivative of the Hosford - * equivalent stress with respect to the eigenvalue - * \param[in] n0: first eigen tensor - * \param[in] n1: second eigen tensor - * \param[in] n2: third eigen tensor - * \param[in] vp: eigen values - * \param[in] m: matrix for the eigen vectors - * \param[in] e: criterion used to check if two eigenvalues are equal - */ - template - typename std::enable_if() == - 3u, - void>::type - computeHosfordStressSecondDerivative( - tfel::material::HosfordStressSecondDerivativeType& - d2Psi_ds2, - const tfel::math::tvector< - 3u, - tfel::material::HosfordBaseType>& dPsi_dvp, - const tfel::math::tvector< - 6u, - tfel::material::HosfordInvertStressType>& d2Psi_dvp2, - const tfel::material::HosfordStressEigenTensorType& n0, - const tfel::material::HosfordStressEigenTensorType& n1, - const tfel::material::HosfordStressEigenTensorType& n2, - const tfel::math::tvector<3u, HosfordStressType>& vp, - const tfel::math::tmatrix<3u, 3u, HosfordBaseType>& m, - const tfel::material::HosfordStressType e) { - using namespace tfel::math; - using base = tfel::material::HosfordBaseType; - constexpr auto cste = Cste::isqrt2; - const tvector<3u, base> v0 = m.template column_view<0u>(); - const tvector<3u, base> v1 = m.template column_view<1u>(); - const tvector<3u, base> v2 = m.template column_view<2u>(); - const stensor<3u, base> n01 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v1) * - cste; - const stensor<3u, base> n02 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v0, v2) * - cste; - const stensor<3u, base> n12 = - stensor<3u, base>::buildFromVectorsSymmetricDiadicProduct(v1, v2) * - cste; - d2Psi_ds2 = d2Psi_dvp2[0] * (n0 ^ n0) + d2Psi_dvp2[3] * (n0 ^ n1) + - d2Psi_dvp2[4] * (n0 ^ n2) + d2Psi_dvp2[1] * (n1 ^ n1) + - d2Psi_dvp2[3] * (n1 ^ n0) + d2Psi_dvp2[5] * (n1 ^ n2) + - d2Psi_dvp2[2] * (n2 ^ n2) + d2Psi_dvp2[4] * (n2 ^ n0) + - d2Psi_dvp2[5] * (n2 ^ n1); - if ((tfel::math::abs(vp(0) - vp(1)) < e) && - (tfel::math::abs(vp(0) - vp(2)) < e)) { - d2Psi_ds2 += - (((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * - (n01 ^ n01) + - ((d2Psi_dvp2[0] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[4]) / 2) * - (n02 ^ n02) + - ((d2Psi_dvp2[1] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[5]) / 2) * - (n12 ^ n12)); - } else if (tfel::math::abs(vp(0) - vp(1)) < e) { - d2Psi_ds2 += - (((d2Psi_dvp2[0] + d2Psi_dvp2[1] - 2 * d2Psi_dvp2[3]) / 2) * - (n01 ^ n01) + - dPsi_dvp[0] * (n02 ^ n02) / (vp[0] - vp[2]) + - dPsi_dvp[1] * (n12 ^ n12) / (vp[1] - vp[2]) + - dPsi_dvp[2] * ((n12 ^ n12) / (vp[2] - vp[1]) + - (n02 ^ n02) / (vp[2] - vp[0]))); - } else if (tfel::math::abs(vp(0) - vp(2)) < e) { - d2Psi_ds2 += - (((d2Psi_dvp2[0] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[4]) / 2) * - (n02 ^ n02) + - dPsi_dvp[1] * ((n01 ^ n01) / (vp[1] - vp[0]) + - (n12 ^ n12) / (vp[1] - vp[2])) + - dPsi_dvp[0] * (n01 ^ n01) / (vp[0] - vp[1]) + - dPsi_dvp[2] * (n12 ^ n12) / (vp[2] - vp[1])); - } else if (tfel::math::abs(vp(1) - vp(2)) < e) { - d2Psi_ds2 += - (((d2Psi_dvp2[1] + d2Psi_dvp2[2] - 2 * d2Psi_dvp2[5]) / 2) * - (n12 ^ n12) + - dPsi_dvp[0] * ((n01 ^ n01) / (vp[0] - vp[1]) + - (n02 ^ n02) / (vp[0] - vp[2])) + - dPsi_dvp[1] * (n01 ^ n01) / (vp[1] - vp[0]) + - dPsi_dvp[2] * (n02 ^ n02) / (vp[2] - vp[0])); - } else { - d2Psi_ds2 += (dPsi_dvp[0] * ((n01 ^ n01) / (vp[0] - vp[1]) + - (n02 ^ n02) / (vp[0] - vp[2])) + - dPsi_dvp[1] * ((n01 ^ n01) / (vp[1] - vp[0]) + - (n12 ^ n12) / (vp[1] - vp[2])) + - dPsi_dvp[2] * ((n12 ^ n12) / (vp[2] - vp[1]) + - (n02 ^ n02) / (vp[2] - vp[0]))); - } - } // end of computeHosfordStressSecondDerivative +} // end of namespace tfel::material::internals - } // end of namespace internals +namespace tfel::material { - template TFEL_HOST_DEVICE HosfordStressType computeHosfordStress( @@ -237,7 +227,7 @@ namespace tfel::material { 1 / real(a)); } // end of computeHosfordYieldStress - template TFEL_HOST_DEVICE std::tuple, @@ -289,7 +279,7 @@ namespace tfel::material { dPsi_ds[2] * std::get<2>(n))); } // end of computeHosfordStressNormal - template TFEL_HOST_DEVICE std::tuple, diff --git a/include/TFEL/Material/StiffnessTensor.hxx b/include/TFEL/Material/StiffnessTensor.hxx index 640316fb0..4b2115851 100644 --- a/include/TFEL/Material/StiffnessTensor.hxx +++ b/include/TFEL/Material/StiffnessTensor.hxx @@ -21,7 +21,19 @@ namespace tfel::material { - //! a small enumerattion + /*! + * \brief enumeration describing how stifness tensors must be computed: + * - in the `UNALTERED` case, the modelling hypothesis is not taken into + * account. + * - in the `ALTERED` case, the modelling hypothesis is taken into account. + * + * The modelling hypotesis is only meaningful when plane stress is taken into + * account: + * - in the `UNALTERED` case, the same stiffness tensor than in generalized + * plane strain is returned. + * - in the `ALTERED` case, the stiffness tensor if the effective stiffness + * tensor obtained by eliminating the effect of axial strain. + */ enum struct StiffnessTensorAlterationCharacteristic { UNALTERED, ALTERED @@ -68,7 +80,7 @@ namespace tfel::material { StressType>&, const tfel::math::st2tost2< ModellingHypothesisToSpaceDimension::value, - StressType>&); + StressType>&) noexcept; }; /*! * \brief compute the altered stiffness tensor from the unaltered @@ -83,7 +95,7 @@ namespace tfel::material { template TFEL_HOST_DEVICE static constexpr void exe( tfel::math::st2tost2<2u, StressType>&, - const tfel::math::st2tost2<2u, StressType>&); + const tfel::math::st2tost2<2u, StressType>&) noexcept; }; /*! @@ -96,7 +108,9 @@ namespace tfel::material { typename StressType, typename RealType> TFEL_HOST_DEVICE constexpr void computeIsotropicStiffnessTensorII( - tfel::math::st2tost2&, const StressType, const RealType); + tfel::math::st2tost2&, + const StressType, + const RealType) noexcept; /*! * \param[out] D: stiffness tensor * \param[in] yg1: young modulus in the first direction @@ -123,7 +137,7 @@ namespace tfel::material { const RealType, const StressType, const StressType, - const StressType); + const StressType) noexcept; /*! * \param[out] D: stiffness tensor @@ -138,7 +152,7 @@ namespace tfel::material { tfel::math::st2tost2::value, StressType>&, const StressType, - const RealType); + const RealType) noexcept; /*! * \param[out] D: stiffness tensor * \param[in] yg1: young modulus in the first direction @@ -166,7 +180,7 @@ namespace tfel::material { const RealType, const StressType, const StressType, - const StressType); + const StressType) noexcept; /*! * \param[out] D: stiffness tensor @@ -196,7 +210,7 @@ namespace tfel::material { const RealType, const StressType, const StressType, - const StressType); + const StressType) noexcept; } // end of namespace tfel::material diff --git a/include/TFEL/Material/StiffnessTensor.ixx b/include/TFEL/Material/StiffnessTensor.ixx index 8ac9c8013..b14a93833 100644 --- a/include/TFEL/Material/StiffnessTensor.ixx +++ b/include/TFEL/Material/StiffnessTensor.ixx @@ -16,544 +16,544 @@ #include -namespace tfel::material { +namespace tfel::material::internals { + + template + struct ComputeIsotropicStiffnessTensorI; + + template + struct ComputeOrthotropicStiffnessTensorI; + + template <> + struct ComputeIsotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::UNALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<1u, StressType>& C, + const StressType E, + const RealType n) noexcept { + const StressType l = E * n / ((1. - 2 * n) * (1 + n)); + const StressType G = E / (1 + n); + const StressType C11 = l + G; + C(0, 0) = C11; + C(0, 1) = C(0, 2) = l; + C(1, 1) = C11; + C(1, 0) = C(1, 2) = l; + C(2, 0) = C(2, 1) = l; + C(2, 2) = C11; + } + }; + + template <> + struct ComputeIsotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::ALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<1u, StressType>& C, + const StressType E, + const RealType n) noexcept + + { + constexpr StressType zero = StressType(0); + const StressType C1 = E / (1 - n * n); + const StressType C2 = n * C1; + C(0, 0) = C1; + C(0, 1) = C2; + C(0, 2) = C(0, 3) = zero; + C(1, 0) = C2; + C(1, 1) = C1; + C(1, 2) = C(1, 3) = zero; + C(2, 0) = C(2, 1) = zero; + } // end of struct computeIsotropicPlaneStressAlteredStiffnessTensor + }; + + template <> + struct ComputeIsotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::UNALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E, + const RealType n) noexcept { + constexpr StressType zero = StressType(0); + const StressType l = E * n / ((1 - 2 * n) * (1 + n)); + const StressType G = E / (1 + n); + const StressType C11 = l + G; + C(0, 0) = C11; + C(0, 1) = l; + C(0, 2) = l; + C(0, 3) = zero; + C(1, 0) = l; + C(1, 1) = C11; + C(1, 2) = l; + C(1, 3) = zero; + C(2, 0) = l; + C(2, 1) = l; + C(2, 2) = C11; + C(2, 3) = C(3, 0) = zero; + C(3, 1) = C(3, 2) = zero; + C(3, 3) = G; + } + }; // end of struct ComputeIsotropicStiffnessTensorI + + template <> + struct ComputeIsotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::ALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E, + const RealType n) noexcept { + constexpr StressType zero = StressType(0); + const StressType C1 = E / (1 - n * n); + const StressType C2 = n * C1; + const StressType C3 = (1 - n) * C1; + C(0, 0) = C1; + C(0, 1) = C2; + C(0, 2) = C(0, 3) = zero; + C(1, 0) = C2; + C(1, 1) = C1; + C(1, 2) = C(1, 3) = zero; + C(2, 0) = C(2, 1) = zero; + C(2, 2) = C(2, 3) = zero; + C(3, 0) = C(3, 1) = zero; + C(3, 2) = zero; + C(3, 3) = C3; + } // end of struct computeIsotropicPlaneStressAlteredStiffnessTensor + }; + + template + struct ComputeIsotropicStiffnessTensorI<3u, smt> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<3u, StressType>& C, + const StressType E, + const RealType n) noexcept { + constexpr StressType zero = StressType(0); + const StressType l = E * n / ((1 - 2 * n) * (1 + n)); + const StressType G = E / (1 + n); + const StressType C11 = l + G; + C(0, 0) = C11; + C(0, 1) = C(0, 2) = l; + C(0, 3) = C(0, 4) = C(0, 5) = zero; + C(1, 0) = C(1, 2) = l; + C(1, 1) = C11; + C(1, 3) = C(1, 4) = C(1, 5) = zero; + C(2, 0) = C(2, 1) = l; + C(2, 2) = C11; + C(2, 3) = C(2, 4) = C(2, 5) = zero; + C(3, 0) = C(3, 1) = C(3, 2) = zero; + C(3, 3) = G; + C(3, 4) = C(3, 5) = C(4, 0) = zero; + C(4, 1) = C(4, 2) = C(4, 3) = zero; + C(4, 4) = G; + C(4, 5) = C(5, 0) = C(5, 1) = zero; + C(5, 2) = C(5, 3) = C(5, 4) = zero; + C(5, 5) = G; + } // end of struct computeStiffnessTensor + }; + + template <> + struct ComputeOrthotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::UNALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<1u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType, + const StressType, + const StressType) noexcept { + const auto S11 = 1 / E1; + const auto S22 = 1 / E2; + const auto S33 = 1 / E3; + const auto S12 = -n12 / E1; + const auto S13 = -n13 / E1; + const auto S23 = -n23 / E2; + const auto inv_detS = + 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - + S22 * S13 * S13 - S33 * S12 * S12); + C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; + C(0, 1) = (S13 * S23 - S12 * S33) * inv_detS; + C(0, 2) = (S12 * S23 - S13 * S22) * inv_detS; + C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; + C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; + C(1, 2) = (S12 * S13 - S11 * S23) * inv_detS; + C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; + C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; + C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; + } + }; + + template <> + struct ComputeOrthotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::ALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<1u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType, + const StressType, + const StressType) noexcept { + const auto S11 = 1 / E1; + const auto S22 = 1 / E2; + const auto S33 = 1 / E3; + const auto S12 = -n12 / E1; + const auto S13 = -n13 / E1; + const auto S23 = -n23 / E2; + const auto inv_detS = + 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - + S22 * S13 * S13 - S33 * S12 * S12); + const auto C00 = (S22 * S33 - S23 * S23) * inv_detS; + const auto C01 = (S13 * S23 - S12 * S33) * inv_detS; + const auto C02 = (S12 * S23 - S13 * S22) * inv_detS; + const auto C10 = (S13 * S23 - S12 * S33) * inv_detS; + const auto C11 = (S11 * S33 - S13 * S13) * inv_detS; + const auto C12 = (S12 * S13 - S11 * S23) * inv_detS; + const auto C20 = (S12 * S23 - S13 * S22) * inv_detS; + const auto C21 = (S12 * S13 - S11 * S23) * inv_detS; + const auto C22 = (S11 * S22 - S12 * S12) * inv_detS; + const auto tmp20 = C20 / C22; + const auto tmp21 = C21 / C22; + std::fill(C.begin(), C.end(), StressType(0.)); + C(0, 0) = C00 - C02 * tmp20; + C(0, 1) = C01 - C02 * tmp21; + C(1, 0) = C10 - C12 * tmp20; + C(1, 1) = C11 - C12 * tmp21; + } // end of exe + }; + + template <> + struct ComputeOrthotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::UNALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType, + const StressType) noexcept { + const auto S11 = 1 / E1; + const auto S22 = 1 / E2; + const auto S33 = 1 / E3; + const auto S12 = -n12 / E1; + const auto S13 = -n13 / E1; + const auto S23 = -n23 / E2; + const auto inv_detS = + 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - + S22 * S13 * S13 - S33 * S12 * S12); + std::fill(C.begin(), C.end(), StressType(0.)); + C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; + C(0, 1) = (S13 * S23 - S12 * S33) * inv_detS; + C(0, 2) = (S12 * S23 - S13 * S22) * inv_detS; + C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; + C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; + C(1, 2) = (S12 * S13 - S11 * S23) * inv_detS; + C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; + C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; + C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; + C(3, 3) = 2 * G12; + } // end of exe + }; + + template <> + struct ComputeOrthotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::ALTERED> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType, + const StressType) noexcept { + const auto S11 = 1 / E1; + const auto S22 = 1 / E2; + const auto S33 = 1 / E3; + const auto S12 = -n12 / E1; + const auto S13 = -n13 / E1; + const auto S23 = -n23 / E2; + const auto inv_detS = + 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - + S22 * S13 * S13 - S33 * S12 * S12); + const auto C00 = (S22 * S33 - S23 * S23) * inv_detS; + const auto C01 = (S13 * S23 - S12 * S33) * inv_detS; + const auto C02 = (S12 * S23 - S13 * S22) * inv_detS; + const auto C10 = (S13 * S23 - S12 * S33) * inv_detS; + const auto C11 = (S11 * S33 - S13 * S13) * inv_detS; + const auto C12 = (S12 * S13 - S11 * S23) * inv_detS; + const auto C20 = (S12 * S23 - S13 * S22) * inv_detS; + const auto C21 = (S12 * S13 - S11 * S23) * inv_detS; + const auto C22 = (S11 * S22 - S12 * S12) * inv_detS; + const auto tmp20 = C20 / C22; + const auto tmp21 = C21 / C22; + std::fill(C.begin(), C.end(), StressType(0.)); + C(0, 0) = C00 - C02 * tmp20; + C(0, 1) = C01 - C02 * tmp21; + C(1, 0) = C10 - C12 * tmp20; + C(1, 1) = C11 - C12 * tmp21; + C(3, 3) = 2 * G12; + } // end of exe + }; + + template + struct ComputeOrthotropicStiffnessTensorI<3u, smt> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<3u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType G23, + const StressType G13) noexcept { + const auto S11 = 1 / E1; + const auto S22 = 1 / E2; + const auto S33 = 1 / E3; + const auto S12 = -n12 / E1; + const auto S13 = -n13 / E1; + const auto S23 = -n23 / E2; + const auto inv_detS = + 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - + S22 * S13 * S13 - S33 * S12 * S12); + std::fill(C.begin(), C.end(), StressType(0.)); + C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; + C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; + C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; + C(0, 1) = C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; + C(0, 2) = C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; + C(1, 2) = C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; + C(3, 3) = 2 * G12; + C(4, 4) = 2 * G13; + C(5, 5) = 2 * G23; + } // end of struct exe + }; + + template + struct ComputeIsotropicStiffnessTensorII + : public ComputeIsotropicStiffnessTensorI< + ModellingHypothesisToSpaceDimension::value, + StiffnessTensorAlterationCharacteristic::UNALTERED> {}; + + template <> + struct ComputeIsotropicStiffnessTensorII< + ModellingHypothesis::PLANESTRESS, + StiffnessTensorAlterationCharacteristic::ALTERED> + : public ComputeIsotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::ALTERED> {}; + + template <> + struct ComputeIsotropicStiffnessTensorII< + ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS, + StiffnessTensorAlterationCharacteristic::ALTERED> + : public ComputeIsotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::ALTERED> {}; + + template + struct ComputeOrthotropicStiffnessTensorII + : public ComputeOrthotropicStiffnessTensorI< + ModellingHypothesisToSpaceDimension::value, + StiffnessTensorAlterationCharacteristic::UNALTERED> {}; + + template <> + struct ComputeOrthotropicStiffnessTensorII< + ModellingHypothesis::PLANESTRESS, + StiffnessTensorAlterationCharacteristic::ALTERED> + : public ComputeOrthotropicStiffnessTensorI< + 2u, + StiffnessTensorAlterationCharacteristic::ALTERED> {}; + + template <> + struct ComputeOrthotropicStiffnessTensorII< + ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS, + StiffnessTensorAlterationCharacteristic::ALTERED> + : public ComputeOrthotropicStiffnessTensorI< + 1u, + StiffnessTensorAlterationCharacteristic::ALTERED> {}; + + /*! + * \brief class in charge of computing an orthotropic stiffness + * tensor according to: + * - The modelling hypothesis. + * - The choice of computing an altered or unaltered stiffness + * tensor. This parameter is only useful in plane stress + * modelling hypotheses. + * - The orthotropic axes convention. + * \tparam H: modelling hypothesis + * \tparam smt: stiffness matrix alteration choice + * \tparam c: orthotropic axis convention + */ + template + struct ComputeOrthotropicStiffnessTensor; + /*! + * \brief partial specialisation for the + * `OrthotropicAxesConvention::DEFAULT` orthotropic axes + * convention. + * \tparam H: modelling hypothesis + * \tparam smt: stiffness matrix alteration choice + */ + template + struct ComputeOrthotropicStiffnessTensor + : public ComputeOrthotropicStiffnessTensorII {}; + /*! + * \brief partial specialisation for the + * `OrthotropicAxesConvention::PIPE` orthotropic axes + * convention. + * \tparam H: modelling hypothesis + * \tparam smt: stiffness matrix alteration choice + */ + template + struct ComputeOrthotropicStiffnessTensor + : public ComputeOrthotropicStiffnessTensorII {}; + /*! + * \brief partial specialisation for the: + * - `ModellingHypothesis::PLANESTRESS` modelling hypothesis. + * - `OrthotropicAxesConvention::PIPE` orthotropic axes + * convention. + * \tparam smt: stiffness matrix alteration choice + */ + template + struct ComputeOrthotropicStiffnessTensor { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType G23, + const StressType G13) noexcept { + using COST = + ComputeOrthotropicStiffnessTensorII; + COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); + } + }; + /*! + * \brief partial specialisation for the: + * - `ModellingHypothesis::PLANESTRAIN` modelling hypothesis. + * - `OrthotropicAxesConvention::PIPE` orthotropic axes + * convention. + * \tparam smt: stiffness matrix alteration choice + */ + template + struct ComputeOrthotropicStiffnessTensor { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType G23, + const StressType G13) noexcept { + using COST = + ComputeOrthotropicStiffnessTensorII; + COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); + } + }; + /*! + * \brief partial specialisation for the: + * - `ModellingHypothesis::GENERALISEDPLANESTRAIN` modelling + * hypothesis. + * - `OrthotropicAxesConvention::PIPE` orthotropic axes + * convention. + * \tparam smt: stiffness matrix alteration choice + */ + template + struct ComputeOrthotropicStiffnessTensor< + ModellingHypothesis::GENERALISEDPLANESTRAIN, + smt, + OrthotropicAxesConvention::PIPE> { + template + TFEL_HOST_DEVICE static constexpr void exe( + tfel::math::st2tost2<2u, StressType>& C, + const StressType E1, + const StressType E2, + const StressType E3, + const RealType n12, + const RealType n23, + const RealType n13, + const StressType G12, + const StressType G23, + const StressType G13) noexcept { + using COST = ComputeOrthotropicStiffnessTensorII< + ModellingHypothesis::GENERALISEDPLANESTRAIN, smt>; + COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); + } + }; + +} // end of namespace tfel::material::internals - namespace internals { - - template - struct ComputeIsotropicStiffnessTensorI; - - template - struct ComputeOrthotropicStiffnessTensorI; - - template <> - struct ComputeIsotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::UNALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<1u, StressType>& C, - const StressType E, - const RealType n) { - const StressType l = E * n / ((1. - 2 * n) * (1 + n)); - const StressType G = E / (1 + n); - const StressType C11 = l + G; - C(0, 0) = C11; - C(0, 1) = C(0, 2) = l; - C(1, 1) = C11; - C(1, 0) = C(1, 2) = l; - C(2, 0) = C(2, 1) = l; - C(2, 2) = C11; - } - }; - - template <> - struct ComputeIsotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::ALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<1u, StressType>& C, - const StressType E, - const RealType n) - - { - constexpr StressType zero = StressType(0); - const StressType C1 = E / (1 - n * n); - const StressType C2 = n * C1; - C(0, 0) = C1; - C(0, 1) = C2; - C(0, 2) = C(0, 3) = zero; - C(1, 0) = C2; - C(1, 1) = C1; - C(1, 2) = C(1, 3) = zero; - C(2, 0) = C(2, 1) = zero; - } // end of struct computeIsotropicPlaneStressAlteredStiffnessTensor - }; - - template <> - struct ComputeIsotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::UNALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E, - const RealType n) { - constexpr StressType zero = StressType(0); - const StressType l = E * n / ((1 - 2 * n) * (1 + n)); - const StressType G = E / (1 + n); - const StressType C11 = l + G; - C(0, 0) = C11; - C(0, 1) = l; - C(0, 2) = l; - C(0, 3) = zero; - C(1, 0) = l; - C(1, 1) = C11; - C(1, 2) = l; - C(1, 3) = zero; - C(2, 0) = l; - C(2, 1) = l; - C(2, 2) = C11; - C(2, 3) = C(3, 0) = zero; - C(3, 1) = C(3, 2) = zero; - C(3, 3) = G; - } - }; // end of struct ComputeIsotropicStiffnessTensorI - - template <> - struct ComputeIsotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::ALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E, - const RealType n) - - { - constexpr StressType zero = StressType(0); - const StressType C1 = E / (1 - n * n); - const StressType C2 = n * C1; - const StressType C3 = (1 - n) * C1; - C(0, 0) = C1; - C(0, 1) = C2; - C(0, 2) = C(0, 3) = zero; - C(1, 0) = C2; - C(1, 1) = C1; - C(1, 2) = C(1, 3) = zero; - C(2, 0) = C(2, 1) = zero; - C(2, 2) = C(2, 3) = zero; - C(3, 0) = C(3, 1) = zero; - C(3, 2) = zero; - C(3, 3) = C3; - } // end of struct computeIsotropicPlaneStressAlteredStiffnessTensor - }; - - template - struct ComputeIsotropicStiffnessTensorI<3u, smt> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<3u, StressType>& C, - const StressType E, - const RealType n) { - constexpr StressType zero = StressType(0); - const StressType l = E * n / ((1 - 2 * n) * (1 + n)); - const StressType G = E / (1 + n); - const StressType C11 = l + G; - C(0, 0) = C11; - C(0, 1) = C(0, 2) = l; - C(0, 3) = C(0, 4) = C(0, 5) = zero; - C(1, 0) = C(1, 2) = l; - C(1, 1) = C11; - C(1, 3) = C(1, 4) = C(1, 5) = zero; - C(2, 0) = C(2, 1) = l; - C(2, 2) = C11; - C(2, 3) = C(2, 4) = C(2, 5) = zero; - C(3, 0) = C(3, 1) = C(3, 2) = zero; - C(3, 3) = G; - C(3, 4) = C(3, 5) = C(4, 0) = zero; - C(4, 1) = C(4, 2) = C(4, 3) = zero; - C(4, 4) = G; - C(4, 5) = C(5, 0) = C(5, 1) = zero; - C(5, 2) = C(5, 3) = C(5, 4) = zero; - C(5, 5) = G; - } // end of struct computeStiffnessTensor - }; - - template <> - struct ComputeOrthotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::UNALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<1u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType, - const StressType, - const StressType) { - const auto S11 = 1 / E1; - const auto S22 = 1 / E2; - const auto S33 = 1 / E3; - const auto S12 = -n12 / E1; - const auto S13 = -n13 / E1; - const auto S23 = -n23 / E2; - const auto inv_detS = - 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - - S22 * S13 * S13 - S33 * S12 * S12); - C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; - C(0, 1) = (S13 * S23 - S12 * S33) * inv_detS; - C(0, 2) = (S12 * S23 - S13 * S22) * inv_detS; - C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; - C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; - C(1, 2) = (S12 * S13 - S11 * S23) * inv_detS; - C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; - C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; - C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; - } - }; - - template <> - struct ComputeOrthotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::ALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<1u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType, - const StressType, - const StressType) { - const auto S11 = 1 / E1; - const auto S22 = 1 / E2; - const auto S33 = 1 / E3; - const auto S12 = -n12 / E1; - const auto S13 = -n13 / E1; - const auto S23 = -n23 / E2; - const auto inv_detS = - 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - - S22 * S13 * S13 - S33 * S12 * S12); - const auto C00 = (S22 * S33 - S23 * S23) * inv_detS; - const auto C01 = (S13 * S23 - S12 * S33) * inv_detS; - const auto C02 = (S12 * S23 - S13 * S22) * inv_detS; - const auto C10 = (S13 * S23 - S12 * S33) * inv_detS; - const auto C11 = (S11 * S33 - S13 * S13) * inv_detS; - const auto C12 = (S12 * S13 - S11 * S23) * inv_detS; - const auto C20 = (S12 * S23 - S13 * S22) * inv_detS; - const auto C21 = (S12 * S13 - S11 * S23) * inv_detS; - const auto C22 = (S11 * S22 - S12 * S12) * inv_detS; - const auto tmp20 = C20 / C22; - const auto tmp21 = C21 / C22; - std::fill(C.begin(), C.end(), StressType(0.)); - C(0, 0) = C00 - C02 * tmp20; - C(0, 1) = C01 - C02 * tmp21; - C(1, 0) = C10 - C12 * tmp20; - C(1, 1) = C11 - C12 * tmp21; - } // end of exe - }; - - template <> - struct ComputeOrthotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::UNALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType, - const StressType) { - const auto S11 = 1 / E1; - const auto S22 = 1 / E2; - const auto S33 = 1 / E3; - const auto S12 = -n12 / E1; - const auto S13 = -n13 / E1; - const auto S23 = -n23 / E2; - const auto inv_detS = - 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - - S22 * S13 * S13 - S33 * S12 * S12); - std::fill(C.begin(), C.end(), StressType(0.)); - C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; - C(0, 1) = (S13 * S23 - S12 * S33) * inv_detS; - C(0, 2) = (S12 * S23 - S13 * S22) * inv_detS; - C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; - C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; - C(1, 2) = (S12 * S13 - S11 * S23) * inv_detS; - C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; - C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; - C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; - C(3, 3) = 2 * G12; - } // end of exe - }; - - template <> - struct ComputeOrthotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::ALTERED> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType, - const StressType) { - const auto S11 = 1 / E1; - const auto S22 = 1 / E2; - const auto S33 = 1 / E3; - const auto S12 = -n12 / E1; - const auto S13 = -n13 / E1; - const auto S23 = -n23 / E2; - const auto inv_detS = - 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - - S22 * S13 * S13 - S33 * S12 * S12); - const auto C00 = (S22 * S33 - S23 * S23) * inv_detS; - const auto C01 = (S13 * S23 - S12 * S33) * inv_detS; - const auto C02 = (S12 * S23 - S13 * S22) * inv_detS; - const auto C10 = (S13 * S23 - S12 * S33) * inv_detS; - const auto C11 = (S11 * S33 - S13 * S13) * inv_detS; - const auto C12 = (S12 * S13 - S11 * S23) * inv_detS; - const auto C20 = (S12 * S23 - S13 * S22) * inv_detS; - const auto C21 = (S12 * S13 - S11 * S23) * inv_detS; - const auto C22 = (S11 * S22 - S12 * S12) * inv_detS; - const auto tmp20 = C20 / C22; - const auto tmp21 = C21 / C22; - std::fill(C.begin(), C.end(), StressType(0.)); - C(0, 0) = C00 - C02 * tmp20; - C(0, 1) = C01 - C02 * tmp21; - C(1, 0) = C10 - C12 * tmp20; - C(1, 1) = C11 - C12 * tmp21; - C(3, 3) = 2 * G12; - } // end of exe - }; - - template - struct ComputeOrthotropicStiffnessTensorI<3u, smt> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<3u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType G23, - const StressType G13) { - const auto S11 = 1 / E1; - const auto S22 = 1 / E2; - const auto S33 = 1 / E3; - const auto S12 = -n12 / E1; - const auto S13 = -n13 / E1; - const auto S23 = -n23 / E2; - const auto inv_detS = - 1 / (S11 * S22 * S33 + 2 * S23 * S13 * S12 - S11 * S23 * S23 - - S22 * S13 * S13 - S33 * S12 * S12); - std::fill(C.begin(), C.end(), StressType(0.)); - C(0, 0) = (S22 * S33 - S23 * S23) * inv_detS; - C(1, 1) = (S11 * S33 - S13 * S13) * inv_detS; - C(2, 2) = (S11 * S22 - S12 * S12) * inv_detS; - C(0, 1) = C(1, 0) = (S13 * S23 - S12 * S33) * inv_detS; - C(0, 2) = C(2, 0) = (S12 * S23 - S13 * S22) * inv_detS; - C(1, 2) = C(2, 1) = (S12 * S13 - S11 * S23) * inv_detS; - C(3, 3) = 2 * G12; - C(4, 4) = 2 * G13; - C(5, 5) = 2 * G23; - } // end of struct exe - }; - - template - struct ComputeIsotropicStiffnessTensorII - : public ComputeIsotropicStiffnessTensorI< - ModellingHypothesisToSpaceDimension::value, - StiffnessTensorAlterationCharacteristic::UNALTERED> {}; - - template <> - struct ComputeIsotropicStiffnessTensorII< - ModellingHypothesis::PLANESTRESS, - StiffnessTensorAlterationCharacteristic::ALTERED> - : public ComputeIsotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::ALTERED> {}; - - template <> - struct ComputeIsotropicStiffnessTensorII< - ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS, - StiffnessTensorAlterationCharacteristic::ALTERED> - : public ComputeIsotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::ALTERED> {}; - - template - struct ComputeOrthotropicStiffnessTensorII - : public ComputeOrthotropicStiffnessTensorI< - ModellingHypothesisToSpaceDimension::value, - StiffnessTensorAlterationCharacteristic::UNALTERED> {}; - - template <> - struct ComputeOrthotropicStiffnessTensorII< - ModellingHypothesis::PLANESTRESS, - StiffnessTensorAlterationCharacteristic::ALTERED> - : public ComputeOrthotropicStiffnessTensorI< - 2u, - StiffnessTensorAlterationCharacteristic::ALTERED> {}; - - template <> - struct ComputeOrthotropicStiffnessTensorII< - ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS, - StiffnessTensorAlterationCharacteristic::ALTERED> - : public ComputeOrthotropicStiffnessTensorI< - 1u, - StiffnessTensorAlterationCharacteristic::ALTERED> {}; - - /*! - * \brief class in charge of computing an orthotropic stiffness - * tensor according to: - * - The modelling hypothesis. - * - The choice of computing an altered or unaltered stiffness - * tensor. This parameter is only useful in plane stress - * modelling hypotheses. - * - The orthotropic axes convention. - * \tparam H: modelling hypothesis - * \tparam smt: stiffness matrix alteration choice - * \tparam c: orthotropic axis convention - */ - template - struct ComputeOrthotropicStiffnessTensor; - /*! - * \brief partial specialisation for the - * `OrthotropicAxesConvention::DEFAULT` orthotropic axes - * convention. - * \tparam H: modelling hypothesis - * \tparam smt: stiffness matrix alteration choice - */ - template - struct ComputeOrthotropicStiffnessTensor - : public ComputeOrthotropicStiffnessTensorII {}; - /*! - * \brief partial specialisation for the - * `OrthotropicAxesConvention::PIPE` orthotropic axes - * convention. - * \tparam H: modelling hypothesis - * \tparam smt: stiffness matrix alteration choice - */ - template - struct ComputeOrthotropicStiffnessTensor - : public ComputeOrthotropicStiffnessTensorII {}; - /*! - * \brief partial specialisation for the: - * - `ModellingHypothesis::PLANESTRESS` modelling hypothesis. - * - `OrthotropicAxesConvention::PIPE` orthotropic axes - * convention. - * \tparam smt: stiffness matrix alteration choice - */ - template - struct ComputeOrthotropicStiffnessTensor { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType G23, - const StressType G13) { - using COST = ComputeOrthotropicStiffnessTensorII< - ModellingHypothesis::PLANESTRESS, smt>; - COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); - } - }; - /*! - * \brief partial specialisation for the: - * - `ModellingHypothesis::PLANESTRAIN` modelling hypothesis. - * - `OrthotropicAxesConvention::PIPE` orthotropic axes - * convention. - * \tparam smt: stiffness matrix alteration choice - */ - template - struct ComputeOrthotropicStiffnessTensor { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType G23, - const StressType G13) { - using COST = ComputeOrthotropicStiffnessTensorII< - ModellingHypothesis::PLANESTRAIN, smt>; - COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); - } - }; - /*! - * \brief partial specialisation for the: - * - `ModellingHypothesis::GENERALISEDPLANESTRAIN` modelling - * hypothesis. - * - `OrthotropicAxesConvention::PIPE` orthotropic axes - * convention. - * \tparam smt: stiffness matrix alteration choice - */ - template - struct ComputeOrthotropicStiffnessTensor< - ModellingHypothesis::GENERALISEDPLANESTRAIN, - smt, - OrthotropicAxesConvention::PIPE> { - template - TFEL_HOST_DEVICE static constexpr void exe( - tfel::math::st2tost2<2u, StressType>& C, - const StressType E1, - const StressType E2, - const StressType E3, - const RealType n12, - const RealType n23, - const RealType n13, - const StressType G12, - const StressType G23, - const StressType G13) { - using COST = ComputeOrthotropicStiffnessTensorII< - ModellingHypothesis::GENERALISEDPLANESTRAIN, smt>; - COST::exe(C, E1, E3, E2, n13, n23 * E3 / E2, n12, G13, G23, G12); - } - }; - - } // end of namespace internals +namespace tfel::material { template template - constexpr void ComputeAlteredStiffnessTensor::exe( + TFEL_HOST_DEVICE constexpr void ComputeAlteredStiffnessTensor::exe( tfel::math::st2tost2::value, StressType>& Da, const tfel::math::st2tost2::value, - StressType>& D) { + StressType>& D) noexcept { Da = D; } template - constexpr void + TFEL_HOST_DEVICE constexpr void ComputeAlteredStiffnessTensor::exe( tfel::math::st2tost2<2u, StressType>& Da, - const tfel::math::st2tost2<2u, StressType>& D) { + const tfel::math::st2tost2<2u, StressType>& D) noexcept { Da(0, 0) = D(0, 0) - D(2, 0) / D(2, 2) * D(0, 2); Da(0, 1) = D(0, 1) - D(2, 1) / D(2, 2) * D(0, 2); Da(1, 0) = D(1, 0) - D(2, 0) / D(2, 2) * D(1, 2); @@ -576,10 +576,10 @@ namespace tfel::material { StiffnessTensorAlterationCharacteristic smt, typename StressType, typename RealType> - constexpr void computeIsotropicStiffnessTensorII( + TFEL_HOST_DEVICE constexpr void computeIsotropicStiffnessTensorII( tfel::math::st2tost2& C, const StressType E, - const RealType n) { + const RealType n) noexcept { tfel::material::internals::ComputeIsotropicStiffnessTensorI::exe( C, E, n); } @@ -588,7 +588,7 @@ namespace tfel::material { StiffnessTensorAlterationCharacteristic smt, typename StressType, typename RealType> - constexpr void computeOrthotropicStiffnessTensorII( + TFEL_HOST_DEVICE constexpr void computeOrthotropicStiffnessTensorII( tfel::math::st2tost2& C, const StressType E1, const StressType E2, @@ -598,7 +598,7 @@ namespace tfel::material { const RealType n13, const StressType G12, const StressType G23, - const StressType G13) { + const StressType G13) noexcept { tfel::material::internals::ComputeOrthotropicStiffnessTensorI::exe( C, E1, E2, E3, n12, n23, n13, G12, G23, G13); } @@ -607,11 +607,11 @@ namespace tfel::material { StiffnessTensorAlterationCharacteristic smt, typename StressType, typename RealType> - constexpr void computeIsotropicStiffnessTensor( + TFEL_HOST_DEVICE constexpr void computeIsotropicStiffnessTensor( tfel::math::st2tost2::value, StressType>& C, const StressType E, - const RealType n) { + const RealType n) noexcept { tfel::material::internals::ComputeIsotropicStiffnessTensorII::exe( C, E, n); } @@ -620,7 +620,7 @@ namespace tfel::material { StiffnessTensorAlterationCharacteristic smt, typename StressType, typename RealType> - constexpr void computeOrthotropicStiffnessTensor( + TFEL_HOST_DEVICE constexpr void computeOrthotropicStiffnessTensor( tfel::math::st2tost2::value, StressType>& C, const StressType E1, @@ -631,7 +631,7 @@ namespace tfel::material { const RealType n13, const StressType G12, const StressType G23, - const StressType G13) { + const StressType G13) noexcept { tfel::material::internals::ComputeOrthotropicStiffnessTensorII::exe( C, E1, E2, E3, n12, n23, n13, G12, G23, G13); } @@ -641,7 +641,7 @@ namespace tfel::material { OrthotropicAxesConvention c, typename StressType, typename RealType> - constexpr void computeOrthotropicStiffnessTensor( + TFEL_HOST_DEVICE constexpr void computeOrthotropicStiffnessTensor( tfel::math::st2tost2::value, StressType>& C, const StressType E1, @@ -652,7 +652,7 @@ namespace tfel::material { const RealType n13, const StressType G12, const StressType G23, - const StressType G13) { + const StressType G13) noexcept { internals::ComputeOrthotropicStiffnessTensor::exe( C, E1, E2, E3, n12, n23, n13, G12, G23, G13); } diff --git a/include/TFEL/Math/Array/ArrayCommonMethods.hxx b/include/TFEL/Math/Array/ArrayCommonMethods.hxx index 18c358a76..1756e2332 100644 --- a/include/TFEL/Math/Array/ArrayCommonMethods.hxx +++ b/include/TFEL/Math/Array/ArrayCommonMethods.hxx @@ -120,10 +120,9 @@ namespace tfel::math { * \param[in] values: values to be assigned */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo(), - Child&> - operator=(const std::initializer_list&) noexcept; + TFEL_HOST_DEVICE constexpr Child& + operator=(const std::initializer_list&) noexcept requires( + isAssignableTo()); /*! * \brief import array values from a sequence * \param[in] p: random access iterator to the first element of the @@ -140,21 +139,18 @@ namespace tfel::math { * \param[in] v: value */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo(), - void> - fill(const ValueType2&); + TFEL_HOST_DEVICE constexpr void fill(const ValueType2&) requires( + isAssignableTo()); /*! * \brief clamp all the values between the given bounds * \param[in] lower_bound: lower bound * \param[in] upper_bound: upper bound */ template - constexpr std::enable_if_t< - (isAssignableTo() && - isAssignableTo()), - void> - TFEL_HOST_DEVICE clamp(const ValueType2&, const ValueType3&); + TFEL_HOST_DEVICE constexpr void + clamp(const ValueType2&, const ValueType3&) requires( + isAssignableTo() && + isAssignableTo()); protected: /*! @@ -188,14 +184,13 @@ namespace tfel::math { * \param[in] s: scalar value */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< + TFEL_HOST_DEVICE constexpr void + multiplyByScalar(const ValueType2&) requires( isAssignableTo< BinaryOperationResult, - typename ArrayPolicyType::value_type>(), - void> - multiplyByScalar(const ValueType2&); + typename ArrayPolicyType::value_type>()); }; } // end of namespace tfel::math diff --git a/include/TFEL/Math/Array/ArrayCommonMethods.ixx b/include/TFEL/Math/Array/ArrayCommonMethods.ixx index 13edb8a2e..74b1ef9c4 100644 --- a/include/TFEL/Math/Array/ArrayCommonMethods.ixx +++ b/include/TFEL/Math/Array/ArrayCommonMethods.ixx @@ -180,11 +180,9 @@ namespace tfel::math { template template - constexpr std::enable_if_t< - isAssignableTo(), - Child&> - MutableArrayCommonMethods::operator=( - const std::initializer_list& values) noexcept { + constexpr Child& MutableArrayCommonMethods:: + operator=(const std::initializer_list& values) noexcept requires( + isAssignableTo()) { auto& child = static_cast(*this); if (values.size() != child.size()) { tfel::reportContractViolation( @@ -221,10 +219,9 @@ namespace tfel::math { template template - constexpr std::enable_if_t< - isAssignableTo(), - void> - MutableArrayCommonMethods::fill(const ValueType2& v) { + constexpr void MutableArrayCommonMethods:: + fill(const ValueType2& v) requires( + isAssignableTo()) { const auto f = makeMultiIndicesUnaryOperatorFunctor( [v](typename ArrayPolicyType::reference a) { a = v; }, *this); auto& child = static_cast(*this); @@ -233,12 +230,12 @@ namespace tfel::math { template template - constexpr std::enable_if_t< - (isAssignableTo() && - isAssignableTo()), - void> - MutableArrayCommonMethods::clamp( - const ValueType2& lower_bound, const ValueType3& upper_bound) { + constexpr void MutableArrayCommonMethods::clamp( + const ValueType2& lower_bound, + const ValueType3& upper_bound) // + requires( + isAssignableTo() && + isAssignableTo()) { const auto f = makeMultiIndicesUnaryOperatorFunctor( [lower_bound, upper_bound](typename ArrayPolicyType::reference a) { if (a < lower_bound) { @@ -254,14 +251,14 @@ namespace tfel::math { template template - constexpr std::enable_if_t< - isAssignableTo, - typename ArrayPolicyType::value_type>(), - void> + constexpr void MutableArrayCommonMethods::multiplyByScalar( - const ValueType2& s) { + const ValueType2& s) // + requires(isAssignableTo< + BinaryOperationResult, + typename ArrayPolicyType::value_type>()) { const auto f = makeMultiIndicesUnaryOperatorFunctor( [s](typename ArrayPolicyType::reference a) { a *= s; }, *this); auto& child = static_cast(*this); diff --git a/include/TFEL/Math/Array/ArrayConcept.hxx b/include/TFEL/Math/Array/ArrayConcept.hxx index 4a0a5aad0..1241d2bab 100644 --- a/include/TFEL/Math/Array/ArrayConcept.hxx +++ b/include/TFEL/Math/Array/ArrayConcept.hxx @@ -47,8 +47,11 @@ namespace tfel::math { */ template concept ArrayConcept = - (std::is_same_v::ConceptTag, ArrayTag>)&& // - (requires(const ArrayType t, const index_type i) { t[i]; }) && // + (std::is_same_v::ConceptTag, + ArrayTag>)&& // + (requires(const ArrayType t, const index_type i) { + t[i]; + }) && // (requires(const ArrayType t, const index_type i) { t(i); }); //! paratial specialisation for arrays diff --git a/include/TFEL/Math/Array/GenericFixedSizeArray.hxx b/include/TFEL/Math/Array/GenericFixedSizeArray.hxx index b2276f313..f80d736a4 100644 --- a/include/TFEL/Math/Array/GenericFixedSizeArray.hxx +++ b/include/TFEL/Math/Array/GenericFixedSizeArray.hxx @@ -20,63 +20,70 @@ #include "TFEL/Math/General/MathObjectTraits.hxx" #include "TFEL/Math/Array/MutableFixedSizeArrayBase.hxx" -#define TFEL_MATH_FIXED_SIZE_ARRAY_DEFAULT_METHODS(X, Y) \ - /*! \brief default constructor */ \ - constexpr X() noexcept = default; \ - /*! \brief move constructor */ \ - constexpr X(X&&) noexcept = default; \ - /*! \brief copy constructor */ \ - constexpr X(const X&) noexcept = default; \ - /*! \brief move assignement */ \ - constexpr X& operator=(X&&) noexcept = default; \ - /*! \brief standard assignement */ \ - constexpr X& operator=(const X&) noexcept = default; \ - /*! \ - * \brief constructor from a value \ - * \param[in] value: value used to initialize the array \ - */ \ - template (), \ - bool>::type = true> \ - TFEL_HOST_DEVICE constexpr explicit X(const ValueType2& value) noexcept \ - : Y(value) {} \ - /*! \ - * \brief constructor from an initializer list \ - * \param[in] values: values \ - */ \ - template (), \ - bool>::type = true> \ - TFEL_HOST_DEVICE constexpr X( \ - const std::initializer_list& values) noexcept \ - : Y(values) {} \ - /*! \ - * \brief copy constructor from an object assignable the X class. \ - * \param[in] src: source \ - * \ - * This is mostly used by expression objects and views. \ - */ \ - template ()) && \ - (!std::is_same_v)), \ - bool>::type = true> \ - TFEL_HOST_DEVICE constexpr X(const OtherArray& src) noexcept : Y(src) {} \ - /*! \ - * \brief Default Constructor. \ - * \param const base_type* \ - * const, pointer to a tabular used to initialise the components \ - * of the stensor. This tabular is left unchanged. \ - */ \ - template < \ - typename InputIterator, \ - std::enable_if_t::value_type, \ - base_type>, \ - bool> = true> \ - TFEL_HOST_DEVICE constexpr explicit X(const InputIterator p) : Y(p) {} \ - /* inheriting GenericFixedSizeArray' assignement operators */ \ +#define TFEL_MATH_FIXED_SIZE_ARRAY_DEFAULT_METHODS(X, Y) \ + /*! \brief default constructor */ \ + TFEL_HOST_DEVICE constexpr X() noexcept = default; \ + /*! \brief move constructor */ \ + TFEL_HOST_DEVICE constexpr X(X&&) noexcept = default; \ + /*! \brief copy constructor */ \ + TFEL_HOST_DEVICE constexpr X(const X&) noexcept = default; \ + /*! \brief move assignement */ \ + TFEL_HOST_DEVICE constexpr X& operator=(X&&) noexcept = default; \ + /*! \brief standard assignement */ \ + TFEL_HOST_DEVICE constexpr X& operator=(const X&) noexcept = default; \ + /*! \ + * \brief constructor from a value \ + * \param[in] value: value used to initialize the array \ + */ \ + template \ + TFEL_HOST_DEVICE constexpr explicit X( \ + const ValueType2& \ + value) noexcept requires(isAssignableTo()) \ + : Y(value) {} \ + /*! \ + * \brief constructor from an initializer list \ + * \param[in] values: values \ + */ \ + TFEL_HOST_DEVICE constexpr X( \ + const std::initializer_list& values) noexcept \ + : Y(values) {} \ + /*! \ + * \brief constructor from an initializer list \ + * \param[in] values: values \ + */ \ + template \ + TFEL_HOST_DEVICE constexpr X( \ + const std::initializer_list& \ + values) noexcept requires(isAssignableTo()) \ + : Y(values) {} \ + /*! \ + * \brief copy constructor from an object assignable the X class. \ + * \param[in] src: source \ + * \ + * This is mostly used by expression objects and views. \ + */ \ + template \ + TFEL_HOST_DEVICE constexpr X(const OtherArray& src) noexcept requires( \ + (isAssignableTo()) && (!std::is_same_v)) \ + : Y(src) {} \ + /*! \ + * \brief Default Constructor. \ + * \param const base_type* \ + * const, pointer to a tabular used to initialise the components \ + * of the stensor. This tabular is left unchanged. \ + */ \ + template \ + TFEL_HOST_DEVICE constexpr explicit X( \ + const InputIterator \ + p) noexcept requires(std:: \ + is_same_v< \ + typename std::iterator_traits< \ + InputIterator>::value_type, \ + base_type>) \ + : Y(p) {} \ + /* inheriting GenericFixedSizeArray' assignement operators */ \ using Y::operator= namespace tfel::math { @@ -114,50 +121,42 @@ namespace tfel::math { * \brief constructor from a value * \param[in] value: value used to initialize the array */ - template (), - bool>::type = true> + template TFEL_HOST_DEVICE constexpr explicit GenericFixedSizeArray( - const ValueType&) noexcept; + const ValueType&) noexcept // + requires(isAssignableTo()); /*! * \brief constructor from an initializer list * \param[in] values: values */ - template (), - bool>::type = true> + template TFEL_HOST_DEVICE constexpr GenericFixedSizeArray( - const std::initializer_list& values) noexcept; + const std::initializer_list& values) noexcept // + requires(isAssignableTo()); /*! - * \brief Default Constructor. - * \param const base_type* - * const, pointer to a tabular used to initialise the components - * of the stensor. This tabular is left unchanged. + * \brief default donstructor. + * \param p pointer to an array used to initialise the components + * of the stensor. This array is left unchanged. */ - template ::value_type, - base_type>, - bool> = true> + template TFEL_HOST_DEVICE constexpr explicit GenericFixedSizeArray( - const InputIterator); + const InputIterator) noexcept // + requires(std::is_same_v< + typename std::iterator_traits::value_type, + base_type>); /*! * \brief copy constructor from an object assignable to the `Child` class. * \param[in] src: source * * This is mostly used by expression objects and views. */ - template ()) && - (!std::is_same_v)), - bool>::type = true> + template TFEL_HOST_DEVICE constexpr GenericFixedSizeArray( - const OtherArray&) noexcept; + const OtherArray&) noexcept // + requires((isAssignableTo()) && + (!std::is_same_v)); /*! * \return the physical size used by the underlying array. This size must * be greater than than the logical number of elements contained in the @@ -175,39 +174,35 @@ namespace tfel::math { * \param[in] src: array to be assigned */ template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), Child&> - operator=(const OtherArray&) noexcept; + TFEL_HOST_DEVICE constexpr Child& + operator=(const OtherArray&) noexcept requires( + isAssignableTo()); // template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), Child&> - operator+=(const OtherArray&) noexcept; + TFEL_HOST_DEVICE constexpr Child& + operator+=(const OtherArray&) noexcept requires( + isAssignableTo()); // template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), Child&> - operator-=(const OtherArray&) noexcept; + TFEL_HOST_DEVICE constexpr Child& + operator-=(const OtherArray&) noexcept requires( + isAssignableTo()); // template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo< - BinaryOperationResult, - typename GenericFixedSizeArray::value_type>(), - Child&> - operator*=(const ValueType2&) noexcept; + TFEL_HOST_DEVICE constexpr Child& operator*=(const ValueType2&) noexcept // + requires(isAssignableTo, + typename GenericFixedSizeArray::value_type>()); // template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo< - BinaryOperationResult, - typename GenericFixedSizeArray::value_type>(), - Child&> - operator/=(const ValueType2&) noexcept; + TFEL_HOST_DEVICE constexpr Child& operator/=(const ValueType2&) noexcept // + requires(isAssignableTo, + typename GenericFixedSizeArray::value_type>()); //! \return a pointer to the underlying array serving as element storage. TFEL_HOST_DEVICE constexpr typename GenericFixedSizeArray::pointer data() noexcept; diff --git a/include/TFEL/Math/Array/GenericFixedSizeArray.ixx b/include/TFEL/Math/Array/GenericFixedSizeArray.ixx index 62a9ec6db..bf28cbb63 100644 --- a/include/TFEL/Math/Array/GenericFixedSizeArray.ixx +++ b/include/TFEL/Math/Array/GenericFixedSizeArray.ixx @@ -44,15 +44,12 @@ namespace tfel::math { template - template < - typename ValueType, - typename std::enable_if< + template + constexpr GenericFixedSizeArray:: + GenericFixedSizeArray(const ValueType& value) noexcept requires( isAssignableTo:: - value_type>(), - bool>::type> - constexpr GenericFixedSizeArray::GenericFixedSizeArray( - const ValueType& value) noexcept + value_type>()) : GenericFixedSizeArray() { this->fill(value); } // end of GenericFixedSizeArray @@ -60,12 +57,11 @@ namespace tfel::math { template - template ()) && - (!std::is_same_v)), - bool>::type> + template constexpr GenericFixedSizeArray::GenericFixedSizeArray( - const OtherArray& src) noexcept + const OtherArray& src) noexcept // + requires((isAssignableTo()) && + (!std::is_same_v)) : GenericFixedSizeArray() { // static_assert(checkIndexingPoliciesCompatiblity< // typename ArrayPolicy::indexing_policy, @@ -73,36 +69,16 @@ namespace tfel::math { this->operator=(src); } // end of GenericFixedSizeArray - // template template < - // typename ArrayPolicy2, - // typename std::enable_if<((checkIndexingPoliciesCompatiblity< - // typename ArrayPolicy::IndexingPolicy, - // typename - // ArrayPolicy2::IndexingPolicy>()) && - // (isAssignableTo< - // typename ArrayPolicy2::value_type, - // typename ArrayPolicy::value_type>())), - // bool>::type> - // constexpr GenericFixedSizeArray::GenericFixedSizeArray( - // const GenericFixedSizeArray& src) noexcept - // : GenericFixedSizeArray() { - // this->operator=(src); - // } - - template - template < - typename ValueType, - typename std::enable_if< + template + template + constexpr GenericFixedSizeArray::GenericFixedSizeArray( + const std::initializer_list& values) noexcept // + requires( isAssignableTo:: - value_type>(), - bool>::type> - constexpr GenericFixedSizeArray::GenericFixedSizeArray( - const std::initializer_list& values) noexcept + value_type>()) : GenericFixedSizeArray() { if (values.size() == 1u) { this->fill(*(values.begin())); @@ -114,16 +90,13 @@ namespace tfel::math { template - template < - typename InputIterator, - std::enable_if_t< - std::is_same_v< - typename std::iterator_traits::value_type, - base_type:: - value_type>>, - bool>> + template constexpr GenericFixedSizeArray::GenericFixedSizeArray( - const InputIterator p) { + const InputIterator p) noexcept // + requires(std::is_same_v< + typename std::iterator_traits::value_type, + base_type:: + value_type>>) { const auto& policy = this->getRowMajorIndexingPolicy(); this->import(policy, p, p + this->size()); } // end of GenericFixedSizeArray @@ -152,9 +125,9 @@ namespace tfel::math { typename ArrayPolicy, typename ArrayPolicy::IndexingPolicy::size_type N> template - constexpr std::enable_if_t(), Child&> - GenericFixedSizeArray::operator=( - const OtherArray& src) noexcept { + constexpr Child& GenericFixedSizeArray:: + operator=(const OtherArray& src) noexcept requires( + isAssignableTo()) { auto& child = static_cast(*this); child.assign(src); return child; @@ -164,9 +137,9 @@ namespace tfel::math { typename ArrayPolicy, typename ArrayPolicy::IndexingPolicy::size_type N> template - constexpr std::enable_if_t(), Child&> - GenericFixedSizeArray::operator+=( - const OtherArray& src) noexcept { + constexpr Child& GenericFixedSizeArray::operator+=( + const OtherArray& src) noexcept // + requires(isAssignableTo()) { auto& child = static_cast(*this); child.addAndAssign(src); return child; @@ -176,9 +149,9 @@ namespace tfel::math { typename ArrayPolicy, typename ArrayPolicy::IndexingPolicy::size_type N> template - constexpr std::enable_if_t(), Child&> - GenericFixedSizeArray::operator-=( - const OtherArray& src) noexcept { + constexpr Child& GenericFixedSizeArray:: + operator-=(const OtherArray& src) noexcept requires( + isAssignableTo()) { auto& child = static_cast(*this); child.substractAndAssign(src); return child; @@ -188,16 +161,16 @@ namespace tfel::math { typename ArrayPolicy, typename ArrayPolicy::IndexingPolicy::size_type N> template - constexpr std::enable_if_t< - isAssignableTo< - BinaryOperationResult< - ValueType2, - typename GenericFixedSizeArray::value_type, - OpMult>, - typename GenericFixedSizeArray::value_type>(), - Child&> - GenericFixedSizeArray::operator*=( - const ValueType2& s) noexcept { + constexpr Child& GenericFixedSizeArray::operator*=( + const ValueType2& s) noexcept // + requires(isAssignableTo< + BinaryOperationResult< + ValueType2, + typename GenericFixedSizeArray:: + value_type, + OpMult>, + typename GenericFixedSizeArray:: + value_type>()) { auto& child = static_cast(*this); child.multiplyByScalar(s); return child; @@ -207,16 +180,16 @@ namespace tfel::math { typename ArrayPolicy, typename ArrayPolicy::IndexingPolicy::size_type N> template - constexpr std::enable_if_t< - isAssignableTo< - BinaryOperationResult< - typename GenericFixedSizeArray::value_type, - ValueType2, - OpDiv>, - typename GenericFixedSizeArray::value_type>(), - Child&> - GenericFixedSizeArray::operator/=( - const ValueType2& s) noexcept { + constexpr Child& GenericFixedSizeArray::operator/=( + const ValueType2& s) noexcept // + requires(isAssignableTo< + BinaryOperationResult< + typename GenericFixedSizeArray:: + value_type, + ValueType2, + OpDiv>, + typename GenericFixedSizeArray:: + value_type>()) { auto& child = static_cast(*this); child.multiplyByScalar(1 / s); return child; diff --git a/include/TFEL/Math/Array/GenericRuntimeArray.hxx b/include/TFEL/Math/Array/GenericRuntimeArray.hxx index 629bf4f3c..19e9c06cf 100644 --- a/include/TFEL/Math/Array/GenericRuntimeArray.hxx +++ b/include/TFEL/Math/Array/GenericRuntimeArray.hxx @@ -20,60 +20,62 @@ #include "TFEL/Math/General/MathObjectTraits.hxx" #include "TFEL/Math/Array/MutableRuntimeArrayBase.hxx" -#define TFEL_MATH_RUNTIME_ARRAY_DEFAULT_METHODS(X, Y) \ - /*! \brief default constructor */ \ - X() = default; \ - /*! \brief move constructor */ \ - X(X&&) = default; \ - /*! \brief copy constructor */ \ - X(const X&) = default; \ - /*! \brief move assignement */ \ - X& operator=(X&&) = default; \ - /*! \brief standard assignement */ \ - X& operator=(const X&) = default; \ - /*! \ - * \brief constructor from a value \ - * \param[in] value: value used to initialize the array \ - */ \ - template (), \ - bool>::type = true> \ - explicit X(const ValueType2& value) : Y(value) {} \ - /*! \ - * \brief constructor from an initializer list \ - * \param[in] values: values \ - */ \ - template (), \ - bool>::type = true> \ - X(const std::initializer_list& values) : Y(values) {} \ - /*! \ - * \brief copy constructor from an object assignable the X class. \ - * \param[in] src: source \ - * \ - * This is mostly used by expression objects and views. \ - */ \ - template ()) && \ - (!std::is_same_v)), \ - bool>::type = true> \ - X(const OtherArray& src) : Y(src) {} \ - /*! \ - * \brief Default Constructor. \ - * \param const base_type* \ - * const, pointer to a tabular used to initialise the components \ - * of the stensor. This tabular is left unchanged. \ - */ \ - template < \ - typename InputIterator, \ - std::enable_if_t::value_type, \ - base_type>, \ - bool> = true> \ - explicit X(const InputIterator p) : Y(p) {} \ - /* inheriting GenericFixedSizeArray' assignement operators */ \ +#define TFEL_MATH_RUNTIME_ARRAY_DEFAULT_METHODS(X, Y) \ + /*! \brief default constructor */ \ + X() = default; \ + /*! \brief move constructor */ \ + X(X&&) = default; \ + /*! \brief copy constructor */ \ + X(const X&) = default; \ + /*! \brief move assignement */ \ + X& operator=(X&&) = default; \ + /*! \brief standard assignement */ \ + X& operator=(const X&) = default; \ + /*! \ + * \brief constructor from a value \ + * \param[in] value: value used to initialize the array \ + */ \ + template \ + explicit X(const ValueType2& value) requires( \ + isAssignableTo()) \ + : Y(value) {} \ + /*! \ + * \brief constructor from an initializer list \ + * \param[in] values: values \ + */ \ + X(const std::initializer_list& values) \ + : Y(values) {} \ + /*! \ + * \brief constructor from an initializer list \ + * \param[in] values: values \ + */ \ + template \ + X(const std::initializer_list& values) \ + requires(isAssignableTo()) \ + : Y(values) {} \ + /*! \ + * \brief copy constructor from an object assignable the X class. \ + * \param[in] src: source \ + * \ + * This is mostly used by expression objects and views. \ + */ \ + template \ + X(const OtherArray& src) \ + requires((isAssignableTo()) && \ + (!std::is_same_v)) \ + : Y(src) {} \ + /*! \ + * \brief Default Constructor. \ + * \param const base_type* \ + * const, pointer to a tabular used to initialise the components \ + * of the stensor. This tabular is left unchanged. \ + */ \ + template \ + explicit X(const InputIterator p) requires( \ + std::is_same_v::value_type, \ + base_type>) \ + : Y(p) {} \ + /* inheriting GenericFixedSizeArray' assignement operators */ \ using Y::operator= namespace tfel::math { @@ -102,51 +104,46 @@ namespace tfel::math { * \brief constructor from a value * \param[in] value: value used to initialize the array */ - template (), - bool>::type = true> - explicit GenericRuntimeArray(const typename ArrayPolicy::IndexingPolicy&, - const ValueType&); + template + explicit GenericRuntimeArray( + const typename ArrayPolicy::IndexingPolicy&, + const ValueType&) requires(isAssignableTo()); /*! * \brief constructor from an initializer list * \param[in] values: values */ - template < - typename ValueType, - typename std::enable_if< - ((isAssignableTo()) && - (ArrayPolicy::IndexingPolicy::arity == 1) && - (ArrayPolicy::IndexingPolicy::areDataContiguous)), - bool>::type = true> - GenericRuntimeArray(const typename GenericRuntimeArray::indexing_policy, - const std::initializer_list&); + template + GenericRuntimeArray( + const typename GenericRuntimeArray::indexing_policy, + const std::initializer_list< + ValueType>&) requires((isAssignableTo()) && + (ArrayPolicy::IndexingPolicy::arity == 1) && + (ArrayPolicy::IndexingPolicy:: + areDataContiguous)); /*! * \brief constructor from an initializer list * \param[in] values: values */ - template < - typename ValueType, - typename std::enable_if< - ((isAssignableTo()) && - (ArrayPolicy::IndexingPolicy::arity == 1) && - (ArrayPolicy::IndexingPolicy::areDataContiguous)), - bool>::type = true> - GenericRuntimeArray(const std::initializer_list&); + template + GenericRuntimeArray(const std::initializer_list&) requires( + (isAssignableTo()) && + (ArrayPolicy::IndexingPolicy::arity == 1) && + (ArrayPolicy::IndexingPolicy::areDataContiguous)); /*! * \brief copy constructor from an object assignable to the `Child` class. * \param[in] src: source * * This is mostly used by expression objects and views. */ - template ()) && - (!std::is_same_v)), - bool>::type = true> - explicit GenericRuntimeArray(const OtherArray&); + template + explicit GenericRuntimeArray(const OtherArray&) requires( + (isAssignableTo()) && + (!std::is_same_v)); //! \return a pointer to the underlying array serving as element storage. typename GenericRuntimeArray::pointer data() noexcept; //! \return a pointer to the underlying array serving as element storage. @@ -168,36 +165,32 @@ namespace tfel::math { * \param[in] src: array to be assigned */ template - std::enable_if_t(), Child&> operator=( - const OtherArray&); + Child& operator=(const OtherArray&) requires( + isAssignableTo()); // template - std::enable_if_t(), Child&> operator+=( - const OtherArray&); + Child& operator+=(const OtherArray&) requires( + isAssignableTo()); // template - std::enable_if_t(), Child&> operator-=( - const OtherArray&); + Child& operator-=(const OtherArray&) requires( + isAssignableTo()); // template - std::enable_if_t< + Child& operator*=(const ValueType2&) noexcept requires( isAssignableTo< BinaryOperationResult, - typename GenericRuntimeArray::value_type>(), - Child&> - operator*=(const ValueType2&) noexcept; + typename GenericRuntimeArray::value_type>()); // template - std::enable_if_t< + Child& operator/=(const ValueType2&) noexcept requires( isAssignableTo< BinaryOperationResult, - typename GenericRuntimeArray::value_type>(), - Child&> - operator/=(const ValueType2&) noexcept; + typename GenericRuntimeArray::value_type>()); // bool empty() const; // diff --git a/include/TFEL/Math/Array/GenericRuntimeArray.ixx b/include/TFEL/Math/Array/GenericRuntimeArray.ixx index 806eb2c61..a098f18f5 100644 --- a/include/TFEL/Math/Array/GenericRuntimeArray.ixx +++ b/include/TFEL/Math/Array/GenericRuntimeArray.ixx @@ -25,60 +25,38 @@ namespace tfel::math { } // end of GenericRuntimeArray template - template < - typename ValueType, - typename std::enable_if< - isAssignableTo< - ValueType, - typename GenericRuntimeArray::value_type>(), - bool>::type> + template GenericRuntimeArray::GenericRuntimeArray( - const typename ArrayPolicy::IndexingPolicy& p, const ValueType& value) + const typename ArrayPolicy::IndexingPolicy& p, + const ValueType& + value) requires(isAssignableTo::value_type>()) + : GenericRuntimeArray(p) { this->fill(value); } // end of GenericRuntimeArray template - template ()) && - (!std::is_same_v)), - bool>::type> + template GenericRuntimeArray::GenericRuntimeArray( - const OtherArray& src) + const OtherArray& src) requires((isAssignableTo()) && + (!std::is_same_v)) : GenericRuntimeArray(src.getIndexingPolicy()) { this->operator=(src); } // end of GenericRuntimeArray - // template - // template < - // typename ArrayPolicy2, - // typename std::enable_if<((checkIndexingPoliciesCompatiblity< - // typename ArrayPolicy::IndexingPolicy, - // typename - // ArrayPolicy2::IndexingPolicy>()) && - // (isAssignableTo< - // typename ArrayPolicy2::value_type, - // typename ArrayPolicy::value_type>())), - // bool>::type> - // constexpr GenericRuntimeArray::GenericRuntimeArray( - // const GenericRuntimeArray& src) noexcept - // : GenericRuntimeArray() { - // this->operator=(src); - // } - - template - template < - typename ValueType, - typename std::enable_if< - ((isAssignableTo:: - value_type>()) && - (ArrayPolicy::IndexingPolicy::arity == 1) && - (ArrayPolicy::IndexingPolicy::areDataContiguous)), - bool>::type> + template + template GenericRuntimeArray::GenericRuntimeArray( - const std::initializer_list& values) + const std::initializer_list& + values) requires((isAssignableTo::value_type>()) && + (ArrayPolicy::IndexingPolicy::arity == 1) && + (ArrayPolicy::IndexingPolicy::areDataContiguous)) : GenericRuntimeArray(values.size()) { this->operator=(values); } // end of GenericRuntimeArray @@ -119,8 +97,8 @@ namespace tfel::math { template template - std::enable_if_t(), Child&> - GenericRuntimeArray::operator=(const OtherArray& src) { + Child& GenericRuntimeArray::operator=( + const OtherArray& src) requires(isAssignableTo()) { auto& child = static_cast(*this); // checkIndexingPoliciesRuntimeCompatiblity(child.getIndexingPolicy(), // src.getIndexingPolicy()); @@ -130,8 +108,8 @@ namespace tfel::math { template template - std::enable_if_t(), Child&> - GenericRuntimeArray::operator+=(const OtherArray& src) { + Child& GenericRuntimeArray::operator+=( + const OtherArray& src) requires(isAssignableTo()) { auto& child = static_cast(*this); // checkIndexingPoliciesRuntimeCompatiblity(child.getIndexingPolicy(), // src.getIndexingPolicy()); @@ -141,8 +119,8 @@ namespace tfel::math { template template - std::enable_if_t(), Child&> - GenericRuntimeArray::operator-=(const OtherArray& src) { + Child& GenericRuntimeArray::operator-=( + const OtherArray& src) requires(isAssignableTo()) { auto& child = static_cast(*this); // checkIndexingPoliciesRuntimeCompatiblity(child.getIndexingPolicy(), // src.getIndexingPolicy()); @@ -152,16 +130,14 @@ namespace tfel::math { template template - std::enable_if_t< + Child& GenericRuntimeArray:: + operator*=(const ValueType2& v) noexcept requires( isAssignableTo< BinaryOperationResult< ValueType2, typename GenericRuntimeArray::value_type, OpMult>, - typename GenericRuntimeArray::value_type>(), - Child&> - GenericRuntimeArray::operator*=( - const ValueType2& v) noexcept { + typename GenericRuntimeArray::value_type>()) { auto& child = static_cast(*this); child.multiplyByScalar(v); return child; @@ -169,16 +145,14 @@ namespace tfel::math { // template template - std::enable_if_t< + Child& GenericRuntimeArray:: + operator/=(const ValueType2& v) noexcept requires( isAssignableTo< BinaryOperationResult< typename GenericRuntimeArray::value_type, ValueType2, OpDiv>, - typename GenericRuntimeArray::value_type>(), - Child&> - GenericRuntimeArray::operator/=( - const ValueType2& v) noexcept { + typename GenericRuntimeArray::value_type>()) { auto& child = static_cast(*this); child.multiplyByScalar(1 / v); return child; diff --git a/include/TFEL/Math/Array/View.hxx b/include/TFEL/Math/Array/View.hxx index fdd4796c3..0b2f2dc0c 100644 --- a/include/TFEL/Math/Array/View.hxx +++ b/include/TFEL/Math/Array/View.hxx @@ -222,9 +222,8 @@ namespace tfel::math { * \param[in] src: array to be assigned */ template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), View&> - operator=(const OtherArray& src) { + TFEL_HOST_DEVICE constexpr View& operator=(const OtherArray& src) requires( + isAssignableTo()) { static_assert(!is_const, "invalid call"); // checkIndexingPoliciesRuntimeCompatiblity(this->getIndexingPolicy(), // src.getIndexingPolicy()); @@ -233,9 +232,8 @@ namespace tfel::math { } // template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), View&> - operator+=(const OtherArray& src) { + TFEL_HOST_DEVICE constexpr View& operator+=(const OtherArray& src) requires( + isAssignableTo()) { static_assert(!is_const, "invalid call"); // checkIndexingPoliciesRuntimeCompatiblity(this->getIndexingPolicy(), // src.getIndexingPolicy()); @@ -244,9 +242,8 @@ namespace tfel::math { } // template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t(), View&> - operator-=(const OtherArray& src) { + TFEL_HOST_DEVICE constexpr View& operator-=(const OtherArray& src) requires( + isAssignableTo()) { static_assert(!is_const, "invalid call"); // checkIndexingPoliciesRuntimeCompatiblity(this->getIndexingPolicy(), // src.getIndexingPolicy()); @@ -255,24 +252,22 @@ namespace tfel::math { } // template - TFEL_HOST_DEVICE constexpr std::enable_if_t< + TFEL_HOST_DEVICE constexpr View& + operator*=(const ValueType2& s) noexcept requires( isAssignableTo< BinaryOperationResult, OpMult>, - numeric_type>(), - View&> - operator*=(const ValueType2& s) noexcept { + numeric_type>()) { static_assert(!is_const, "invalid call"); selectViewArrayBase::multiplyByScalar(s); return *this; } // end of operator*= // template - TFEL_HOST_DEVICE constexpr std::enable_if_t< + TFEL_HOST_DEVICE constexpr View& + operator/=(const ValueType2& s) noexcept requires( isAssignableTo< BinaryOperationResult, ValueType2, OpDiv>, - numeric_type>(), - View&> - operator/=(const ValueType2& s) noexcept { + numeric_type>()) { static_assert(!is_const, "invalid call"); selectViewArrayBase::multiplyByScalar(1 / s); @@ -326,30 +321,27 @@ namespace tfel::math { tfel::meta::InvalidType>; template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), - scalar_view> - map(base_type* const p) { + TFEL_HOST_DEVICE constexpr scalar_view map( + base_type* const p) // + requires(isScalar()) { return scalar_view(*p); } // end of map template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), - scalar_view> - map(base_type& v) { + TFEL_HOST_DEVICE constexpr scalar_view map( + base_type& v) requires(isScalar()) { return scalar_view(v); } // end of map template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), - scalar_view> // - map(const base_type* const p) { + TFEL_HOST_DEVICE constexpr scalar_view // + map(const base_type* const p) requires(isScalar()) { return scalar_view(*p); } // end of map template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), - scalar_view> // - map(const base_type& v) { + TFEL_HOST_DEVICE constexpr scalar_view map( + const base_type& v) requires(isScalar()) { return scalar_view(v); } // end of map @@ -360,22 +352,20 @@ namespace tfel::math { */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!std::is_const_v)&&(!isScalar()) && - (std::remove_cv_t::hasFixedSizes)), - View> - map(const ViewDataPointerType p) { + TFEL_HOST_DEVICE constexpr View + map(const ViewDataPointerType p) requires( + (!std::is_const_v)&&(!isScalar()) && + (std::remove_cv_t::hasFixedSizes)) { return View{p}; } // end of map template ::indexing_policy> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!isScalar()) && - (std::remove_cv_t::indexing_policy::hasFixedSizes)), - View> - map(const ViewConstDataPointerType p) { + TFEL_HOST_DEVICE constexpr View + map(const ViewConstDataPointerType p) requires( + (!isScalar()) && + (std::remove_cv_t::indexing_policy::hasFixedSizes)) { return View{p}; } // end of map @@ -407,14 +397,13 @@ namespace tfel::math { template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!std::is_const_v)&&(!IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename MappedType::indexing_policy>()) && - (canMakeViewFromLastArgument())), - View> - map(Args&&... args) { + TFEL_HOST_DEVICE constexpr View + map(Args&&... args) requires( + (!std::is_const_v)&&(!IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename MappedType::indexing_policy>()) && + (canMakeViewFromLastArgument())) { static_assert(sizeof...(Args) >= 2, "invalid call"); const auto r = buildIndexingPolicyAndExtractPointerToData(args...); @@ -426,15 +415,14 @@ namespace tfel::math { typename... Args, typename IndexingPolicyType = typename std::remove_cv_t::indexing_policy> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!std::remove_cv_t::indexing_policy::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>()) && - (canMakeConstViewFromLastArgument, - Args...>())), - View> - map(const Args&... args) { + TFEL_HOST_DEVICE constexpr View + map(const Args&... args) requires( + (!std::remove_cv_t::indexing_policy::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>()) && + (canMakeConstViewFromLastArgument, + Args...>())) { static_assert(sizeof...(Args) >= 2, "invalid call"); const auto r = buildIndexingPolicyAndExtractPointerToData(args...); diff --git a/include/TFEL/Math/Array/ViewsArray.hxx b/include/TFEL/Math/Array/ViewsArray.hxx index 5186bbb51..78ff1e754 100644 --- a/include/TFEL/Math/Array/ViewsArray.hxx +++ b/include/TFEL/Math/Array/ViewsArray.hxx @@ -19,70 +19,70 @@ #include "TFEL/Math/Array/View.hxx" #include "TFEL/Math/Array/FixedSizeIndexingPolicies.hxx" -namespace tfel::math { +namespace tfel::math::internals { - namespace internals { + /*! + * \brief an helper structure using to define the type of views generate by + * `ViewsArray`. + * \tparam is_scalar: boolean stating if the mapped type is a scalar + * \tparam MappedType: mapped type + * \tparam ViewIndexingPolicyType: indexing policy used by the view + */ + template + struct ViewsArrayBase { + static_assert(!tfel::math::isScalar()); + //! \brief type of views + using view_type = tfel::math::View; + //! \brief type of read-only views + using const_view_type = + tfel::math::View; + }; // end of ViewsArrayBase - /*! - * \brief an helper structure using to define the type of views generate by - * `ViewsArray`. - * \tparam is_scalar: boolean stating if the mapped type is a scalar - * \tparam MappedType: mapped type - * \tparam ViewIndexingPolicyType: indexing policy used by the view - */ - template - struct ViewsArrayBase { - static_assert(!tfel::math::isScalar()); - //! \brief type of views - using view_type = tfel::math::View; - //! \brief type of read-only views - using const_view_type = - tfel::math::View; - }; // end of ViewsArrayBase + /*! + * \brief an helper structure using to define the type of views generate by + * `ViewsArray`. + * \tparam MappedType: mapped type + * \tparam ViewIndexingPolicyType: indexing policy used by the view + */ + template + struct ViewsArrayBase { + static_assert(tfel::math::isScalar()); + //! \brief type of views + using view_type = MappedType&; + //! \brief type of read-only views + using const_view_type = const MappedType&; + }; // end of ViewsArrayBase - /*! - * \brief an helper structure using to define the type of views generate by - * `ViewsArray`. - * \tparam MappedType: mapped type - * \tparam ViewIndexingPolicyType: indexing policy used by the view - */ - template - struct ViewsArrayBase { - static_assert(tfel::math::isScalar()); - //! \brief type of views - using view_type = MappedType&; - //! \brief type of read-only views - using const_view_type = const MappedType&; - }; // end of ViewsArrayBase + /*! + * \brief a metafunction returning the default indexing policy for the given + * mapped type + * \tparam is_scalar: boolean stating if the mapped type is a scalar + * \tparam MappedType: mapped type + */ + template + struct ViewsArrayDefaultViewIndexingPolicy { + static_assert(!tfel::math::isScalar()); + //! \brief default indexing type + using type = typename MappedType::indexing_policy; + }; // end of ViewsArrayDefaultViewIndexingPolicy - /*! - * \brief a metafunction returning the default indexing policy for the given - * mapped type - * \tparam is_scalar: boolean stating if the mapped type is a scalar - * \tparam MappedType: mapped type - */ - template - struct ViewsArrayDefaultViewIndexingPolicy { - static_assert(!tfel::math::isScalar()); - //! \brief default indexing type - using type = typename MappedType::indexing_policy; - }; // end of ViewsArrayDefaultViewIndexingPolicy + /*! + * \brief a metafunction returning the default indexing policy for the given + * scalar mapped type + * \tparam MappedType: mapped type + */ + template + struct ViewsArrayDefaultViewIndexingPolicy { + static_assert(tfel::math::isScalar()); + //! \brief default indexing type + using type = tfel::math::ScalarIndexingPolicy; + }; // end of ViewsArrayDefaultViewIndexingPolicy - /*! - * \brief a metafunction returning the default indexing policy for the given - * scalar mapped type - * \tparam MappedType: mapped type - */ - template - struct ViewsArrayDefaultViewIndexingPolicy { - static_assert(tfel::math::isScalar()); - //! \brief default indexing type - using type = tfel::math::ScalarIndexingPolicy; - }; // end of ViewsArrayDefaultViewIndexingPolicy +} // end of namespace tfel::math::internals - } // end of namespace internals +namespace tfel::math { //! \brief the numeric type used by the mapped type template @@ -315,12 +315,11 @@ namespace tfel::math { } // \brief multiplication by a scalar template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((isScalar()) && - (isAssignableTo, - MappedType>())), - ViewsArray&> - operator*=(const ValueType2& s) noexcept { + TFEL_HOST_DEVICE constexpr ViewsArray& + operator*=(const ValueType2& s) noexcept requires( + (isScalar()) && + (isAssignableTo, + MappedType>())) { static_assert(!std::is_const_v, "invalid call"); const auto f = makeMultiIndicesUnaryOperatorFunctor([s](auto& a) { a *= s; }, *this); @@ -341,12 +340,11 @@ namespace tfel::math { } // end of operator*= // \brief division by a scalar template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((isScalar()) && - (isAssignableTo, - MappedType>())), - ViewsArray&> - operator/=(const ValueType2& s) noexcept { + TFEL_HOST_DEVICE constexpr ViewsArray& + operator/=(const ValueType2& s) noexcept requires( + (isScalar()) && + (isAssignableTo, + MappedType>())) { static_assert(!std::is_const_v, "invalid call"); return this->operator*=(1 / s); } // end of operator/= diff --git a/include/TFEL/Math/ExpressionTemplates/Expr.hxx b/include/TFEL/Math/ExpressionTemplates/Expr.hxx index 4042952da..c94f5e454 100644 --- a/include/TFEL/Math/ExpressionTemplates/Expr.hxx +++ b/include/TFEL/Math/ExpressionTemplates/Expr.hxx @@ -15,7 +15,6 @@ #define LIB_TFEL_MATH_EXPRESSION_EXPR_HXX #include -#include "TFEL/Metaprogramming/ResultOf.hxx" #include "TFEL/TypeTraits/IsScalar.hxx" #include "TFEL/TypeTraits/IsAssignableTo.hxx" #include "TFEL/Math/General/MathObjectTraits.hxx" @@ -70,7 +69,7 @@ namespace tfel::math { */ TFEL_HOST_DEVICE constexpr value_type operator[](const size_type i) const { // may not be defined - static_assert(tfel::meta::IsConstCallable::cond, + static_assert(std::is_invocable_v, "Expr is not callable"); return Operation::operator()(i); } @@ -128,7 +127,7 @@ namespace tfel::math { TFEL_HOST_DEVICE constexpr value_type operator[](const size_type i) const { static_assert( isUnaryOperationResultTypeValid< - tfel::meta::result_of, Op>(), + std::invoke_result_t, Op>(), "invalid call to unary operation operator[]"); return Op::apply(this->a(i)); } @@ -140,13 +139,13 @@ namespace tfel::math { -> UnaryOperationHandler< std::conditional_t< std::is_lvalue_reference_v< - tfel::meta::result_of>, - tfel::meta::result_of, - tfel::meta::result_of&&>, + std::invoke_result_t>, + std::invoke_result_t, + std::invoke_result_t&&>, Op> { static_assert( isUnaryOperationResultTypeValid< - tfel::meta::result_of, Op>(), + std::invoke_result_t, Op>(), "invalid call to unary operation operator()"); return Op::apply(this->a(i...)); } // end of operator() @@ -199,8 +198,8 @@ namespace tfel::math { TFEL_HOST_DEVICE constexpr value_type operator[](const size_type i) const { static_assert( isBinaryOperationResultTypeValid< - tfel::meta::result_of, - tfel::meta::result_of, Op>(), + std::invoke_result_t, + std::invoke_result_t, Op>(), "invalid call to unary operation operator[]"); return Op::apply(this->a(i), this->b(i)); } @@ -211,20 +210,20 @@ namespace tfel::math { TFEL_HOST_DEVICE constexpr BinaryOperationHandler< std::conditional_t< std::is_lvalue_reference_v< - tfel::meta::result_of>, - tfel::meta::result_of, - tfel::meta::result_of&&>, + std::invoke_result_t>, + std::invoke_result_t, + std::invoke_result_t&&>, std::conditional_t< std::is_lvalue_reference_v< - tfel::meta::result_of>, - tfel::meta::result_of, - tfel::meta::result_of&&>, + std::invoke_result_t>, + std::invoke_result_t, + std::invoke_result_t&&>, Op> operator()(const Indexes... i) const { static_assert( isBinaryOperationResultTypeValid< - tfel::meta::result_of, - tfel::meta::result_of, Op>(), + std::invoke_result_t, + std::invoke_result_t, Op>(), "invalid call to binary operation operator()"); return Op::apply(this->a(i...), this->b(i...)); } // end of operator() @@ -279,7 +278,7 @@ namespace tfel::math { static_assert( isBinaryOperationResultTypeValid< std::add_lvalue_reference_t, - tfel::meta::result_of, Op>(), + std::invoke_result_t, Op>(), "invalid call"); return Op::apply(this->a, this->b(i)); } @@ -291,15 +290,15 @@ namespace tfel::math { std::add_lvalue_reference_t, std::conditional_t< std::is_lvalue_reference_v< - tfel::meta::result_of>, - tfel::meta::result_of, - tfel::meta::result_of&&>, + std::invoke_result_t>, + std::invoke_result_t, + std::invoke_result_t&&>, Op> operator()(const Indexes... i) const { static_assert( isBinaryOperationResultTypeValid< std::add_lvalue_reference_t, - tfel::meta::result_of, Op>(), + std::invoke_result_t, Op>(), "invalid call"); return Op::apply(this->a, this->b(i...)); } // end of operator() @@ -352,7 +351,7 @@ namespace tfel::math { */ TFEL_HOST_DEVICE constexpr value_type operator[](const size_type i) const { static_assert(isBinaryOperationResultTypeValid< - tfel::meta::result_of, + std::invoke_result_t, std::add_lvalue_reference_t, Op>(), "invalid call"); return Op::apply(this->a(i), this->b); @@ -364,14 +363,14 @@ namespace tfel::math { TFEL_HOST_DEVICE constexpr BinaryOperationHandler< std::conditional_t< std::is_lvalue_reference_v< - tfel::meta::result_of>, - tfel::meta::result_of, - tfel::meta::result_of&&>, + std::invoke_result_t>, + std::invoke_result_t, + std::invoke_result_t&&>, std::add_lvalue_reference_t, Op> operator()(const Indexes... i) const { static_assert(isBinaryOperationResultTypeValid< - tfel::meta::result_of, + std::invoke_result_t, std::add_lvalue_reference_t, Op>(), "invalid call"); return Op::apply(this->a(i...), this->b); @@ -424,8 +423,8 @@ namespace tfel::math { * \param[in] i : column index */ TFEL_HOST_DEVICE constexpr BinaryOperationHandler< - tfel::meta::result_of, - tfel::meta::result_of, + std::invoke_result_t, + std::invoke_result_t, OpMult> operator()(const size_type i, const size_type j) const { return (this->a(i)) * (this->b(j)); diff --git a/include/TFEL/Math/ExpressionTemplates/StandardOperations.hxx b/include/TFEL/Math/ExpressionTemplates/StandardOperations.hxx index 2103ba76e..d0475ae57 100644 --- a/include/TFEL/Math/ExpressionTemplates/StandardOperations.hxx +++ b/include/TFEL/Math/ExpressionTemplates/StandardOperations.hxx @@ -36,11 +36,11 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator-(T1&& a) -> std::enable_if_t< - ((!isScalar()) && - (isUnaryOperationResultTypeValid()) && - (!isInvalid>())), - UnaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator-(T1&& a) noexcept + -> UnaryOperationHandler requires( + (!isScalar()) && + (isUnaryOperationResultTypeValid()) && + (!isInvalid>())) { return UnaryOperationHandler(std::forward(a)); } @@ -60,10 +60,12 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator+(T1&& a, T2&& b) -> std::enable_if_t< - ((isBinaryOperationResultTypeValid()) && - (!((isScalar()) && (isScalar())))), - BinaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator+(T1&& a, T2&& b) noexcept + -> BinaryOperationHandler requires( + (isBinaryOperationResultTypeValid()) && + (!((isScalar()) && (isScalar())))) { return BinaryOperationHandler( std::forward(a), std::forward(b)); } @@ -84,12 +86,12 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator-(T1&& a, T2&& b) -> std::enable_if_t< - ((isBinaryOperationResultTypeValid()) && - (!((isScalar()) && (isScalar())))), - BinaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator-(T1&& a, T2&& b) noexcept + -> BinaryOperationHandler requires( + (isBinaryOperationResultTypeValid()) && + (!((isScalar()) && (isScalar())))) { return BinaryOperationHandler( std::forward(a), std::forward(b)); } @@ -110,10 +112,12 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator*(T1&& a, T2&& b) -> std::enable_if_t< - ((isBinaryOperationResultTypeValid()) && - (!((isScalar()) && (isScalar())))), - BinaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator*(T1&& a, T2&& b) noexcept + -> BinaryOperationHandler requires( + (isBinaryOperationResultTypeValid()) && + (!((isScalar()) && (isScalar())))) { return BinaryOperationHandler( std::forward(a), std::forward(b)); } @@ -134,10 +138,12 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator/(T1&& a, T2&& b) -> std::enable_if_t< - ((isBinaryOperationResultTypeValid()) && - (!((isScalar()) && (isScalar())))), - BinaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator/(T1&& a, T2&& b) noexcept + -> BinaryOperationHandler requires( + (isBinaryOperationResultTypeValid()) && + (!((isScalar()) && (isScalar())))) { return BinaryOperationHandler( std::forward(a), std::forward(b)); } @@ -158,12 +164,12 @@ namespace tfel::math { * \see IsInvalidType */ template - TFEL_HOST_DEVICE constexpr auto operator^(T1&& a, T2&& b) -> std::enable_if_t< - ((isBinaryOperationResultTypeValid()) && - (!((isScalar()) && (isScalar())))), - BinaryOperationHandler> { + TFEL_HOST_DEVICE constexpr auto operator^(T1&& a, T2&& b) noexcept + -> BinaryOperationHandler requires( + (isBinaryOperationResultTypeValid()) && + (!((isScalar()) && (isScalar())))) { return BinaryOperationHandler( std::forward(a), std::forward(b)); } diff --git a/include/TFEL/Math/General/Abs.hxx b/include/TFEL/Math/General/Abs.hxx index 2cb1eeb8b..823c65c33 100644 --- a/include/TFEL/Math/General/Abs.hxx +++ b/include/TFEL/Math/General/Abs.hxx @@ -27,18 +27,17 @@ namespace tfel::math { * \param[in] s: value */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - tfel::typetraits::isFundamentalNumericType(), - NumericType> - abs(const NumericType& s) noexcept { + TFEL_HOST_DEVICE constexpr auto abs(const NumericType& s) noexcept requires( + tfel::typetraits::isFundamentalNumericType()) { return (s < NumericType(0)) ? -s : s; } - + /*! + * \return the norm of a complex + * \param[in] s: value + */ template - TFEL_MATH_INLINE std::enable_if_t< - tfel::typetraits::IsFundamentalNumericType::cond, - NumericType> - abs(const Complex& s) { + TFEL_HOST_DEVICE constexpr auto abs(const Complex& s) requires( + tfel::typetraits::IsFundamentalNumericType::cond) { return s.norm(); } @@ -52,14 +51,14 @@ namespace tfel::math { //! \brief a simple alias using result_type = void; //! \param [in] v : initial value - AbsSum(const T& v = T()) : result(v) {} // end of AbsSum + TFEL_HOST_DEVICE constexpr AbsSum(const T& v = T()) + : result(v) {} // end of AbsSum /*! * \brief add the absolute value of the argument to the result member */ TFEL_HOST_DEVICE constexpr void operator()(const T& v) noexcept { result += abs(v); } - //! \brief result T result; }; // end of struct AbsSum diff --git a/include/TFEL/Math/General/BasicOperations.hxx b/include/TFEL/Math/General/BasicOperations.hxx index b47fb0da4..a953d228d 100644 --- a/include/TFEL/Math/General/BasicOperations.hxx +++ b/include/TFEL/Math/General/BasicOperations.hxx @@ -198,20 +198,16 @@ namespace tfel::math { TFEL_MATH_RESULT_TYPE(long double); template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - tfel::typetraits::isScalar() && - (!tfel::typetraits::IsComplex::cond), - T> - conj(const T src) { + TFEL_HOST_DEVICE constexpr auto conj(const T src) noexcept requires( + (tfel::typetraits::isScalar()) && + (!tfel::typetraits::IsComplex::cond)) { return src; - } + } // end of conj template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - tfel::typetraits::isScalar() && - (!tfel::typetraits::IsComplex::cond), - T> - real(const T src) { + TFEL_HOST_DEVICE constexpr auto real(const T src) noexcept requires( + (tfel::typetraits::isScalar()) && + (!tfel::typetraits::IsComplex::cond)) { return src; } diff --git a/include/TFEL/Math/General/CubicRoots.hxx b/include/TFEL/Math/General/CubicRoots.hxx index 9f7046999..4d72bc08c 100644 --- a/include/TFEL/Math/General/CubicRoots.hxx +++ b/include/TFEL/Math/General/CubicRoots.hxx @@ -41,17 +41,21 @@ namespace tfel::math { * \return the cubic root of a real number of type float * \param[in] x : value */ - static TFEL_MATH_INLINE float cbrt(const float x) { return ::cbrtf(x); } + TFEL_HOST_DEVICE static float cbrt(const float x) noexcept { + return ::cbrtf(x); + } /*! * \return the cubic root of a real number of type double * \param[in] x : value */ - static TFEL_MATH_INLINE double cbrt(const double x) { return ::cbrt(x); } + TFEL_HOST_DEVICE static double cbrt(const double x) noexcept { + return ::cbrt(x); + } /*! * \return the cubic root of a real number of type long double * \param[in] x : value */ - static TFEL_MATH_INLINE long double cbrt(const long double x) { + TFEL_HOST_DEVICE static long double cbrt(const long double x) noexcept { return ::cbrtl(x); } #endif /* LIB_TFEL_MATH_CUBICROOTS_HXX */ @@ -61,7 +65,7 @@ namespace tfel::math { * \param[in] x : value */ template - static TFEL_HOST_DEVICE TFEL_MATH_INLINE T cbrt(const T x) { + TFEL_HOST_DEVICE static T cbrt(const T x) noexcept { constexpr const auto one_third = T(1) / T(3); if (x < 0) { return -std::pow(-x, one_third); @@ -88,12 +92,15 @@ namespace tfel::math { * - x2 and x3 contain the real part of the two other roots */ template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 std::enable_if_t< - tfel::typetraits::IsReal::cond && - tfel::typetraits::IsFundamentalNumericType::cond, - unsigned short> - find_roots( - T& x1, T& x2, T& x3, const T a3, const T a2, const T a1, const T a0) { + TFEL_HOST_DEVICE static unsigned short find_roots(T& x1, + T& x2, + T& x3, + const T a3, + const T a2, + const T a1, + const T a0) // + requires((tfel::typetraits::IsReal::cond) && + (tfel::typetraits::IsFundamentalNumericType::cond)) { constexpr auto C_1_2 = T{1} / T{2}; constexpr auto C_1_3 = T{1} / T{3}; constexpr auto C_2_3 = T{2} * C_1_3; @@ -203,18 +210,16 @@ namespace tfel::math { * refine the roots found */ template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 std::enable_if_t< - tfel::typetraits::IsReal::cond && - tfel::typetraits::IsFundamentalNumericType::cond, - unsigned short> - exe(T& x1, - T& x2, - T& x3, - const T a3, - const T a2, - const T a1, - const T a0, - const bool b = false) { + TFEL_HOST_DEVICE static unsigned short exe(T& x1, + T& x2, + T& x3, + const T a3, + const T a2, + const T a1, + const T a0, + const bool b = false) // + requires((tfel::typetraits::IsReal::cond) && + (tfel::typetraits::IsFundamentalNumericType::cond)) { const auto nb = CubicRoots::find_roots(x1, x2, x3, a3, a2, a1, a0); if ((nb > 0) && (b)) { CubicRoots::improve(x1, a3, a2, a1, a0); diff --git a/include/TFEL/Math/General/MathObjectTraits.hxx b/include/TFEL/Math/General/MathObjectTraits.hxx index 82dd275d5..d8db8dfe5 100644 --- a/include/TFEL/Math/General/MathObjectTraits.hxx +++ b/include/TFEL/Math/General/MathObjectTraits.hxx @@ -137,6 +137,9 @@ namespace tfel::math { return tfel::typetraits::isScalar(); } // end of isScalar + template + concept ScalarConcept = tfel::typetraits::IsScalar>::cond; + } // end of namespace tfel::math #endif /* LIB_TFEL_MATH_GENERAL_MATHOBJECTTRAITS_HXX */ diff --git a/include/TFEL/Math/LU/TinyMatrixSolve.ixx b/include/TFEL/Math/LU/TinyMatrixSolve.ixx index f6bb8b95c..10f2eb4df 100644 --- a/include/TFEL/Math/LU/TinyMatrixSolve.ixx +++ b/include/TFEL/Math/LU/TinyMatrixSolve.ixx @@ -26,16 +26,14 @@ namespace tfel::math { typename T, bool use_exceptions, bool perfom_runtime_checks> - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyMatrixSolveBase:: - back_substitute(const FixedSizeMatrixType& m, - const TinyPermutation& p, - FixedSizeVectorType& b, - const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolveBase:: + back_substitute(const FixedSizeMatrixType& m, + const TinyPermutation& p, + FixedSizeVectorType& b, + const T eps) noexcept(!use_exceptions) { using size_type = index_type>; if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != N) { @@ -115,7 +113,7 @@ namespace tfel::math { back_substitute(const tmatrix& m, const TinyPermutation& p, tfel::math::tmatrix& b, - const T eps) { + const T eps) noexcept(!use_exceptions) { using size_type = typename MathObjectTraits>::IndexType; auto x = b; if (p.isIdentity()) { @@ -200,11 +198,12 @@ namespace tfel::math { typename T, bool use_exceptions, bool perfom_runtime_checks> - template - TFEL_HOST_DEVICE - std::enable_if_t(), bool> - TinyMatrixSolveBase::decomp( - FixedSizeMatrixType& m, TinyPermutation& p, const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolveBase::decomp( + FixedSizeMatrixType& m, + TinyPermutation& p, + const T eps) noexcept(!use_exceptions) { if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != N) { return false; @@ -220,13 +219,13 @@ namespace tfel::math { typename T, bool use_exceptions, bool perfom_runtime_checks> - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyMatrixSolve::exe( - FixedSizeMatrixType& m, FixedSizeVectorType& b, const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolve::exe( + FixedSizeMatrixType& m, + FixedSizeVectorType& b, + const T eps) noexcept(!use_exceptions) { if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != N) { return false; @@ -255,7 +254,9 @@ namespace tfel::math { template TFEL_HOST_DEVICE bool TinyMatrixSolve::exe( - tmatrix& m, tmatrix& b, const T eps) { + tmatrix& m, + tmatrix& b, + const T eps) noexcept(!use_exceptions) { TinyPermutation p; if (!TinyMatrixSolve::decomp( m, p, eps)) { @@ -268,13 +269,13 @@ namespace tfel::math { // Partial specialisation for 1*1 matrix template - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyMatrixSolve<1u, T, use_exceptions, perfom_runtime_checks>::exe( - const FixedSizeMatrixType& m, FixedSizeVectorType& b, const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolve<1u, T, use_exceptions, perfom_runtime_checks>::exe( + const FixedSizeMatrixType& m, + FixedSizeVectorType& b, + const T eps) noexcept(!use_exceptions) { if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != 1u) { return false; @@ -301,7 +302,9 @@ namespace tfel::math { template TFEL_HOST_DEVICE bool TinyMatrixSolve<1u, T, use_exceptions, perfom_runtime_checks>::exe( - const tmatrix<1u, 1u, T>& m, tmatrix<1u, M, T>& b, const T eps) { + const tmatrix<1u, 1u, T>& m, + tmatrix<1u, M, T>& b, + const T eps) noexcept(!use_exceptions) { if (tfel::math::abs(m(0, 0)) < eps) { if constexpr (use_exceptions) { tfel::raise(); @@ -315,13 +318,13 @@ namespace tfel::math { // Partial specialisation for 2*2 matrix template - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyMatrixSolve<2u, T, use_exceptions, perfom_runtime_checks>::exe( - const FixedSizeMatrixType& m, FixedSizeVectorType& b, const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolve<2u, T, use_exceptions, perfom_runtime_checks>::exe( + const FixedSizeMatrixType& m, + FixedSizeVectorType& b, + const T eps) noexcept(!use_exceptions) { if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != 2u) { return false; @@ -352,7 +355,9 @@ namespace tfel::math { template TFEL_HOST_DEVICE bool TinyMatrixSolve<2u, T, use_exceptions, perfom_runtime_checks>::exe( - const tmatrix<2u, 2u, T>& m, tmatrix<2u, M, T>& b, const T eps) { + const tmatrix<2u, 2u, T>& m, + tmatrix<2u, M, T>& b, + const T eps) noexcept(!use_exceptions) { const auto det = m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0); if (tfel::math::abs(det) < eps) { if constexpr (use_exceptions) { @@ -372,13 +377,13 @@ namespace tfel::math { // Partial specialisation for 3*3 matrix template - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyMatrixSolve<3u, T, use_exceptions, perfom_runtime_checks>::exe( - const FixedSizeMatrixType& m, FixedSizeVectorType& b, const T eps) { + template + TFEL_HOST_DEVICE bool + TinyMatrixSolve<3u, T, use_exceptions, perfom_runtime_checks>::exe( + const FixedSizeMatrixType& m, + FixedSizeVectorType& b, + const T eps) noexcept(!use_exceptions) { if constexpr (perfom_runtime_checks) { if (m.getIndexingPolicy().size(0) != 3u) { return false; @@ -422,7 +427,9 @@ namespace tfel::math { template TFEL_HOST_DEVICE bool TinyMatrixSolve<3u, T, use_exceptions, perfom_runtime_checks>::exe( - const tmatrix<3u, 3u, T>& m, tmatrix<3u, M, T>& b, const T eps) { + const tmatrix<3u, 3u, T>& m, + tmatrix<3u, M, T>& b, + const T eps) noexcept(!use_exceptions) { const auto det = m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)); diff --git a/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.hxx b/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.hxx index 59cbdf45f..71b162fc2 100644 --- a/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.hxx +++ b/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.hxx @@ -99,7 +99,8 @@ namespace tfel::math { * \param[in] args: arguments forwarded to the external workspace */ template - TFEL_HOST_DEVICE TinyNonLinearSolverBase(ExternalWorkSpaceArguments&&...); + TFEL_HOST_DEVICE TinyNonLinearSolverBase( + ExternalWorkSpaceArguments&&...) noexcept; //! \brief default constructor TinyNonLinearSolverBase(TinyNonLinearSolverBase&) noexcept = default; //! \brief default constructor @@ -135,14 +136,14 @@ namespace tfel::math { * * \return true on success */ - TFEL_HOST_DEVICE bool solveNonLinearSystem(); + TFEL_HOST_DEVICE bool solveNonLinearSystem() noexcept; /*! * \brief solve the non linear problem. This method is called by the * `solveNonLinearSystem` and must contain the core of the resolution * algorithm. * \return true on success */ - TFEL_HOST_DEVICE bool solveNonLinearSystem2(); + TFEL_HOST_DEVICE bool solveNonLinearSystem2() noexcept; /*! * \brief this method is called at the beginning of the * `solveNonLinearSystem` method. @@ -180,12 +181,10 @@ namespace tfel::math { * \param[in] m: matrix * \param[in,out] v: right hand side on input, solution on output */ - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - solveLinearSystem(FixedSizeMatrixType&, FixedSizeVectorType&) const + template + TFEL_HOST_DEVICE bool solveLinearSystem(FixedSizeMatrixType&, + FixedSizeVectorType&) const noexcept; /*! * \brief update the jacobian matrix if required. diff --git a/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.ixx b/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.ixx index 0df545c92..7a671dba9 100644 --- a/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.ixx +++ b/include/TFEL/Math/NonLinearSolvers/TinyNonLinearSolverBase.ixx @@ -27,7 +27,7 @@ namespace tfel::math { template TFEL_HOST_DEVICE TinyNonLinearSolverBase:: - TinyNonLinearSolverBase(ExternalWorkSpaceArguments&&... args) + TinyNonLinearSolverBase(ExternalWorkSpaceArguments&&... args) noexcept : ExternalWorkSpace( std::forward(args)...) { } // end of TinyNonLinearSolverBase @@ -39,7 +39,7 @@ namespace tfel::math { typename ExternalWorkSpace> TFEL_HOST_DEVICE bool TinyNonLinearSolverBase:: - solveNonLinearSystem2() { + solveNonLinearSystem2() noexcept { auto& child = static_cast(*this); auto converged = false; child.executeInitialisationTaskBeforeBeginningOfCoreAlgorithm(); @@ -84,7 +84,7 @@ namespace tfel::math { typename ExternalWorkSpace> TFEL_HOST_DEVICE bool TinyNonLinearSolverBase:: - solveNonLinearSystem() { + solveNonLinearSystem() noexcept { constexpr auto one_half = NumericType(1) / 2; auto& child = static_cast(*this); child.reportBeginningOfResolution(); @@ -118,14 +118,12 @@ namespace tfel::math { typename Child, template typename ExternalWorkSpace> - template - TFEL_HOST_DEVICE - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - TinyNonLinearSolverBase:: - solveLinearSystem(FixedSizeMatrixType& m, - FixedSizeVectorType& v) const noexcept { + template + TFEL_HOST_DEVICE bool + TinyNonLinearSolverBase:: + solveLinearSystem(FixedSizeMatrixType& m, FixedSizeVectorType& v) const + noexcept { return TinyMatrixSolve::exe(m, v); } // end of solveLinearSystem diff --git a/include/TFEL/Math/ST2toST2/StensorSymmetricProductDerivative.hxx b/include/TFEL/Math/ST2toST2/StensorSymmetricProductDerivative.hxx index be4014146..532d08408 100644 --- a/include/TFEL/Math/ST2toST2/StensorSymmetricProductDerivative.hxx +++ b/include/TFEL/Math/ST2toST2/StensorSymmetricProductDerivative.hxx @@ -26,11 +26,10 @@ namespace tfel::math { template struct StensorSymmetricProductDerivative<1u, T> { template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE - std::enable_if_t() == 1u && - isAssignableTo, T>(), - tfel::math::st2tost2<1u, T>> - exe(const StensorType& s) { + TFEL_HOST_DEVICE static constexpr tfel::math::st2tost2<1u, T> + exe(const StensorType& s) noexcept requires( + (getSpaceDimension() == 1u) && + (isAssignableTo, T>())) { using real = base_type; constexpr real zero = real(0); return {2 * s[0], zero, zero, zero, 2 * s[1], zero, zero, zero, 2 * s[2]}; @@ -40,11 +39,10 @@ namespace tfel::math { template struct StensorSymmetricProductDerivative<2u, T> { template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE - std::enable_if_t() == 2u && - isAssignableTo, T>(), - tfel::math::st2tost2<2u, T>> - exe(const StensorType& s) { + TFEL_HOST_DEVICE static constexpr tfel::math::st2tost2<2u, T> + exe(const StensorType& s) noexcept requires( + (getSpaceDimension() == 2u) && + (isAssignableTo, T>())) { using real = base_type; constexpr real zero = real(0); return {2 * s[0], zero, zero, s[3], zero, 2 * s[1], @@ -56,11 +54,10 @@ namespace tfel::math { template struct StensorSymmetricProductDerivative<3u, T> { template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE - std::enable_if_t() == 3u && - isAssignableTo, T>(), - tfel::math::st2tost2<3u, T>> - exe(const StensorType& s) { + TFEL_HOST_DEVICE static constexpr tfel::math::st2tost2<3u, T> + exe(const StensorType& s) noexcept requires( + (getSpaceDimension() == 3u) && + (isAssignableTo, T>())) { using real = base_type; constexpr auto icste = Cste::isqrt2; constexpr auto zero = real(0); diff --git a/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.hxx b/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.hxx index 5716db806..ceadb9411 100644 --- a/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.hxx +++ b/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.hxx @@ -26,11 +26,12 @@ namespace tfel::math { * \param[in] b: the second symmetric tensor */ template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 1u) && - (getSpaceDimension() == 1u)), - st2tost2<1u, decltype(a[0] * b[0])>>::type; + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<1u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 1u) && + (getSpaceDimension() == 1u)); + /*! * \brief compute the derivative of the product * \(a\,\dot\,b\,\dot\,a\) with respect to \(a\), where \(a\) and @@ -39,24 +40,24 @@ namespace tfel::math { * \param[in] b: the second symmetric tensor */ template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 2u) && - (getSpaceDimension() == 2u)), - st2tost2<2u, decltype(a[0] * b[0])>>::type; + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<2u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 2u) && + (getSpaceDimension() == 2u)); + /*! - * \brief compute the derivative of the product \(a\,\dot\,b\,\dot\,a\) with - * respect to \(a\), where \(a\) and \(b) are two symmetric tensor. + * \brief compute the derivative of the product \(a\,\dot\,b\,\dot\,a\) + * with respect to \(a\), where \(a\) and \(b) are two symmetric tensor. * \param[in] a: the first symmetric tensor * \param[in] b: the second symmetric tensor */ template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 3u) && - (getSpaceDimension() == 3u)), - st2tost2<3u, decltype(a[0] * b[0])>>::type; - + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<3u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 3u) && + (getSpaceDimension() == 3u)); /*! * \brief compute the derivative of the product * \(a\,\dot\,b\,\dot\,a\) with respect to \(b\), where \(a\) and @@ -64,9 +65,9 @@ namespace tfel::math { * \param[in] a: the first symmetric tensor */ template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 1u, - st2tost2<1u, decltype(a[0] * a[0])>>::type; + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<1u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 1u); /*! * \brief compute the derivative of the product * \(a\,\dot\,b\,\dot\,a\) with respect to \(b\), where \(a\) and @@ -74,9 +75,9 @@ namespace tfel::math { * \param[in] a: the first symmetric tensor */ template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 2u, - st2tost2<2u, decltype(a[0] * a[0])>>::type; + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<2u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 2u); /*! * \brief compute the derivative of the product * \(a\,\dot\,b\,\dot\,a\) with respect to \(b\), where \(a\) and @@ -84,9 +85,9 @@ namespace tfel::math { * \param[in] a: the first symmetric tensor */ template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 3u, - st2tost2<3u, decltype(a[0] * a[0])>>::type; + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<3u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 3u); } // end of namespace tfel::math diff --git a/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.ixx b/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.ixx index 0d8a64b31..a07c160f2 100644 --- a/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.ixx +++ b/include/TFEL/Math/ST2toST2/SymmetricStensorProductDerivative.ixx @@ -17,28 +17,28 @@ namespace tfel::math { template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 1u) && - (getSpaceDimension() == 1u)), - st2tost2<1u, decltype(a[0] * b[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<1u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 1u) && + (getSpaceDimension() == 1u)) { using NumType = decltype(a[0] * b[0]); using real = base_type; - constexpr auto zero = real(0); + TFEL_HOST_DEVICE constexpr auto zero = real(0); return {2 * a[0] * b[0], zero, zero, zero, 2 * a[1] * b[1], zero, zero, zero, 2 * a[2] * b[2]}; } // end of symmetric_product_aba template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 2u) && - (getSpaceDimension() == 2u)), - st2tost2<2u, decltype(a[0] * b[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<2u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 2u) && + (getSpaceDimension() == 2u)) { using NumType = decltype(a[0] * b[0]); using real = base_type; - constexpr auto zero = real(0); + TFEL_HOST_DEVICE constexpr auto zero = real(0); return {a[3] * b[3] + 2 * a[0] * b[0], zero, zero, @@ -58,15 +58,15 @@ namespace tfel::math { } // end of symmetric_product_aba template - auto symmetric_product_derivative_daba_da(const StensorType1& a, - const StensorType2& b) -> - typename std::enable_if<((getSpaceDimension() == 3u) && - (getSpaceDimension() == 3u)), - st2tost2<3u, decltype(a[0] * b[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_da( + const StensorType1& a, const StensorType2& b) noexcept + -> st2tost2<3u, decltype(a[0] * b[0])> // + requires((getSpaceDimension() == 3u) && + (getSpaceDimension() == 3u)) { using NumType = decltype(a[0] * b[0]); using real = base_type; - constexpr auto zero = real(0); - constexpr auto cste = Cste::sqrt2; + TFEL_HOST_DEVICE constexpr auto zero = real(0); + TFEL_HOST_DEVICE constexpr auto cste = Cste::sqrt2; return {a[4] * b[4] + a[3] * b[3] + 2 * a[0] * b[0], zero, zero, (cste * a[4] * b[5] + 2 * a[0] * b[3] + 2 * a[3] * b[1]) / 2, (cste * a[3] * b[5] + 2 * a[0] * b[4] + 2 * a[4] * b[2]) / 2, zero, @@ -102,24 +102,24 @@ namespace tfel::math { (2 * a[5] * b[5] + a[4] * b[4] + a[3] * b[3] + 2 * a[2] * b[2] + 2 * a[1] * b[1]) / 2}; - } // end of symmetric_product_aba + } // namespace tfel::math template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 1u, - st2tost2<1u, decltype(a[0] * a[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<1u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 1u) { using NumType = decltype(a[0] * a[0]); using real = base_type; - constexpr auto zero = real(0); + TFEL_HOST_DEVICE constexpr auto zero = real(0); return {a[0] * a[0], zero, zero, // zero, a[1] * a[1], zero, // zero, zero, a[2] * a[2]}; } // end of symmetric_product_derivative_daba_db template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 2u, - st2tost2<2u, decltype(a[0] * a[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<2u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 2u) { using NumType = decltype(a[0] * a[0]); using real = base_type; constexpr auto zero = real(0); @@ -142,9 +142,9 @@ namespace tfel::math { } // end of symmetric_product_derivative_daba_db template - auto symmetric_product_derivative_daba_db(const StensorType& a) -> - typename std::enable_if() == 3u, - st2tost2<3u, decltype(a[0] * a[0])>>::type { + TFEL_HOST_DEVICE constexpr auto symmetric_product_derivative_daba_db( + const StensorType& a) noexcept -> st2tost2<3u, decltype(a[0] * a[0])> // + requires(getSpaceDimension() == 3u) { using NumType = decltype(a[0] * a[0]); using real = base_type; constexpr auto cste = Cste::sqrt2; diff --git a/include/TFEL/Math/Stensor/Internals/StensorComputeEigenValuesDerivatives.hxx b/include/TFEL/Math/Stensor/Internals/StensorComputeEigenValuesDerivatives.hxx index 5836a48bc..0bf7d56bd 100644 --- a/include/TFEL/Math/Stensor/Internals/StensorComputeEigenValuesDerivatives.hxx +++ b/include/TFEL/Math/Stensor/Internals/StensorComputeEigenValuesDerivatives.hxx @@ -22,13 +22,12 @@ namespace tfel::math::internals { template <> struct StensorComputeEigenValuesDerivatives<1u> { template - static TFEL_MATH_INLINE2 - typename std::enable_if() == 1u, - void>::type - exe(StensorType& n0, - StensorType& n1, - StensorType& n2, - const rotation_matrix>&) { + TFEL_HOST_DEVICE static constexpr void exe( + StensorType& n0, + StensorType& n1, + StensorType& n2, + const rotation_matrix>&) // + noexcept requires(getSpaceDimension() == 1u) { using real = base_type>; constexpr auto zero = real(0); constexpr auto one = real(1); @@ -41,13 +40,12 @@ namespace tfel::math::internals { template <> struct StensorComputeEigenValuesDerivatives<2u> { template - static TFEL_MATH_INLINE2 - typename std::enable_if() == 2u, - void>::type - exe(StensorType& n0, - StensorType& n1, - StensorType& n2, - const rotation_matrix>& m) { + TFEL_HOST_DEVICE static constexpr void exe( + StensorType& n0, + StensorType& n1, + StensorType& n2, + const rotation_matrix>& m) noexcept // + requires(getSpaceDimension() == 2u) { using real = base_type>; constexpr auto zero = real(0); constexpr auto one = real(1); @@ -62,13 +60,12 @@ namespace tfel::math::internals { template <> struct StensorComputeEigenValuesDerivatives<3u> { template - static TFEL_MATH_INLINE2 - typename std::enable_if() == 3u, - void>::type - exe(StensorType& n0, - StensorType& n1, - StensorType& n2, - const rotation_matrix>& m) { + TFEL_HOST_DEVICE static constexpr void exe( + StensorType& n0, + StensorType& n1, + StensorType& n2, + const rotation_matrix>& m) noexcept // + requires(getSpaceDimension() == 3u) { using real = base_type>; const tvector<3u, real> v0 = m.template column_view<0u>(); const tvector<3u, real> v1 = m.template column_view<1u>(); diff --git a/include/TFEL/Math/Stensor/StensorProduct.hxx b/include/TFEL/Math/Stensor/StensorProduct.hxx index 7a67970b2..7be309c97 100644 --- a/include/TFEL/Math/Stensor/StensorProduct.hxx +++ b/include/TFEL/Math/Stensor/StensorProduct.hxx @@ -70,8 +70,8 @@ namespace tfel::math { } TFEL_MATH_INLINE - BinaryOperationResult, - tfel::meta::result_of, + BinaryOperationResult, + std::invoke_result_t, OpMult> operator()(const size_type i) const { return (this->a(i)) * (this->b(i)); @@ -91,8 +91,8 @@ namespace tfel::math { } TFEL_MATH_INLINE - BinaryOperationResult, - tfel::meta::result_of, + BinaryOperationResult, + std::invoke_result_t, OpMult> operator()(const size_type i) const { typedef typename StensorProductExprBase::NumType T; @@ -128,8 +128,8 @@ namespace tfel::math { } TFEL_MATH_INLINE - BinaryOperationResult, - tfel::meta::result_of, + BinaryOperationResult, + std::invoke_result_t, OpMult> operator()(const size_type i) const { typedef typename StensorProductExprBase::NumType T; diff --git a/include/TFEL/Math/Stensor/stensor.ixx b/include/TFEL/Math/Stensor/stensor.ixx index dda06605b..d0d43193d 100644 --- a/include/TFEL/Math/Stensor/stensor.ixx +++ b/include/TFEL/Math/Stensor/stensor.ixx @@ -33,11 +33,10 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - stensor::importVoigt(const InputIterator p) { + TFEL_HOST_DEVICE constexpr void + stensor::importVoigt(const InputIterator p) noexcept requires( + std::is_same_v::value_type, + base_type>) { tfel::fsalgo::transform<3u>::exe( p, this->begin(), [](const auto& value) { return T(value); }); if constexpr (N == 2) { @@ -54,11 +53,10 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - stensor::importTab(const InputIterator p) { + TFEL_HOST_DEVICE constexpr void + stensor::importTab(const InputIterator p) noexcept requires( + std::is_same_v::value_type, + base_type>) { tfel::fsalgo::transform<3>::exe(p, this->begin(), [](const auto& value) { return T(value); }); if constexpr (N == 2) { @@ -75,18 +73,17 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - stensor::import(const InputIterator p) { + TFEL_HOST_DEVICE constexpr void + stensor::import(const InputIterator p) noexcept requires( + std::is_same_v::value_type, + base_type>) { tfel::fsalgo::transform::value>::exe( p, this->begin(), [](const auto& value) { return T(value); }); } // end of import template TFEL_HOST_DEVICE constexpr void stensor::exportTab( - base_type* const p) const { + base_type* const p) const noexcept { tfel::fsalgo::transform<3u>::exe(this->cbegin(), p, [](const auto& value) { return base_type_cast(value); }); @@ -104,11 +101,11 @@ namespace tfel::math { template TFEL_HOST_DEVICE constexpr void stensor::write( - base_type* const t) const { + base_type* const t) const noexcept { tfel::fsalgo::transform::value>::exe( this->cbegin(), t, [](const auto& value) { return base_type_cast(value); }); - } + } // end of write template template @@ -218,29 +215,26 @@ namespace tfel::math { } template - TFEL_HOST_DEVICE std::tuple, stensor, stensor> - stensor::computeEigenValuesDerivatives( - const tmatrix<3u, 3u, base_type>& m) { + TFEL_HOST_DEVICE constexpr auto stensor::computeEigenValuesDerivatives( + const rotation_matrix& m) noexcept { return stensor::computeEigenTensors(m); } // end of stensor::computeEigenValuesDerivatives template template - TFEL_HOST_DEVICE std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, numeric_type>()), - void> - stensor::computeEigenValuesDerivatives( + TFEL_HOST_DEVICE constexpr void stensor::computeEigenValuesDerivatives( StensorType& n0, StensorType& n1, StensorType& n2, - const tmatrix<3u, 3u, base_type>& m) { + const rotation_matrix& m) noexcept // + requires((getSpaceDimension() == N) && + (isAssignableTo, numeric_type>())) { return stensor::computeEigenTensors(n0, n1, n2, m); } // end of stensor::computeEigenValuesDerivatives template - TFEL_HOST_DEVICE std::tuple, stensor, stensor> - stensor::computeEigenTensors(const tmatrix<3u, 3u, base_type>& m) { + TFEL_HOST_DEVICE constexpr auto stensor::computeEigenTensors( + const rotation_matrix& m) noexcept { std::tuple, stensor, stensor> r; tfel::math::internals::StensorComputeEigenValuesDerivatives::exe( std::get<0>(r), std::get<1>(r), std::get<2>(r), m); @@ -249,56 +243,53 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, numeric_type>()), - void> - stensor::computeEigenTensors(StensorType& n0, - StensorType& n1, - StensorType& n2, - const rotation_matrix& m) { + TFEL_HOST_DEVICE constexpr void stensor::computeEigenTensors( + StensorType& n0, + StensorType& n1, + StensorType& n2, + const rotation_matrix& m) noexcept // + requires((getSpaceDimension() == N) && + (isAssignableTo, numeric_type>())) { return tfel::math::internals::StensorComputeEigenValuesDerivatives::exe( n0, n1, n2, m); } // end of stensor::computeEigenTensors template template - TFEL_HOST_DEVICE std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, T, OpDiv>, - numeric_type>()), - void> - stensor::computeEigenTensorsDerivatives(ST2toST2Type& dn0_ds, - ST2toST2Type& dn1_ds, - ST2toST2Type& dn2_ds, - const tvector<3u, T>& vp, - const rotation_matrix& m, - const T eps) { + TFEL_HOST_DEVICE void stensor::computeEigenTensorsDerivatives( + ST2toST2Type& dn0_ds, + ST2toST2Type& dn1_ds, + ST2toST2Type& dn2_ds, + const tvector<3u, T>& vp, + const rotation_matrix& m, + const T eps) requires((getSpaceDimension() == N) && + (isAssignableTo< + BinaryOperationResult, T, OpDiv>, + numeric_type>())) { return tfel::math::internals::StensorComputeEigenTensorsDerivatives::exe( dn0_ds, dn1_ds, dn2_ds, vp, m, eps); } template template - TFEL_HOST_DEVICE stensor> - stensor::computeIsotropicFunction(const Function& f, - const tvector<3u, T>& vp, - const rotation_matrix& m) { + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunction( + const Function& f, + const tvector<3u, T>& vp, + const rotation_matrix& m) { return stensor::buildFromEigenValuesAndVectors(f(vp(0)), f(vp(1)), f(vp(2)), m); } template template - TFEL_HOST_DEVICE stensor stensor::computeIsotropicFunction( - const tvector<3u, T2>& f, const rotation_matrix& m) { + TFEL_HOST_DEVICE constexpr auto stensor::computeIsotropicFunction( + const tvector<3u, T2>& f, const rotation_matrix& m) noexcept { return stensor::buildFromEigenValuesAndVectors(f[0], f[1], f[2], m); } template template - TFEL_HOST_DEVICE st2tost2> - stensor::computeIsotropicFunctionDerivative( + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunctionDerivative( const Function& f, const FunctionDerivative& df, const tvector<3u, T>& vp, @@ -313,30 +304,28 @@ namespace tfel::math { template - TFEL_HOST_DEVICE std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, T, OpDiv>, - numeric_type>()), - void> - stensor::computeIsotropicFunctionDerivative( + TFEL_HOST_DEVICE void stensor::computeIsotropicFunctionDerivative( ST2toST2Type& d, const Function& f, const FunctionDerivative& df, const tvector<3u, T>& vp, const rotation_matrix& m, - const T eps) { + const T eps) requires((getSpaceDimension() == N) && + (isAssignableTo< + BinaryOperationResult, T, OpDiv>, + numeric_type>())) { tfel::math::internals::StensorComputeIsotropicFunctionDerivative::exe2( d, f, df, vp, m, eps); - } + } // end of computeIsotropicFunctionDerivative template template - TFEL_HOST_DEVICE st2tost2 - stensor::computeIsotropicFunctionDerivative(const tvector<3u, T1>& f, - const tvector<3u, T2>& df, - const tvector<3u, T>& vp, - const rotation_matrix& m, - const T eps) { + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunctionDerivative( + const tvector<3u, T1>& f, + const tvector<3u, T2>& df, + const tvector<3u, T>& vp, + const rotation_matrix& m, + const T eps) { st2tost2 r; stensor::computeIsotropicFunctionDerivative(r, f, df, vp, m, eps); return r; @@ -344,49 +333,40 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, T, OpDiv>, - numeric_type>()), - void> - stensor::computeIsotropicFunctionDerivative(ST2toST2Type& d, - const tvector<3u, T1>& f, - const tvector<3u, T2>& df, - const tvector<3u, T>& vp, - const rotation_matrix& m, - const T eps) { + TFEL_HOST_DEVICE void stensor::computeIsotropicFunctionDerivative( + ST2toST2Type& d, + const tvector<3u, T1>& f, + const tvector<3u, T2>& df, + const tvector<3u, T>& vp, + const rotation_matrix& m, + const T eps) requires((getSpaceDimension() == N) && + (isAssignableTo< + BinaryOperationResult, T, OpDiv>, + numeric_type>())) { tfel::math::internals::StensorComputeIsotropicFunctionDerivative::exe( d, f, df, vp, m, eps); } template template - TFEL_HOST_DEVICE stensor> - stensor::computeIsotropicFunction(const Function& f, - const bool b) const { - using base = base_type; - tvector<3u, T> vp; - tmatrix<3u, 3u, base> m; - this->template computeEigenVectors(vp, m, b); + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunction( + const Function& f, const bool b) const { + const auto [vp, m] = this->template computeEigenVectors(b); return stensor::buildFromEigenValuesAndVectors(f(vp(0)), f(vp(1)), f(vp(2)), m); - } + } // end of computeIsotropicFunction template template - TFEL_HOST_DEVICE st2tost2> - stensor::computeIsotropicFunctionDerivative( + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunctionDerivative( const Function& f, const FunctionDerivative& df, const T eps, const bool b) const { - using base = base_type; + const auto [vp, m] = this->template computeEigenVectors(b); st2tost2 r; - tvector<3u, T> vp; - tmatrix<3u, 3u, base> m; - this->template computeEigenVectors(vp, m, b); stensor::computeIsotropicFunctionDerivative(r, f, df, vp, m, eps); return r; } @@ -395,21 +375,15 @@ namespace tfel::math { template - TFEL_HOST_DEVICE - std::pair>, - st2tost2>> - stensor::computeIsotropicFunctionAndDerivative( - const Function& f, - const FunctionDerivative& df, - const T eps, - const bool b) const { - using base = base_type; - std::pair, st2tost2> r; - tvector<3u, T> vp; - tmatrix<3u, 3u, base> m; - this->template computeEigenVectors(vp, m, b); + TFEL_HOST_DEVICE auto stensor::computeIsotropicFunctionAndDerivative( + const Function& f, + const FunctionDerivative& df, + const T eps, + const bool b) const { + const auto [vp, m] = this->template computeEigenVectors(b); const auto fv = map(f, vp); const auto dfv = map(df, vp); + std::pair, st2tost2> r; r.first = stensor::buildFromEigenValuesAndVectors(fv(0), fv(1), fv(2), m); stensor::computeIsotropicFunctionDerivative(r.second, fv, dfv, vp, m, @@ -438,13 +412,15 @@ namespace tfel::math { template template - TFEL_HOST_DEVICE void stensor::copy(const InputIterator src) { + TFEL_HOST_DEVICE constexpr void stensor::copy( + const InputIterator src) noexcept { tfel::fsalgo::copy::value>::exe(src, *this); } template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), void> - exportToBaseTypeArray(const stensor& s, OutputIterator p) { + TFEL_HOST_DEVICE constexpr void exportToBaseTypeArray( + const stensor& s, + OutputIterator p) noexcept requires(isScalar()) { tfel::fsalgo::transform::value>::exe( s.cbegin(), p, [](const auto& v) { return base_type_cast(v); }); } @@ -471,22 +447,16 @@ namespace tfel::math { return tmp2; } // end of tresca - template - TFEL_HOST_DEVICE - stensor(), numeric_type> - square_root(const StensorType& s) { - using tfel::fsalgo::copy; - typedef numeric_type T; - typedef base_type real; + TFEL_HOST_DEVICE auto square_root(const StensorConcept auto& s) { + using StensorType = decltype(s); + using T = numeric_type; stensor(), T> tmp(s); stensor(), T> r(T(0)); - tmatrix<3u, 3u, real> vec; - tvector<3u, T> vp; - tmp.computeEigenVectors(vp, vec); + const auto [vp, m] = tmp.computeEigenVectors(); r[0] = std::sqrt(vp[0]); r[1] = std::sqrt(vp[1]); r[2] = std::sqrt(vp[2]); - r.changeBasis(transpose(vec)); + r.changeBasis(transpose(m)); return r; } // end of square_root @@ -537,352 +507,279 @@ namespace tfel::math { } // end of invert template - template - TFEL_HOST_DEVICE constexpr std:: - enable_if_t, T>(), stensor> - stensor::buildFromMatrix(const MatrixType& m) { + template + TFEL_HOST_DEVICE constexpr auto + stensor::buildFromMatrix(const MatrixType& m) noexcept requires( + isAssignableTo, T>()) { if constexpr (N == 1) { - return {m(0, 0), m(1, 1), m(2, 2)}; + return stensor{m(0, 0), m(1, 1), m(2, 2)}; } else if constexpr (N == 2) { constexpr auto cste = Cste::isqrt2; - return {m(0, 0), m(1, 1), m(2, 2), (m(0, 1) + m(1, 0)) * cste}; + return stensor{m(0, 0), m(1, 1), m(2, 2), + (m(0, 1) + m(1, 0)) * cste}; } else { constexpr auto cste = Cste::isqrt2; - return {m(0, 0), - m(1, 1), - m(2, 2), - (m(0, 1) + m(1, 0)) * cste, - (m(0, 2) + m(2, 0)) * cste, - (m(2, 1) + m(1, 2)) * cste}; + return stensor{m(0, 0), + m(1, 1), + m(2, 2), + (m(0, 1) + m(1, 0)) * cste, + (m(0, 2) + m(2, 0)) * cste, + (m(2, 1) + m(1, 2)) * cste}; } } // end of buildFromMatrix template - template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo, - Power<2>>::Result, - T>(), - stensor> - stensor::buildFromVectorDiadicProduct(const VectorType& v) { + template + TFEL_HOST_DEVICE constexpr auto stensor::buildFromVectorDiadicProduct( + const VectorType& v) noexcept // + requires( + isAssignableTo, + Power<2>>::Result, + T>()) { if constexpr (N == 1) { - return {v(0) * v(0), v(1) * v(1), v(2) * v(2)}; + return stensor{v(0) * v(0), v(1) * v(1), v(2) * v(2)}; } else if constexpr (N == 2) { constexpr auto cste = Cste::sqrt2; - return {v(0) * v(0), v(1) * v(1), v(2) * v(2), v(0) * v(1) * cste}; + return stensor{v(0) * v(0), v(1) * v(1), v(2) * v(2), + v(0) * v(1) * cste}; } else { constexpr auto cste = Cste::sqrt2; - return {v(0) * v(0), v(1) * v(1), v(2) * v(2), - v(0) * v(1) * cste, v(0) * v(2) * cste, v(1) * v(2) * cste}; + return stensor{v(0) * v(0), v(1) * v(1), + v(2) * v(2), v(0) * v(1) * cste, + v(0) * v(2) * cste, v(1) * v(2) * cste}; } } // end of buildFromVectorDiadicProduct template - template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isAssignableTo, - numeric_type, - OpMult>, - T>(), - stensor> - stensor::buildFromVectorsSymmetricDiadicProduct(const VectorType& v1, - const VectorType2& v2) { + template + TFEL_HOST_DEVICE constexpr auto + stensor::buildFromVectorsSymmetricDiadicProduct( + const VectorType& v1, + const VectorType2& v2) noexcept // + requires(isAssignableTo, + numeric_type, + OpMult>, + T>()) { if constexpr (N == 1) { - return {2 * v1(0) * v2(0), 2 * v1(1) * v2(1), 2 * v1(2) * v2(2)}; + return stensor{2 * v1(0) * v2(0), 2 * v1(1) * v2(1), + 2 * v1(2) * v2(2)}; } else if constexpr (N == 2) { constexpr auto cste = Cste::sqrt2; - return {2 * v1(0) * v2(0), 2 * v1(1) * v2(1), 2 * v1(2) * v2(2), - cste * (v1(0) * v2(1) + v2(0) * v1(1))}; + return stensor{2 * v1(0) * v2(0), 2 * v1(1) * v2(1), + 2 * v1(2) * v2(2), + cste * (v1(0) * v2(1) + v2(0) * v1(1))}; } else { constexpr auto cste = Cste::sqrt2; - return {2 * v1(0) * v2(0), - 2 * v1(1) * v2(1), - 2 * v1(2) * v2(2), - (v1(0) * v2(1) + v2(0) * v1(1)) * cste, - (v1(0) * v2(2) + v2(0) * v1(2)) * cste, - (v1(1) * v2(2) + v2(1) * v1(2)) * cste}; + return stensor{2 * v1(0) * v2(0), + 2 * v1(1) * v2(1), + 2 * v1(2) * v2(2), + (v1(0) * v2(1) + v2(0) * v1(1)) * cste, + (v1(0) * v2(2) + v2(0) * v1(2)) * cste, + (v1(1) * v2(2) + v2(1) * v1(2)) * cste}; } } // end of buildFromVectorsSymmetricDiadicProduct template - TFEL_HOST_DEVICE constexpr stensor - stensor::buildFromEigenValuesAndVectors( + TFEL_HOST_DEVICE constexpr auto stensor::buildFromEigenValuesAndVectors( const T& v1, const T& v2, const T& v3, - const tmatrix<3u, 3u, base_type>& m) { + const rotation_matrix& m) noexcept { if constexpr (N == 1) { - return {v1, v2, v3}; + return stensor{v1, v2, v3}; } else if constexpr (N == 2) { constexpr auto cste = Cste::sqrt2; - return {v1 * m(0, 0) * m(0, 0) + v2 * m(0, 1) * m(0, 1), - v1 * m(1, 0) * m(1, 0) + v2 * m(1, 1) * m(1, 1), v3, - (v1 * m(0, 0) * m(1, 0) + v2 * m(0, 1) * m(1, 1)) * cste}; + return stensor{ + v1 * m(0, 0) * m(0, 0) + v2 * m(0, 1) * m(0, 1), + v1 * m(1, 0) * m(1, 0) + v2 * m(1, 1) * m(1, 1), v3, + (v1 * m(0, 0) * m(1, 0) + v2 * m(0, 1) * m(1, 1)) * cste}; } else { constexpr auto cste = Cste::sqrt2; - return {v1 * m(0, 0) * m(0, 0) + v2 * m(0, 1) * m(0, 1) + - v3 * m(0, 2) * m(0, 2), - v1 * m(1, 0) * m(1, 0) + v2 * m(1, 1) * m(1, 1) + - v3 * m(1, 2) * m(1, 2), - v1 * m(2, 0) * m(2, 0) + v2 * m(2, 1) * m(2, 1) + - v3 * m(2, 2) * m(2, 2), - (v1 * m(0, 0) * m(1, 0) + v2 * m(0, 1) * m(1, 1) + - v3 * m(0, 2) * m(1, 2)) * - cste, - (v1 * m(0, 0) * m(2, 0) + v2 * m(0, 1) * m(2, 1) + - v3 * m(0, 2) * m(2, 2)) * - cste, - (v1 * m(1, 0) * m(2, 0) + v2 * m(1, 1) * m(2, 1) + - v3 * m(1, 2) * m(2, 2)) * - cste}; + return stensor{v1 * m(0, 0) * m(0, 0) + v2 * m(0, 1) * m(0, 1) + + v3 * m(0, 2) * m(0, 2), + v1 * m(1, 0) * m(1, 0) + v2 * m(1, 1) * m(1, 1) + + v3 * m(1, 2) * m(1, 2), + v1 * m(2, 0) * m(2, 0) + v2 * m(2, 1) * m(2, 1) + + v3 * m(2, 2) * m(2, 2), + (v1 * m(0, 0) * m(1, 0) + v2 * m(0, 1) * m(1, 1) + + v3 * m(0, 2) * m(1, 2)) * + cste, + (v1 * m(0, 0) * m(2, 0) + v2 * m(0, 1) * m(2, 1) + + v3 * m(0, 2) * m(2, 2)) * + cste, + (v1 * m(1, 0) * m(2, 0) + v2 * m(1, 1) * m(2, 1) + + v3 * m(1, 2) * m(2, 2)) * + cste}; } } // end of buildFromEigenValuesAndVectors template - TFEL_HOST_DEVICE constexpr stensor - stensor::buildFromEigenValuesAndVectors( - const tvector<3u, T>& vp, const tmatrix<3u, 3u, base_type>& m) { + TFEL_HOST_DEVICE constexpr auto stensor::buildFromEigenValuesAndVectors( + const tvector<3u, T>& vp, const rotation_matrix& m) noexcept { return stensor::buildFromEigenValuesAndVectors(vp(0), vp(1), vp(2), m); } // end of buildFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor - stensor::buildLogarithmFromEigenValuesAndVectors( + TFEL_HOST_DEVICE auto stensor::buildLogarithmFromEigenValuesAndVectors( const T& v1, const T& v2, const T& v3, - const tmatrix<3u, 3u, base_type>& m) { + const rotation_matrix& m) noexcept { return stensor::buildFromEigenValuesAndVectors(std::log(v1), std::log(v2), std::log(v3), m); } // end of buildLogarithmFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor - stensor::buildLogarithmFromEigenValuesAndVectors( - const tvector<3u, T>& vp, const tmatrix<3u, 3u, base_type>& m) { + TFEL_HOST_DEVICE auto stensor::buildLogarithmFromEigenValuesAndVectors( + const tvector<3u, T>& vp, const rotation_matrix& m) noexcept { return stensor::buildFromEigenValuesAndVectors( std::log(vp(0)), std::log(vp(1)), std::log(vp(2)), m); } // end of buildLogarithmFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor + TFEL_HOST_DEVICE constexpr auto stensor::buildPositivePartFromEigenValuesAndVectors( const T& v1, const T& v2, const T& v3, - const tmatrix<3u, 3u, base_type>& m) { + const rotation_matrix& m) noexcept { + constexpr auto zero = T{}; return stensor::buildFromEigenValuesAndVectors( - std::max(T(0), v1), std::max(T(0), v2), std::max(T(0), v3), m); + std::max(zero, v1), std::max(zero, v2), std::max(zero, v3), m); } // end of buildPositivePartFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor + TFEL_HOST_DEVICE constexpr auto stensor::buildPositivePartFromEigenValuesAndVectors( - const tvector<3u, T>& vp, const tmatrix<3u, 3u, base_type>& m) { + const tvector<3u, T>& vp, const rotation_matrix& m) noexcept { + constexpr auto zero = T{}; return stensor::buildFromEigenValuesAndVectors( - std::max(T(0), vp(0)), std::max(T(0), vp(1)), std::max(T(0), vp(2)), m); + std::max(zero, vp(0)), std::max(zero, vp(1)), std::max(zero, vp(2)), m); } // end of buildPositivePartFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor + TFEL_HOST_DEVICE constexpr auto stensor::buildNegativePartFromEigenValuesAndVectors( const T& v1, const T& v2, const T& v3, - const tmatrix<3u, 3u, base_type>& m) { + const rotation_matrix& m) noexcept { + constexpr auto zero = T{}; return stensor::buildFromEigenValuesAndVectors( - std::min(T(0), v1), std::min(T(0), v2), std::min(T(0), v3), m); + std::min(zero, v1), std::min(zero, v2), std::min(zero, v3), m); } // end of buildNegativePartFromEigenValuesAndVectors template - TFEL_HOST_DEVICE stensor + TFEL_HOST_DEVICE constexpr auto stensor::buildNegativePartFromEigenValuesAndVectors( - const tvector<3u, T>& vp, const tmatrix<3u, 3u, base_type>& m) { + const tvector<3u, T>& vp, const rotation_matrix& m) noexcept { + constexpr auto zero = T{}; return stensor::buildFromEigenValuesAndVectors( - std::min(T(0), vp(0)), std::min(T(0), vp(1)), std::min(T(0), vp(2)), m); + std::min(zero, vp(0)), std::min(zero, vp(1)), std::min(zero, vp(2)), m); } // end of buildNegativePartFromEigenValuesAndVectors template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - logarithm(const StensorType& s, const bool) { - typedef numeric_type NumType; - stensor<1u, NumType> l; - l(0) = std::log(s(0)); - l(1) = std::log(s(1)); - l(2) = std::log(s(2)); - return l; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - logarithm(const StensorType& s_, const bool b) { - typedef numeric_type NumType; - typedef base_type base; - typedef stensor(), NumType> Stensor; - tvector<3u, NumType> vp; - tmatrix<3u, 3u, base> m; - stensor(), NumType> s(s_); - s.computeEigenVectors(vp, m, b); - return Stensor::buildFromEigenValuesAndVectors( - std::log(vp(0)), std::log(vp(1)), std::log(vp(2)), m); - } - - template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - absolute_value(const StensorType& s, const bool) { - return {tfel::math::abs(s(0)), tfel::math::abs(s(1)), - tfel::math::abs(s(2))}; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - absolute_value(const StensorType& s_, const bool b) { - typedef numeric_type NumType; - typedef base_type base; - typedef stensor(), NumType> Stensor; - tvector<3u, NumType> vp; - tmatrix<3u, 3u, base> m; - stensor(), NumType> s(s_); - s.computeEigenVectors(vp, m, b); - return Stensor::buildFromEigenValuesAndVectors(tfel::math::abs(vp(0)), - tfel::math::abs(vp(1)), - tfel::math::abs(vp(2)), m); - } - - template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - positive_part(const StensorType& s, const bool) { - typedef numeric_type NumType; - return {std::max(s(0), NumType(0)), std::max(s(1), NumType(0)), - std::max(s(2), NumType(0))}; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - positive_part(const StensorType& s_, const bool b) { - typedef numeric_type NumType; - typedef base_type base; - typedef stensor(), NumType> Stensor; - tvector<3u, NumType> vp; - tmatrix<3u, 3u, base> m; - stensor(), NumType> s(s_); - s.computeEigenVectors(vp, m, b); - return Stensor::buildFromEigenValuesAndVectors( - std::max(vp(0), NumType(0)), std::max(vp(1), NumType(0)), - std::max(vp(2), NumType(0)), m); - } - - template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - negative_part(const StensorType& s, const bool) { - typedef numeric_type NumType; - return {std::min(s(0), NumType(0)), std::min(s(1), NumType(0)), - std::min(s(2), NumType(0))}; - } + TFEL_HOST_DEVICE auto logarithm(const StensorType& s, const bool b) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond) { + using NumType = numeric_type; + constexpr auto N = getSpaceDimension(); + if constexpr (N == 1) { + return stensor<1u, NumType>{std::log(s(0)), std::log(s(1)), + std::log(s(2))}; + } else { + stensor tmp(s); + const auto [vp, m] = tmp.computeEigenVectors(b); + return stensor::buildFromEigenValuesAndVectors( + std::log(vp(0)), std::log(vp(1)), std::log(vp(2)), m); + } + } // end of logarithm template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - negative_part(const StensorType& s_, const bool b) { - typedef numeric_type NumType; - typedef base_type base; - typedef stensor(), NumType> Stensor; - tvector<3u, NumType> vp; - tmatrix<3u, 3u, base> m; - stensor(), NumType> s(s_); - s.computeEigenVectors(vp, m, b); - return Stensor::buildFromEigenValuesAndVectors( - std::min(vp(0), NumType(0)), std::min(vp(1), NumType(0)), - std::min(vp(2), NumType(0)), m); - } + TFEL_HOST_DEVICE auto + absolute_value(const StensorType& s, const bool b) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond) { + using NumType = numeric_type; + constexpr auto N = getSpaceDimension(); + if constexpr (N == 1) { + return stensor<1u, NumType>{tfel::math::abs(s(0)), tfel::math::abs(s(1)), + tfel::math::abs(s(2))}; + } else { + stensor tmp(s); + const auto [vp, m] = tmp.computeEigenVectors(b); + return stensor::buildFromEigenValuesAndVectors( + tfel::math::abs(vp(0)), tfel::math::abs(vp(1)), + tfel::math::abs(vp(2)), m); + } + } // end of absolute_value template - TFEL_HOST_DEVICE - std::enable_if_t() == 1u, - stensor<1u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType& s) { - using T = numeric_type; - using T2 = BinaryOperationResult; - return stensor<1u, T2>{s(0) * s(0), s(1) * s(1), s(2) * s(2)}; - } + TFEL_HOST_DEVICE auto + positive_part(const StensorType& s, const bool b) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond) { + using NumType = numeric_type; + constexpr auto N = getSpaceDimension(); + constexpr auto zero = NumType{}; + if constexpr (N == 1) { + return stensor<1u, NumType>{std::max(s(0), zero), std::max(s(1), zero), + std::max(s(2), zero)}; + } else { + stensor tmp(s); + const auto [vp, m] = tmp.computeEigenVectors(b); + return stensor::buildFromEigenValuesAndVectors( + std::max(vp(0), zero), // + std::max(vp(1), zero), std::max(vp(2), zero), m); + } + } // end of positive_part template - TFEL_HOST_DEVICE - std::enable_if_t() == 2u, - stensor<2u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType& s) { - using T = numeric_type; - using T2 = BinaryOperationResult; - using base = base_type; - constexpr const base one_half = 1 / base(2); - return stensor<2u, T2>{(s(3) * s(3) + 2 * s(0) * s(0)) * one_half, - (s(3) * s(3) + 2 * s(1) * s(1)) * one_half, - s(2) * s(2), (s(1) + s(0)) * s(3)}; - } + TFEL_HOST_DEVICE auto + negative_part(const StensorType& s, const bool b) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond) { + using NumType = numeric_type; + constexpr auto N = getSpaceDimension(); + constexpr auto zero = NumType{}; + if constexpr (N == 1) { + return stensor<1u, NumType>{std::min(s(0), zero), std::min(s(1), zero), + std::min(s(2), zero)}; + } else { + stensor tmp(s); + const auto [vp, m] = tmp.computeEigenVectors(b); + return stensor::buildFromEigenValuesAndVectors( + std::min(vp(0), zero), // + std::min(vp(1), zero), std::min(vp(2), zero), m); + } + } // end of negative_part - template - TFEL_HOST_DEVICE - std::enable_if_t() == 3u, - stensor<3u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType& s) { + TFEL_HOST_DEVICE auto square(const StensorConcept auto& s) { + using StensorType = decltype(s); + constexpr auto N = getSpaceDimension(); using T = numeric_type; using T2 = BinaryOperationResult; - using base = base_type; - typedef numeric_type T; - constexpr base cste = Cste::sqrt2; - constexpr const base one_half = 1 / (base(2)); - return stensor<3u, T2>{ - (s(4) * s(4) + s(3) * s(3) + 2 * s(0) * s(0)) * one_half, - (s(5) * s(5) + s(3) * s(3) + 2 * s(1) * s(1)) * one_half, - (s(5) * s(5) + s(4) * s(4) + 2 * s(2) * s(2)) * one_half, - (cste * s(4) * s(5) + 2 * (s(1) + s(0)) * s(3)) * one_half, - (cste * s(3) * s(5) + 2 * (s(2) + s(0)) * s(4)) * one_half, - (2 * (s(2) + s(1)) * s(5) + cste * s(3) * s(4)) * one_half}; - } + if constexpr (N == 1) { + return stensor<1u, T2>{s(0) * s(0), s(1) * s(1), s(2) * s(2)}; + } else if constexpr (N == 2) { + using base = base_type; + constexpr const base one_half = 1 / base(2); + return stensor<2u, T2>{(s(3) * s(3) + 2 * s(0) * s(0)) * one_half, + (s(3) * s(3) + 2 * s(1) * s(1)) * one_half, + s(2) * s(2), (s(1) + s(0)) * s(3)}; + } else { + using base = base_type; + constexpr base cste = Cste::sqrt2; + constexpr const base one_half = 1 / (base(2)); + return stensor<3u, T2>{ + (s(4) * s(4) + s(3) * s(3) + 2 * s(0) * s(0)) * one_half, + (s(5) * s(5) + s(3) * s(3) + 2 * s(1) * s(1)) * one_half, + (s(5) * s(5) + s(4) * s(4) + 2 * s(2) * s(2)) * one_half, + (cste * s(4) * s(5) + 2 * (s(1) + s(0)) * s(3)) * one_half, + (cste * s(3) * s(5) + 2 * (s(2) + s(0)) * s(4)) * one_half, + (2 * (s(2) + s(1)) * s(5) + cste * s(3) * s(4)) * one_half}; + } + } // end of square template TFEL_HOST_DEVICE constexpr auto change_basis( @@ -896,11 +793,9 @@ namespace tfel::math { template - TFEL_HOST_DEVICE - stensor(), numeric_type> - computeIsotropicFunction(const Function& f, - const StensorType& s, - const bool b) { + TFEL_HOST_DEVICE auto computeIsotropicFunction(const Function& f, + const StensorType& s, + const bool b) { return s.template computeIsotropicFunction(f, b); } @@ -908,13 +803,12 @@ namespace tfel::math { typename Function, typename FunctionDerivative, StensorConcept StensorType> - TFEL_HOST_DEVICE - st2tost2(), numeric_type> - computeIsotropicFunctionDerivative(const Function& f, - const FunctionDerivative& df, - const StensorType& s, - const numeric_type eps, - const bool b) { + TFEL_HOST_DEVICE auto computeIsotropicFunctionDerivative( + const Function& f, + const FunctionDerivative& df, + const StensorType& s, + const numeric_type eps, + const bool b) { return s.template computeIsotropicFunctionDerivative(f, df, eps, b); } @@ -922,232 +816,202 @@ namespace tfel::math { typename Function, typename FunctionDerivative, StensorConcept StensorType> - TFEL_HOST_DEVICE std::pair< - stensor(), numeric_type>, - st2tost2(), numeric_type>> - computeIsotropicFunctionDerivative(const Function& f, - const FunctionDerivative& df, - const StensorType& s, - const numeric_type eps, - const bool b) { - return s.template computeIsotropicFunctionDerivative(f, df, eps, b); - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 1u) && (getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<1u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T& s, - const T2& U) { - const auto J = det(U); - return {J * s[0] / (U[0] * U[0]), J * s[1] / (U[1] * U[1]), - J * s[2] / (U[2] * U[2])}; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 2u) && (getSpaceDimension() == 2u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<2u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T& s, - const T2& U) { - const auto J = det(U); - const auto iU = invert(U); - return {J * - (s[1] * iU[3] * iU[3] + 2 * s[3] * iU[0] * iU[3] + - 2 * s[0] * iU[0] * iU[0]) / - 2, - J * - (s[0] * iU[3] * iU[3] + 2 * s[3] * iU[1] * iU[3] + - 2 * s[1] * iU[1] * iU[1]) / - 2, - J * s[2] * iU[2] * iU[2], - J * - (s[3] * iU[3] * iU[3] + - (2 * s[1] * iU[1] + 2 * s[0] * iU[0]) * iU[3] + - 2 * s[3] * iU[0] * iU[1]) / - 2}; + TFEL_HOST_DEVICE auto computeIsotropicFunctionAndDerivative( + const Function& f, + const FunctionDerivative& df, + const StensorType& s, + const numeric_type eps, + const bool b) { + return s.template computeIsotropicFunctionAndDerivative(f, df, eps, b); } template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 3u) && (getSpaceDimension() == 3u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<3u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T& s, - const T2& U) { - using real = base_type>; - constexpr real cste = Cste::sqrt2; + TFEL_HOST_DEVICE constexpr auto + convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress( + const T& s, + const T2& + U) noexcept requires((getSpaceDimension() == + getSpaceDimension()) && + (tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond)) { + constexpr auto N = getSpaceDimension(); + using Result = stensor>; const auto J = det(U); - const auto iU = invert(U); - return {J * - (s[2] * iU[4] * iU[4] + - (cste * s[5] * iU[3] + 2 * s[4] * iU[0]) * iU[4] + - s[1] * iU[3] * iU[3] + 2 * s[3] * iU[0] * iU[3] + - 2 * s[0] * iU[0] * iU[0]) / - 2, - J * - (s[2] * iU[5] * iU[5] + - (cste * s[4] * iU[3] + 2 * s[5] * iU[1]) * iU[5] + - s[0] * iU[3] * iU[3] + 2 * s[3] * iU[1] * iU[3] + - 2 * s[1] * iU[1] * iU[1]) / - 2, - J * - (s[1] * iU[5] * iU[5] + - (cste * s[3] * iU[4] + 2 * s[5] * iU[2]) * iU[5] + - s[0] * iU[4] * iU[4] + 2 * s[4] * iU[2] * iU[4] + - 2 * s[2] * iU[2] * iU[2]) / - 2, - J * - ((cste * s[2] * iU[4] + s[5] * iU[3] + cste * s[4] * iU[0]) * - iU[5] + - (s[4] * iU[3] + cste * s[5] * iU[1]) * iU[4] + - s[3] * iU[3] * iU[3] + - (2 * s[1] * iU[1] + 2 * s[0] * iU[0]) * iU[3] + - 2 * s[3] * iU[0] * iU[1]) / - 2, - J * - ((s[5] * iU[4] + cste * s[1] * iU[3] + cste * s[3] * iU[0]) * - iU[5] + - s[4] * iU[4] * iU[4] + - (s[3] * iU[3] + 2 * s[2] * iU[2] + 2 * s[0] * iU[0]) * iU[4] + - cste * s[5] * iU[2] * iU[3] + 2 * s[4] * iU[0] * iU[2]) / - 2, - J * - (s[5] * iU[5] * iU[5] + - (s[4] * iU[4] + s[3] * iU[3] + 2 * s[2] * iU[2] + - 2 * s[1] * iU[1]) * - iU[5] + - (cste * s[0] * iU[3] + cste * s[3] * iU[1]) * iU[4] + - cste * s[4] * iU[2] * iU[3] + 2 * s[5] * iU[1] * iU[2]) / - 2}; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 1u) && (getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<1u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T& S, - const T2& U) { - const auto iJ = 1 / det(U); - return {iJ * U[0] * S[0] * U[0], iJ * U[1] * S[1] * U[1], - iJ * U[2] * S[2] * U[2]}; - } - - template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 2u) && (getSpaceDimension() == 2u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<2u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T& S, - const T2& U) { - const auto iJ = 1 / det(U); - return { - iJ * - (S[1] * U[3] * U[3] + 2 * S[3] * U[0] * U[3] + - 2 * S[0] * U[0] * U[0]) / - 2, - iJ * - (S[0] * U[3] * U[3] + 2 * S[3] * U[1] * U[3] + - 2 * S[1] * U[1] * U[1]) / - 2, - iJ * S[2] * U[2] * U[2], - iJ * - (S[3] * U[3] * U[3] + (2 * S[1] * U[1] + 2 * S[0] * U[0]) * U[3] + - 2 * S[3] * U[0] * U[1]) / - 2}; + if constexpr (N == 1) { + return Result{J * s[0] / (U[0] * U[0]), J * s[1] / (U[1] * U[1]), + J * s[2] / (U[2] * U[2])}; + } else if constexpr (N == 2) { + const auto iU = invert(U); + return Result{J * + (s[1] * iU[3] * iU[3] + 2 * s[3] * iU[0] * iU[3] + + 2 * s[0] * iU[0] * iU[0]) / + 2, + J * + (s[0] * iU[3] * iU[3] + 2 * s[3] * iU[1] * iU[3] + + 2 * s[1] * iU[1] * iU[1]) / + 2, + J * s[2] * iU[2] * iU[2], + J * + (s[3] * iU[3] * iU[3] + + (2 * s[1] * iU[1] + 2 * s[0] * iU[0]) * iU[3] + + 2 * s[3] * iU[0] * iU[1]) / + 2}; + } else { + constexpr auto cste = Cste>::sqrt2; + const auto iU = invert(U); + return Result{ + J * + (s[2] * iU[4] * iU[4] + + (cste * s[5] * iU[3] + 2 * s[4] * iU[0]) * iU[4] + + s[1] * iU[3] * iU[3] + 2 * s[3] * iU[0] * iU[3] + + 2 * s[0] * iU[0] * iU[0]) / + 2, + J * + (s[2] * iU[5] * iU[5] + + (cste * s[4] * iU[3] + 2 * s[5] * iU[1]) * iU[5] + + s[0] * iU[3] * iU[3] + 2 * s[3] * iU[1] * iU[3] + + 2 * s[1] * iU[1] * iU[1]) / + 2, + J * + (s[1] * iU[5] * iU[5] + + (cste * s[3] * iU[4] + 2 * s[5] * iU[2]) * iU[5] + + s[0] * iU[4] * iU[4] + 2 * s[4] * iU[2] * iU[4] + + 2 * s[2] * iU[2] * iU[2]) / + 2, + J * + ((cste * s[2] * iU[4] + s[5] * iU[3] + cste * s[4] * iU[0]) * + iU[5] + + (s[4] * iU[3] + cste * s[5] * iU[1]) * iU[4] + + s[3] * iU[3] * iU[3] + + (2 * s[1] * iU[1] + 2 * s[0] * iU[0]) * iU[3] + + 2 * s[3] * iU[0] * iU[1]) / + 2, + J * + ((s[5] * iU[4] + cste * s[1] * iU[3] + cste * s[3] * iU[0]) * + iU[5] + + s[4] * iU[4] * iU[4] + + (s[3] * iU[3] + 2 * s[2] * iU[2] + 2 * s[0] * iU[0]) * iU[4] + + cste * s[5] * iU[2] * iU[3] + 2 * s[4] * iU[0] * iU[2]) / + 2, + J * + (s[5] * iU[5] * iU[5] + + (s[4] * iU[4] + s[3] * iU[3] + 2 * s[2] * iU[2] + + 2 * s[1] * iU[1]) * + iU[5] + + (cste * s[0] * iU[3] + cste * s[3] * iU[1]) * iU[4] + + cste * s[4] * iU[2] * iU[3] + 2 * s[5] * iU[1] * iU[2]) / + 2}; + } } template - TFEL_HOST_DEVICE std::enable_if_t< - ((getSpaceDimension() == 3u) && (getSpaceDimension() == 3u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<3u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T& S, - const T2& U) { - using real = base_type>; - constexpr auto cste = Cste::sqrt2; + TFEL_HOST_DEVICE constexpr auto + convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress( + const T& S, + const T2& U) noexcept // + requires((getSpaceDimension() == getSpaceDimension()) && + (tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond)) { + constexpr auto N = getSpaceDimension(); + using Result = stensor>; const auto iJ = 1 / det(U); - return { - iJ * - (S[2] * U[4] * U[4] + - (cste * S[5] * U[3] + 2 * S[4] * U[0]) * U[4] + - S[1] * U[3] * U[3] + 2 * S[3] * U[0] * U[3] + - 2 * S[0] * U[0] * U[0]) / - 2, - iJ * - (S[2] * U[5] * U[5] + - (cste * S[4] * U[3] + 2 * S[5] * U[1]) * U[5] + - S[0] * U[3] * U[3] + 2 * S[3] * U[1] * U[3] + - 2 * S[1] * U[1] * U[1]) / - 2, - iJ * - (S[1] * U[5] * U[5] + - (cste * S[3] * U[4] + 2 * S[5] * U[2]) * U[5] + - S[0] * U[4] * U[4] + 2 * S[4] * U[2] * U[4] + - 2 * S[2] * U[2] * U[2]) / - 2, - iJ * - ((cste * S[2] * U[4] + S[5] * U[3] + cste * S[4] * U[0]) * U[5] + - (S[4] * U[3] + cste * S[5] * U[1]) * U[4] + S[3] * U[3] * U[3] + - (2 * S[1] * U[1] + 2 * S[0] * U[0]) * U[3] + - 2 * S[3] * U[0] * U[1]) / - 2, - iJ * - ((S[5] * U[4] + cste * S[1] * U[3] + cste * S[3] * U[0]) * U[5] + - S[4] * U[4] * U[4] + - (S[3] * U[3] + 2 * S[2] * U[2] + 2 * S[0] * U[0]) * U[4] + - cste * S[5] * U[2] * U[3] + 2 * S[4] * U[0] * U[2]) / - 2, - iJ * - (S[5] * U[5] * U[5] + - (S[4] * U[4] + S[3] * U[3] + 2 * S[2] * U[2] + 2 * S[1] * U[1]) * - U[5] + - (cste * S[0] * U[3] + cste * S[3] * U[1]) * U[4] + - cste * S[4] * U[2] * U[3] + 2 * S[5] * U[1] * U[2]) / - 2}; - } + if constexpr (N == 1) { + return Result{iJ * U[0] * S[0] * U[0], iJ * U[1] * S[1] * U[1], + iJ * U[2] * S[2] * U[2]}; + } else if constexpr (N == 2) { + return Result{ + iJ * + (S[1] * U[3] * U[3] + 2 * S[3] * U[0] * U[3] + + 2 * S[0] * U[0] * U[0]) / + 2, + iJ * + (S[0] * U[3] * U[3] + 2 * S[3] * U[1] * U[3] + + 2 * S[1] * U[1] * U[1]) / + 2, + iJ * S[2] * U[2] * U[2], + iJ * + (S[3] * U[3] * U[3] + (2 * S[1] * U[1] + 2 * S[0] * U[0]) * U[3] + + 2 * S[3] * U[0] * U[1]) / + 2}; + } else { + constexpr auto cste = Cste>::sqrt2; + return Result{ + iJ * + (S[2] * U[4] * U[4] + + (cste * S[5] * U[3] + 2 * S[4] * U[0]) * U[4] + + S[1] * U[3] * U[3] + 2 * S[3] * U[0] * U[3] + + 2 * S[0] * U[0] * U[0]) / + 2, + iJ * + (S[2] * U[5] * U[5] + + (cste * S[4] * U[3] + 2 * S[5] * U[1]) * U[5] + + S[0] * U[3] * U[3] + 2 * S[3] * U[1] * U[3] + + 2 * S[1] * U[1] * U[1]) / + 2, + iJ * + (S[1] * U[5] * U[5] + + (cste * S[3] * U[4] + 2 * S[5] * U[2]) * U[5] + + S[0] * U[4] * U[4] + 2 * S[4] * U[2] * U[4] + + 2 * S[2] * U[2] * U[2]) / + 2, + iJ * + ((cste * S[2] * U[4] + S[5] * U[3] + cste * S[4] * U[0]) * U[5] + + (S[4] * U[3] + cste * S[5] * U[1]) * U[4] + S[3] * U[3] * U[3] + + (2 * S[1] * U[1] + 2 * S[0] * U[0]) * U[3] + + 2 * S[3] * U[0] * U[1]) / + 2, + iJ * + ((S[5] * U[4] + cste * S[1] * U[3] + cste * S[3] * U[0]) * U[5] + + S[4] * U[4] * U[4] + + (S[3] * U[3] + 2 * S[2] * U[2] + 2 * S[0] * U[0]) * U[4] + + cste * S[5] * U[2] * U[3] + 2 * S[4] * U[0] * U[2]) / + 2, + iJ * + (S[5] * U[5] * U[5] + + (S[4] * U[4] + S[3] * U[3] + 2 * S[2] * U[2] + 2 * S[1] * U[1]) * + U[5] + + (cste * S[0] * U[3] + cste * S[3] * U[1]) * U[4] + + cste * S[4] * U[2] * U[3] + 2 * S[5] * U[1] * U[2]) / + 2}; + } + } // end of convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == - getSpaceDimension())), - stensor(), - result_type, - numeric_type, - OpMult>>> - symmetric_product(const StensorType1& s1, const StensorType2& s2) { + TFEL_HOST_DEVICE constexpr auto symmetric_product( + const StensorType1& s1, + const StensorType2& + s2) noexcept requires(getSpaceDimension() == + getSpaceDimension()) { + using Result = stensor(), + result_type, + numeric_type, OpMult>>; constexpr auto N = getSpaceDimension(); static_assert((N == 1) || (N == 2) || (N == 3), "invalid space dimension"); if constexpr (N == 1u) { - return {2 * s1[0] * s2[0], 2 * s1[1] * s2[1], 2 * s1[2] * s2[2]}; + return Result{2 * s1[0] * s2[0], 2 * s1[1] * s2[1], 2 * s1[2] * s2[2]}; } else if constexpr (N == 2u) { - return {2 * s1[0] * s2[0] + s1[3] * s2[3], - 2 * s1[1] * s2[1] + s1[3] * s2[3], 2 * s1[2] * s2[2], - (s1[1] + s1[0]) * s2[3] + s1[3] * s2[1] + s1[3] * s2[0]}; + return Result{2 * s1[0] * s2[0] + s1[3] * s2[3], + 2 * s1[1] * s2[1] + s1[3] * s2[3], 2 * s1[2] * s2[2], + (s1[1] + s1[0]) * s2[3] + s1[3] * s2[1] + s1[3] * s2[0]}; } else { using res = result_type, numeric_type, OpMult>; constexpr auto icste = Cste::isqrt2; - return {s1[4] * s2[4] + s1[3] * s2[3] + 2 * s1[0] * s2[0], - s1[5] * s2[5] + s1[3] * s2[3] + 2 * s1[1] * s2[1], - s1[5] * s2[5] + s1[4] * s2[4] + 2 * s1[2] * s2[2], - icste * s1[4] * s2[5] + icste * s1[5] * s2[4] + - (s1[1] + s1[0]) * s2[3] + s1[3] * s2[1] + s1[3] * s2[0], - icste * s1[3] * s2[5] + (s1[2] + s1[0]) * s2[4] + - icste * s1[5] * s2[3] + s1[4] * s2[2] + s1[4] * s2[0], - (s1[2] + s1[1]) * s2[5] + icste * s1[3] * s2[4] + - icste * s1[4] * s2[3] + s1[5] * s2[2] + s1[5] * s2[1]}; + return Result{s1[4] * s2[4] + s1[3] * s2[3] + 2 * s1[0] * s2[0], + s1[5] * s2[5] + s1[3] * s2[3] + 2 * s1[1] * s2[1], + s1[5] * s2[5] + s1[4] * s2[4] + 2 * s1[2] * s2[2], + icste * s1[4] * s2[5] + icste * s1[5] * s2[4] + + (s1[1] + s1[0]) * s2[3] + s1[3] * s2[1] + s1[3] * s2[0], + icste * s1[3] * s2[5] + (s1[2] + s1[0]) * s2[4] + + icste * s1[5] * s2[3] + s1[4] * s2[2] + s1[4] * s2[0], + (s1[2] + s1[1]) * s2[5] + icste * s1[3] * s2[4] + + icste * s1[4] * s2[3] + s1[5] * s2[2] + s1[5] * s2[1]}; } - } + } // end of symmetric_product - template - TFEL_HOST_DEVICE stensor< - getSpaceDimension(), - typename ComputeUnaryResult, Power<2>>::Result> - computeDeterminantDerivative(const StensorType& s) { + TFEL_HOST_DEVICE constexpr auto computeDeterminantDerivative( + const StensorConcept auto& s) noexcept { + using StensorType = decltype(s); stensor(), typename ComputeUnaryResult, Power<2>>::Result> @@ -1156,11 +1020,9 @@ namespace tfel::math { return dJ; } - template - TFEL_HOST_DEVICE stensor< - getSpaceDimension(), - typename ComputeUnaryResult, Power<2>>::Result> - computeDeviatorDeterminantDerivative(const StensorType& s) { + TFEL_HOST_DEVICE constexpr auto computeDeviatorDeterminantDerivative( + const StensorConcept auto& s) noexcept { + using StensorType = decltype(s); stensor(), typename ComputeUnaryResult, Power<2>>::Result> diff --git a/include/TFEL/Math/TinyMatrixSolve.hxx b/include/TFEL/Math/TinyMatrixSolve.hxx index 22fc39715..374961cb1 100644 --- a/include/TFEL/Math/TinyMatrixSolve.hxx +++ b/include/TFEL/Math/TinyMatrixSolve.hxx @@ -43,12 +43,12 @@ namespace tfel::math { * \param p : permutation vector * \param eps : numerical parameter to detect null pivot */ - template - TFEL_HOST_DEVICE static std:: - enable_if_t(), bool> - decomp(FixedSizeMatrixType&, - TinyPermutation&, - const T = 100 * std::numeric_limits::min()); + template + TFEL_HOST_DEVICE static bool decomp( + FixedSizeMatrixType&, + TinyPermutation&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * \brief solve the linear system m.x = b once the matrix has been @@ -58,15 +58,14 @@ namespace tfel::math { * \param b : right member * \param eps : numerical parameter to detect null pivot */ - template - TFEL_HOST_DEVICE static std::enable_if_t< - (implementsMatrixConcept() && - implementsVectorConcept()), - bool> - back_substitute(const FixedSizeMatrixType&, - const TinyPermutation&, - FixedSizeVectorType&, - const T = 100 * std::numeric_limits::min()); + template + TFEL_HOST_DEVICE static bool back_substitute( + const FixedSizeMatrixType&, + const TinyPermutation&, + FixedSizeVectorType&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * \brief solve the linear system m.x = b once the matrix has been * decomposed @@ -80,7 +79,8 @@ namespace tfel::math { const tmatrix&, const TinyPermutation&, tmatrix&, - const T = 100 * std::numeric_limits::min()); + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); }; /*! @@ -104,14 +104,13 @@ namespace tfel::math { * \note the matrix m is overwritten during computations * \note the right member is overwritten by the solution */ - template - TFEL_HOST_DEVICE static std::enable_if_t< - (implementsMatrixConcept() && - implementsVectorConcept()), - bool> - exe(FixedSizeMatrixType&, + template + TFEL_HOST_DEVICE static bool exe( + FixedSizeMatrixType&, FixedSizeVectorType&, - const T = 100 * std::numeric_limits::min()); + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * solve the linear system m.x = b * \param m : matrix to be inverted @@ -121,10 +120,11 @@ namespace tfel::math { * \note the right member is overwritten by the solution */ template - TFEL_HOST_DEVICE static bool exe(tmatrix& m, - tmatrix&, - const T = 100 * - std::numeric_limits::min()); + TFEL_HOST_DEVICE static bool exe( + tmatrix& m, + tmatrix&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); }; /*! @@ -144,14 +144,13 @@ namespace tfel::math { * \param eps : numerical paramater to detect null pivot * \note the right member is overwritten by the solution */ - template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - exe(const FixedSizeMatrixType&, - FixedSizeVectorType&, - const T = 100 * std::numeric_limits::min()); + template + TFEL_HOST_DEVICE static bool exe( + const FixedSizeMatrixType&, + FixedSizeVectorType&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * solve the linear system m.x = b * \param m : matrix to be inverted @@ -160,10 +159,11 @@ namespace tfel::math { * \note the right member is overwritten by the solution */ template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 bool exe( + TFEL_HOST_DEVICE static bool exe( const tmatrix<1u, 1u, T>& m, tmatrix<1u, M, T>&, - const T = 100 * std::numeric_limits::min()); + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); }; /*! @@ -183,14 +183,13 @@ namespace tfel::math { * \param eps : numerical paramater to detect null pivot * \note the right member is overwritten by the solution */ - template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - exe(const FixedSizeMatrixType& m, - FixedSizeVectorType&, - const T = 100 * std::numeric_limits::min()); + template + TFEL_HOST_DEVICE static bool exe( + const FixedSizeMatrixType& m, + FixedSizeVectorType&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * solve the linear system m.x = b * \param m : matrix to be inverted @@ -199,10 +198,11 @@ namespace tfel::math { * \note the right member is overwritten by the solution */ template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 bool exe( + TFEL_HOST_DEVICE static bool exe( const tmatrix<2u, 2u, T>& m, tmatrix<2u, M, T>&, - const T = 100 * std::numeric_limits::min()); + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); }; /*! @@ -223,14 +223,13 @@ namespace tfel::math { * \note the right member is overwritten by the solution * \note the matrix is destroyed */ - template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 - std::enable_if_t<(implementsMatrixConcept() && - implementsVectorConcept()), - bool> - exe(const FixedSizeMatrixType&, - FixedSizeVectorType&, - const T = 100 * std::numeric_limits::min()); + template + TFEL_HOST_DEVICE static bool exe( + const FixedSizeMatrixType&, + FixedSizeVectorType&, + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); /*! * \brief solve the linear system m.x = b * \param m : matrix to be inverted @@ -240,10 +239,11 @@ namespace tfel::math { * \note the matrix is destroyed */ template - TFEL_HOST_DEVICE static TFEL_MATH_INLINE2 bool exe( + TFEL_HOST_DEVICE static bool exe( const tmatrix<3u, 3u, T>& m, tmatrix<3u, M, T>&, - const T = 100 * std::numeric_limits::min()); + const T = 100 * + std::numeric_limits::min()) noexcept(!use_exceptions); }; } // end of namespace tfel::math diff --git a/include/TFEL/Math/Vector/VectorConcept.hxx b/include/TFEL/Math/Vector/VectorConcept.hxx index 3b3daca73..6a65782d2 100644 --- a/include/TFEL/Math/Vector/VectorConcept.hxx +++ b/include/TFEL/Math/Vector/VectorConcept.hxx @@ -41,8 +41,11 @@ namespace tfel::math { */ template concept VectorConcept = - (std::is_same_v::ConceptTag, VectorTag>)&& // - (requires(const VectorType t, const index_type i) { t[i]; }) && // + (std::is_same_v::ConceptTag, + VectorTag>)&& // + (requires(const VectorType t, const index_type i) { + t[i]; + }) && // (requires(const VectorType t, const index_type i) { t(i); }); //! paratial specialisation for vectors diff --git a/include/TFEL/Math/Vector/tvector.ixx b/include/TFEL/Math/Vector/tvector.ixx index 4b71cb533..c25793caa 100644 --- a/include/TFEL/Math/Vector/tvector.ixx +++ b/include/TFEL/Math/Vector/tvector.ixx @@ -24,80 +24,79 @@ namespace tfel::math { template - TFEL_HOST_DEVICE tvector::tvector(const fsarray& src) { + TFEL_HOST_DEVICE tvector::tvector(const fsarray& src) noexcept { tfel::fsalgo::copy::exe(src.begin(), this->v); } // end of tvector template template - TFEL_HOST_DEVICE constexpr void tvector::copy(const InputIterator src) { + TFEL_HOST_DEVICE constexpr void tvector::copy( + const InputIterator src) noexcept { tfel::fsalgo::copy::exe(src, this->v); } template template - TFEL_HOST_DEVICE constexpr auto tvector::slice() { + TFEL_HOST_DEVICE constexpr auto tvector::slice() noexcept { return tfel::math::slice(*this); } // end of slice template template - TFEL_HOST_DEVICE constexpr auto tvector::slice() { + TFEL_HOST_DEVICE constexpr auto tvector::slice() noexcept { return tfel::math::slice(*this); } // end of slice template template - TFEL_HOST_DEVICE constexpr auto tvector::slice() const { + TFEL_HOST_DEVICE constexpr auto tvector::slice() const noexcept { return tfel::math::slice(*this); } // end of slice template template - TFEL_HOST_DEVICE constexpr auto tvector::slice() const { + TFEL_HOST_DEVICE constexpr auto tvector::slice() const noexcept { return tfel::math::slice(*this); } // end of slice template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), void> - exportToBaseTypeArray(const tvector& v, OutputIterator p) { + TFEL_HOST_DEVICE constexpr void exportToBaseTypeArray( + const tvector& v, + OutputIterator p) noexcept requires(isScalar()) { tfel::fsalgo::transform::exe( v.begin(), p, [](const auto& value) { return base_type_cast(value); }); } // end of exportToBaseTypePointer - // Norm2 template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isScalar(), - typename tfel::typetraits::RealPartType::type> - norm(const tvector& vec) noexcept { + TFEL_HOST_DEVICE constexpr auto norm( + const tvector& vec) noexcept requires(isScalar()) { typedef result_type squareT; - return std::sqrt( + return power<1, 2>( real(dotProduct::exe(vec.begin(), vec.begin(), squareT(0u)))); - } + } // end of norm template - TFEL_HOST_DEVICE constexpr auto abs(const tvector& v) { + TFEL_HOST_DEVICE constexpr auto abs(const tvector& v) noexcept { AbsSum a; tfel::fsalgo::for_each::exe(v.begin(), a); return a.result; } template - TFEL_HOST_DEVICE constexpr tvector<1u, T> makeTVector1D(const T v) { + TFEL_HOST_DEVICE constexpr tvector<1u, T> makeTVector1D(const T v) noexcept { return {v}; } // end of makeTVector1D template TFEL_HOST_DEVICE constexpr tvector<2u, T> makeTVector2D(const T v1, - const T v2) { + const T v2) noexcept { return {v1, v2}; } // end of makeTVector2D template TFEL_HOST_DEVICE constexpr tvector<3u, T> makeTVector3D(const T v1, const T v2, - const T v3) { + const T v3) noexcept { return {v1, v2, v3}; } // end of makeTVector3D @@ -116,21 +115,21 @@ namespace tfel::math { template TFEL_HOST_DEVICE constexpr tvector<3u, T> cross_product( - const tvector<2u, T>& v1, const tvector<2u, T>& v2) { + const tvector<2u, T>& v1, const tvector<2u, T>& v2) noexcept { constexpr auto zero = T(0); return {zero, zero, v1[0] * v2[1] - v1[1] * v2[0]}; } // end of cross_product template TFEL_HOST_DEVICE constexpr tvector<3u, T> cross_product( - const tvector<3u, T>& v1, const tvector<3u, T>& v2) { + const tvector<3u, T>& v1, const tvector<3u, T>& v2) noexcept { return {v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]}; } // end of cross_product template TFEL_HOST_DEVICE constexpr void find_perpendicular_vector( - tvector<3u, T>& y, const tvector<3u, T>& x) { + tvector<3u, T>& y, const tvector<3u, T>& x) noexcept { using real = base_type; constexpr auto zero = T(0); constexpr auto one = T(1); @@ -168,13 +167,13 @@ namespace tfel::math { } template - TFEL_HOST_DEVICE constexpr auto slice(tvector& v) { + TFEL_HOST_DEVICE constexpr auto slice(tvector& v) noexcept { static_assert(N > I, "invalid index"); return map, I>(v); } // end of slice template - TFEL_HOST_DEVICE constexpr auto slice(tvector& v) { + TFEL_HOST_DEVICE constexpr auto slice(tvector& v) noexcept { static_assert(N > I, "invalid index"); static_assert(N >= J, "invalid index"); static_assert(J > I, "invalid index"); @@ -182,37 +181,36 @@ namespace tfel::math { } // end of slice template - TFEL_HOST_DEVICE constexpr auto slice(const tvector& v) { + TFEL_HOST_DEVICE constexpr auto slice(const tvector& v) noexcept { static_assert(N > I, "invalid index"); return map, I>(v); } // end of slice template - TFEL_HOST_DEVICE constexpr auto slice(const tvector& v) { + TFEL_HOST_DEVICE constexpr auto slice(const tvector& v) noexcept { return map, I>(v); } // end of slice template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!isScalar()) && (IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(tvector>>& v) { + TFEL_HOST_DEVICE constexpr auto + map(tvector>>& v) noexcept requires( + (!isScalar()) && (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())) { static_assert(N >= getUnderlyingArrayMinimalSize(), "invalid vector size"); return map(v.data()); } // end of map template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!isScalar()) && (IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(const tvector>>& v) { + TFEL_HOST_DEVICE constexpr auto map( + const tvector>>& v) noexcept // + requires((!isScalar()) && + (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())) { static_assert(N >= getUnderlyingArrayMinimalSize(), "invalid vector size"); return map(v.data()); @@ -223,13 +221,11 @@ namespace tfel::math { typename IndexingPolicyType, unsigned short N, typename real> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!std::is_const_v)&&(IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename MappedType::indexing_policy>())), - View> - map(tvector& v) { + TFEL_HOST_DEVICE constexpr auto map(tvector& v) noexcept requires( + (!std::is_const_v)&&(IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename MappedType::indexing_policy>())) { static_assert( N >= offset + getUnderlyingArrayMinimalSize(), "invalid vector size"); @@ -241,13 +237,12 @@ namespace tfel::math { typename IndexingPolicyType, unsigned short N, typename real> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(const tvector& v) { + TFEL_HOST_DEVICE constexpr auto + map(const tvector& v) noexcept requires( + (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())) { static_assert( N >= offset + getUnderlyingArrayMinimalSize(), "invalid vector size"); @@ -259,10 +254,9 @@ namespace tfel::math { unsigned short offset, unsigned short stride, unsigned short N> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - !std::is_const_v, - ViewsFixedSizeVector> - map(tvector>& v) { + TFEL_HOST_DEVICE constexpr auto + map(tvector>& v) noexcept requires( + !std::is_const_v) { constexpr auto mstride = getViewsArrayMinimalStride(); static_assert(stride >= mstride, "invalid stride"); static_assert(N >= offset + M * mstride, "invalid vector size"); diff --git a/include/TFEL/Math/Vector/vector.ixx b/include/TFEL/Math/Vector/vector.ixx index b18fbfd73..4a383e918 100644 --- a/include/TFEL/Math/Vector/vector.ixx +++ b/include/TFEL/Math/Vector/vector.ixx @@ -87,15 +87,13 @@ namespace tfel::math { template vector::~vector() noexcept = default; - template - std::enable_if_t(), - typename tfel::typetraits::RealPartType::type> - norm(const vector& vec) { + template + TFEL_HOST_DEVICE auto norm(const vector& vec) noexcept { auto n = ValueType{} * ValueType{}; for (const auto& v : vec) { n += v * v; } - return std::sqrt(real(n)); + return power<1, 2>(real(n)); } // end of norm } // end of namespace tfel::math diff --git a/include/TFEL/Math/power.hxx b/include/TFEL/Math/power.hxx index 12f27e484..e3cd5eb4f 100644 --- a/include/TFEL/Math/power.hxx +++ b/include/TFEL/Math/power.hxx @@ -14,41 +14,65 @@ #ifndef LIB_TFEL_MATH_POWER_HXX #define LIB_TFEL_MATH_POWER_HXX +#include #include #include "TFEL/Config/TFELConfig.hxx" #include "TFEL/Math/General/ComputeUnaryResult.hxx" namespace tfel::math { + //! \brief an help structure used to specialize the UnaryResultType class template struct Power; - + /*! + * \brief partial specialisation for the UnaryResultType class + * for exponentation of floating point number using rational + * exponent + * \tparam N: + * \tparam D: + */ template - struct UnaryResultType> { + requires(D != 0) struct UnaryResultType> { using type = float; }; - + /*! + * \brief partial specialisation for the UnaryResultType class + * for exponentation of floating point number using rational + * exponent + * \tparam N: + * \tparam D: + */ template - struct UnaryResultType> { + requires(D != 0) struct UnaryResultType> { using type = double; }; - + /*! + * \brief partial specialisation for the UnaryResultType class + * for exponentation of floating point number using rational + * exponent + * \tparam N: + * \tparam D: + */ template - struct UnaryResultType> { + requires(D != 0) struct UnaryResultType> { using type = long double; }; - - template - TFEL_HOST_DEVICE - TFEL_HOST_DEVICE constexpr std::enable_if_t, - T> - power(const T); - + /*! + * \brief computes x to the power N + * \tparam N: exponent + * \param x: value + */ + template + TFEL_HOST_DEVICE auto power(const std::floating_point auto) noexcept; + /*! + * \brief computes x to the power N/D + * \tparam N: exponent numerator + * \tparam M: exponent denumerator + * \param x: value + */ template - TFEL_HOST_DEVICE - TFEL_HOST_DEVICE constexpr std::enable_if_t, - T> - power(const T); + TFEL_HOST_DEVICE auto power(const std::floating_point auto) noexcept // + requires(D != 0); } // end of namespace tfel::math diff --git a/include/TFEL/Math/power.ixx b/include/TFEL/Math/power.ixx index bf7e8236b..56cc7db0f 100644 --- a/include/TFEL/Math/power.ixx +++ b/include/TFEL/Math/power.ixx @@ -23,9 +23,9 @@ namespace tfel::math::internals { template struct TFEL_VISIBILITY_LOCAL PowerGenerator { - template - static constexpr T exe(const T& x) { - return std::pow(x, static_cast(N) / static_cast(D)); + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { + return std::pow( + x, static_cast(N) / static_cast(D)); } }; @@ -37,8 +37,7 @@ namespace tfel::math::internals { template struct TFEL_VISIBILITY_LOCAL PowerPosImpl { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { const auto tmp = PowerPos::exe(x); const auto tmp2 = PowerPos::exe(x); return tmp * tmp * tmp * tmp * tmp2; @@ -47,8 +46,7 @@ namespace tfel::math::internals { template struct TFEL_VISIBILITY_LOCAL PowerPosImpl { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { const auto tmp = PowerPos::exe(x); return tmp * tmp * tmp * tmp; } @@ -56,48 +54,42 @@ namespace tfel::math::internals { template struct TFEL_VISIBILITY_LOCAL PowerPosImpl<0u, M> { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { return PowerPos::exe(x); } }; template <> struct TFEL_VISIBILITY_LOCAL PowerPosImpl<0u, 0u> { - template - static constexpr T exe(const T&) { - return {1}; + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { + return static_cast(1); } }; template <> struct TFEL_VISIBILITY_LOCAL PowerPos<0u> { - template - static constexpr T exe(const T&) { - return {1}; + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { + return static_cast(1); } }; template <> struct TFEL_VISIBILITY_LOCAL PowerPos<1u> { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { return x; } }; template <> struct TFEL_VISIBILITY_LOCAL PowerPos<2u> { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { return x * x; } }; template <> struct TFEL_VISIBILITY_LOCAL PowerPos<3u> { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { return x * x * x; } }; @@ -108,22 +100,20 @@ namespace tfel::math::internals { */ template struct TFEL_VISIBILITY_LOCAL PowerNeg { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { static_assert(N < 0, "invalid exponent"); constexpr auto opposite = static_cast(-N); - constexpr auto one = T{1}; + constexpr auto one = static_cast(1); return PowerPos::exe(one / x); } }; template struct TFEL_VISIBILITY_LOCAL PowerSqrtNeg { - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { static_assert(N < 0, "invalid exponent"); constexpr auto opposite = static_cast(-N); - constexpr auto one = T{1}; + constexpr auto one = static_cast(1); return std::sqrt(PowerPos::exe(one / x)); } }; @@ -139,8 +129,7 @@ namespace tfel::math::internals { * \result std::sqrt(power(x)) * \param x: variable whose square root of the power N must be computed */ - template - static constexpr T exe(const T& x) { + TFEL_HOST_DEVICE static auto exe(const std::floating_point auto x) { return std::sqrt(PowerPos::exe(x)); } }; @@ -150,8 +139,8 @@ namespace tfel::math::internals { template class TFEL_VISIBILITY_LOCAL PowerImplSelector { - static constexpr unsigned short AbsN = - static_cast((N < 0) ? -N : N); + static constexpr unsigned int AbsN = + static_cast((N < 0) ? -N : N); using PowerImplSpe = std::conditional_t<(N < 0), PowerNeg, PowerPos>; @@ -163,8 +152,8 @@ namespace tfel::math::internals { template class TFEL_VISIBILITY_LOCAL PowerImplSelector { - static constexpr unsigned short AbsN = - static_cast((N < 0) ? -N : N); + static constexpr unsigned int AbsN = + static_cast((N < 0) ? -N : N); using PowerImplSpe = std::conditional_t<(N < 0), @@ -197,26 +186,14 @@ namespace tfel::math::internals { namespace tfel::math { - /*! - * \brief computes the power of x - * \tparam N: exponent - * \result pow(x,N) - * \param x: variable power to be calculated - */ - template - constexpr std::enable_if_t, T> power(const T x) { + template + TFEL_HOST_DEVICE auto power(const std::floating_point auto x) noexcept { return tfel::math::internals::PowerImplSelector::type::exe(x); } - /*! - * \brief computes the power of x with a rational exponent - * \tparam N: exponent numerator - * \tparam M: exponent denumerator - * \result pow(x,N/D) - * \param x: variable power to be calculated - */ - template - constexpr std::enable_if_t, T> power(const T x) { + template + TFEL_HOST_DEVICE auto power( + const std::floating_point auto x) noexcept requires(D != 0) { return tfel::math::internals::PowerImplSelector::type::exe(x); } diff --git a/include/TFEL/Math/qt.hxx b/include/TFEL/Math/qt.hxx index b008e0a68..1c4c2e871 100644 --- a/include/TFEL/Math/qt.hxx +++ b/include/TFEL/Math/qt.hxx @@ -52,25 +52,23 @@ namespace tfel::math::internals { * \brief constructor from a value * \param src: the src. */ - template )&& // - (std::is_convertible_v)&& // - (!AllowImplicitConversion)), - bool> = false> + template TFEL_HOST_DEVICE constexpr explicit QuantityValueOwnershipPolicy( - const T& src) noexcept + const T& src) noexcept // + requires((std::is_constructible_v)&& // + (std::is_convertible_v)&& // + (!AllowImplicitConversion)) : value(src) {} /*! * \brief constructor from a value * \param src: the src. */ - template )&& // - (std::is_convertible_v)&& // - (AllowImplicitConversion)), - bool> = false> + template TFEL_HOST_DEVICE constexpr QuantityValueOwnershipPolicy( - const T& src) noexcept + const T& src) noexcept // + requires((std::is_constructible_v)&& // + (std::is_convertible_v)&& // + (AllowImplicitConversion)) : value(src) {} //! \brief return the value TFEL_HOST_DEVICE constexpr ValueType& getValue() noexcept { @@ -91,29 +89,26 @@ namespace tfel::math::internals { * \param src: the src. */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((std::is_constructible_v)&& // - (std::is_convertible_v)&& // - (AllowImplicitConversion)), - QuantityValueOwnershipPolicy&> - operator=(const T& src) noexcept { + TFEL_HOST_DEVICE constexpr QuantityValueOwnershipPolicy& + operator=(const T& src) noexcept requires( + (std::is_constructible_v)&& // + (std::is_convertible_v)&& // + (AllowImplicitConversion)) { this->value = src; return *this; } //! \brief conversion operator - template )&& // - (AllowImplicitConversion)), - bool> = false> - TFEL_HOST_DEVICE constexpr operator T&() noexcept { + template + TFEL_HOST_DEVICE constexpr operator T&() noexcept requires( + (std::is_same_v)&& // + (AllowImplicitConversion)) { return this->value; } //! \brief conversion operator - template )&& // - (AllowImplicitConversion)), - bool> = false> - TFEL_HOST_DEVICE constexpr operator T() const noexcept { + template + TFEL_HOST_DEVICE constexpr operator T() const + noexcept requires((std::is_same_v)&& // + (AllowImplicitConversion)) { return this->value; } //! \brief destructor @@ -160,29 +155,26 @@ namespace tfel::math::internals { * \param src: the src. */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((std::is_constructible_v)&& // - (std::is_convertible_v)&& // - (AllowImplicitConversion)), - QuantityReferenceOwnershipPolicy&> - operator=(const T& src) noexcept { + TFEL_HOST_DEVICE constexpr QuantityReferenceOwnershipPolicy& + operator=(const T& src) noexcept requires( + (std::is_constructible_v)&& // + (std::is_convertible_v)&& // + (AllowImplicitConversion)) { this->value = src; return *this; } //! \brief conversion operator - template )&& // - (AllowImplicitConversion)), - bool> = false> - TFEL_HOST_DEVICE constexpr operator T&() noexcept { + template + TFEL_HOST_DEVICE constexpr operator T&() noexcept requires( + (std::is_same_v)&& // + (AllowImplicitConversion)) { return this->value; } //! \brief conversion operator - template )&& // - (AllowImplicitConversion)), - bool> = false> - TFEL_HOST_DEVICE constexpr operator const T&() const noexcept { + template + TFEL_HOST_DEVICE constexpr operator const T&() const + noexcept requires((std::is_same_v)&& // + (AllowImplicitConversion)) { return this->value; } //! \brief destructor @@ -221,43 +213,40 @@ namespace tfel::math { // using OwnershipPolicy::OwnershipPolicy; // - template , ValueType>, - bool> = true> + template TFEL_HOST_DEVICE constexpr Quantity( - const Quantity& src) noexcept + const Quantity& + src) noexcept // + requires(std::is_same_v, ValueType>) : OwnershipPolicy(src.getValue()) {} // end of Quantity // using OwnershipPolicy::operator=; //! \brief assignement operator template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same_v, ValueType>, - Quantity&> - operator=( - const Quantity& src) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& operator=( + const Quantity& + src) noexcept requires(std::is_same_v, + ValueType>) { this->getValue() = src.getValue(); return *this; } //! \brief operator += template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same_v, ValueType>, - Quantity&> - operator+=( - const Quantity& src) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& operator+=( + const Quantity& + src) noexcept requires(std::is_same_v, + ValueType>) { this->getValue() += src.getValue(); return *this; } //! \brief operator -= template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same, ValueType>::value, - Quantity&> - operator-=( - const Quantity& src) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& operator-=( + const Quantity& + src) noexcept requires(std::is_same, + ValueType>::value) { this->getValue() -= src.getValue(); return *this; } @@ -267,10 +256,9 @@ namespace tfel::math { * \param[in] a: a scalar */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - IsQtScalarOperationValid::cond, - Quantity&> - operator*=(const ValueType2& a) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& + operator*=(const ValueType2& a) noexcept requires( + IsQtScalarOperationValid::cond) { this->getValue() *= a; return *this; } @@ -280,11 +268,10 @@ namespace tfel::math { * \param[in] a: a scalar */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - IsQtScalarOperationValid::cond, - Quantity&> - operator*=( - const Quantity& a) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& operator*=( + const Quantity& + a) noexcept requires(IsQtScalarOperationValid::cond) { this->getValue() *= a.getValue(); return *this; } @@ -294,10 +281,9 @@ namespace tfel::math { * \param[in] a: a scalar */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - IsQtScalarOperationValid::cond, - Quantity&> - operator/=(const ValueType2& a) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& + operator/=(const ValueType2& a) noexcept requires( + IsQtScalarOperationValid::cond) { this->getValue() /= a; return *this; } @@ -307,11 +293,10 @@ namespace tfel::math { * \param[in] a: a scalar */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - IsQtScalarOperationValid::cond, - Quantity&> - operator/=( - const Quantity& a) noexcept { + TFEL_HOST_DEVICE constexpr Quantity& operator/=( + const Quantity& + a) noexcept requires(IsQtScalarOperationValid::cond) { this->getValue() /= a.getValue(); return *this; } @@ -431,11 +416,9 @@ namespace tfel::math { }; template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_floating_point_v, - typename UnaryResultType, - Power>::type> - power(const Quantity& x) { + TFEL_HOST_DEVICE constexpr auto + power(const Quantity& x) requires( + std::is_floating_point_v) { using Result = typename UnaryResultType, Power>::type; @@ -447,11 +430,9 @@ namespace tfel::math { typename Unit, typename ValueType, typename OwnershipPolicy> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_floating_point_v, - typename UnaryResultType, - Power>::type> - power(const Quantity& x) { + TFEL_HOST_DEVICE constexpr auto + power(const Quantity& x) requires( + std::is_floating_point_v) { using Result = typename UnaryResultType, Power>::type; diff --git a/include/TFEL/Math/stensor.hxx b/include/TFEL/Math/stensor.hxx index 83e294ec1..549d7eb34 100644 --- a/include/TFEL/Math/stensor.hxx +++ b/include/TFEL/Math/stensor.hxx @@ -123,32 +123,32 @@ namespace tfel::math { //! \brief import from external memory location which uses Voigt notations //! for strains template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - importVoigt(const InputIterator); + TFEL_HOST_DEVICE constexpr void + importVoigt(const InputIterator) noexcept requires( + std::is_same_v::value_type, + base_type>); //! \brief import from external memory location which uses Voigt notations //! for stresses template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - importTab(const InputIterator); + TFEL_HOST_DEVICE constexpr void + importTab(const InputIterator) noexcept requires( + std::is_same_v::value_type, + base_type>); //! \brief import values from external memory location template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - std::is_same::value_type, - base_type>::value, - void> - import(const InputIterator); - //! \brief export to external memory location using Voigt notations for - //! stresses - TFEL_HOST_DEVICE constexpr void exportTab( - base_type* const) const; + TFEL_HOST_DEVICE constexpr void + import(const InputIterator) noexcept requires( + std::is_same_v::value_type, + base_type>); + /*! + * \brief export to external memory location using Voigt notations for0 + * stresses + */ + TFEL_HOST_DEVICE constexpr void // + exportTab(base_type* const) const noexcept; //! \brief write to external memory location - TFEL_HOST_DEVICE constexpr void write(base_type* const) const; + TFEL_HOST_DEVICE constexpr void // + write(base_type* const) const noexcept; /*! * compute eigenvalues * \tparam es: eigen solver @@ -289,29 +289,27 @@ namespace tfel::math { * copy the value from a container */ template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 void copy(const InputIterator src); + TFEL_HOST_DEVICE void constexpr copy(const InputIterator src) noexcept; /*! * build a symmetric tensor from a matrix * \param[in] m : matrix */ - template - TFEL_HOST_DEVICE constexpr static TFEL_MATH_INLINE2 - std::enable_if_t, ValueType>(), - stensor> - buildFromMatrix(const MatrixType&); + template + TFEL_HOST_DEVICE static constexpr auto + buildFromMatrix(const MatrixType&) noexcept requires( + isAssignableTo, ValueType>()); /*! * build a symmetric tensor from the diadic product of a vector with * itself * \param[in] v : vector */ - template - TFEL_HOST_DEVICE constexpr static TFEL_MATH_INLINE2 std::enable_if_t< + template + TFEL_HOST_DEVICE static constexpr auto + buildFromVectorDiadicProduct(const VectorType&) noexcept requires( isAssignableTo, Power<2>>::Result, - ValueType>(), - stensor> - buildFromVectorDiadicProduct(const VectorType&); + ValueType>()); /*! * build a symmetric tensor from the symmetric diadic product of two @@ -319,15 +317,13 @@ namespace tfel::math { * \param[in] v1 : first vector * \param[in] v1 : second vector */ - template - TFEL_HOST_DEVICE constexpr static TFEL_MATH_INLINE2 std::enable_if_t< + template + TFEL_HOST_DEVICE static constexpr auto + buildFromVectorsSymmetricDiadicProduct(const VectorType&, const VectorType2&) noexcept requires( isAssignableTo, numeric_type, OpMult>, - ValueType>(), - stensor> - buildFromVectorsSymmetricDiadicProduct(const VectorType&, - const VectorType2&); + ValueType>()); /*! * build a symmetric tensor from its eigen values and vectors @@ -336,20 +332,20 @@ namespace tfel::math { * \param[in] v2 : third eigen value * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE constexpr static stensor - buildFromEigenValuesAndVectors(const ValueType&, - const ValueType&, - const ValueType&, - const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr auto buildFromEigenValuesAndVectors( + const ValueType&, + const ValueType&, + const ValueType&, + const rotation_matrix&) noexcept; /*! * build a symmetric tensor from its eigen values and vectors * \param[in] vp : eigen values * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE constexpr static stensor - buildFromEigenValuesAndVectors(const tvector<3u, ValueType>&, - const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr auto buildFromEigenValuesAndVectors( + const tvector<3u, ValueType>&, + const rotation_matrix&) noexcept; /*! * build the logarithm of a symmetric tensor given through its eigen @@ -359,11 +355,11 @@ namespace tfel::math { * \param[in] v2 : third eigen value * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor - buildLogarithmFromEigenValuesAndVectors(const ValueType&, - const ValueType&, - const ValueType&, - const rotation_matrix&); + TFEL_HOST_DEVICE static auto buildLogarithmFromEigenValuesAndVectors( + const ValueType&, + const ValueType&, + const ValueType&, + const rotation_matrix&) noexcept; /*! * build the logarithm of a symmetric tensor given through its eigen @@ -371,32 +367,34 @@ namespace tfel::math { * \param[in] vp : eigen values * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor - buildLogarithmFromEigenValuesAndVectors(const tvector<3u, ValueType>&, - const rotation_matrix&); + TFEL_HOST_DEVICE static auto buildLogarithmFromEigenValuesAndVectors( + const tvector<3u, ValueType>&, + const rotation_matrix&) noexcept; /*! * build the absolute value of a symmetric tensor given through its - * eigen values and vectors \param[in] v1 : first eigen value + * eigen values and vectors + * \param[in] v1 : first eigen value * \param[in] v2 : second eigen value * \param[in] v2 : third eigen value * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildAbsoluteValueFromEigenValuesAndVectors( const ValueType&, const ValueType&, const ValueType&, - const rotation_matrix&); + const rotation_matrix&) noexcept; /*! * build the absolute value of a symmetric tensor given through its * eigen values and vectors \param[in] vp : eigen values \param[in] m : * matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildAbsoluteValueFromEigenValuesAndVectors( - const tvector<3u, ValueType>&, const rotation_matrix&); + const tvector<3u, ValueType>&, + const rotation_matrix&) noexcept; /*! * build the positive part of a symmetric tensor given through its eigen @@ -406,21 +404,22 @@ namespace tfel::math { * \param[in] v2 : third eigen value * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildPositivePartFromEigenValuesAndVectors( const ValueType&, const ValueType&, const ValueType&, - const rotation_matrix&); + const rotation_matrix&) noexcept; /*! * build the positive part of a symmetric tensor given through its eigen * values and vectors * \param[in] vp : eigen values * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildPositivePartFromEigenValuesAndVectors( - const tvector<3u, ValueType>&, const rotation_matrix&); + const tvector<3u, ValueType>&, + const rotation_matrix&) noexcept; /*! * build the positive part of a symmetric tensor given through its eigen * values and vectors @@ -429,26 +428,27 @@ namespace tfel::math { * \param[in] v2 : third eigen value * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildNegativePartFromEigenValuesAndVectors( const ValueType&, const ValueType&, const ValueType&, - const rotation_matrix&); - + const rotation_matrix&) noexcept; /*! * build the negative part of a symmetric tensor given through its eigen * values and vectors * \param[in] vp : eigen values * \param[in] m : matrix containing the eigen vectors */ - TFEL_HOST_DEVICE static stensor + TFEL_HOST_DEVICE static constexpr auto buildNegativePartFromEigenValuesAndVectors( - const tvector<3u, ValueType>&, const rotation_matrix&); + const tvector<3u, ValueType>&, + const rotation_matrix&) noexcept; /*! * compute the eigenvalues derivatives with respect with this tensor - * \param[out] n : derivatives of the eigenvalues - * \param[in] m : eigenvectors + * \param[out] n: derivatives of the eigenvalues + * \param[in] m: eigenvectors + * * This eigenvalues of the derivatives is given by~: * \f[ * \frac{\displaystyle \partial}{\lambda_{i}}{\displaystyle @@ -457,10 +457,8 @@ namespace tfel::math { * \(\underbrace{n}_{i}\) are the eigen tensors associated to the given * tensor. */ - TFEL_HOST_DEVICE std::tuple, - stensor, - stensor> - computeEigenValuesDerivatives(const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr auto computeEigenValuesDerivatives( + const rotation_matrix&) noexcept; /*! * compute the eigenvalues derivatives with respect with this tensor * \param[out] n0 : derivative of the first eigenvalue @@ -476,39 +474,36 @@ namespace tfel::math { * given tensor. */ template - TFEL_HOST_DEVICE static std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, numeric_type>()), - void> - computeEigenValuesDerivatives(StensorType&, - StensorType&, - StensorType&, - const rotation_matrix&); - /*! - * \brief compute the "eigentensors" - * \param[out] n: derivativse of the eigenvalues + TFEL_HOST_DEVICE static constexpr void computeEigenValuesDerivatives( + StensorType&, + StensorType&, + StensorType&, + const rotation_matrix&) noexcept // + requires((getSpaceDimension() == N) && + (isAssignableTo, + numeric_type>())); + /*! + * \return the eigentensors * \param[in] m: eigenvectors */ - TFEL_HOST_DEVICE static std::tuple, - stensor, - stensor> - computeEigenTensors(const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr auto computeEigenTensors( + const rotation_matrix&) noexcept; /*! - * compute the "eigentensors" + * \brief compute the eigentensors * \param[out] n0: derivative of the first eigenvalue * \param[out] n1: derivative of the second eigenvalue * \param[out] n2: derivative of the third eigenvalue * \param[in] m: eigenvectors */ template - TFEL_HOST_DEVICE static std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo, numeric_type>()), - void> - computeEigenTensors(StensorType&, - StensorType&, - StensorType&, - const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr void computeEigenTensors( + StensorType&, + StensorType&, + StensorType&, + const rotation_matrix&) noexcept // + requires((getSpaceDimension() == N) && + (isAssignableTo, + numeric_type>())); /*! * \brief compute the "eigentensors" derivatives * \param[out] dn0_ds: derivative of the first eigentensor @@ -519,38 +514,37 @@ namespace tfel::math { * \param[in] eps: numerical parameter for regularisation */ template - TFEL_HOST_DEVICE static std::enable_if_t< - (getSpaceDimension() == N) && + TFEL_HOST_DEVICE static void computeEigenTensorsDerivatives( + ST2toST2Type&, + ST2toST2Type&, + ST2toST2Type&, + const tvector<3u, ValueType>&, + const rotation_matrix&, + const ValueType) // + requires( + (getSpaceDimension() == N) && (isAssignableTo< BinaryOperationResult, ValueType, OpDiv>, - numeric_type>()), - void> - computeEigenTensorsDerivatives(ST2toST2Type&, - ST2toST2Type&, - ST2toST2Type&, - const tvector<3u, ValueType>&, - const rotation_matrix&, - const ValueType); + numeric_type>())); /*! - * compute an isotropic function + * \brief compute an isotropic function * \param[in] f: function * \param[in] vp: eigen values * \param[in] m: eigenvectors */ template - TFEL_HOST_DEVICE static stensor> - computeIsotropicFunction(const Function&, - const tvector<3u, ValueType>&, - const rotation_matrix&); + TFEL_HOST_DEVICE static auto computeIsotropicFunction( + const Function&, + const tvector<3u, ValueType>&, + const rotation_matrix&); /*! * compute an isotropic function * \param[in] f: function values for each eigen values * \param[in] m: eigenvectors */ template - TFEL_HOST_DEVICE static stensor computeIsotropicFunction( - const tvector<3u, T2>&, const rotation_matrix&); + TFEL_HOST_DEVICE static constexpr auto computeIsotropicFunction( + const tvector<3u, T2>&, const rotation_matrix&) noexcept; /*! * \return the derivative of an isotropic function * \param[in] f: function values @@ -561,7 +555,7 @@ namespace tfel::math { * equals */ template - TFEL_HOST_DEVICE static st2tost2 computeIsotropicFunctionDerivative( + TFEL_HOST_DEVICE static auto computeIsotropicFunctionDerivative( const tvector<3u, T1>&, const tvector<3u, T2>&, const tvector<3u, ValueType>&, @@ -578,18 +572,19 @@ namespace tfel::math { * equals */ template - TFEL_HOST_DEVICE static std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo< - BinaryOperationResult, ValueType, OpDiv>, - numeric_type>()), - void> - computeIsotropicFunctionDerivative(ST2toST2Type&, - const tvector<3u, T1>&, - const tvector<3u, T2>&, - const tvector<3u, ValueType>&, - const rotation_matrix&, - const ValueType); + TFEL_HOST_DEVICE static void computeIsotropicFunctionDerivative( + ST2toST2Type&, + const tvector<3u, T1>&, + const tvector<3u, T2>&, + const tvector<3u, ValueType>&, + const rotation_matrix&, + const ValueType) requires((getSpaceDimension() == N) && + (isAssignableTo< + BinaryOperationResult< + base_type, + ValueType, + OpDiv>, + numeric_type>())); /*! * compute the derivative of an isotropic function * \param[out] d: result @@ -601,14 +596,12 @@ namespace tfel::math { * equals */ template - TFEL_HOST_DEVICE static st2tost2< - N, - std::invoke_result_t> - computeIsotropicFunctionDerivative(const Function&, - const FunctionDerivative&, - const tvector<3u, ValueType>&, - const rotation_matrix&, - const ValueType); + TFEL_HOST_DEVICE static auto computeIsotropicFunctionDerivative( + const Function&, + const FunctionDerivative&, + const tvector<3u, ValueType>&, + const rotation_matrix&, + const ValueType); /*! * compute the derivative of an isotropic function * \param[out] d: result @@ -622,26 +615,27 @@ namespace tfel::math { template - TFEL_HOST_DEVICE static std::enable_if_t< - (getSpaceDimension() == N) && - (isAssignableTo< - BinaryOperationResult, ValueType, OpDiv>, - numeric_type>()), - void> - computeIsotropicFunctionDerivative(ST2toST2Type&, - const Function&, - const FunctionDerivative&, - const tvector<3u, ValueType>&, - const rotation_matrix&, - const ValueType); + TFEL_HOST_DEVICE static void computeIsotropicFunctionDerivative( + ST2toST2Type&, + const Function&, + const FunctionDerivative&, + const tvector<3u, ValueType>&, + const rotation_matrix&, + const ValueType) requires((getSpaceDimension() == N) && + (isAssignableTo< + BinaryOperationResult< + base_type, + ValueType, + OpDiv>, + numeric_type>())); /*! * \return the value of an isotropic function * \param[in] f: function * \param[in] b: if true, refinement of eigen values is performed */ template - TFEL_HOST_DEVICE stensor> - computeIsotropicFunction(const Function&, const bool = false) const; + TFEL_HOST_DEVICE auto computeIsotropicFunction(const Function&, + const bool = false) const; /*! * \return the derivative of an isotropic function * \param[in] f: function @@ -653,12 +647,11 @@ namespace tfel::math { template - TFEL_HOST_DEVICE - st2tost2> - computeIsotropicFunctionDerivative(const Function&, - const FunctionDerivative&, - const ValueType, - const bool = false) const; + TFEL_HOST_DEVICE auto computeIsotropicFunctionDerivative( + const Function&, + const FunctionDerivative&, + const ValueType, + const bool = false) const; /*! * \return the derivative of an isotropic function * \param[in] f: function @@ -670,13 +663,11 @@ namespace tfel::math { template - TFEL_HOST_DEVICE std::pair< - stensor>, - st2tost2>> - computeIsotropicFunctionAndDerivative(const Function&, - const FunctionDerivative&, - const ValueType, - const bool = false) const; + TFEL_HOST_DEVICE auto computeIsotropicFunctionAndDerivative( + const Function&, + const FunctionDerivative&, + const ValueType, + const bool = false) const; }; // end of struct stensor /*! @@ -693,13 +684,12 @@ namespace tfel::math { */ template using ConstStensorView = ConstView>; - /*! - * export the given vector to an array of the + * \brief export the given vector to an array */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), void> - exportToBaseTypeArray(const stensor&, OutputIterator); + TFEL_HOST_DEVICE constexpr void exportToBaseTypeArray( + const stensor&, OutputIterator) noexcept requires(isScalar()); /*! * compute the tresca stress @@ -721,22 +711,16 @@ namespace tfel::math { template TFEL_HOST_DEVICE constexpr T tresca(const stensor<1u, T>&, const bool = false); - - template - TFEL_HOST_DEVICE - stensor(), numeric_type> - square_root(const StensorType&); - + //! \return the square root of a symmetric tensor + TFEL_HOST_DEVICE auto square_root(const StensorConcept auto&); + //! \return the determinant of a symmetric tensor TFEL_HOST_DEVICE constexpr auto det(const StensorConcept auto&) noexcept; /*! * \return the derivative of the determinant * \param[in] s: tensor where the the determinant is evaluated */ - template - TFEL_HOST_DEVICE stensor< - getSpaceDimension(), - typename ComputeUnaryResult, Power<2>>::Result> - computeDeterminantDerivative(const StensorType&); + TFEL_HOST_DEVICE constexpr auto computeDeterminantDerivative( + const StensorConcept auto&) noexcept; /*! * \return the derivative of the determinant of the deviator of * symmetric tensor. @@ -755,11 +739,8 @@ namespace tfel::math { * * \param[in] s: tensor where the the determinant is evaluated */ - template - TFEL_HOST_DEVICE stensor< - getSpaceDimension(), - typename ComputeUnaryResult, Power<2>>::Result> - computeDeviatorDeterminantDerivative(const StensorType&); + TFEL_HOST_DEVICE constexpr auto computeDeviatorDeterminantDerivative( + const StensorConcept auto&) noexcept; /*! * \brief rotate a symmetric tensor using a rotation matrix * \param[in] s: symmetric tensor to be rotated @@ -781,136 +762,45 @@ namespace tfel::math { * \param b : if true, refinement of eigen values is performed */ template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - logarithm(const StensorType&, const bool = false); - /*! - * \brief compute the logarithm of a symmetric tensor - * \param s : tensor - * \param b : if true, refinement of eigen values is performed - */ - template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - logarithm(const StensorType&, const bool = false); - /*! - * \brief compute the absolute value of a symmetric tensor - * \param s : tensor - * \param b : if true, refinement of eigen values is performed - */ - template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - absolute_value(const StensorType&, const bool = false); + TFEL_HOST_DEVICE auto + logarithm(const StensorType&, const bool = false) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond); /*! * \brief compute the absolute value of a symmetric tensor * \param s : tensor * \param b : if true, refinement of eigen values is performed */ template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - absolute_value(const StensorType&, const bool = false); + TFEL_HOST_DEVICE auto + absolute_value(const StensorType&, const bool = false) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond); /*! * \brief compute the positive part of a symmetric tensor * \param s : tensor * \param b : if true, refinement of eigen values is performed */ template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - positive_part(const StensorType&, const bool = false); - /*! - * \brief compute the positive part of a symmetric tensor - * \param s : tensor - * \param b : if true, refinement of eigen values is performed - */ - template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - positive_part(const StensorType&, const bool = false); + TFEL_HOST_DEVICE auto + positive_part(const StensorType&, const bool = false) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond); /*! * \brief compute the negative part of a symmetric tensor * \param s : tensor * \param b : if true, refinement of eigen values is performed */ template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor<1u, numeric_type>> - negative_part(const StensorType&, const bool = false); - /*! - * \brief compute the negative part of a symmetric tensor - * \param s : tensor - * \param b : if true, refinement of eigen values is performed - */ - template - TFEL_HOST_DEVICE std::enable_if_t< - (((getSpaceDimension() == 2u) || - (getSpaceDimension() == 3u)) && - (tfel::typetraits::IsFundamentalNumericType< - numeric_type>::cond)), - stensor(), numeric_type>> - negative_part(const StensorType&, const bool = false); + TFEL_HOST_DEVICE auto + negative_part(const StensorType&, const bool = false) requires( + tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond); /*! * \return the square of a symmetric stensor * \param[in] s : squared tensor */ - template - TFEL_HOST_DEVICE - std::enable_if_t() == 1u, - stensor<1u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType&); - /*! - * \return the square of a symmetric stensor - * \param[in] s : squared tensor - */ - template - TFEL_HOST_DEVICE - std::enable_if_t() == 2u, - stensor<2u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType&); - /*! - * \return the square of a symmetric stensor - * \param[in] s : squared tensor - */ - template - TFEL_HOST_DEVICE - std::enable_if_t() == 3u, - stensor<3u, - BinaryOperationResult, - numeric_type, - OpMult>>> - square(const StensorType&); + TFEL_HOST_DEVICE auto square(const StensorConcept auto&); /*! * \return the value of an isotropic function * \param[in] f: function @@ -921,11 +811,9 @@ namespace tfel::math { typename stensor_common::EigenSolver = stensor_common::TFELEIGENSOLVER, typename Function, StensorConcept StensorType> - TFEL_HOST_DEVICE - stensor(), numeric_type> - computeIsotropicFunction(const Function&, - const StensorType&, - const bool = false); + TFEL_HOST_DEVICE auto computeIsotropicFunction(const Function&, + const StensorType&, + const bool = false); /*! * \return the derivative of an isotropic function * \param[in] f: function @@ -940,15 +828,14 @@ namespace tfel::math { typename Function, typename FunctionDerivative, StensorConcept StensorType> - TFEL_HOST_DEVICE - st2tost2(), numeric_type> - computeIsotropicFunctionDerivative(const Function&, - const FunctionDerivative&, - const StensorType&, - const numeric_type, - const bool = false); + TFEL_HOST_DEVICE auto computeIsotropicFunctionDerivative( + const Function&, + const FunctionDerivative&, + const StensorType&, + const numeric_type, + const bool = false); /*! - * \return the derivative of an isotropic function + * \return the value and the derivative of an isotropic function * \param[in] f: function * \param[in] df: derivative of the function * \param[in] s: symmetric tensor @@ -961,50 +848,12 @@ namespace tfel::math { typename Function, typename FunctionDerivative, StensorConcept StensorType> - TFEL_HOST_DEVICE std::pair< - stensor(), numeric_type>, - st2tost2(), numeric_type>> - computeIsotropicFunctionDerivative(const Function&, - const FunctionDerivative&, - const StensorType&, - const numeric_type, - const bool = false); - /*! - * \brief convert the corotationnal cauchy stress to the second - * Piola-Kirchhoff stress - * \f[ - * \underline{S} = - * J\,\underline{U}^{-1}\,.\,\underline{\sigma}\,.\,\underline{U}^{-1} - * \f] - * \param[in] s: corotationnal cauchy stress - * \param[in] U: stretch tensor - * \return the second Piola-Kirchhoff stress - */ - template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 1u) && (getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<1u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T&, - const T2&); - /*! - * \brief convert the corotationnal cauchy stress to the second - * Piola-Kirchhoff stress - * \f[ - * \underline{S} = - * J\,\underline{U}^{-1}\,.\,\underline{\sigma}\,.\,\underline{U}^{-1} - * \f] - * \param[in] s: corotationnal cauchy stress - * \param[in] U: stretch tensor - * \return the second Piola-Kirchhoff stress - */ - template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 2u) && (getSpaceDimension() == 2u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<2u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T&, - const T2&); + TFEL_HOST_DEVICE auto computeIsotropicFunctionAndDerivative( + const Function&, + const FunctionDerivative&, + const StensorType&, + const numeric_type, + const bool = false); /*! * \brief convert the corotationnal cauchy stress to the second * Piola-Kirchhoff stress @@ -1017,12 +866,13 @@ namespace tfel::math { * \return the second Piola-Kirchhoff stress */ template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 3u) && (getSpaceDimension() == 3u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<3u, numeric_type>> - convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress(const T&, - const T2&); + TFEL_HOST_DEVICE constexpr auto + convertCorotationnalCauchyStressToSecondPiolaKirchhoffStress( + const T&, + const T2&) noexcept requires((getSpaceDimension() == + getSpaceDimension()) && + (tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond)); /*! * \brief convert the second Piola-Kirchhoff stress to the * corotationnal cauchy stress: @@ -1035,65 +885,25 @@ namespace tfel::math { * \return the corotationnal cauchy stress */ template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 1u) && (getSpaceDimension() == 1u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<1u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T&, - const T2&); - /*! - * \brief convert the second Piola-Kirchhoff stress to the - * corotationnal cauchy stress: - * \f[ - * \underline{S} = - * J\,\underline{U}^{-1}\,.\,\underline{\sigma}\,.\,\underline{U}^{-1} - * \f] - * \param[in] S: the second Piola-Kirchhoff stress - * \param[in] U: stretch tensor - * \return the corotationnal cauchy stress - */ - template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 2u) && (getSpaceDimension() == 2u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<2u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T&, - const T2&); - /*! - * \brief convert the second Piola-Kirchhoff stress to the - * corotationnal cauchy stress: - * \f[ - * \underline{S} = - * J\,\underline{U}^{-1}\,.\,\underline{\sigma}\,.\,\underline{U}^{-1} - * \f] - * \param[in] S: the second Piola-Kirchhoff stress - * \param[in] U: stretch tensor - * \return the corotationnal cauchy stress - */ - template - TFEL_HOST_DEVICE TFEL_MATH_INLINE2 std::enable_if_t< - ((getSpaceDimension() == 3u) && (getSpaceDimension() == 3u) && - (tfel::typetraits::IsFundamentalNumericType>::cond)), - stensor<3u, numeric_type>> - convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress(const T&, - const T2&); - /*! - * \brief return the symmetric product of two stensors as a symmetric tensor + TFEL_HOST_DEVICE constexpr auto + convertSecondPiolaKirchhoffStressToCorotationnalCauchyStress( + const T&, + const T2&) noexcept requires((getSpaceDimension() == + getSpaceDimension()) && + (tfel::typetraits::IsFundamentalNumericType< + numeric_type>::cond)); + /*! + * \brief return the symmetric product of two stensors as a symmetric tensor: * \f[ - * s1*s2+s2*s1 + * s1 * s2 + s2 * s1 * \f] * \param[in] s1: first tensor * \param[in] s2: second tensor */ template - TFEL_HOST_DEVICE - std::enable_if_t<((getSpaceDimension() == - getSpaceDimension())), - stensor(), - result_type, - numeric_type, - OpMult>>> - symmetric_product(const StensorType1&, const StensorType2&); + TFEL_HOST_DEVICE constexpr auto + symmetric_product(const StensorType1&, const StensorType2&) noexcept requires( + getSpaceDimension() == getSpaceDimension()); } // end of namespace tfel::math diff --git a/include/TFEL/Math/tvector.hxx b/include/TFEL/Math/tvector.hxx index f24b9d0ce..3cf6ee3bb 100644 --- a/include/TFEL/Math/tvector.hxx +++ b/include/TFEL/Math/tvector.hxx @@ -95,7 +95,7 @@ namespace tfel::math { * compatibility. * \param[in] src: object to be copied */ - TFEL_HOST_DEVICE tvector(const fsarray&); + TFEL_HOST_DEVICE tvector(const fsarray&) noexcept; // inheriting GenericFixedSizeArray' access operators using GenericFixedSizeArrayBase::operator[]; using GenericFixedSizeArrayBase::operator(); @@ -106,13 +106,13 @@ namespace tfel::math { */ template TFEL_HOST_DEVICE TFEL_MATH_INLINE constexpr void copy( - const InputIterator src); + const InputIterator src) noexcept; /*! * \brief create a slice * \param[in] I : the starting index */ template - TFEL_HOST_DEVICE constexpr auto slice(); + TFEL_HOST_DEVICE constexpr auto slice() noexcept; /*! * \brief create a slice * \param[in] I : the starting index @@ -121,7 +121,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice(); + TFEL_HOST_DEVICE constexpr auto slice() noexcept; /*! * \brief create a slice (const version) * \param[in] I : the starting index @@ -129,7 +129,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice() const; + TFEL_HOST_DEVICE constexpr auto slice() const noexcept; /*! * \brief create a slice (const version) * \param[in] I : the starting index @@ -138,7 +138,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice() const; + TFEL_HOST_DEVICE constexpr auto slice() const noexcept; }; // end of tvector /*! @@ -168,43 +168,42 @@ namespace tfel::math { * export the given vector to an array of the */ template - TFEL_HOST_DEVICE constexpr std::enable_if_t(), void> - exportToBaseTypeArray(const tvector&, OutputIterator); + TFEL_HOST_DEVICE constexpr void exportToBaseTypeArray( + const tvector&, OutputIterator) noexcept requires(isScalar()); template - TFEL_HOST_DEVICE constexpr std::enable_if_t< - isScalar(), - typename tfel::typetraits::RealPartType::type> - norm(const tvector&) noexcept; + TFEL_HOST_DEVICE constexpr auto norm(const tvector&) noexcept // + requires(isScalar()); template - TFEL_HOST_DEVICE constexpr auto abs(const tvector& v); + TFEL_HOST_DEVICE constexpr auto abs(const tvector& v) noexcept; template - TFEL_HOST_DEVICE constexpr tvector<1u, T> makeTVector1D(const T); + TFEL_HOST_DEVICE constexpr tvector<1u, T> makeTVector1D(const T) noexcept; template - TFEL_HOST_DEVICE constexpr tvector<2u, T> makeTVector2D(const T, const T); + TFEL_HOST_DEVICE constexpr tvector<2u, T> makeTVector2D(const T, + const T) noexcept; template TFEL_HOST_DEVICE constexpr tvector<3u, T> makeTVector3D(const T, const T, - const T); + const T) noexcept; template TFEL_HOST_DEVICE constexpr tvector<3u, T> cross_product( - const tvector<2u, T>&, const tvector<2u, T>&); + const tvector<2u, T>&, const tvector<2u, T>&) noexcept; template TFEL_HOST_DEVICE constexpr tvector<3u, T> cross_product( - const tvector<3u, T>&, const tvector<3u, T>&); + const tvector<3u, T>&, const tvector<3u, T>&) noexcept; /*! * find a vector perpendicular to the second one */ template TFEL_HOST_DEVICE constexpr void find_perpendicular_vector( - tvector<3u, T>&, const tvector<3u, T>&); + tvector<3u, T>&, const tvector<3u, T>&) noexcept; /*! * \brief create a slice from a tiny vector @@ -213,7 +212,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice(tvector&); + TFEL_HOST_DEVICE constexpr auto slice(tvector&) noexcept; /*! * \brief create a slice from a tiny vector * \param[in] v : vector @@ -221,7 +220,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice(tvector&); + TFEL_HOST_DEVICE constexpr auto slice(tvector&) noexcept; /*! * \brief create a slice from a tiny vector * \param[in] v : vector @@ -229,7 +228,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice(const tvector&); + TFEL_HOST_DEVICE constexpr auto slice(const tvector&) noexcept; /*! * \brief create a slice from a tiny vector (const version) * \param[in] v : vector @@ -237,7 +236,7 @@ namespace tfel::math { * vector, so this vector shall not be destroyed before the slice */ template - TFEL_HOST_DEVICE constexpr auto slice(const tvector&); + TFEL_HOST_DEVICE constexpr auto slice(const tvector&) noexcept; /*! * \brief create a view of a math object from a tiny vector @@ -250,13 +249,12 @@ namespace tfel::math { typename IndexingPolicyType = typename std::remove_cv_t::indexing_policy, unsigned short N> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!isScalar()) && (IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(tvector>>&); + TFEL_HOST_DEVICE constexpr auto + map(tvector>>&) noexcept requires( + (!isScalar()) && (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())); /*! * \brief create a constant view of a math object from a tiny vector @@ -269,14 +267,12 @@ namespace tfel::math { typename IndexingPolicyType = typename std::remove_cv_t::indexing_policy, unsigned short N> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!isScalar()) && (IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(const tvector>>&); - + TFEL_HOST_DEVICE constexpr auto + map(const tvector>>&) noexcept requires( + (!isScalar()) && (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())); /*! * \brief create a view of a math object from a tiny vector * \tparam MappedType : type of mapped object @@ -290,13 +286,11 @@ namespace tfel::math { typename IndexingPolicyType = typename MappedType::indexing_policy, unsigned short N, typename real> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((!std::is_const_v)&&(IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename MappedType::indexing_policy>())), - View> - map(tvector&); + TFEL_HOST_DEVICE constexpr auto map(tvector&) noexcept requires( + (!std::is_const_v)&&(IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename MappedType::indexing_policy>())); /*! * \brief create a constant view of a math object from a tiny vector @@ -312,13 +306,12 @@ namespace tfel::math { typename std::remove_cv_t::indexing_policy, unsigned short N, typename real> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - ((IndexingPolicyType::hasFixedSizes) && - (checkIndexingPoliciesCompatiblity< - IndexingPolicyType, - typename std::remove_cv_t::indexing_policy>())), - View> - map(const tvector&); + TFEL_HOST_DEVICE constexpr auto + map(const tvector&) noexcept requires( + (IndexingPolicyType::hasFixedSizes) && + (checkIndexingPoliciesCompatiblity< + IndexingPolicyType, + typename std::remove_cv_t::indexing_policy>())); /*! * \brief create a view on an array of fixed sized math objects from a tiny @@ -333,11 +326,9 @@ namespace tfel::math { unsigned short offset = 0u, unsigned short stride = getViewsArrayMinimalStride(), unsigned short N> - TFEL_HOST_DEVICE constexpr std::enable_if_t< - !std::is_const_v, - ViewsFixedSizeVector> - map(tvector>&); - + TFEL_HOST_DEVICE constexpr auto + map(tvector>&) noexcept requires( + !std::is_const_v); /*! * \brief create a const view on an array of fixed sized math objects from a * tiny vector diff --git a/include/TFEL/Math/vector.hxx b/include/TFEL/Math/vector.hxx index accf1f530..77f4d2739 100644 --- a/include/TFEL/Math/vector.hxx +++ b/include/TFEL/Math/vector.hxx @@ -77,11 +77,8 @@ namespace tfel::math { * \return the euclidian norm of a vector * \param v: the vector. */ - template - TFEL_HOST_DEVICE - std::enable_if_t(), - typename tfel::typetraits::RealPartType::type> - norm(const vector&); + template + TFEL_HOST_DEVICE auto norm(const vector&) noexcept; } // end of namespace tfel::math diff --git a/include/TFEL/Metaprogramming/HasRandomAccessConstIterator.hxx b/include/TFEL/Metaprogramming/HasRandomAccessConstIterator.hxx index d09d31610..423c65bed 100644 --- a/include/TFEL/Metaprogramming/HasRandomAccessConstIterator.hxx +++ b/include/TFEL/Metaprogramming/HasRandomAccessConstIterator.hxx @@ -50,13 +50,10 @@ namespace tfel::meta { * Can only be called if B defines a random access const iterator. */ template - static typename std::enable_if< + static Small Test(const Subs) requires( std::is_same::iterator_category, - std::random_access_iterator_tag>::value, - Small>::type - Test(const Subs); - + std::random_access_iterator_tag>::value); /* * A Test fonction which returns a Big. * It is called if B does not defines a random access const iterator. diff --git a/include/TFEL/Metaprogramming/HasRandomAccessIterator.hxx b/include/TFEL/Metaprogramming/HasRandomAccessIterator.hxx index b081a389e..e522d0546 100644 --- a/include/TFEL/Metaprogramming/HasRandomAccessIterator.hxx +++ b/include/TFEL/Metaprogramming/HasRandomAccessIterator.hxx @@ -50,13 +50,10 @@ namespace tfel::meta { * Can only be called if B defines a random access iterator. */ template - static typename std::enable_if< + static Small Test(const Subs) requires( IsSameType::iterator_category, - std::random_access_iterator_tag>::cond, - Small>::type - Test(const Subs); - + std::random_access_iterator_tag>::cond); /* * A Test fonction which returns a Big. * It is called only if B does not defines a random access iterator. diff --git a/include/TFEL/Metaprogramming/IsConstCallable.hxx b/include/TFEL/Metaprogramming/IsConstCallable.hxx deleted file mode 100644 index 05a82ba24..000000000 --- a/include/TFEL/Metaprogramming/IsConstCallable.hxx +++ /dev/null @@ -1,64 +0,0 @@ -/*! - * \file IsConstCallable.hxx - * \brief - * \author Thomas Helfer - * \date 27 févr. 2015 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence - * or the CECILL-A licence. A copy of thoses licences are delivered - * with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#ifndef LIB_TFEL_METAPROGRAMMING_ISCONSTCALLABLE_HXX -#define LIB_TFEL_METAPROGRAMMING_ISCONSTCALLABLE_HXX - -#include -#include "TFEL/Config/TFELConfig.hxx" -#include "TFEL/Metaprogramming/InvalidType.hxx" - -namespace tfel::meta { - - /*! - * \brief a metafunction which determines of the - * T::operator()(declval()...) const exists. - */ - template - struct IsConstCallable { - //! a simple alias - using Small = char; - //! a type type which size is higher than Small's one - struct TFEL_VISIBILITY_LOCAL Big { - Small dummy[2]; - }; - - protected: - /*! - * A Test fonction which returns a Small. - * Can only be called if B defines an iterator. - */ - template - static std::enable_if_t< - !std::is_same_v().operator()( - std::declval()...)), - InvalidType>, - Small> - test(const T2&, const Args2&...); - /*! - * A Test fonction which returns a Big. - * It is called only if B does not defines an iterator. - */ - static Big test(...); - - public: - //! The result of the metafunction. - static constexpr bool cond = - sizeof(test(std::declval::type>(), - std::declval::type>()...)) == - sizeof(Small); - }; // end of struct IsConstCallable - -} // end of namespace tfel::meta - -#endif /* LIB_TFEL_METAPROGRAMMING_ISCONSTCALLABLE_HXX */ diff --git a/include/TFEL/Metaprogramming/ResultOf.hxx b/include/TFEL/Metaprogramming/ResultOf.hxx deleted file mode 100644 index dba48d08d..000000000 --- a/include/TFEL/Metaprogramming/ResultOf.hxx +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * \file include/TFEL/Metaprogramming/ResultOf.hxx - * \brief - * \author Thomas Helfer - * \date 14 févr. 2015 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence - * or the CECILL-A licence. A copy of thoses licences are delivered - * with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#ifndef LIB_TFEL_METAPROGRAMMING_RESULTOF_HXX -#define LIB_TFEL_METAPROGRAMMING_RESULTOF_HXX - -#include -#include "TFEL/Metaprogramming/InvalidType.hxx" -#include "TFEL/Metaprogramming/IsConstCallable.hxx" - -namespace tfel::meta { - - template - struct ResultOfDispatch { - using type = InvalidType; - }; - - template - struct ResultOfDispatch { - using type = decltype(std::declval()(std::declval()...)); - }; - - template - struct ResultOf - : ResultOfDispatch::cond, T, Args...> { - }; // end of struct ResultOf - - template - struct ResultOf { - using type = InvalidType; - }; // end of struct ResultOf - - //! \brief a simple alias - template - using result_of = typename ResultOf::type; - -} // end of namespace tfel::meta - -#endif /* LIB_TFEL_METAPROGRAMMING_RESULTOF_HXX */ diff --git a/include/TFEL/Utilities/Data.hxx b/include/TFEL/Utilities/Data.hxx index 97cd4cde3..6664cfbb2 100644 --- a/include/TFEL/Utilities/Data.hxx +++ b/include/TFEL/Utilities/Data.hxx @@ -114,11 +114,10 @@ namespace tfel::utilities { //! a simple alias using CallBack = std::function; //! constructor from a value - template , - DataTypes>::value == 1, - bool> = true> - TFEL_INLINE Data(T1&& v) : GenTypeBase(std::forward(v)) {} + template + TFEL_INLINE Data(T1&& v) requires( + tfel::meta::TLCountNbrOfT, DataTypes>::value == 1) + : GenTypeBase(std::forward(v)) {} /*! * \brief read a JSON-like structure * \return the values read @@ -226,10 +225,8 @@ namespace tfel::utilities { const DataValidator&); //! template - std::enable_if_t< - tfel::meta::TLCountNbrOfT, DataTypes>::value == 1, - DataMapValidator&> - addDataTypeValidator(const std::string& k); + DataMapValidator& addDataTypeValidator(const std::string& k) requires( + tfel::meta::TLCountNbrOfT, DataTypes>::value == 1); //! \brief validate a data-map void validate(const DataMap&) const; //! \brief destructor diff --git a/include/TFEL/Utilities/Data.ixx b/include/TFEL/Utilities/Data.ixx index ccbcfa87d..5003f286f 100644 --- a/include/TFEL/Utilities/Data.ixx +++ b/include/TFEL/Utilities/Data.ixx @@ -131,10 +131,9 @@ namespace tfel::utilities::internals { namespace tfel::utilities { template - std::enable_if_t< - tfel::meta::TLCountNbrOfT, DataTypes>::value == 1, - DataMapValidator&> - DataMapValidator::addDataTypeValidator(const std::string& k) { + DataMapValidator& + DataMapValidator::addDataTypeValidator(const std::string& k) requires( + tfel::meta::TLCountNbrOfT, DataTypes>::value == 1) { return this->addDataValidator(k, [](const Data& d) { if (!d.template is()) { tfel::raise("invalid type"); diff --git a/include/TFEL/Utilities/GenTypeBase.hxx b/include/TFEL/Utilities/GenTypeBase.hxx index 9768402d7..b31b05b03 100644 --- a/include/TFEL/Utilities/GenTypeBase.hxx +++ b/include/TFEL/Utilities/GenTypeBase.hxx @@ -116,22 +116,10 @@ namespace tfel::utilities { public tfel::utilities::internals::StdVariantFromTypeList::type { // a simple check static_assert(tfel::meta::TLElementsAreUnique::cond); - - /*! - * \brief a simple wrapper around std::enable_if - * \tparam T: tested type which must belong to List for the requirement - * to hold true \tparam R: result - */ - template - using count = - typename tfel::meta::TLCountNbrOfT::type, List>; - /*! - * \brief a simple wrapper around std::enable_if - * \tparam T: tested type which must belong to List for the requirement to - * hold true \tparam R: result - */ - template - using type_check = typename std::enable_if::value == 1, R>::type; + //! \brief a variable checking if the given type is valid + template + static constexpr bool isValidType = + tfel::meta::TLCountNbrOfT::type, List>::value; //! \brief a simple alias using variant = typename tfel::utilities::internals::StdVariantFromTypeList::type; @@ -142,15 +130,16 @@ namespace tfel::utilities { //! \brief copy constructor GenTypeBase(const GenTypeBase &) = default; //! \brief constructor from a value - template > - GenTypeBase(T1 &&value) : variant(std::forward(value)) {} + template + GenTypeBase(T1 &&value) requires(isValidType) + : variant(std::forward(value)) {} // \brief assignement operator GenTypeBase &operator=(GenTypeBase &&) = default; // \brief assignement operator GenTypeBase &operator=(const GenTypeBase &) = default; // \brief assignement operator from a value - template > - GenTypeBase &operator=(T1 &&value) { + template + GenTypeBase &operator=(T1 &&value) requires(isValidType) { variant::operator=(std::forward(value)); return *this; } @@ -170,23 +159,23 @@ namespace tfel::utilities { * \pre T1 must be a type that the GenType can hold. */ template - TFEL_INLINE type_check set(T1 &&src) { + TFEL_INLINE void set(T1 &&src) requires(isValidType) { this->operator=(std::forward(src)); } // template - TFEL_INLINE type_check is() const { + TFEL_INLINE bool is() const requires(isValidType) { return std::holds_alternative(*this); } //! \return the value hold by the `GenTypeBase`. template - TFEL_INLINE type_check get() const { + TFEL_INLINE const T1 &get() const requires(isValidType) { tfel::raise_if(!this->template is()); return std::get(*this); } //! \return the value hold by the `GenTypeBase`. template - TFEL_INLINE type_check get() { + TFEL_INLINE T1 &get() requires(isValidType) { tfel::raise_if(!this->template is()); return std::get(*this); } @@ -198,7 +187,7 @@ namespace tfel::utilities { TFEL_INLINE void clear() { variant::operator=(std::monostate()); } //! \brief set the value of the GenType. template - TFEL_INLINE type_check set_uninitialised() { + TFEL_INLINE void set_uninitialised() requires(isValidType) { this->operator=(T1()); } }; diff --git a/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.hxx b/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.hxx index 07f378491..f089302fc 100644 --- a/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.hxx +++ b/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.hxx @@ -20,92 +20,93 @@ #include "TFEL/Math/st2tost2.hxx" #include "TFEL/Material/ModellingHypothesis.hxx" -namespace mfront { +namespace mfront::gb { - namespace gb { + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<1u, stress>&, + const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 1u); + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<2u, stress>&, + const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 2u); + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<3u, stress>&, + const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 3u); + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<1u, stress>&, + const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 1u); + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<2u, stress>&, + const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 2u); + /*! + * \brief compute the unaltered elastic stiffness tensor + * \param[out] C: stiffness tensor + * \param[out] mps: elastic material properties + */ + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<3u, stress>&, const real* const) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 3u); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 1u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<1u, stress>&, const real* const); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 2u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<2u, stress>&, const real* const); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 3u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<3u, stress>&, const real* const); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 1u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<1u, stress>&, const real* const); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 2u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<2u, stress>&, const real* const); - /*! - * \brief compute the unaltered elastic stiffness tensor - * \param[out] C: stiffness tensor - * \param[out] mps: elastic material properties - */ - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 3u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<3u, stress>&, const real* const); - - } // end of namespace gb - -} // end of namespace mfront +} // end of namespace mfront::gb #include "MFront/GenericBehaviour/ComputeStiffnessTensor.ixx" diff --git a/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.ixx b/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.ixx index e41ed3c90..7dfeeda04 100644 --- a/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.ixx +++ b/mfront/include/MFront/GenericBehaviour/ComputeStiffnessTensor.ixx @@ -16,112 +16,115 @@ #include "TFEL/Material/StiffnessTensor.hxx" -namespace mfront { +namespace mfront::gb { - namespace gb { + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<1u, stress>& C, + const real* const mps) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 1u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::UNALTERED; + // last three parameters are unused + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[0]), stress(mps[1]), stress(mps[2])); + } // end of computeOrthotropicUnAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 1u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<1u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::UNALTERED; - // last three parameters are unused - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[0]), stress(mps[1]), stress(mps[2])); - } // end of computeOrthotropicUnAlteredElasticStiffnessTensor + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<2u, stress>& C, + const real* const mps) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 2u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::UNALTERED; + // last two parameters are unused + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[6]), stress(mps[1]), stress(mps[2])); + } // end of computeOrthotropicUnAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 2u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<2u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::UNALTERED; - // last two parameters are unused - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[6]), stress(mps[1]), stress(mps[2])); - } // end of computeOrthotropicUnAlteredElasticStiffnessTensor + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicUnAlteredElasticStiffnessTensor( + tfel::math::st2tost2<3u, stress>& C, + const real* const + mps) noexcept requires(tfel::material:: + ModellingHypothesisToSpaceDimension< + H>::value == 3u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::UNALTERED; + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[6]), stress(mps[7]), stress(mps[8])); + } // end of computeOrthotropicUnAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 3u, - void>::type - computeOrthotropicUnAlteredElasticStiffnessTensor( - tfel::math::st2tost2<3u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::UNALTERED; - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[6]), stress(mps[7]), stress(mps[8])); - } // end of computeOrthotropicUnAlteredElasticStiffnessTensor + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<1u, stress>& C, + const real* const mps) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 1u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::ALTERED; + // last three parameters are unused + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[0]), stress(mps[1]), stress(mps[2])); + } // end of computeOrthotropicAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 1u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<1u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::ALTERED; - // last three parameters are unused - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[0]), stress(mps[1]), stress(mps[2])); - } // end of computeOrthotropicAlteredElasticStiffnessTensor + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<2u, stress>& C, + const real* const mps) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 2u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::ALTERED; + // last two parameters are unused + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[6]), stress(mps[1]), stress(mps[2])); + } // end of computeOrthotropicAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 2u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<2u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::ALTERED; - // last two parameters are unused - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[6]), stress(mps[1]), stress(mps[2])); - } // end of computeOrthotropicAlteredElasticStiffnessTensor + template + TFEL_HOST_DEVICE constexpr void + computeOrthotropicAlteredElasticStiffnessTensor( + tfel::math::st2tost2<3u, stress>& C, + const real* const mps) noexcept // + requires(tfel::material::ModellingHypothesisToSpaceDimension::value == + 3u) { + using namespace tfel::material; + constexpr StiffnessTensorAlterationCharacteristic stac = + StiffnessTensorAlterationCharacteristic::ALTERED; + computeOrthotropicStiffnessTensor( + C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], + mps[5], stress(mps[6]), stress(mps[7]), stress(mps[8])); + } // end of computeOrthotropicAlteredElasticStiffnessTensor - template - typename std::enable_if< - tfel::material::ModellingHypothesisToSpaceDimension::value == 3u, - void>::type - computeOrthotropicAlteredElasticStiffnessTensor( - tfel::math::st2tost2<3u, stress>& C, const real* const mps) { - using namespace tfel::material; - constexpr StiffnessTensorAlterationCharacteristic stac = - StiffnessTensorAlterationCharacteristic::ALTERED; - computeOrthotropicStiffnessTensor( - C, stress(mps[0]), stress(mps[1]), stress(mps[2]), mps[3], mps[4], - mps[5], stress(mps[6]), stress(mps[7]), stress(mps[8])); - } // end of computeOrthotropicAlteredElasticStiffnessTensor - - } // end of namespace gb - -} // end of namespace mfront +} // end of namespace mfront::gb #endif /* LIB_MFRONT_GENERIC_COMPUTESTIFFNESSTENSOR_HXX */ diff --git a/mfront/include/MFront/MaterialKnowledgeDescription.hxx b/mfront/include/MFront/MaterialKnowledgeDescription.hxx index f593f8ae4..35f908f77 100644 --- a/mfront/include/MFront/MaterialKnowledgeDescription.hxx +++ b/mfront/include/MFront/MaterialKnowledgeDescription.hxx @@ -86,23 +86,23 @@ namespace mfront { * \param[in] n : name */ template - std::enable_if_t(), T&> getAttribute( - const std::string_view); + T& getAttribute(const std::string_view) requires( + isMaterialKnowledgeAttributeType()); /*! * \return the attribute with the given name * \param[in] n : name */ template - std::enable_if_t(), const T&> - getAttribute(const std::string_view) const; + const T& getAttribute(const std::string_view) const + requires(isMaterialKnowledgeAttributeType()); /*! * \return the attribute with the given name * \param[in] n: name * \param[in] v: default value if the attribute is not defined */ template - std::enable_if_t(), T> getAttribute( - const std::string_view, const T&) const; + T getAttribute(const std::string_view, const T&) const + requires(isMaterialKnowledgeAttributeType()); /*! * \return all the attribute registred * \param[in] n : name diff --git a/mfront/include/MFront/MaterialKnowledgeDescription.ixx b/mfront/include/MFront/MaterialKnowledgeDescription.ixx index 1500d7d39..a61a28336 100644 --- a/mfront/include/MFront/MaterialKnowledgeDescription.ixx +++ b/mfront/include/MFront/MaterialKnowledgeDescription.ixx @@ -17,8 +17,8 @@ namespace mfront { template - std::enable_if_t(), T&> - MaterialKnowledgeDescription::getAttribute(const std::string_view n) { + T& MaterialKnowledgeDescription::getAttribute(const std::string_view n) // + requires(isMaterialKnowledgeAttributeType()) { auto p = this->attributes.find(n); if (p == this->attributes.end()) { p = this->attributes @@ -29,8 +29,9 @@ namespace mfront { } // end of getAttribute template - std::enable_if_t(), const T&> - MaterialKnowledgeDescription::getAttribute(const std::string_view n) const { + const T& MaterialKnowledgeDescription::getAttribute( + const std::string_view n) const // + requires(isMaterialKnowledgeAttributeType()) { const auto p = this->attributes.find(n); if (p == this->attributes.end()) { MaterialKnowledgeDescription::throwUndefinedAttribute(n); @@ -39,9 +40,9 @@ namespace mfront { } // end of getAttribute template - std::enable_if_t(), T> - MaterialKnowledgeDescription::getAttribute(const std::string_view n, - const T& v) const { + T MaterialKnowledgeDescription::getAttribute(const std::string_view n, + const T& v) const // + requires(isMaterialKnowledgeAttributeType()) { const auto p = this->attributes.find(n); if (p == this->attributes.end()) { return v; diff --git a/mfront/include/MFront/VariableDescription.hxx b/mfront/include/MFront/VariableDescription.hxx index c58bc3012..b1a19c253 100644 --- a/mfront/include/MFront/VariableDescription.hxx +++ b/mfront/include/MFront/VariableDescription.hxx @@ -32,6 +32,10 @@ namespace mfront { //! \brief structure standing for a standard (non static) variable struct MFRONT_VISIBILITY_EXPORT VariableDescription : public VariableDescriptionBase { + // + template + static constexpr bool isVariableAttribute = + tfel::meta::TLCountNbrOfT::value == 1; //! \brief standard attribute name static const char* const depth; //! \brief standard attribute name @@ -110,19 +114,14 @@ namespace mfront { * \param[in] n : name */ template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - T&>::type - getAttribute(const std::string&); + T& getAttribute(const std::string&) requires(isVariableAttribute); /*! * \return the attribute with the given name * \param[in] n : name */ template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - const T&>::type - getAttribute(const std::string&) const; + const T& getAttribute(const std::string&) const + requires(isVariableAttribute); /*! * \return the attribute with the given name or the given default * value if the variable does not exists @@ -130,10 +129,8 @@ namespace mfront { * \param[in] v : value */ template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - T>::type - getAttribute(const std::string&, const T&) const; + T getAttribute(const std::string&, const T&) const + requires(isVariableAttribute); /*! * \return all the attribute registred * \param[in] n : name diff --git a/mfront/include/MFront/VariableDescription.ixx b/mfront/include/MFront/VariableDescription.ixx index 3c137b67b..4c5343503 100644 --- a/mfront/include/MFront/VariableDescription.ixx +++ b/mfront/include/MFront/VariableDescription.ixx @@ -17,10 +17,8 @@ namespace mfront { template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - T&>::type - VariableDescription::getAttribute(const std::string& n) { + T& VariableDescription::getAttribute(const std::string& n) requires( + isVariableAttribute) { auto p = this->attributes.find(n); if (p == this->attributes.end()) { p = this->attributes.insert({n, VariableAttribute(T())}).first; @@ -29,10 +27,8 @@ namespace mfront { } // end of VariableDescription::getAttribute template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - const T&>::type - VariableDescription::getAttribute(const std::string& n) const { + const T& VariableDescription::getAttribute(const std::string& n) const + requires(isVariableAttribute) { auto p = this->attributes.find(n); if (p == this->attributes.end()) { VariableDescription::throwUndefinedAttribute(n); @@ -41,10 +37,8 @@ namespace mfront { } // end of VariableDescription::getAttribute template - typename std::enable_if< - tfel::meta::TLCountNbrOfT::value == 1, - T>::type - VariableDescription::getAttribute(const std::string& n, const T& v) const { + T VariableDescription::getAttribute(const std::string& n, const T& v) const + requires(isVariableAttribute) { auto p = this->attributes.find(n); if (p != this->attributes.end()) { return p->second.template get(); diff --git a/mfront/include/MFront/ZMAT/ZMATInterface.hxx b/mfront/include/MFront/ZMAT/ZMATInterface.hxx index 2bd87c319..3c2309443 100644 --- a/mfront/include/MFront/ZMAT/ZMATInterface.hxx +++ b/mfront/include/MFront/ZMAT/ZMATInterface.hxx @@ -35,172 +35,109 @@ namespace zmat { * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::stensor<1u, T>&, const double* const); + static void convert(tfel::math::stensor<1u, double>&, const double* const); /*! * convert an 2D ZMAT symmetric tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::stensor<2u, T>&, const double* const); + static void convert(tfel::math::stensor<2u, double>&, const double* const); /*! * convert an 3D ZMAT symmetric tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::stensor<3u, T>&, const double* const); + static void convert(tfel::math::stensor<3u, double>&, const double* const); /*! - * convert an 1D TFEL symmetric tensor to a ZMAT one - * \param[in] src : source + * convert an 1D TFEL symmetric tensor to + * a ZMAT one \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::stensor<1u, T>&); + static void convert(double* const, const tfel::math::stensor<1u, double>&); /*! * convert an 2D TFEL symmetric tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::stensor<2u, T>&); + static void convert(double* const, const tfel::math::stensor<2u, double>&); /*! * convert an 3D TFEL symmetric tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::stensor<3u, T>&); + static void convert(double* const, const tfel::math::stensor<3u, double>&); /*! * convert an 1D ZMAT tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::tensor<1u, T>&, const double* const); + static void convert(tfel::math::tensor<1u, double>&, const double* const); /*! * convert an 2D ZMAT tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::tensor<2u, T>&, const double* const); + static void convert(tfel::math::tensor<2u, double>&, const double* const); /*! * convert an 3D ZMAT tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::tensor<3u, T>&, const double* const); + static void convert(tfel::math::tensor<3u, double>&, const double* const); /*! * convert an 1D TFEL tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::tensor<1u, T>&); + static void convert(double* const, const tfel::math::tensor<1u, double>&); /*! * convert an 2D TFEL tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::tensor<2u, T>&); + static void convert(double* const, const tfel::math::tensor<2u, double>&); /*! * convert an 3D TFEL tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(double* const, const tfel::math::tensor<3u, T>&); + static void convert(double* const, const tfel::math::tensor<3u, double>&); /*! * convert an 1D TFEL stiffness tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(ZSET::MATRIX&, const tfel::math::st2tost2<1u, T>&); + static void convert(ZSET::MATRIX&, const tfel::math::st2tost2<1u, double>&); /*! * convert an 2D TFEL stiffness tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(ZSET::MATRIX&, const tfel::math::st2tost2<2u, T>&); + static void convert(ZSET::MATRIX&, const tfel::math::st2tost2<2u, double>&); /*! * convert an 3D TFEL stiffness tensor to a ZMAT one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type - convert(ZSET::MATRIX&, const tfel::math::st2tost2<3u, T>&); + static void convert(ZSET::MATRIX&, const tfel::math::st2tost2<3u, double>&); /*! * convert an 1D ZMAT stiffness tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::st2tost2<1u, T>&, const ZSET::MATRIX&); + static void convert(tfel::math::st2tost2<1u, double>&, const ZSET::MATRIX&); /*! * convert a 2D ZMAT stiffness tensor to a TFEL one * \param[in] src : source * \param[in] dest : destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::st2tost2<2u, T>&, const ZSET::MATRIX&); + static void convert(tfel::math::st2tost2<2u, double>&, const ZSET::MATRIX&); /*! * \brief convert an ZSET stiffness tensor to a TFEL one * \param[in] src: source * \param[in] dest: destination */ - template - static inline typename std::enable_if< - std::is_same, double>::value, - void>::type convert(tfel::math::st2tost2<3u, T>&, const ZSET::MATRIX&); + static void convert(tfel::math::st2tost2<3u, double>&, const ZSET::MATRIX&); }; } // end of namespace zmat diff --git a/mfront/include/MFront/ZMAT/ZMATInterface.ixx b/mfront/include/MFront/ZMAT/ZMATInterface.ixx index aeaf5bd3f..8e85f75b0 100644 --- a/mfront/include/MFront/ZMAT/ZMATInterface.ixx +++ b/mfront/include/MFront/ZMAT/ZMATInterface.ixx @@ -16,35 +16,23 @@ namespace zmat { - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::stensor<1u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::stensor<1u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::stensor<2u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::stensor<2u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::stensor<3u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::stensor<3u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -53,35 +41,23 @@ namespace zmat { dest[5] = src[4]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::stensor<1u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::stensor<1u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::stensor<2u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::stensor<2u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::stensor<3u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::stensor<3u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -90,12 +66,8 @@ namespace zmat { dest[5] = src[4]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(ZSET::MATRIX& dest, - const tfel::math::st2tost2<1u, T>& src) { + inline void ZMATInterface::convert( + ZSET::MATRIX& dest, const tfel::math::st2tost2<1u, double>& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -107,12 +79,8 @@ namespace zmat { dest(2, 2) = src(2, 2); } - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(ZSET::MATRIX& dest, - const tfel::math::st2tost2<2u, T>& src) { + inline void ZMATInterface::convert( + ZSET::MATRIX& dest, const tfel::math::st2tost2<2u, double>& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -131,12 +99,8 @@ namespace zmat { dest(3, 3) = src(3, 3); } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(ZSET::MATRIX& dest, - const tfel::math::st2tost2<3u, T>& src) { + inline void ZMATInterface::convert( + ZSET::MATRIX& dest, const tfel::math::st2tost2<3u, double>& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -175,12 +139,8 @@ namespace zmat { dest(5, 5) = src(4, 4); } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::st2tost2<1u, T>& dest, - const ZSET::MATRIX& src) { + inline void ZMATInterface::convert(tfel::math::st2tost2<1u, double>& dest, + const ZSET::MATRIX& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -192,12 +152,8 @@ namespace zmat { dest(2, 2) = src(2, 2); } - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::st2tost2<2u, T>& dest, - const ZSET::MATRIX& src) { + inline void ZMATInterface::convert(tfel::math::st2tost2<2u, double>& dest, + const ZSET::MATRIX& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -216,12 +172,8 @@ namespace zmat { dest(3, 3) = src(3, 3); } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::st2tost2<3u, T>& dest, - const ZSET::MATRIX& src) { + inline void ZMATInterface::convert(tfel::math::st2tost2<3u, double>& dest, + const ZSET::MATRIX& src) { dest(0, 0) = src(0, 0); dest(1, 0) = src(1, 0); dest(2, 0) = src(2, 0); @@ -260,23 +212,15 @@ namespace zmat { dest(5, 5) = src(4, 4); } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::tensor<1u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::tensor<1u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::tensor<2u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::tensor<2u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -284,12 +228,8 @@ namespace zmat { dest[4] = src[4]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(tfel::math::tensor<3u, T>& dest, - const double* const src) { + inline void ZMATInterface::convert(tfel::math::tensor<3u, double>& dest, + const double* const src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -301,23 +241,15 @@ namespace zmat { dest[5] = src[8]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::tensor<1u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::tensor<1u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::tensor<2u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::tensor<2u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -325,12 +257,8 @@ namespace zmat { dest[4] = src[4]; } // end of ZMATInterface::convert - template - typename std::enable_if< - std::is_same, double>::value, - void>::type - ZMATInterface::convert(double* const dest, - const tfel::math::tensor<3u, T>& src) { + inline void ZMATInterface::convert( + double* const dest, const tfel::math::tensor<3u, double>& src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; diff --git a/mfront/src/BehaviourCodeGeneratorBase.cxx b/mfront/src/BehaviourCodeGeneratorBase.cxx index b0dec60ce..616c59e05 100644 --- a/mfront/src/BehaviourCodeGeneratorBase.cxx +++ b/mfront/src/BehaviourCodeGeneratorBase.cxx @@ -4802,39 +4802,38 @@ namespace mfront { << "* \\brief scale the integration data by a scalar.\n" << "*/\n" << "template\n" - << "TFEL_HOST_DEVICE typename std::enable_if<\n" - << "tfel::typetraits::IsFundamentalNumericType::cond&&\n" - << "tfel::typetraits::IsScalar::cond&&\n" - << "tfel::typetraits::IsReal::cond&&\n" - << "std::is_same::type>::value,\n" - << this->bd.getClassName() << "IntegrationData&\n" - << ">::type\n"; + << "TFEL_HOST_DEVICE " << this->bd.getClassName() + << "IntegrationData&\n"; if (!iknown) { if (this->bd.useQt()) { os << "scale(const " << this->bd.getClassName() << "BehaviourData& behaviourData, " "const " - "Scal time_scaling_factor){\n"; + "Scal time_scaling_factor)\n"; } else { os << "scale(const " << this->bd.getClassName() << "BehaviourData& behaviourData, " "const Scal " - "time_scaling_factor){\n"; + "time_scaling_factor)\n"; } } else { if (this->bd.useQt()) { os << "scale(const " << this->bd.getClassName() << "BehaviourData&, const Scal " - "time_scaling_factor){\n"; + "time_scaling_factor)\n"; } else { os << "scale(const " << this->bd.getClassName() << "BehaviourData&, const Scal " - "time_scaling_factor){\n"; + "time_scaling_factor)\n"; } } - os << "this->dt *= time_scaling_factor;\n"; + os << "requires(tfel::typetraits::IsFundamentalNumericType::cond&&\n" + << "tfel::typetraits::IsScalar::cond&&\n" + << "tfel::typetraits::IsReal::cond&&\n" + << "std::is_same::type>::value){\n" + << "this->dt *= time_scaling_factor;\n"; for (const auto& v : this->bd.getMainVariables()) { if (Gradient::isIncrementKnown(v.first)) { os << "this->d" << v.first.name << " *= time_scaling_factor;\n"; diff --git a/mfront/src/BehaviourData.cxx b/mfront/src/BehaviourData.cxx index 351b86cc0..80e22c7ac 100644 --- a/mfront/src/BehaviourData.cxx +++ b/mfront/src/BehaviourData.cxx @@ -392,7 +392,7 @@ namespace mfront { } } tfel::raise( - "MaterialPropertyDSL::getIntegerConstant: " + "BehaviourData::getIntegerConstant: " "unknown variable '" + n + "'"); } // end of getIntegerConstant diff --git a/mfront/src/CMaterialPropertyInterfaceBase.cxx b/mfront/src/CMaterialPropertyInterfaceBase.cxx index 28a32bf3c..44ae33ff3 100644 --- a/mfront/src/CMaterialPropertyInterfaceBase.cxx +++ b/mfront/src/CMaterialPropertyInterfaceBase.cxx @@ -396,8 +396,8 @@ namespace mfront { void CMaterialPropertyInterfaceBase::writeMaterialKnowledgeTypeSymbol( std::ostream& os, const MaterialPropertyDescription& mpd) const { - mfront::writeMaterialKnowledgeTypeSymbol(os, this->getSymbolName(mpd), - MaterialKnowledgeType::MATERIALPROPERTY); + mfront::writeMaterialKnowledgeTypeSymbol( + os, this->getSymbolName(mpd), MaterialKnowledgeType::MATERIALPROPERTY); } // end of writeMaterialKnowledgeTypeSymbol void CMaterialPropertyInterfaceBase::writeVariablesNamesSymbol( diff --git a/mfront/src/CastemMaterialPropertyInterface.cxx b/mfront/src/CastemMaterialPropertyInterface.cxx index 29ef322bf..b4cdeeb56 100644 --- a/mfront/src/CastemMaterialPropertyInterface.cxx +++ b/mfront/src/CastemMaterialPropertyInterface.cxx @@ -378,7 +378,8 @@ namespace mfront { writeInterfaceSymbol(out, name, "Castem"); writeLawSymbol(out, name, mpd.law); writeMaterialSymbol(out, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(out, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(out, name, + MaterialKnowledgeType::MATERIALPROPERTY); writeParametersSymbols(out, name, mpd); exportStringSymbol( out, name + "_src", diff --git a/mfront/src/CppMaterialPropertyInterface.cxx b/mfront/src/CppMaterialPropertyInterface.cxx index 095e3fe77..fa84383c4 100644 --- a/mfront/src/CppMaterialPropertyInterface.cxx +++ b/mfront/src/CppMaterialPropertyInterface.cxx @@ -243,7 +243,8 @@ namespace mfront { writeUnitSystemSymbol(src, name, mpd); writeInterfaceSymbol(src, name, "C++"); writeMaterialSymbol(src, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(src, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(src, name, + MaterialKnowledgeType::MATERIALPROPERTY); src << "#ifdef __cplusplus\n" << "} // end of extern \"C\"\n" << "#endif /* __cplusplus */\n\n"; diff --git a/mfront/src/GenericMaterialPropertyInterfaceBase.cxx b/mfront/src/GenericMaterialPropertyInterfaceBase.cxx index bc4ab3d75..cf33079fc 100644 --- a/mfront/src/GenericMaterialPropertyInterfaceBase.cxx +++ b/mfront/src/GenericMaterialPropertyInterfaceBase.cxx @@ -371,7 +371,8 @@ namespace mfront { writeInterfaceSymbol(os, name, this->getInterfaceNameInCamelCase()); writeLawSymbol(os, name, mpd.law); writeMaterialSymbol(os, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(os, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(os, name, + MaterialKnowledgeType::MATERIALPROPERTY); writeParametersSymbols(os, name, mpd); exportStringSymbol( os, name + "_src", diff --git a/mfront/src/JavaMaterialPropertyInterface.cxx b/mfront/src/JavaMaterialPropertyInterface.cxx index 70e3f4ccd..71159b97e 100644 --- a/mfront/src/JavaMaterialPropertyInterface.cxx +++ b/mfront/src/JavaMaterialPropertyInterface.cxx @@ -335,7 +335,8 @@ namespace mfront { writeInterfaceSymbol(srcFile, name, "Java"); writeLawSymbol(srcFile, name, mpd.material); writeMaterialSymbol(srcFile, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(srcFile, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(srcFile, name, + MaterialKnowledgeType::MATERIALPROPERTY); // java srcFile << "JNIEXPORT jdouble JNICALL\n"; if (this->package.empty()) { diff --git a/mfront/src/OctaveMaterialPropertyInterface.cxx b/mfront/src/OctaveMaterialPropertyInterface.cxx index 2cba49ecf..61a4c9bcf 100644 --- a/mfront/src/OctaveMaterialPropertyInterface.cxx +++ b/mfront/src/OctaveMaterialPropertyInterface.cxx @@ -163,7 +163,8 @@ namespace mfront { writeInterfaceSymbol(out, name, "Octave"); writeLawSymbol(out, name, mpd.material); writeMaterialSymbol(out, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(out, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(out, name, + MaterialKnowledgeType::MATERIALPROPERTY); if (mpd.inputs.size() > 1) { out << "static double\n" diff --git a/mfront/src/PythonMaterialPropertyInterface.cxx b/mfront/src/PythonMaterialPropertyInterface.cxx index 74548bba5..e778ca4e7 100644 --- a/mfront/src/PythonMaterialPropertyInterface.cxx +++ b/mfront/src/PythonMaterialPropertyInterface.cxx @@ -365,7 +365,8 @@ namespace mfront { writeInterfaceSymbol(srcFile, name, "Python"); writeLawSymbol(srcFile, name, mpd.material); writeMaterialSymbol(srcFile, name, mpd.material); - writeMaterialKnowledgeTypeSymbol(srcFile, name, MaterialKnowledgeType::MATERIALPROPERTY); + writeMaterialKnowledgeTypeSymbol(srcFile, name, + MaterialKnowledgeType::MATERIALPROPERTY); writeParametersSymbols(srcFile, name, mpd); // parameters if ((!areParametersTreatedAsStaticVariables(mpd)) && diff --git a/src/Utilities/Data.cxx b/src/Utilities/Data.cxx index 29a58fd87..76c8b48b8 100644 --- a/src/Utilities/Data.cxx +++ b/src/Utilities/Data.cxx @@ -294,8 +294,7 @@ namespace tfel::utilities { using return_type = bool; // default implementation template - static typename std::enable_if::value, bool>::type - apply(const T1&, const T2&) { + static bool apply(const T1&, const T2&) requires(!std::is_same_v) { return false; } // end of apply static bool apply(const std::string& x1, const std::string& x2) { diff --git a/tests/MetaProgramming/CMakeLists.txt b/tests/MetaProgramming/CMakeLists.txt index cce11abde..1d360ad5b 100644 --- a/tests/MetaProgramming/CMakeLists.txt +++ b/tests/MetaProgramming/CMakeLists.txt @@ -10,7 +10,5 @@ macro(tests_metaprogramming test_arg) target_link_libraries(${test_arg} TFELUtilities TFELTests) endmacro(tests_metaprogramming) -tests_metaprogramming(ResultOf) -tests_metaprogramming(IsConstCallable) tests_metaprogramming(HasConstIterator) tests_metaprogramming(typelist2) diff --git a/tests/MetaProgramming/IsConstCallable.cxx b/tests/MetaProgramming/IsConstCallable.cxx deleted file mode 100644 index 60f79c1c1..000000000 --- a/tests/MetaProgramming/IsConstCallable.cxx +++ /dev/null @@ -1,55 +0,0 @@ -/*! - * \file IsConstCallable.cxx - * \brief - * \author Thomas Helfer - * \date 15 févr. 2015 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence with - * linking exception or the CECILL-A licence. A copy of thoses licences are - * delivered with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#include -#include - -#include "TFEL/Tests/TestCase.hxx" -#include "TFEL/Tests/TestProxy.hxx" -#include "TFEL/Tests/TestManager.hxx" -#include "TFEL/Metaprogramming/IsConstCallable.hxx" -#include "TFEL/Metaprogramming/ResultOf.hxx" - -struct ConstCallableType { - void operator()(double) const; -}; - -struct IsConstCallableTest final : public tfel::tests::TestCase { - IsConstCallableTest() - : tfel::tests::TestCase("TFEL/Math", "IsConstCallableTest") { - } // end of IsConstCallableTest - tfel::tests::TestResult execute() override { - using namespace tfel::meta; - TFEL_TESTS_STATIC_ASSERT((!IsConstCallable::cond)); - TFEL_TESTS_STATIC_ASSERT( - (IsConstCallable::cond)); - TFEL_TESTS_STATIC_ASSERT((IsConstCallable::cond)); - TFEL_TESTS_STATIC_ASSERT( - (!IsConstCallable::cond)); - TFEL_TESTS_STATIC_ASSERT(( - std::is_same::type, InvalidType>::value)); - TFEL_TESTS_STATIC_ASSERT( - (std::is_same::type, void>::value)); - return this->result; - } // end of execute -}; - -TFEL_TESTS_GENERATE_PROXY(IsConstCallableTest, "IsConstCallableTest"); - -/* coverity [UNCAUGHT_EXCEPT]*/ -int main() { - auto& m = tfel::tests::TestManager::getTestManager(); - m.addTestOutput(std::cout); - m.addXMLTestOutput("ResultOf.xml"); - return m.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE; -} // end of main diff --git a/tests/MetaProgramming/ResultOf.cxx b/tests/MetaProgramming/ResultOf.cxx deleted file mode 100644 index eb38564ed..000000000 --- a/tests/MetaProgramming/ResultOf.cxx +++ /dev/null @@ -1,70 +0,0 @@ -/*! - * \file ResultOf.cxx - * \brief - * \author Thomas Helfer - * \date 28 août 2015 - * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights - * reserved. - * This project is publicly released under either the GNU GPL Licence with - * linking exception or the CECILL-A licence. A copy of thoses licences are - * delivered with the sources of TFEL. CEA or EDF may also distribute this - * project under specific licensing conditions. - */ - -#include -#include -#include -#include -#include - -#include "TFEL/Tests/TestCase.hxx" -#include "TFEL/Tests/TestProxy.hxx" -#include "TFEL/Tests/TestManager.hxx" - -#include "TFEL/Metaprogramming/ResultOf.hxx" -#include "TFEL/Math/tvector.hxx" -#include "TFEL/Math/tmatrix.hxx" - -struct F { - double operator()(const double) const; - int operator()(const double, const double) const; -}; - -struct ResultOfTest final : public tfel::tests::TestCase { - ResultOfTest() - : tfel::tests::TestCase("TFEL/Math", "ResultOfTest") { - } // end of ResultOfTest - tfel::tests::TestResult execute() override { - using namespace tfel::meta; - using namespace tfel::math; - using my_vector = tvector<1u, double>; - using handler1 = BinaryOperationHandler; - using handler2 = - BinaryOperationHandler; - TFEL_TESTS_ASSERT((std::is_same::type>::value)); - TFEL_TESTS_ASSERT( - (std::is_same::type>::value)); - TFEL_TESTS_ASSERT( - (std::is_same::type>::value)); - TFEL_TESTS_ASSERT( - (std::is_same::type>::value)); - TFEL_TESTS_ASSERT(( - std::is_same::type>::value)); - TFEL_TESTS_ASSERT( - (std::is_same::type>::value)); - return this->result; - } // end of execute -}; - -TFEL_TESTS_GENERATE_PROXY(ResultOfTest, "ResultOfTest"); - -/* coverity [UNCAUGHT_EXCEPT]*/ -int main() { - auto& manager = tfel::tests::TestManager::getTestManager(); - manager.addTestOutput(std::cout); - manager.addXMLTestOutput("ResultOf.xml"); - return manager.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE; -} // end of main diff --git a/tests/MetaProgramming/typelist2.cxx b/tests/MetaProgramming/typelist2.cxx index 07de25fd9..621077910 100644 --- a/tests/MetaProgramming/typelist2.cxx +++ b/tests/MetaProgramming/typelist2.cxx @@ -48,9 +48,8 @@ class generic_container : public generic_container_ { public: template - typename std::enable_if<(N < tfel::meta::TLSize::value), - typename tfel::meta::TLFindNthElt::type>::type - get() const { + typename tfel::meta::TLFindNthElt::type get() const + requires(N < tfel::meta::TLSize::value) { return static_cast< const holder::type>*>( this) @@ -58,8 +57,8 @@ class generic_container : public generic_container_ { } template - typename std::enable_if<(N < tfel::meta::TLSize::value), void>::type set( - const typename tfel::meta::TLFindNthElt::type& src) { + void set(const typename tfel::meta::TLFindNthElt::type& src) requires( + N < tfel::meta::TLSize::value) { static_cast::type>*>(this) ->set(src); }