Page MenuHomec4science

tests.cc
No OneTemporary

File Metadata

Created
Sat, May 18, 23:56

tests.cc

/**
* @file
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2018 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Expolit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Expolit is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Expolit. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <expolit>
#include <complex>
#include <gtest/gtest.h>
using namespace expolit;
static constexpr Polynomial<Int, 1> Zi({0, 1});
static constexpr Polynomial<std::complex<Real>, 1> Zc({0, 1});
static constexpr Polynomial<Real, 1> Zr({0, 1});
using lin = std::remove_cv_t<decltype(Zr)>;
template <typename T, UInt order, typename CT>
constexpr void compare(const Polynomial<T, order, CT>& p1,
const Polynomial<T, order, CT>& p2) {
for (UInt i = 0; i < p1.terms; ++i)
ASSERT_NEAR(std::abs(p1.coeffs[i] - p2.coeffs[i]), 0, 1e-14)
<< "Polynomials are not equal (i = " << i << ")";
}
template <typename T, UInt order>
constexpr void compare(const Polynomial<T, order, Int>& p1,
const Polynomial<T, order, Int>& p2) {
for (UInt i = 0; i < p1.terms; ++i)
ASSERT_EQ(p1.coeffs[i], p2.coeffs[i])
<< "Polynomials are not equal (i = " << i << ")";
}
TEST(Polynomial, initialization) {
constexpr auto p = 1 + 2 * Zi * Zi + Zi * Zi * Zi;
constexpr Int z = 3;
constexpr Int res = p(z);
ASSERT_EQ(1 + 2 * z * z + z * z * z, res) << "Bad coefficients";
// This guy cannot be consexpr because std::complex is stupid
auto p2 = 1. + Zc * Zc;
std::complex<Real> z2(0, 1);
ASSERT_NEAR(std::abs(p2(z2)), 0, 1e-14) << "Bad coefficents (complex)";
}
TEST(Polynomial, sum) {
constexpr auto p = 1 + 2 * Zi * Zi + Zi * Zi * Zi;
constexpr auto p2 = Zi + 2 * Zi * Zi;
constexpr auto res = 1 + Zi + 4 * Zi * Zi + Zi * Zi * Zi;
compare(p + p2, res);
}
TEST(Polynomial, product) {
constexpr auto p = 1 + 2 * Zi * Zi + Zi * Zi * Zi;
constexpr auto p2 = Zi + 2 * Zi * Zi;
constexpr auto res = Zi + 2 * Zi * Zi + 2 * Zi * Zi * Zi +
5 * Zi * Zi * Zi * Zi + 2 * Zi * Zi * Zi * Zi * Zi;
compare(p * p2, res);
}
TEST(Polynomial, derivative) {
constexpr auto p = 1 + 2 * Zi * Zi + Zi * Zi * Zi;
constexpr auto res = 4 * Zi + 3 * Zi * Zi;
compare(differentiate(p), res);
}
TEST(Polynomial, integration) {
constexpr auto p = 1. + 2. * Zr * Zr + Zr * Zr * Zr;
constexpr auto res = Zr + 2 / 3. * Zr * Zr * Zr + 1 / 4. * Zr * Zr * Zr * Zr;
compare(integrate(p), res);
}
TEST(Exponential, evaluation) {
constexpr auto p = 2. * Zr;
constexpr Exponential<lin> e(p);
constexpr Real z = 3.4;
const Real res = e(z); // cannot be constexpr because of exponential
ASSERT_NEAR(std::exp(2 * z), res, 1e-14) << "Exponential evaluation fail";
}
TEST(Exponential, derivative) {
constexpr Exponential<lin> e(2. * Zr);
constexpr auto diff = differentiate(e);
constexpr auto res = Constant<Real>({2}) * e;
compare(res.operands.first, diff.operands.first);
compare(e.expression, diff.operands.second.expression);
}
TEST(Exponential, integration) {
constexpr Exponential<lin> e(2. * Zr);
constexpr auto integ = integrate(e);
constexpr auto res = Constant<Real>({1 / 2.}) * e;
compare(res.operands.first, integ.operands.first);
compare(e.expression, integ.operands.second.expression);
}
TEST(Integration, parts) {
constexpr Exponential<lin> e(2. * Zr);
constexpr auto expr = e * (2. * Zr);
constexpr auto res = Zr * e - Constant<Real>({1 / 2.}) * e;
constexpr auto integ = integrate(expr);
compare(integ.operands.first.operands.first,
res.operands.first.operands.first);
compare(integ.operands.second.operands.first,
res.operands.second.operands.first);
}
TEST(Integration, definite_integral) {
constexpr auto p = Zr;
constexpr std::pair<Real, Real> bounds(0, 1);
constexpr auto res = definite_integral(bounds, p);
ASSERT_NEAR(0.5, res, 1e-14) << "Definite integral fail";
}

Event Timeline