diff --git a/src/scion/integration/FirstMomentLinearLinear.hpp b/src/scion/integration/FirstMomentLinearLinear.hpp new file mode 100644 index 0000000..22af260 --- /dev/null +++ b/src/scion/integration/FirstMomentLinearLinear.hpp @@ -0,0 +1,58 @@ +#ifndef NJOY_SCION_INTEGRATION_LINEARLINEAR +#define NJOY_SCION_INTEGRATION_LINEARLINEAR + +// system includes + +// other includes +#include "scion/integration/IntegratorBase.hpp" + +namespace njoy { +namespace scion { +namespace integration { + + /** + * @class + * @brief First raw moment of a Linear-linear panel (y is linear in x) + * + * The first raw moment or mean is defined as the integral of x * f(x) + */ + class FirstMomentLinearLinear : public IntegratorBase< FirstMomentLinearLinear > { + + /* friend declarations */ + friend class IntegratorBase< FirstMomentLinearLinear >; + + /* interface implementation functions */ + + /** + * @brief Perform first raw moment integration of a linear-linear panel (y is linear in x) + * + * @param[in] xLeft the left value on the x interval + * @param[in] xRight the right value on the x interval + * @param[in] yLeft the left value on the y interval + * @param[in] yRight the right value on the y interval + */ + template < typename X, typename Y, + typename I = decltype( std::declval< X >() * std::declval< X >() * std::declval< Y >() ) > + I integrate( const X& xLeft, const X& xRight, + const Y& yLeft, const Y& yRight ) const noexcept { + + auto delta = ( xRight - xLeft ); + auto slope = ( yRight - yLeft ) / delta / 3.; + auto constant = 0.5 * ( xRight * yLeft - xLeft * yRight ) / delta; + return xRight * xRight * ( slope * xRight + constant ) + - xLeft * xLeft * ( slope * yLeft + constant ); + } + + public: + + using IntegratorBase::operator(); + }; + + // integration function + static constexpr FirstMomentLinearLinear firstMomentLinLin; + +} // integration namespace +} // scion namespace +} // njoy namespace + +#endif diff --git a/src/scion/integration/FirstMomentLinearLinear/test/CMakeLists.txt b/src/scion/integration/FirstMomentLinearLinear/test/CMakeLists.txt new file mode 100644 index 0000000..afa78c6 --- /dev/null +++ b/src/scion/integration/FirstMomentLinearLinear/test/CMakeLists.txt @@ -0,0 +1 @@ +add_cpp_test( integration.FirstMomentLinearLinear FirstMomentLinearLinear.test.cpp ) diff --git a/src/scion/integration/FirstMomentLinearLinear/test/FirstMomentLinearLinear.test.cpp b/src/scion/integration/FirstMomentLinearLinear/test/FirstMomentLinearLinear.test.cpp new file mode 100644 index 0000000..4ea61f7 --- /dev/null +++ b/src/scion/integration/FirstMomentLinearLinear/test/FirstMomentLinearLinear.test.cpp @@ -0,0 +1,57 @@ +// include Catch2 +#include +#include +using Catch::Matchers::WithinRel; + +// what we are testing +#include "scion/integration/FirstMomentLinearLinear.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::scion; + +SCENARIO( "MeanLinearLinear" ) { + + GIVEN( "MeanLinearLinear integration object" ) { + + WHEN( "integrating an interval" ) { + + integration::FirstMomentLinearLinear integrator{}; + + THEN( "the integration is performed correctly" ) { + + double xLeft = 1.0; + double xRight = 2.0; + double yLeft = 1.0; + double yRight = 4.0; + + // both y values are the same + CHECK_THAT( 1.5, WithinRel( integrator( xLeft, xRight, yLeft, yLeft ) ) ); + + // the y values are different + CHECK_THAT( 4.0, WithinRel( integrator( xLeft, xRight, yLeft, yRight ) ) ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "linlin integration function" ) { + + WHEN( "integrating an interval" ) { + + THEN( "the integration is performed correctly" ) { + + double xLeft = 1.0; + double xRight = 2.0; + double yLeft = 1.0; + double yRight = 4.0; + + // both y values are the same + CHECK_THAT( 1.5, WithinRel( integration::firstMomentLinLin( xLeft, xRight, yLeft, yLeft ) ) ); + + // the y values are different + CHECK_THAT( 4.0, WithinRel( integration::firstMomentLinLin( xLeft, xRight, yLeft, yRight ) ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO