// Copyright (c) 2025 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _MathInteg_Set_HeaderFile #define _MathInteg_Set_HeaderFile #include "MathUtils_Types.hxx" #include "MathUtils_Config.hxx" #include "math_Vector.hxx" #include "MathUtils_GaussKronrodWeights.hxx" #include namespace MathInteg { using namespace MathUtils; //! Result for vector function integration. struct SetResult { MathUtils::Status Status = MathUtils::Status::NotConverged; std::optional Values; //!< Integral of each component int NbEquations = 0; bool IsDone() const { return Status == MathUtils::Status::OK; } explicit operator bool() const { return IsDone(); } }; //! Gauss-Legendre integration of a vector-valued function. //! //! Integrates F: R -> R^N over interval [Lower, Upper]: //! Result[i] = integral_{Lower}^{Upper} F_i(x) dx //! //! Uses Gauss-Legendre quadrature applied to each component. //! //! Note: Only 1D input is supported (M=1). Multi-dimensional input //! is not implemented in the legacy API. //! //! @tparam Func function type with: //! - int NbEquations() - number of output components //! - bool Value(const math_Vector& theX, math_Vector& theF) //! @param theFunc vector-valued function to integrate //! @param theLower lower bound //! @param theUpper upper bound //! @param theOrder integration order (max 61) //! @return SetResult containing vector of integrals template SetResult GaussSet(Func& theFunc, double theLower, double theUpper, int theOrder) { SetResult aResult; // Get function dimensions const int aNbEqua = theFunc.NbEquations(); if (aNbEqua <= 0) { aResult.Status = Status::InvalidInput; return aResult; } aResult.NbEquations = aNbEqua; // Clamp order int aOrder = std::min(theOrder, 61); aOrder = std::max(aOrder, 1); // Get Gauss points and weights math_Vector aGP(1, aOrder); math_Vector aGW(1, aOrder); if (!GetOrderedGaussPointsAndWeights(aOrder, aGP, aGW)) { aResult.Status = Status::InvalidInput; return aResult; } math_Vector aPoints(0, aOrder - 1); math_Vector aWeights(0, aOrder - 1); for (int i = 0; i < aOrder; ++i) { aPoints(i) = aGP(i + 1); aWeights(i) = aGW(i + 1); } // Coordinate transformation const double aXm = 0.5 * (theLower + theUpper); const double aXr = 0.5 * (theUpper - theLower); // Initialize result vector math_Vector aVal(1, aNbEqua, 0.0); math_Vector aTval(1, 1); // Input vector (1D) math_Vector aFVal1(1, aNbEqua); math_Vector aFVal2(1, aNbEqua); const int aInd = aOrder / 2; const int aInd1 = (aOrder + 1) / 2; // Handle odd order case (middle point) if (aInd1 > aInd) { aTval(1) = aXm; if (!theFunc.Value(aTval, aVal)) { aResult.Status = Status::NotConverged; return aResult; } for (int j = 1; j <= aNbEqua; ++j) { aVal(j) *= aWeights(aInd1 - 1); } } // Symmetric Gauss quadrature for (int i = 0; i < aInd; ++i) { aTval(1) = aXm + aXr * aPoints(i); if (!theFunc.Value(aTval, aFVal1)) { aResult.Status = Status::NotConverged; return aResult; } aTval(1) = aXm - aXr * aPoints(i); if (!theFunc.Value(aTval, aFVal2)) { aResult.Status = Status::NotConverged; return aResult; } for (int j = 1; j <= aNbEqua; ++j) { aVal(j) += (aFVal1(j) + aFVal2(j)) * aWeights(i); } } // Scale by half-width for (int j = 1; j <= aNbEqua; ++j) { aVal(j) *= aXr; } aResult.Values = aVal; aResult.Status = Status::OK; return aResult; } //! Gauss-Legendre integration of vector function using math_Vector bounds. //! //! Convenience overload that extracts scalar bounds from math_Vector. //! //! @tparam Func function type //! @param theFunc vector-valued function //! @param theLower lower bound vector (only first element used) //! @param theUpper upper bound vector (only first element used) //! @param theOrder integration order //! @return SetResult containing vector of integrals template SetResult GaussSet(Func& theFunc, const math_Vector& theLower, const math_Vector& theUpper, int theOrder) { return GaussSet(theFunc, theLower(theLower.Lower()), theUpper(theUpper.Lower()), theOrder); } } // namespace MathInteg #endif // _MathInteg_Set_HeaderFile