first commit

This commit is contained in:
Your Name
2022-10-20 20:29:11 +08:00
commit 4d531f8044
3238 changed files with 1387862 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
set(TESTSUITE_SOURCES
${TESTSUITE_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/TestSuite.cxx
${CMAKE_CURRENT_SOURCE_DIR}/test_ls_matrix.cxx
${CMAKE_CURRENT_SOURCE_DIR}/testAeroElement.cxx
${CMAKE_CURRENT_SOURCE_DIR}/testYASimAtmosphere.cxx
${CMAKE_CURRENT_SOURCE_DIR}/testYASimGear.cxx
PARENT_SCOPE
)
set(TESTSUITE_HEADERS
${TESTSUITE_HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/test_ls_matrix.hxx
${CMAKE_CURRENT_SOURCE_DIR}/testAeroElement.hxx
${CMAKE_CURRENT_SOURCE_DIR}/testYASimAtmosphere.hxx
${CMAKE_CURRENT_SOURCE_DIR}/testYASimGear.hxx
PARENT_SCOPE
)

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2018 Edward d'Auvergne
*
* This file is part of the program FlightGear.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "test_ls_matrix.hxx"
#include "testAeroElement.hxx"
#include "testYASimAtmosphere.hxx"
#include "testYASimGear.hxx"
// Set up the unit tests.
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AeroElementTests, "Unit tests");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LaRCSimMatrixTests, "Unit tests");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(YASimAtmosphereTests, "Unit tests");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(YASimGearTests, "Unit tests");

View File

@@ -0,0 +1,134 @@
#include <simgear/constants.h>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGVec3.hxx>
#include "FDM/AIWake/AeroElement.hxx"
#include "testAeroElement.hxx"
void AeroElementTests::testNormal()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d n = el->getNormal();
CPPUNIT_ASSERT_DOUBLES_EQUAL(n[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(n[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(n[2], -1.0, 1e-9);
}
void AeroElementTests::testCollocationPoint()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d cp = el->getCollocationPoint();
CPPUNIT_ASSERT_DOUBLES_EQUAL(cp[0], -0.75, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(cp[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(cp[2], 0.0, 1e-9);
}
void AeroElementTests::testBoundVortexMidPoint()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
CPPUNIT_ASSERT_DOUBLES_EQUAL(mp[0], -0.25, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(mp[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(mp[2], 0.0, 1e-9);
}
void AeroElementTests::testBoundVortex()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d v = el->getBoundVortex();
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 1.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], 0.0, 1e-9);
}
void AeroElementTests::testInducedVelocityOnBoundVortex()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
SGVec3d v = el->getInducedVelocity(mp);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], 1.0/M_PI, 1e-9);
}
void AeroElementTests::testInducedVelocityOnCollocationPoint()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d cp = el->getCollocationPoint();
SGVec3d v = el->getInducedVelocity(cp);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], (1.0+sqrt(2.0)/M_PI), 1e-9);
}
void AeroElementTests::testInducedVelocityAtFarField()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
SGVec3d v = el->getInducedVelocity(mp+SGVec3d(-1000.,0.,0.));
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], 2.0/M_PI, 1e-7);
}
void AeroElementTests::testInducedVelocityAbove()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
SGVec3d v = el->getInducedVelocity(mp+SGVec3d(0.,0.,-0.5));
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], -1.0/(sqrt(2.0)*M_PI), 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], 0.5/M_PI, 1e-9);
}
void AeroElementTests::testInducedVelocityAboveWithOffset()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
SGVec3d v = el->getInducedVelocity(mp+SGVec3d(0.0, 0.5, -1.0));
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], -1.0/(4.0*M_PI*sqrt(2.0)), 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], -0.125/M_PI, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], 0.125/M_PI, 1e-9);
}
void AeroElementTests::testInducedVelocityUpstream()
{
AeroElement_ptr el = new AeroElement(SGVec3d(-1., -0.5, 0.),
SGVec3d(0., -0.5, 0.),
SGVec3d(0., 0.5, 0.),
SGVec3d(-1., 0.5, 0.));
SGVec3d mp = el->getBoundVortexMidPoint();
SGVec3d v = el->getInducedVelocity(mp+SGVec3d(0.5, 0.0, 0.0));
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[1], 0.0, 1e-9);
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[2], (1.0-sqrt(2.0))/M_PI, 1e-9);
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2018 Edward d'Auvergne
*
* This file is part of the program FlightGear.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FG_AERO_ELEMENT_UNIT_TESTS_HXX
#define _FG_AERO_ELEMENT_UNIT_TESTS_HXX
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
// The unit tests.
class AeroElementTests : public CppUnit::TestFixture
{
// Set up the test suite.
CPPUNIT_TEST_SUITE(AeroElementTests);
CPPUNIT_TEST(testBoundVortex);
CPPUNIT_TEST(testBoundVortexMidPoint);
CPPUNIT_TEST(testCollocationPoint);
CPPUNIT_TEST(testInducedVelocityAbove);
CPPUNIT_TEST(testInducedVelocityAboveWithOffset);
CPPUNIT_TEST(testInducedVelocityAtFarField);
CPPUNIT_TEST(testInducedVelocityOnBoundVortex);
//CPPUNIT_TEST(testInducedVelocityOnCollocationPoint); // Not run in the original ctest.
CPPUNIT_TEST(testInducedVelocityUpstream);
CPPUNIT_TEST(testNormal);
CPPUNIT_TEST_SUITE_END();
public:
// Set up function for each test.
void setUp() {}
// Clean up after each test.
void tearDown() {}
// The tests.
void testBoundVortex();
void testBoundVortexMidPoint();
void testCollocationPoint();
void testInducedVelocityAbove();
void testInducedVelocityAboveWithOffset();
void testInducedVelocityAtFarField();
void testInducedVelocityOnBoundVortex();
void testInducedVelocityOnCollocationPoint();
void testInducedVelocityUpstream();
void testNormal();
};
#endif // _FG_AERO_ELEMENT_UNIT_TESTS_HXX

