Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Air drag model and test #1

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ CMAKE_DEPENDENT_OPTION(BUILD_COVERAGE_ANALYSIS "Build code coverage analysis"
set(TEST_SRC
"${TEST_SRC_PATH}/testAstro.cpp"
"${TEST_SRC_PATH}/testConstants.cpp"
"${TEST_SRC_PATH}/testDragAccelerationModel.cpp"
"${TEST_SRC_PATH}/testEddyTorqueModel.cpp"
"${TEST_SRC_PATH}/testOrbitalElementConversions.cpp"
"${TEST_SRC_PATH}/testTwoBodyMethods.cpp"
)
Expand Down
69 changes: 69 additions & 0 deletions include/Astro/dragAccelerationModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2014-2015 Kartik Kumar (me@kartikkumar.com)
* Distributed under the MIT License.
* See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
*/

#ifndef ASTRO_DRAG_ACCELERATION_MODEL_HPP
#define ASTRO_DRAG_ACCELERATION_MODEL_HPP

#include <SML/linearAlgebra.hpp>

namespace astro
{

//! Compute drag acceleration on a cannonball.
/*!
* Computes drag acceleration using a cannonball model. The model for the acceleration is given by
*
* \f[
* a_{drag} = \frac{1}{2} \frac{C_{d}}{m} \rho S V \vec{V}
* \f]
*
* where \f$a_{drag}\f$ is the drag acceleration, \f$C_{d}\f$ is the drag coefficient, \f$m\f$ is
* the mass, \f$\rho\f$ is the atmospheric density, \f$\vec{V}\f$ is the relative velocity with
* respect to the body-fixed frame and \f$S\f$ is the drag area, that is, the projected area
* of the object perpendicular to \f$\vec{V}\f$.
*
* @param[in] dragCoefficient Drag coefficient [adim]
* @param[in] atmosphericDensity Atmospheric density [kg m^-3]
* @param[in] velocity Velocity vector (3x1) [m s^-1]
* @param[in] dragArea Drag area [m^2]
* @param[in] mass Mass [kg]
* @return Drag acceleration vector (3x1) [m s^-2]
*/
template< typename Real, typename Vector3 >
Vector3 computeDragAcceleration( const Real dragCoefficient,
const Real atmosphericDensity,
const Vector3& velocity,
const Real dragArea,
const Real mass );

//! Compute drag acceleration on a cannonball.
template< typename Real, typename Vector3 >
Vector3 computeDragAcceleration( const Real dragCoefficient,
const Real atmosphericDensity,
const Vector3& velocity,
const Real dragArea,
const Real mass )
{
Vector3 dragAcceleration = velocity;

// Compute the squared norm of the velocity.
const Real normVelocity = sml::norm< Real >( velocity );

// Compute a premultiplier so that it does not have to be written several times.
const Real preMultiplier = 0.5 * dragCoefficient * atmosphericDensity
* dragArea * normVelocity / mass;

// Compute the drag acceleration vector.
dragAcceleration[ 0 ] = preMultiplier * velocity[ 0 ];
dragAcceleration[ 1 ] = preMultiplier * velocity[ 1 ];
dragAcceleration[ 2 ] = preMultiplier * velocity[ 2 ];

return dragAcceleration;
}

} // namespace astro

#endif // ASTRO_DRAG_ACCELERATION_MODEL_HPP
45 changes: 45 additions & 0 deletions include/Astro/eddyCurrentModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c)
*/

#ifndef ASTRO_EDDY_CURRENT_HPP
#define ASTRO_EDDY_CURRENT_HPP

#include <SML/linearAlgebra.hpp>

