Line data Source code
1 : #ifndef __mx_astro_blackbody_hpp__
2 : #define __mx_astro_blackbody_hpp__
3 :
4 : #include <vector>
5 :
6 : #include "units.hpp"
7 : #include "constants.hpp"
8 : #include "../math/constants.hpp"
9 :
10 : namespace mx
11 : {
12 : namespace astro
13 : {
14 :
15 : template <typename units>
16 : typename units::realT equilibriumTemp( typename units::realT L, ///< [in] Stellar luminosity
17 : typename units::realT r, ///< [in] Distance from star
18 : typename units::realT Ab, ///< [in] Bond Albedo
19 : typename units::realT f ///< [in] Redistribution factor
20 : )
21 : {
22 : typedef typename units::realT realT;
23 :
24 : return pow( ( L * ( 1 - Ab ) / f ) /
25 : ( static_cast<realT>( 16.0 ) * constants::sigma<units>() * math::pi<realT>() * r * r ),
26 : static_cast<realT>( 0.25 ) );
27 : }
28 :
29 : /// The blackbody spectral energy distribution in the mx::astro::astroSpectrum form.
30 : /** You specify the temperature, and optionally the radius and distance of the blackbody.
31 : *
32 : * \tparam units specifies the units of the spectrum
33 : * \tparam freq if true, then the blackbody is calcuated as a frequency distribution. If false (default), it is a
34 : * wavelength distribution.
35 : */
36 : template <typename units, bool freq = false>
37 : struct blackbody
38 : {
39 : typedef typename units::realT realT; ///< The real floating point type used for calculations
40 :
41 : realT _temperature; ///< The temperature of the blackbody. Default value is the effective temperature of the Sun.
42 : realT _radius; ///< The optional radius of the blackbody.
43 : realT _distance; ///< The optional distance to the blackbody.
44 :
45 : std::vector<realT> _spectrum; ///< The calculated spectral energy distribution.
46 :
47 : /// Default c'tor.
48 0 : blackbody()
49 0 : {
50 0 : _temperature = constants::TeffSun<units>();
51 0 : _radius = 0;
52 0 : _distance = 0;
53 0 : }
54 :
55 : /// Constructor used to initialize parameters.
56 0 : blackbody(
57 : realT
58 : T, ///< [in] The effective temperature of the blackbody. Units as specified by the units template-parameter.
59 : realT R =
60 : 0, ///< [in] [optional] The radius of the blackbody. Units as specified by the units template-parameter.
61 : realT d =
62 : 0 ///< [in] [optional] The distance to the blackbody. Units as specified by the units template-parameter.
63 : )
64 0 : {
65 0 : setParameters( T, R, d );
66 0 : }
67 :
68 : /// Set the parameters of the blackbody.
69 0 : void setParameters(
70 : realT
71 : T, ///< [in] The effective temperature of the blackbody. Units as specified by the units template-parameter.
72 : realT R, ///< [in] The radius of the blackbody. Units as specified by the units template-parameter.
73 : realT d ///< [in] The distance to the blackbody. Units as specified by the units template-parameter.
74 : )
75 : {
76 0 : _temperature = T;
77 0 : _radius = R;
78 0 : _distance = d;
79 0 : }
80 :
81 : template <typename gridT>
82 : int setSpectrum( gridT &grid )
83 : {
84 : constexpr realT h = constants::h<units>();
85 : constexpr realT c = constants::c<units>();
86 : constexpr realT k = constants::k<units>();
87 :
88 : realT solidang = 1.0;
89 :
90 : if( _radius != 0 and _distance != 0 )
91 : {
92 : solidang = math::pi<realT>() * pow( _radius / _distance, 2 );
93 : }
94 :
95 : _spectrum.resize( grid.size() );
96 :
97 : for( int i = 0; i < grid.size(); ++i )
98 : {
99 : if( !freq )
100 : {
101 : _spectrum[i] =
102 : 2 * h * pow( c, 2 ) * solidang / pow( grid[i], 5 ) /
103 : expm1( h * c / ( grid[i] * k * _temperature ) ); // (exp(h*c/(grid[i]*k*_temperature))-1.0);
104 : }
105 : else
106 : {
107 : _spectrum[i] =
108 : 2 * h / pow( c, 2 ) * solidang * pow( grid[i], 3 ) /
109 : expm1( exp( h * grid[i] / ( k * _temperature ) ) ); // (exp(h*grid[i]/(k*_temperature))-1.0);
110 : }
111 : }
112 : return 0;
113 : }
114 :
115 0 : realT operator[]( int i )
116 : {
117 0 : return _spectrum[i];
118 : }
119 : };
120 :
121 : } // namespace astro
122 : } // namespace mx
123 : #endif //__mx_astro_blackbody_hpp__
|