View File

@@ -0,0 +1,44 @@
#include "test_suite/FGTestApi/PrivateAccessorFDM.hxx"
#include "testYASimAtmosphere.hxx"
#include <FDM/YASim/Math.hpp>
#include <simgear/debug/logstream.hxx>
using namespace yasim;
void YASimAtmosphereTests::setUp()
{
a.reset(new Atmosphere());
}
void YASimAtmosphereTests::tearDown()
{
a.reset();
}
void YASimAtmosphereTests::testAtmosphere()
{
auto accessor = FGTestApi::PrivateAccessor::FDM::Accessor();
int numColumns = accessor.read_FDM_YASim_Atmosphere_numColumns(a);
int maxTableIndex = a->maxTableIndex();
int rows = maxTableIndex + 1;
const float maxDeviation = 0.0002f;
SG_LOG(SG_GENERAL, SG_INFO, "Columns = " << numColumns);
SG_LOG(SG_GENERAL, SG_INFO, "Rows = " << rows);
for (int alt = 0; alt <= maxTableIndex; alt++) {
float density = a->calcStdDensity(accessor.read_FDM_YASim_Atmosphere_data(a, alt, a->PRESSURE), accessor.read_FDM_YASim_Atmosphere_data(a, alt, a->TEMPERATURE));
float delta = accessor.read_FDM_YASim_Atmosphere_data(a, alt, a->DENSITY) - density;
SG_LOG(SG_GENERAL, SG_INFO, "alt: " << alt << ", delta: " << delta);
if (Math::abs(delta) > maxDeviation)
CPPUNIT_FAIL("Deviation above limit of 0.0002");
}
SG_LOG(SG_GENERAL, SG_INFO, "Deviation below " << maxDeviation << " for all rows.");
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2018 Edward d'Auvergne
*
* This file is part of the program FlightGear.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FG_YASIM_ATMOSPHERE_UNIT_TESTS_HXX
#define _FG_YASIM_ATMOSPHERE_UNIT_TESTS_HXX
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <src/FDM/YASim/Atmosphere.hpp>
// The unit tests.
class YASimAtmosphereTests : public CppUnit::TestFixture
{
// Set up the test suite.
CPPUNIT_TEST_SUITE(YASimAtmosphereTests);
CPPUNIT_TEST(testAtmosphere);
CPPUNIT_TEST_SUITE_END();
public:
// Set up function for each test.
void setUp();
// Clean up after each test.
void tearDown();
// The tests.
void testAtmosphere();
// Data.
std::unique_ptr<yasim::Atmosphere> a;
};
#endif // _FG_YASIM_ATMOSPHERE_UNIT_TESTS_HXX

View File

@@ -0,0 +1,128 @@
#include "testYASimGear.hxx"
#include "test_suite/FGTestApi/testGlobals.hxx"
#include "FDM/YASim/Gear.hpp"
#include <simgear/debug/logstream.hxx>
#include <sstream>
void YASimGearTests::setUp()
{
FGTestApi::setUp::initTestGlobals("");
}
void YASimGearTests::tearDown()
{
FGTestApi::tearDown::shutdownTestGlobals();
}
void YASimGearTests::test()
{
/* Check we get expected values for a particular set of inputs. */
float ground[4] = { -0.22097, 0.00507429, -0.975263, 2.35943};
float wheel_pos[3] = { -0.953044, 2.20823, -2.00883};
yasim::GearVector wheel_axle( -0, 0.16383, -0.114715);
float wheel_radius = 0.261257;
float tyre_radius = 0.130629;
yasim::GearVector compression( -0.139389, -0, 0.480178);
float contact[3];
float compress_distance_vertical;
float compress_norm;
bool on_ground = yasim::gearCompression(
ground,
compression,
wheel_pos,
wheel_axle,
wheel_radius,
tyre_radius,
[] () { return 0; },
/* output params: */
contact,
compress_distance_vertical,
compress_norm
);
SG_LOG( SG_GENERAL, SG_ALERT, "on_ground=" << on_ground);
SG_LOG( SG_GENERAL, SG_ALERT, "contact=(" << contact[0] << ", " << contact[1] << ", " << contact[1] << ")");
SG_LOG( SG_GENERAL, SG_ALERT, "compress_distance_vertical=" << compress_distance_vertical);
SG_LOG( SG_GENERAL, SG_ALERT, "compress_norm=" << compress_norm);
double e = 0.0001;
CPPUNIT_ASSERT( on_ground);
CPPUNIT_ASSERT_DOUBLES_EQUAL( -1.1053, contact[0], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0645, contact[1], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( -2.1581, contact[2], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.167955, compress_distance_vertical, e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.383887, compress_norm, e);
/* Now check we get same results as old point-contact algorithm, when using
wheel_radius=0 and tyre_radius=0. */
/* For this test we set gear contact point to bottom of what was the wheel,
so that it will be approximately in same position as earlier contact point,
and so slightly underground. */
wheel_pos[2] -= wheel_radius + tyre_radius;
float bump_altitude_override = 0.1;
on_ground = yasim::gearCompression(
ground,
compression,
wheel_pos /* contact point. */,
wheel_axle /* values don't matter. */,
0 /*wheel_radius*/,
0 /*tyre_radius*/,
[bump_altitude_override] () { return bump_altitude_override; },
/* output params: */
contact,
compress_distance_vertical,
compress_norm
);
float contact_old[3];
float compress_distance_vertical_old;
float compress_norm_old;
bool on_ground_old = yasim::gearCompressionOld(
ground,
compression,
wheel_pos /* contact point. */,
[bump_altitude_override] () { return bump_altitude_override; },
/* output params: */
contact_old,
compress_distance_vertical_old,
compress_norm_old
);
SG_LOG( SG_GENERAL, SG_ALERT, "comparing with old algorithm.");
SG_LOG( SG_GENERAL, SG_ALERT, "old:");
SG_LOG( SG_GENERAL, SG_ALERT, " on_ground_old=" << on_ground_old);
SG_LOG( SG_GENERAL, SG_ALERT, " contact=(" << contact_old[0] << ", " << contact_old[1] << ", " << contact_old[1] << ")");
SG_LOG( SG_GENERAL, SG_ALERT, " compress_distance_vertical=" << compress_distance_vertical_old);
SG_LOG( SG_GENERAL, SG_ALERT, " compress_norm=" << compress_norm_old);
SG_LOG( SG_GENERAL, SG_ALERT, "new:");
SG_LOG( SG_GENERAL, SG_ALERT, " on_ground=" << on_ground);
SG_LOG( SG_GENERAL, SG_ALERT, " contact=(" << contact[0] << ", " << contact[1] << ", " << contact[1] << ")");
SG_LOG( SG_GENERAL, SG_ALERT, " compress_distance_vertical=" << compress_distance_vertical);
SG_LOG( SG_GENERAL, SG_ALERT, " compress_norm=" << compress_norm);
CPPUNIT_ASSERT( on_ground);
CPPUNIT_ASSERT_EQUAL( on_ground_old, on_ground);
CPPUNIT_ASSERT_DOUBLES_EQUAL( contact_old[0], contact[0], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( contact_old[1], contact[1], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( contact_old[2], contact[2], e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( compress_distance_vertical_old, compress_distance_vertical, e);
CPPUNIT_ASSERT_DOUBLES_EQUAL( compress_norm_old, compress_norm, e);
}

View File

@@ -0,0 +1,15 @@
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
struct YASimGearTests : CppUnit::TestFixture
{
void setUp();
void tearDown();
void test();
CPPUNIT_TEST_SUITE(YASimGearTests);
CPPUNIT_TEST(test);
CPPUNIT_TEST_SUITE_END();
};

View File

@@ -0,0 +1,155 @@
#include "test_ls_matrix.hxx"
#include <simgear/constants.h>
#include <simgear/misc/test_macros.hxx>
extern "C" {
#include "src/FDM/LaRCsim/ls_matrix.h"
}
void LaRCSimMatrixTests::testCopyMatrix()
{
int nelm = 20;
double **src = nr_matrix(1, nelm, 1, nelm);
double **dest = nr_matrix(1, nelm, 1, nelm);
double invmaxlong = 1.0/(double)RAND_MAX;
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
src[i][j] = 2.0 - 4.0*invmaxlong*(double) rand();
nr_copymat(src, nelm, dest);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
CPPUNIT_ASSERT_EQUAL(src[i][j], dest[i][j]);
nr_free_matrix(src, 1, nelm, 1, nelm);
nr_free_matrix(dest, 1, nelm, 1, nelm);
}
void LaRCSimMatrixTests::testIdentityMatrix()
{
int nelm = 10;
double **id = nr_matrix(1, nelm, 1, nelm);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
id[i][j] = i == j ? 1.0 : 0.0;
nr_gaussj(id, nelm, 0, 0);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
CPPUNIT_ASSERT_DOUBLES_EQUAL(id[i][j], i == j ? 1.0 : 0.0, 1e-9);
nr_free_matrix(id, 1, nelm, 1, nelm);
}
void LaRCSimMatrixTests::testOrthogonalMatrix()
{
int nelm = 3;
double **m = nr_matrix(1, nelm, 1, nelm);
double **inv = nr_matrix(1, nelm, 1, nelm);
double angle = M_PI/3.0;
m[1][1] = cos(angle);
m[1][2] = sin(angle);
m[1][3] = 0.0;
m[2][1] = -m[1][2];
m[2][2] = m[1][1];
m[2][3] = 0.0;
m[3][1] = 0.0;
m[3][2] = 0.0;
m[3][3] = 1.0;
nr_copymat(m, nelm, inv);
nr_gaussj(inv, nelm, 0, 0);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
CPPUNIT_ASSERT_DOUBLES_EQUAL(m[i][j], inv[j][i], 1e-9);
nr_free_matrix(m, 1, nelm, 1, nelm);
nr_free_matrix(inv, 1, nelm, 1, nelm);
}
void LaRCSimMatrixTests::testRandomMatrix()
{
int nelm = 20;
double **src = nr_matrix(1, nelm, 1, nelm);
double **inv = nr_matrix(1, nelm, 1, nelm);
double **id = nr_matrix(1, nelm, 1, nelm);
double invmaxlong = 1.0/(double)RAND_MAX;
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
src[i][j] = 2.0 - 4.0*invmaxlong*(double) rand();
nr_copymat(src, nelm, inv);
nr_gaussj(inv, nelm, 0, 0);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j) {
id[i][j] = 0.0;
for (int k=1; k<=nelm; ++k)
id[i][j] += src[i][k]*inv[k][j];
}
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
CPPUNIT_ASSERT_DOUBLES_EQUAL(id[i][j], i == j ? 1.0 : 0.0, 1e-9);
nr_free_matrix(src, 1, nelm, 1, nelm);
nr_free_matrix(inv, 1, nelm, 1, nelm);
nr_free_matrix(id, 1, nelm, 1, nelm);
}
void LaRCSimMatrixTests::testSolveLinearSystem()
{
int nelm = 20;
double **src = nr_matrix(1, nelm, 1, nelm);
double **inv = nr_matrix(1, nelm, 1, nelm);
double **rhs = nr_matrix(1, nelm, 1, 1);
double **sol = nr_matrix(1, nelm, 1, 1);
double **check = nr_matrix(1, nelm, 1, nelm);
double invmaxlong = 1.0/(double)RAND_MAX;
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
src[i][j] = 2.0 - 4.0*invmaxlong*(double) rand();
for (int i=1; i<=nelm; ++i) {
rhs[i][1] = 2.0+cos(i*M_PI/nelm);
sol[i][1] = rhs[i][1];
}
nr_copymat(src, nelm, inv);
nr_gaussj(inv, nelm, sol, 1);
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j) {
check[i][j] = 0.0;
for (int k=1; k<=nelm; ++k)
check[i][j] += src[i][k]*inv[k][j];
}
for (int i=1; i<=nelm; ++i)
for (int j=1; j<=nelm; ++j)
CPPUNIT_ASSERT_DOUBLES_EQUAL(check[i][j], i == j ? 1.0 : 0.0, 1e-9);
for (int i=1; i<=nelm; ++i) {
check[i][1] = 0.0;
for (int j=1; j<=nelm; ++j)
check[i][1] += src[i][j]*sol[j][1];
}
for (int i=1; i<=nelm; ++i)
CPPUNIT_ASSERT_DOUBLES_EQUAL(check[i][1], rhs[i][1], 1e-9);
nr_free_matrix(src, 1, nelm, 1, nelm);
nr_free_matrix(inv, 1, nelm, 1, nelm);
nr_free_matrix(check, 1, nelm, 1, nelm);
nr_free_matrix(rhs, 1, nelm, 1, 1);
nr_free_matrix(sol, 1, nelm, 1, 1);
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2018 Edward d'Auvergne
*
* This file is part of the program FlightGear.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FG_LARCSIM_MATRIX_UNIT_TESTS_HXX
#define _FG_LARCSIM_MATRIX_UNIT_TESTS_HXX
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
// The LaRCSim matrix unit tests.
class LaRCSimMatrixTests : public CppUnit::TestFixture
{
// Set up the test suite.
CPPUNIT_TEST_SUITE(LaRCSimMatrixTests);
CPPUNIT_TEST(testCopyMatrix);
CPPUNIT_TEST(testIdentityMatrix);
CPPUNIT_TEST(testOrthogonalMatrix);
CPPUNIT_TEST(testRandomMatrix);
CPPUNIT_TEST(testSolveLinearSystem);
CPPUNIT_TEST_SUITE_END();
public:
// Set up function for each test.
void setUp() {}
// Clean up after each test.
void tearDown() {}
// The tests.
void testCopyMatrix();
void testIdentityMatrix();
void testOrthogonalMatrix();
void testRandomMatrix();
void testSolveLinearSystem();
};
#endif // _FG_LARCSIM_MATRIX_UNIT_TESTS_HXX