Page MenuHomec4science

testAdamsMoulton.cpp
No OneTemporary

File Metadata

Created
Tue, Jun 11, 21:28

testAdamsMoulton.cpp

# include <gtest/gtest.h>
# include <cmath>
# include <cassert>
#include <fstream>
# include <exception>
#include "../ODElibrary/AdamsMoulton.h"
// Function g(t) for testing
Eigen::VectorXd ForcedOscillations(double t){
Eigen::VectorXd s(2);
s[0] = 0;
s[1] = sin(2*M_PI*t); // derivative of velocity
return s;
};
// Fixture class
class AdamsMoultonSolverTest : public ::testing::Test {
protected:
void SetUp() override {
// create a solver
solver.setInitialTime(-3);
Eigen::VectorXd y0(2); // set the spring at rest
y0[0] = 0;
y0[1] = 0;
double k = 0.1; // spring constant
Eigen::MatrixXd m(2,2); // from spring equation
m(0,0)=0;
m(0,1)=1;
m(1,0)=-k;
m(1,1)=0.3;
solver.setInitialTime(0.);
solver.setFinalTime(1.);
solver.setNumberOfSteps(100);
solver.setStepsAlgo(2);
solver.setRightHandSide(m, ForcedOscillations);
solver.setInitialValue(y0);
}
void TearDown() override {
// clear particles
// solver;
}
AdamsMoulton solver;
double yFinal0Exact = 0.182532458;
double yFinal1Exact = 0.046017418;
};
// tests that we can assign and read a positive initial time
TEST_F(AdamsMoultonSolverTest, initialAndFinalTimes) {
solver.setInitialTime(0.5);
EXPECT_EQ(solver.getInitialTime(), 0.5);
solver.setFinalTime(4.2);
EXPECT_EQ(solver.getFinalTime(), 4.2);
}
// tests that we can assign and read a positive timestep
TEST_F(AdamsMoultonSolverTest, positiveTimestep) {
solver.setStepSize(0.3);
EXPECT_EQ(solver.getStepSize(), 0.3);
}
// tests we cannot assign a 0 or negative timestep
TEST_F(AdamsMoultonSolverTest, nonPositiveTimestep) {
ASSERT_THROW(solver.setStepSize(-0.1), std::domain_error);
ASSERT_THROW(solver.setStepSize(0), std::domain_error);
}
// tests we cannot assign a different size inputs for the initial value
TEST_F(AdamsMoultonSolverTest, differentSizedInitialValue) {
Eigen::VectorXd yTooLong(3);
ASSERT_THROW(solver.setInitialValue(yTooLong), std::length_error);
}
// tests we cannot assign a different size inputs for the rhs matrix
TEST_F(AdamsMoultonSolverTest, differentSizedRHS) {
Eigen::MatrixXd mFalse1(2,3);
Eigen::MatrixXd mFalse2(1,2);
Eigen::MatrixXd mFalse3(3,3);
ASSERT_THROW(solver.setRightHandSide(mFalse1, ForcedOscillations), std::length_error);
ASSERT_THROW(solver.setRightHandSide(mFalse2, ForcedOscillations), std::length_error);
ASSERT_THROW(solver.setRightHandSide(mFalse3, ForcedOscillations), std::length_error);
}
// tests we cannot assign a rhs function
Eigen::VectorXd RHSgTooLong(double t){
Eigen::VectorXd s(4);
return s;
};
Eigen::VectorXd RHSgThrowingException(double t){
Eigen::VectorXd s(2);
throw std::exception();
return s;
};
Eigen::VectorXd RHSgThrowingInteger(double t){
Eigen::VectorXd s(2);
throw 42;
return s;
};
TEST_F(AdamsMoultonSolverTest, timeDependentRHSFunction) {
Eigen::MatrixXd m(2,2);
ASSERT_THROW(solver.setRightHandSide(m, RHSgTooLong), std::length_error);
ASSERT_THROW(solver.setRightHandSide(m, RHSgThrowingException), std::runtime_error);
ASSERT_THROW(solver.setRightHandSide(m, RHSgThrowingInteger), std::runtime_error);
}
TEST_F(AdamsMoultonSolverTest, testSolve) {
for(int s=1;s<=4;s++) {
solver.setStepsAlgo(s);
Eigen::MatrixXd m(2,2); // from spring equation
m(0,0)=0;
m(0,1)=1;
m(1,0)=-0.1;
m(1,1)=0.3;
solver.setRightHandSide(m, ForcedOscillations);
// writes the output to the file
std::ofstream testFile;
testFile.open("AMSolverTest.dat");
assert(testFile.is_open());
solver.solve(testFile);
testFile.close();
// read the file where the output is
std::ifstream readFile("AMSolverTest.dat");
assert(readFile.is_open());
double t = 0, x = 0, y = 0;
int i = 0;
while (!readFile.eof()) {
readFile >> t >> x >> y;
i++;
}
readFile.close();
// check the value are close enough to the specified values
//std::cout << t << " " << x << " " << y << " " << i;
ASSERT_NEAR(x, yFinal0Exact, 2e-2);
ASSERT_NEAR(y, yFinal1Exact, 2e-2);
}
}

Event Timeline