namespace astro
{

//! Compute eddy current torque.
/*!
* Computes the eddy current torque on a certain object generated by an external source. The model
* for the torque is given by
*
* \f[
* \vec{T}_{eddy} = \vec{m} \times \vec{B}
* \f]
*
* where \f$\vec{m}\f$ is the magnetic moment of the object and \f$\vec{B}\f$ is the magnetic field
* generated by an external source.
*
* @param magneticMoment Magnetic Moment [A * m^2]
* @param magneticField Magnetic Field [T]
* @return Eddy Current Torque [N * m]
*/
template< typename Vector3 >
Vector3 computeEddyTorque( const Vector3& magneticMoment,
const Vector3& magneticField );

//! Compute eddy current torque.
template< typename Vector3 >
Vector3 computeEddyTorque( const Vector3& magneticMoment,
const Vector3& magneticField )

{
// Compute the eddy current torque.
return sml::cross< Vector3 >( magneticMoment, magneticField);
}

} // namespace astro

#endif // ASTRO_EDDY_CURRENT_HPP
109 changes: 109 additions & 0 deletions test/testDragAccelerationModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2015 Kartik Kumar (me@kartikkumar.com)
* Distributed under the MIT License.
* See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
*/

#include <cmath>
#include <vector>

#include <catch.hpp>

#include "Astro/dragAccelerationModel.hpp"

namespace astro
{
namespace tests
{

typedef double Real;
typedef std::vector< Real > Vector;

TEST_CASE( "Obtain drag acceleration: test 1", "[drag, acceleration, models]" )
{
// Set expected drag acceleration vector [m/s].
Vector expectedDragAcceleration( 3 );
expectedDragAcceleration[ 0 ] = 0.107800109999944e-4;
expectedDragAcceleration[ 1 ] = 0.0;
expectedDragAcceleration[ 2 ] = 0.000154000157143e-4;

// Set epsilon = error between expected value and computed value.
const Real epsilon = 1.0e-10;

// Set drag coefficient.
const Real dragCoefficient = 2.2;

// Set atmospheric density [kg/m^3].
const Real atmosphericDensity = 2.0e-11;

// Velocity vector in [m/s].
Vector velocity( 3 );
velocity[ 0 ] = 7000.0;
velocity[ 1 ] = 0.0;
velocity[ 2 ] = 10.0;

// Set drag area [m^2].
const Real dragArea = 5.0;

// Set mass [kg].
const Real mass = 500.0;

//! Compute drag acceleration.
const Vector dragAcceleration = computeDragAcceleration( dragCoefficient,
atmosphericDensity,
velocity,
dragArea,
mass );

// Check if computed mean motion matches expected value.
REQUIRE( std::fabs( dragAcceleration[ 0 ] - expectedDragAcceleration[ 0 ] ) <= epsilon );
REQUIRE( std::fabs( dragAcceleration[ 1 ] - expectedDragAcceleration[ 1 ] ) <= epsilon );
REQUIRE( std::fabs( dragAcceleration[ 2 ] - expectedDragAcceleration[ 2 ] ) <= epsilon );
}

TEST_CASE( "Obtain drag acceleration: test 2", "[obtain-drag-acceleration-2]" )
{
// Reference: http://tudat.tudelft.nl/

// Set expected drag acceleration vector [m/s].
Vector expectedDragAcceleration( 3 );
expectedDragAcceleration[ 0 ] = 0.0;
expectedDragAcceleration[ 1 ] = 0.0;
expectedDragAcceleration[ 2 ] = 267.4211815284975;

// Set epsilon = error between expected value and computed value.
const Real epsilon = 1.0e-10;

// Set drag coefficient.
const Real dragCoefficient = 1.1;

// Set atmospheric density [kg/m3].
const Real atmosphericDensity = 3.5e-5;

// Velocity vector in [m/s].
Vector velocity( 3 );
velocity[ 0 ] = 0.0;
velocity[ 1 ] = 0.0;
velocity[ 2 ] = 3491.0;

// Set drag area [m^2]
const Real dragArea = 2.2;

// Set mass [kg]
const Real mass = 1.93;

//! Compute drag acceleration.
const Vector dragAcceleration = computeDragAcceleration( dragCoefficient,
atmosphericDensity,
velocity,
dragArea,
mass );

// Check if computed mean motion matches expected value.
REQUIRE( std::fabs(dragAcceleration[ 0 ] - expectedDragAcceleration[ 0 ]) <= epsilon );
REQUIRE( std::fabs(dragAcceleration[ 1 ] - expectedDragAcceleration[ 1 ]) <= epsilon );
REQUIRE( std::fabs(dragAcceleration[ 2 ] - expectedDragAcceleration[ 2 ]) <= epsilon );
}

} // namespace tests
} // namespace astro
91 changes: 91 additions & 0 deletions test/testEddyTorqueModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c)
*/
#include <cmath>

