diff --git a/Tudat/Astrodynamics/Aerodynamics/CMakeLists.txt b/Tudat/Astrodynamics/Aerodynamics/CMakeLists.txt index 3103d2e594..a6310bfbd5 100644 --- a/Tudat/Astrodynamics/Aerodynamics/CMakeLists.txt +++ b/Tudat/Astrodynamics/Aerodynamics/CMakeLists.txt @@ -104,6 +104,10 @@ add_executable(test_TabulatedAtmosphere "${SRCROOT}${AERODYNAMICSDIR}/UnitTests/ setup_custom_test_program(test_TabulatedAtmosphere "${SRCROOT}${AERODYNAMICSDIR}") target_link_libraries(test_TabulatedAtmosphere tudat_aerodynamics tudat_interpolators tudat_basic_mathematics tudat_input_output ${Boost_LIBRARIES}) +add_executable(test_TabulatedAerodynamicCoefficients "${SRCROOT}${AERODYNAMICSDIR}/UnitTests/unitTestTabulatedAerodynamicCoefficients.cpp") +setup_custom_test_program(test_TabulatedAerodynamicCoefficients "${SRCROOT}${AERODYNAMICSDIR}") +target_link_libraries(test_TabulatedAerodynamicCoefficients ${TUDAT_PROPAGATION_LIBRARIES} ${Boost_LIBRARIES}) + if(USE_NRLMSISE00) add_executable(test_NRLMSISE00Atmosphere "${SRCROOT}${AERODYNAMICSDIR}/UnitTests/unitTestNRLMSISE00Atmosphere.cpp") setup_custom_test_program(test_NRLMSISE00Atmosphere "${SRCROOT}${AERODYNAMICSDIR}") diff --git a/Tudat/Astrodynamics/Aerodynamics/UnitTests/applicationOutput.h b/Tudat/Astrodynamics/Aerodynamics/UnitTests/applicationOutput.h new file mode 100755 index 0000000000..1e061a52fe --- /dev/null +++ b/Tudat/Astrodynamics/Aerodynamics/UnitTests/applicationOutput.h @@ -0,0 +1,21 @@ +#ifndef TUDAT_APPLICATIONOUTPUT_H +#define TUDAT_APPLICATIONOUTPUT_H + +namespace tudat_applications +{ + +//! Get path for output directory. +static inline std::string getOutputPath( ) +{ + // Declare file path string assigned to filePath. + // __FILE__ only gives the absolute path of the header file! + std::string filePath_( __FILE__ ); + + // Strip filename from temporary string and return root-path string. + return filePath_.substr( 0, filePath_.length( ) - + std::string( "applicationOutput.h" ).length( ) ); +} + +} + +#endif // TUDAT_APPLICATIONOUTPUT_H diff --git a/Tudat/Astrodynamics/Aerodynamics/UnitTests/tabulatedDragCoefficient.txt b/Tudat/Astrodynamics/Aerodynamics/UnitTests/tabulatedDragCoefficient.txt new file mode 100644 index 0000000000..5a32e7fc79 --- /dev/null +++ b/Tudat/Astrodynamics/Aerodynamics/UnitTests/tabulatedDragCoefficient.txt @@ -0,0 +1,63 @@ +% Altitude [km] Drag coefficient +121.73913 2.0711009 +126.6087 2.0733945 +136.34783 2.0779817 +146.08696 2.0802752 +155.82609 2.0848624 +165.56522 2.0894495 +177.73913 2.0917431 +197.21739 2.0940367 +204.52174 2.0986239 +221.56522 2.0986239 +236.17391 2.103211 +250.78261 2.1055046 +270.26087 2.1055046 +292.17391 2.1077982 +318.95652 2.1100917 +343.30435 2.1100917 +372.52174 2.1123853 +394.43478 2.1169725 +423.65217 2.1215596 +448 2.1307339 +474.78261 2.1422018 +494.26087 2.1513761 +511.30435 2.1651376 +530.78261 2.1788991 +547.82609 2.190367 +562.43478 2.2041284 +579.47826 2.2224771 +598.95652 2.2408257 +611.13043 2.2545872 +620.86957 2.2683486 +633.04348 2.2889908 +645.21739 2.3050459 +654.95652 2.3233945 +667.13043 2.3348624 +676.86957 2.353211 +689.04348 2.3761468 +703.65217 2.4036697 +715.82609 2.4311927 +742.6087 2.4816514 +776.69565 2.5504587 +803.47826 2.603211 +832.69565 2.6605505 +861.91304 2.7087156 +888.69565 2.75 +908.17391 2.7821101 +927.65217 2.8004587 +947.13043 2.8211009 +969.04348 2.8440367 +993.3913 2.8600917 +1022.6087 2.8784404 +1039.6522 2.8899083 +1061.5652 2.9013761 +1090.7826 2.912844 +1122.4348 2.9243119 +1158.9565 2.9334862 +1188.1739 2.940367 +1224.6957 2.9449541 +1258.7826 2.9518349 +1295.3043 2.956422 +1326.9565 2.9587156 +1358.6087 2.9633028 +1385.3913 2.9633028 diff --git a/Tudat/Astrodynamics/Aerodynamics/UnitTests/unitTestTabulatedAerodynamicCoefficients.cpp b/Tudat/Astrodynamics/Aerodynamics/UnitTests/unitTestTabulatedAerodynamicCoefficients.cpp new file mode 100755 index 0000000000..062c124a6d --- /dev/null +++ b/Tudat/Astrodynamics/Aerodynamics/UnitTests/unitTestTabulatedAerodynamicCoefficients.cpp @@ -0,0 +1,259 @@ +/* Copyright (c) 2010-2016, Delft University of Technology + * All rigths reserved + * + * This file is part of the Tudat. Redistribution and use in source and + * binary forms, with or without modification, are permitted exclusively + * under the terms of the Modified BSD license. You should have received + * semiMajorAixscopy of the license with this file. If not, please or visit: + * http://tudat.tudelft.nl/LICENSE. + */ + +#define BOOST_TEST_MAIN + +#include + +#include + +#include "applicationOutput.h" +#include "Tudat/InputOutput/basicInputOutput.h" + + +namespace tudat +{ + +namespace unit_tests +{ + +BOOST_AUTO_TEST_SUITE( test_aerodynamic_acceleration_force_moment_models ) + +BOOST_AUTO_TEST_CASE( testTabulatedDragCoefficient ) +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// USING STATEMENTS ////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + using namespace tudat; + using namespace simulation_setup; + using namespace propagators; + using namespace numerical_integrators; + using namespace orbital_element_conversions; + using namespace basic_mathematics; + using namespace basic_astrodynamics; + using namespace gravitation; + using namespace numerical_integrators; + using namespace interpolators; + using namespace input_output; + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// CREATE ENVIRONMENT AND VEHICLE ////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Load Spice kernels. + spice_interface::loadSpiceKernelInTudat( input_output::getSpiceKernelPath( ) + "pck00009.tpc" ); + spice_interface::loadSpiceKernelInTudat( input_output::getSpiceKernelPath( ) + "de-403-masses.tpc" ); + spice_interface::loadSpiceKernelInTudat( input_output::getSpiceKernelPath( ) + "de421.bsp" ); + + // Set simulation time settings. + const double simulationStartEpoch = 0.0; + const double simulationEndEpoch = tudat::physical_constants::JULIAN_DAY; + + // Define body settings for simulation. + std::vector< std::string > bodiesToCreate; + bodiesToCreate.push_back( "Sun" ); + bodiesToCreate.push_back( "Earth" ); + bodiesToCreate.push_back( "Moon" ); + + // Create body objects. + std::map< std::string, boost::shared_ptr< BodySettings > > bodySettings = + getDefaultBodySettings( bodiesToCreate, simulationStartEpoch - 300.0, simulationEndEpoch + 300.0 ); + + for( unsigned int i = 0; i < bodiesToCreate.size( ); i++ ) { + bodySettings[ bodiesToCreate.at( i ) ]->ephemerisSettings->resetFrameOrientation( "J2000" ); + bodySettings[ bodiesToCreate.at( i ) ]->rotationModelSettings->resetOriginalFrame( "J2000" ); + } + + // EARTH + bodySettings[ "Earth" ]->gravityFieldSettings = boost::make_shared< GravityFieldSettings >( central_spice ); + bodySettings[ "Earth" ]->atmosphereSettings = boost::make_shared< AtmosphereSettings >( nrlmsise00 ); + + // MOON + bodySettings[ "Moon" ]->gravityFieldSettings = boost::make_shared< GravityFieldSettings >( central_spice ); + + NamedBodyMap bodyMap = createBodies( bodySettings ); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// CREATE VEHICLE ///////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Create spacecraft object. + bodyMap[ "Vehicle" ] = boost::make_shared< simulation_setup::Body >( ); + bodyMap[ "Vehicle" ]->setConstantBodyMass( 400.0 ); + double referenceArea = 10.0; + + boost::shared_ptr< AerodynamicCoefficientSettings > aerodynamicCoefficientSettings; + + // Read CD as semiMajorAixsfunction of altitude + Eigen::MatrixXd aerodynamicsDataFromFile = readMatrixFromFile( + tudat_applications::getOutputPath( ) + "tabulatedDragCoefficient.txt" ); + Eigen::VectorXd altitudeInKm = aerodynamicsDataFromFile.col(0); + std::vector< double > altitudes; + for ( unsigned int i = 0; i < altitudeInKm.size( ); i++ ) + { + altitudes.push_back( altitudeInKm( i ) * 1.0E3 ); + } + Eigen::VectorXd dragCoefficientsFromFile = aerodynamicsDataFromFile.col( 1 ); + std::vector< double > dragCoefficients( + dragCoefficientsFromFile.data( ), dragCoefficientsFromFile.data( ) + dragCoefficientsFromFile.size( ) ); + std::vector< Eigen::Vector3d > aerodynamicCoefficients; + for ( unsigned int i = 0; i < dragCoefficients.size( ); i++ ) + { + aerodynamicCoefficients.push_back( dragCoefficients[ i ] * Eigen::Vector3d::UnitX( ) ); + } + + // Create interpolator + boost::shared_ptr< InterpolatorSettings > interpolatorSettings = + boost::make_shared< InterpolatorSettings >( OneDimensionalInterpolatorTypes::linear_interpolator ); + + // Tabulated aerodynamic settings + aerodynamicCoefficientSettings = boost::make_shared< TabulatedAerodynamicCoefficientSettings< 1 > >( + altitudes, aerodynamicCoefficients, referenceArea, + aerodynamics::altitude_dependent, interpolatorSettings, 1, 1 ); + + // Aerodynamics interface + bodyMap[ "Vehicle" ]->setAerodynamicCoefficientInterface( + createAerodynamicCoefficientInterface( aerodynamicCoefficientSettings, "Vehicle" ) ); + + // Finalize body creation. + setGlobalFrameBodyEphemerides( bodyMap, "SSB", "J2000" ); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// CREATE ACCELERATIONS ////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Define propagator settings variables. + SelectedAccelerationMap accelerationMap; + std::vector< std::string > bodiesToPropagate; + std::vector< std::string > centralBodies; + + // Define propagation settings. + std::map< std::string, std::vector< boost::shared_ptr< AccelerationSettings > > > accelerationsOfVehicle; + + accelerationsOfVehicle[ "Earth" ].push_back( boost::make_shared< AccelerationSettings >( + basic_astrodynamics::central_gravity ) ); + accelerationsOfVehicle[ "Sun" ].push_back( boost::make_shared< AccelerationSettings >( + basic_astrodynamics::central_gravity ) ); + accelerationsOfVehicle[ "Moon" ].push_back( boost::make_shared< AccelerationSettings >( + basic_astrodynamics::central_gravity ) ); + accelerationsOfVehicle[ "Earth" ].push_back( boost::make_shared< AccelerationSettings >( + basic_astrodynamics::aerodynamic ) ); + + accelerationMap[ "Vehicle" ] = accelerationsOfVehicle; + + bodiesToPropagate.push_back( "Vehicle" ); + centralBodies.push_back( "Earth" ); + + basic_astrodynamics::AccelerationMap accelerationModelMap = + createAccelerationModelsMap( bodyMap, accelerationMap, bodiesToPropagate, centralBodies ); + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// CREATE PROPAGATION SETTINGS //////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + double meanEarthRadius = 6371.0E3; + double perigeeAltitude = 150.0E3; + double apogeeAltitude = 35780.0E3; + double semiMajorAixs= (apogeeAltitude + perigeeAltitude)/2 + meanEarthRadius; + double eccentricity = (apogeeAltitude - perigeeAltitude)/(apogeeAltitude + perigeeAltitude + 2*meanEarthRadius); + + // Set Keplerian elements for Vehicle. + Vector6d vehicleInitialStateInKeplerianElements; + vehicleInitialStateInKeplerianElements( semiMajorAxisIndex ) = semiMajorAixs; + vehicleInitialStateInKeplerianElements( eccentricityIndex ) = eccentricity; + vehicleInitialStateInKeplerianElements( inclinationIndex ) = mathematical_constants::PI / 180.0 * 23.4; + + double earthGravitationalParameter = bodyMap.at( "Earth" )->getGravityFieldModel( )->getGravitationalParameter( ); + const Vector6d vehicleInitialState = convertKeplerianToCartesianElements( + vehicleInitialStateInKeplerianElements, earthGravitationalParameter ); + + // Hybrid termination conditions + std::vector< boost::shared_ptr< propagators::PropagationTerminationSettings > > constituentSettings; + + // Time limit + constituentSettings.push_back( boost::make_shared< propagators::PropagationTimeTerminationSettings >( + simulationEndEpoch ) ); + + // Altitude limit + boost::shared_ptr< PropagationTerminationSettings > altitudeTerminationSettings = + boost::make_shared< propagators::PropagationDependentVariableTerminationSettings >( + boost::make_shared< propagators::SingleDependentVariableSaveSettings >( + propagators::altitude_dependent_variable, "Vehicle" ), 100.0E3, 1 ); + constituentSettings.push_back( altitudeTerminationSettings ); + + // Stop if ANY of the two is met + boost::shared_ptr< PropagationTerminationSettings > terminationSettings = + boost::make_shared< propagators::PropagationHybridTerminationSettings >( constituentSettings, 1 ); + + // Save dependent variables + std::vector< boost::shared_ptr< SingleDependentVariableSaveSettings > > dependentVariablesToSave; + dependentVariablesToSave.push_back( boost::make_shared< SingleDependentVariableSaveSettings >( + altitude_dependent_variable, "Vehicle" ) ); + dependentVariablesToSave.push_back( boost::make_shared< SingleDependentVariableSaveSettings >( + aerodynamic_moment_coefficients_dependent_variable, "Vehicle" ) ); + + boost::shared_ptr< DependentVariableSaveSettings > dependentVariableSaveSettings = + boost::make_shared< DependentVariableSaveSettings >( dependentVariablesToSave, 0 ) ; + + // Translational propagator settings + boost::shared_ptr< TranslationalStatePropagatorSettings< double > > translationalPropagatorSettings = + boost::make_shared< TranslationalStatePropagatorSettings< double > > ( + centralBodies, accelerationModelMap, bodiesToPropagate, vehicleInitialState, terminationSettings ); + + + boost::shared_ptr< IntegratorSettings< > > integratorSettings = boost::make_shared< IntegratorSettings< > > ( + rungeKutta4, simulationStartEpoch, 300.0 ); + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// PROPAGATE ORBIT //////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Create simulation object and propagate dynamics. + SingleArcDynamicsSimulator< > dynamicsSimulator( + bodyMap, integratorSettings, translationalPropagatorSettings, true, false, false ); + std::map< double, Eigen::Matrix< double, Eigen::Dynamic, 1 > > dependentVariableOutput = + dynamicsSimulator.getDependentVariableHistory( ); + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////// CHECK DRAG COEFFICIENTS //////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Retrieve altitudes and drag coefficients from propagation results + + Eigen::Vector3d currentCoefficients; + double currentAltitude; + double computedDragCoefficient; + LinearInterpolatorDoublePointer dragCoefficientInterpolator = + boost::make_shared( LinearInterpolatorDouble( altitudes, dragCoefficients ) ); + for ( std::map< double, Eigen::Matrix< double, Eigen::Dynamic, 1 > >::iterator outputIterator = + dependentVariableOutput.begin( ); outputIterator != dependentVariableOutput.end( ); ++outputIterator ) + { + currentAltitude = outputIterator->second( 0 ); + computedDragCoefficient = dragCoefficientInterpolator->interpolate( currentAltitude ); + currentCoefficients = outputIterator->second.segment( 1, 3 ); + BOOST_CHECK_CLOSE_FRACTION( computedDragCoefficient, currentCoefficients( 0 ), + 4.0 * std::numeric_limits< double >::epsilon( ) ); + BOOST_CHECK_SMALL( std::fabs( currentCoefficients( 1 ) ), std::numeric_limits< double >::epsilon( ) ); + BOOST_CHECK_SMALL( std::fabs( currentCoefficients( 2 ) ), std::numeric_limits< double >::epsilon( ) ); + + } + +} + +BOOST_AUTO_TEST_SUITE_END( ) + +} + +} diff --git a/Tudat/Astrodynamics/Aerodynamics/aerodynamicCoefficientInterface.h b/Tudat/Astrodynamics/Aerodynamics/aerodynamicCoefficientInterface.h index bd405ffa99..71142b9b4c 100644 --- a/Tudat/Astrodynamics/Aerodynamics/aerodynamicCoefficientInterface.h +++ b/Tudat/Astrodynamics/Aerodynamics/aerodynamicCoefficientInterface.h @@ -66,7 +66,8 @@ enum AerodynamicCoefficientsIndependentVariables mach_number_dependent = 0, angle_of_attack_dependent = 1, angle_of_sideslip_dependent = 2, - undefined_independent_variable = 3 + altitude_dependent = 3, + undefined_independent_variable = 4 }; //! Base class to hold an aerodynamic coefficient interface. diff --git a/Tudat/Astrodynamics/Aerodynamics/flightConditions.cpp b/Tudat/Astrodynamics/Aerodynamics/flightConditions.cpp index 57cd7622cc..189f07bfee 100644 --- a/Tudat/Astrodynamics/Aerodynamics/flightConditions.cpp +++ b/Tudat/Astrodynamics/Aerodynamics/flightConditions.cpp @@ -60,7 +60,8 @@ void FlightConditions::setAerodynamicCoefficientsIndependentVariableFunction( { if( ( independentVariable == mach_number_dependent ) || ( independentVariable == angle_of_attack_dependent ) || - ( independentVariable == angle_of_sideslip_dependent ) ) + ( independentVariable == angle_of_sideslip_dependent )|| + ( independentVariable == altitude_dependent ) ) { throw std::runtime_error( std::string( "Error when setting aerodynamic coefficient function dependency, value of parameter " ) + @@ -162,6 +163,13 @@ void FlightConditions::updateAerodynamicCoefficientInput( ) aerodynamicAngleCalculator_->getAerodynamicAngle( reference_frames::angle_of_sideslip ) ); break; + case altitude_dependent: + if( aerodynamicAngleCalculator_== NULL ) + { + throw std::runtime_error( "Error, aerodynamic angle calculator is null, but require angle of sideslip" ); + } + aerodynamicCoefficientIndependentVariables_.push_back( currentAltitude_ ); + break; default: if( customCoefficientDependencies_.count( aerodynamicCoefficientInterface_->getIndependentVariableName( i ) ) == 0 ) diff --git a/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.cpp b/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.cpp old mode 100644 new mode 100755 index b0788cd639..e68636f202 --- a/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.cpp +++ b/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.cpp @@ -46,6 +46,49 @@ createConstantCoefficientAerodynamicCoefficientInterface( return coefficientInterface; } +//! Factory function for tabulated (1-D independent variables) aerodynamic coefficient interface from coefficient settings. +boost::shared_ptr< aerodynamics::AerodynamicCoefficientInterface > +createUnivariateTabulatedCoefficientAerodynamicCoefficientInterface( + const boost::shared_ptr< AerodynamicCoefficientSettings > coefficientSettings, + const std::string& body ) +{ + // Check consistency of type. + boost::shared_ptr< TabulatedAerodynamicCoefficientSettings< 1 > > tabulatedCoefficientSettings = + boost::dynamic_pointer_cast< TabulatedAerodynamicCoefficientSettings< 1 > >( + coefficientSettings ); + if( tabulatedCoefficientSettings == NULL ) + { + throw std::runtime_error( + "Error, expected tabulated aerodynamic coefficients of size " + + boost::lexical_cast< std::string >( 1 ) + "for body " + body ); + } + else + { + boost::shared_ptr< interpolators::OneDimensionalInterpolator< double, Eigen::Vector3d > > forceInterpolator = + interpolators::createOneDimensionalInterpolator( + tabulatedCoefficientSettings->getForceCoefficients( ), + tabulatedCoefficientSettings->getInterpolationSettings( ) ); + boost::shared_ptr< interpolators::OneDimensionalInterpolator< double, Eigen::Vector3d > > momentInterpolator = + interpolators::createOneDimensionalInterpolator( + tabulatedCoefficientSettings->getForceCoefficients( ), + tabulatedCoefficientSettings->getInterpolationSettings( ) ); + + // Create aerodynamic coefficient interface. + return boost::make_shared< aerodynamics::CustomAerodynamicCoefficientInterface >( + boost::bind( &interpolators::Interpolator + < double, Eigen::Vector3d >::interpolate, forceInterpolator, _1 ), + boost::bind( &interpolators::Interpolator + < double, Eigen::Vector3d >::interpolate, momentInterpolator, _1 ), + tabulatedCoefficientSettings->getReferenceLength( ), + tabulatedCoefficientSettings->getReferenceArea( ), + tabulatedCoefficientSettings->getReferenceLength( ), + tabulatedCoefficientSettings->getMomentReferencePoint( ), + tabulatedCoefficientSettings->getIndependentVariableNames( ), + tabulatedCoefficientSettings->getAreCoefficientsInAerodynamicFrame( ), + tabulatedCoefficientSettings->getAreCoefficientsInNegativeAxisDirection( ) ); + } +} + //! Function to create and aerodynamic coefficient interface. boost::shared_ptr< aerodynamics::AerodynamicCoefficientInterface > createAerodynamicCoefficientInterface( @@ -93,7 +136,7 @@ createAerodynamicCoefficientInterface( { case 1: { - coefficientInterface = createTabulatedCoefficientAerodynamicCoefficientInterface< 1 >( + coefficientInterface = createUnivariateTabulatedCoefficientAerodynamicCoefficientInterface( coefficientSettings, body ); break; } diff --git a/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.h b/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.h old mode 100644 new mode 100755 index 4a9fbe7b4d..4b873f17ab --- a/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.h +++ b/Tudat/SimulationSetup/EnvironmentSetup/createFlightConditions.h @@ -12,6 +12,7 @@ #define TUDAT_CREATEFLIGHTCONDITIONS_H #include +#include #include @@ -315,10 +316,11 @@ class ConstantAerodynamicCoefficientSettings: public AerodynamicCoefficientSetti }; -//! Object for setting aerodynamic coefficients from a user-defined N-dimensional table. +//! Object for setting aerodynamic coefficients from a user-defined N-dimensional table (with N>1). /*! - * Object for setting aerodynamic coefficients from a user-defined N-dimensional table. - * The user must provide the force and moment coefficients in boost multi_arrays, and + * Object for setting aerodynamic coefficients from a user-defined N-dimensional table (with N>1). The N=1 case has its + * own template specialization. + * The user must provide the force (and moment) coefficients in boost multi_arrays, and * define the physical meaning of each of the independent variables. */ template< int NumberOfDimensions > @@ -373,6 +375,42 @@ class TabulatedAerodynamicCoefficientSettings: public AerodynamicCoefficientSett forceCoefficients_( forceCoefficients ), momentCoefficients_( momentCoefficients ){ } + //! Constructor, sets properties of aerodynamic force coefficients, zero moment coefficients. + /*! + * Constructor, sets properties of aerodynamic force coefficients, zero moment coefficients + * \param independentVariables Values of indepependent variables at which the coefficients + * in the input multi arrays are defined. + * \param forceCoefficients Values of force coefficients at independent variables defined + * by independentVariables. + * \param referenceArea Reference area with which aerodynamic forces and moments are + * non-dimensionalized. + * \param independentVariableNames Vector with identifiers the physical meaning of each + * independent variable of the aerodynamic coefficients. + * \param areCoefficientsInAerodynamicFrame Boolean to define whether the aerodynamic + * coefficients are defined in the aerodynamic frame (lift, drag, side force) or in the body + * frame (typically denoted as Cx, Cy, Cz). + * \param areCoefficientsInNegativeAxisDirection Boolean to define whether the aerodynamic + * coefficients are positive along the positive axes of the body or aerodynamic frame + * (see areCoefficientsInAerodynamicFrame). Note that for (lift, drag, side force), the + * coefficients are typically defined in negative direction. + */ + TabulatedAerodynamicCoefficientSettings( + const std::vector< std::vector< double > > independentVariables, + const boost::multi_array< Eigen::Vector3d, NumberOfDimensions > forceCoefficients, + const double referenceArea, + const std::vector< aerodynamics::AerodynamicCoefficientsIndependentVariables > independentVariableNames, + const bool areCoefficientsInAerodynamicFrame = 1, + const bool areCoefficientsInNegativeAxisDirection = 1 ): + AerodynamicCoefficientSettings( + tabulated_coefficients, TUDAT_NAN, referenceArea, + TUDAT_NAN, Eigen::Vector3d::Constant( TUDAT_NAN ), + independentVariableNames, areCoefficientsInAerodynamicFrame, + areCoefficientsInNegativeAxisDirection ), + independentVariables_( independentVariables ), + forceCoefficients_( forceCoefficients ){ } + + ~TabulatedAerodynamicCoefficientSettings( ){ } + //! Function to return the values of the indepependent variables of tables of coefficients. /*! * Function to return the values of the indepependent variables of tables of coefficients. @@ -417,8 +455,174 @@ class TabulatedAerodynamicCoefficientSettings: public AerodynamicCoefficientSett //! Values of moment coefficients at independent variables defined by independentVariables_. boost::multi_array< Eigen::Vector3d, NumberOfDimensions > momentCoefficients_; +}; + +//! Object for setting aerodynamic coefficients from a user-defined 1-dimensional table. +/*! + * Object for setting aerodynamic coefficients from a user-defined 1-dimensional table. + * The user must provide the force (and moment) coefficients in std::vectors, and + * define the physical meaning of the independent variables. + */ +template< > +class TabulatedAerodynamicCoefficientSettings< 1 >: public AerodynamicCoefficientSettings +{ +public: + + //! Constructor, sets properties of aerodynamic coefficients. + /*! + * Constructor, sets properties of aerodynamic coefficients. + * \param independentVariables Values of indepependent variables at which the coefficients + * in the input multi vector are defined. + * \param forceCoefficients Values of force coefficients at independent variables defined + * by independentVariables. + * \param momentCoefficients Values of moment coefficients at independent variables defined + * by independentVariables. + * \param referenceLength Reference length with which aerodynamic moments + * (about x- and z- axes) are non-dimensionalized. + * \param referenceArea Reference area with which aerodynamic forces and moments are + * non-dimensionalized. + * \param lateralReferenceLength Reference length with which aerodynamic moments (about y-axis) + * is non-dimensionalized. + * \param momentReferencePoint Point w.r.t. aerodynamic moment is calculated + * \param independentVariableName Identifiers the of physical meaning of the + * independent variable of the aerodynamic coefficients. + * \param interpolationSettings Settings to be used for creating the one-dimensional interpoaltor of data. + * \param areCoefficientsInAerodynamicFrame Boolean to define whether the aerodynamic + * coefficients are defined in the aerodynamic frame (lift, drag, side force) or in the body + * frame (typically denoted as Cx, Cy, Cz). + * \param areCoefficientsInNegativeAxisDirection Boolean to define whether the aerodynamic + * coefficients are positive along the positive axes of the body or aerodynamic frame + * (see areCoefficientsInAerodynamicFrame). Note that for (lift, drag, side force), the + * coefficients are typically defined in negative direction. + */ + TabulatedAerodynamicCoefficientSettings< 1 >( + const std::vector< double > independentVariables, + const std::vector< Eigen::Vector3d > forceCoefficients, + const std::vector< Eigen::Vector3d > momentCoefficients, + const double referenceLength, + const double referenceArea, + const double lateralReferenceLength, + const Eigen::Vector3d& momentReferencePoint, + const aerodynamics::AerodynamicCoefficientsIndependentVariables independentVariableName, + const boost::shared_ptr< interpolators::InterpolatorSettings > interpolationSettings, + const bool areCoefficientsInAerodynamicFrame = 1, + const bool areCoefficientsInNegativeAxisDirection = 1 ): + AerodynamicCoefficientSettings( + tabulated_coefficients, referenceLength, referenceArea, + lateralReferenceLength, momentReferencePoint, + boost::assign::list_of( independentVariableName ), areCoefficientsInAerodynamicFrame, + areCoefficientsInNegativeAxisDirection ), + interpolationSettings_( interpolationSettings ) + { + if( forceCoefficients.size( ) != independentVariables.size( ) ) + { + throw std::runtime_error( "Error, force coefficient size is inconsistent in TabulatedAerodynamicCoefficientSettings< 1 >" ); + } + + if( momentCoefficients.size( ) != independentVariables.size( ) ) + { + throw std::runtime_error( "Error, moment coefficient size is inconsistent in TabulatedAerodynamicCoefficientSettings< 1 >" ); + } + + for( unsigned int i = 0; i < independentVariables.size( ); i++ ) + { + forceCoefficients_[ independentVariables.at( i ) ] = forceCoefficients.at( i ); + momentCoefficients_[ independentVariables.at( i ) ] = momentCoefficients.at( i ); + } + } + + //! Constructor, sets properties of aerodynamic force coefficients, zero moment coefficients. + /*! + * Constructor, sets properties of aerodynamic force coefficients, zero moment coefficients. + * \param independentVariables Values of indepependent variables at which the coefficients + * in the input multi vector are defined. + * \param forceCoefficients Values of force coefficients at independent variables defined + * by independentVariables. + * \param referenceArea Reference area with which aerodynamic forces and moments are + * non-dimensionalized. + * \param independentVariableName Identifiers the of physical meaning of the + * independent variable of the aerodynamic coefficients. + * \param interpolationSettings Settings to be used for creating the one-dimensional interpoaltor of data. + * \param areCoefficientsInAerodynamicFrame Boolean to define whether the aerodynamic + * coefficients are defined in the aerodynamic frame (lift, drag, side force) or in the body + * frame (typically denoted as Cx, Cy, Cz). + * \param areCoefficientsInNegativeAxisDirection Boolean to define whether the aerodynamic + * coefficients are positive along the positive axes of the body or aerodynamic frame + * (see areCoefficientsInAerodynamicFrame). Note that for (lift, drag, side force), the + * coefficients are typically defined in negative direction. + */ + TabulatedAerodynamicCoefficientSettings< 1 >( + const std::vector< double > independentVariables, + const std::vector< Eigen::Vector3d > forceCoefficients, + const double referenceArea, + const aerodynamics::AerodynamicCoefficientsIndependentVariables independentVariableName, + const boost::shared_ptr< interpolators::InterpolatorSettings > interpolationSettings, + const bool areCoefficientsInAerodynamicFrame = 1, + const bool areCoefficientsInNegativeAxisDirection = 1 ): + AerodynamicCoefficientSettings( + tabulated_coefficients, TUDAT_NAN, referenceArea, + TUDAT_NAN, Eigen::Vector3d::Constant( TUDAT_NAN ), + boost::assign::list_of( independentVariableName ), areCoefficientsInAerodynamicFrame, + areCoefficientsInNegativeAxisDirection ), + interpolationSettings_( interpolationSettings ) + { + if( forceCoefficients.size( ) != independentVariables.size( ) ) + { + throw std::runtime_error( "Error, force coefficient size is inconsistent in TabulatedAerodynamicCoefficientSettings< 1 >" ); + } + + for( unsigned int i = 0; i < independentVariables.size( ); i++ ) + { + forceCoefficients_[ independentVariables.at( i ) ] = forceCoefficients.at( i ); + momentCoefficients_[ independentVariables.at( i ) ] = Eigen::Vector3d::Zero( ); + } + } + + //! Destructor + ~TabulatedAerodynamicCoefficientSettings< 1 >( ){ } + + + //! Function to return values of force coefficients in table. + /*! + * Function to return values of force coefficients in table. + * \return Values of force coefficients in table. + */ + std::map< double, Eigen::Vector3d > getForceCoefficients( ) + { + return forceCoefficients_; + } + + //! Function to return values of moment coefficients in table. + /*! + * Function to return values of moment coefficients in table. + * \return Values of moment coefficients in table. + */ + std::map< double, Eigen::Vector3d > getMomentCoefficients( ) + { + return momentCoefficients_; + } + + //! Function to return settings to be used for creating the one-dimensional interpoaltor of data. + /*! + * Function to return settings to be used for creating the one-dimensional interpoaltor of data. + * \return Settings to be used for creating the one-dimensional interpoaltor of data. + */ + boost::shared_ptr< interpolators::InterpolatorSettings > getInterpolationSettings( ) + { + return interpolationSettings_; + } +private: + + //! Values of force coefficients at independent variables defined by independentVariables_. + std::map< double, Eigen::Vector3d > forceCoefficients_; + + //! Values of moment coefficients at independent variables defined by independentVariables_. + std::map< double, Eigen::Vector3d > momentCoefficients_; + + //! Settings to be used for creating the one-dimensional interpoaltor of data. + boost::shared_ptr< interpolators::InterpolatorSettings > interpolationSettings_; }; //! Function to create an aerodynamic coefficient interface containing constant coefficients. @@ -533,6 +737,19 @@ createTabulatedCoefficientAerodynamicCoefficientInterface( areCoefficientsInAerodynamicFrame, areCoefficientsInNegativeAxisDirection ); } +//! Factory function for tabulated (1-D independent variables) aerodynamic coefficient interface from coefficient settings. +/*! + * Factory function for tabulated (1-D independent variables) aerodynamic coefficient interface from coefficient settings. + * \param coefficientSettings Settings for aerodynamic coefficient interface, must be of derived + * type TabulatedAerodynamicCoefficientSettings< 1 > + * \param body Name of body for which coefficient interface is to be made. + * \return Tabulated aerodynamic coefficient interface pointer. + */ +boost::shared_ptr< aerodynamics::AerodynamicCoefficientInterface > +createUnivariateTabulatedCoefficientAerodynamicCoefficientInterface( + const boost::shared_ptr< AerodynamicCoefficientSettings > coefficientSettings, + const std::string& body ); + //! Factory function for tabulated aerodynamic coefficient interface from coefficient settings. /*! * Factory function for tabulated aerodynamic coefficient interface from coefficient settings.