#include <vector>

#include <catch.hpp>

#include <Astro/eddyCurrentModel.hpp>

using namespace std;

namespace astro
{

namespace tests
{

typedef double Real;
typedef std::vector< Real > Vector3;

TEST_CASE( "Obtain eddy current torque: test 1", "[obtain-eddy-torque-1]" )
{
// Set expected eddy current torque vector [N * m].
Vector3 expectedEddyTorque( 3 );
expectedEddyTorque[ 0 ] = 0.095000000000000;
expectedEddyTorque[ 1 ] = 0.065000000000000;
expectedEddyTorque[ 2 ] = -0.149000000000000;

// Set magnetic moment vector [A * m^2].
Vector3 magneticMoment( 3 );
magneticMoment[ 0 ] = 100.0;
magneticMoment[ 1 ] = 1000.0;
magneticMoment[ 2 ] = 500.0;

// Set magnetic field vector [T].
Vector3 magneticField( 3 );
magneticField[ 0 ] = 150e-6;
magneticField[ 1 ] = 10e-6;
magneticField[ 2 ] = 100e-6;

// Set epsilon = error between expected value and computed value.
const Real epsilon = 1.0e-10;

//! Compute eddy current torque.
const Vector3 eddyTorque = computeEddyTorque( magneticMoment,
magneticField );

// Check if computed torque matches expected value.
REQUIRE( std::fabs(eddyTorque[ 0 ] - expectedEddyTorque[ 0 ]) <= epsilon );
REQUIRE( std::fabs(eddyTorque[ 1 ] - expectedEddyTorque[ 1 ]) <= epsilon );
REQUIRE( std::fabs(eddyTorque[ 2 ] - expectedEddyTorque[ 2 ]) <= epsilon );
}

TEST_CASE( "Obtain eddy current torque: test 2", "[obtain-eddy-torque-2]" )
{
// Set expected eddy current torque vector [N * m].
Vector3 expectedEddyTorque( 3 );
expectedEddyTorque[ 0 ] = 0.0;
expectedEddyTorque[ 1 ] = 0.0;
expectedEddyTorque[ 2 ] = 0.0;

// Set magnetic moment vector [A * m^2].
Vector3 magneticMoment( 3 );
magneticMoment[ 0 ] = 0.0;
magneticMoment[ 1 ] = 0.0;
magneticMoment[ 2 ] = 1150.0;

// Set magnetic field vector [T].
Vector3 magneticField( 3 );
magneticField[ 0 ] = 0.0;
magneticField[ 1 ] = 0.0;
magneticField[ 2 ] = 127e-6;

// Set epsilon = error between expected value and computed value.
const Real epsilon = 1.0e-10;

//! Compute eddy current torque.
const Vector3 eddyTorque = computeEddyTorque( magneticMoment,
magneticField );

// Check if computed torque matches expected value.
REQUIRE( std::fabs(eddyTorque[ 0 ] - expectedEddyTorque[ 0 ]) <= epsilon );
REQUIRE( std::fabs(eddyTorque[ 1 ] - expectedEddyTorque[ 1 ]) <= epsilon );
REQUIRE( std::fabs(eddyTorque[ 2 ] - expectedEddyTorque[ 2 ]) <= epsilon );
}


} // namespace tests
} // namespace astro