8 #ifndef aoAtmosphere_hpp
9 #define aoAtmosphere_hpp
21 #include "../../mxlib.hpp"
22 #include "../../mxError.hpp"
26 #include "../../math/constants.hpp"
28 #include "../../app/appConfigurator.hpp"
46 template<
typename _realT>
176 void L_0(
const std::vector<realT> & L0 );
193 void l_0(
const std::vector<realT> & l0 );
229 void alpha(
const std::vector<realT> & alph );
253 void beta(
const std::vector<realT> & bet );
277 void beta_0(
const std::vector<realT> & bet );
292 size_t currentLayer();
294 void currentLayer(
size_t cl );
314 void layer_z(
const std::vector<realT> & layz );
615 template<
typename iosT>
638 template<
typename realT>
643 template<
typename realT>
646 size_t n = m_L_0.size();
648 if( m_l_0.size() != n)
650 mxError(
"aoAtmosphere", MXE_SIZEERR,
"mismatched layer numbers (inner scale vs. outer scale)");
654 if( m_layer_z.size() != n)
656 mxError(
"aoAtmosphere", MXE_SIZEERR,
"mismatched layer numbers (layer_z vs. outer scale)");
660 if( m_layer_Cn2.size() != n)
662 mxError(
"aoAtmosphere", MXE_SIZEERR,
"mismatched layer numbers (layer_Cn2 vs. outer scale)");
666 if( m_layer_dir.size() != n)
668 mxError(
"aoAtmosphere", MXE_SIZEERR,
"mismatched layer numbers (layer_dir vs. outer scale)");
672 if( m_layer_v_wind.size() != n)
674 mxError(
"aoAtmosphere", MXE_SIZEERR,
"mismatched layer numbers (layer_v_wind vs. outer scale)");
682 template<
typename realT>
688 template<
typename realT>
691 return m_r_0*pow(lam/m_lam_0, math::six_fifths<realT>());
694 template<
typename realT>
709 template<
typename realT>
715 template<
typename realT>
718 return m_layer_Cn2[n];
721 template<
typename realT>
727 template<
typename realT>
732 realT layer_norm = 0;
734 for(
size_t i=0;i < m_layer_Cn2.size();++i)
736 layer_norm += cn2[i];
739 for(
size_t i=0;i< m_layer_Cn2.size();++i) m_layer_Cn2[i] = m_layer_Cn2[i]/layer_norm;
743 m_r_0 = 1.0 / pow(layer_norm * 5.520e13, math::three_fifths<realT>() );
747 m_v_wind_updated =
false;
748 m_z_mean_updated =
false;
751 template<
typename realT>
757 template<
typename realT>
763 template<
typename realT>
769 template<
typename realT>
775 template<
typename realT>
781 template<
typename realT>
787 template<
typename realT>
790 m_nonKolmogorov = nk;
793 template<
typename realT>
796 return m_nonKolmogorov;
799 template<
typename realT>
804 return math::eleven_thirds<realT>();
812 template<
typename realT>
815 m_nonKolmogorov =
true;
819 template<
typename realT>
825 template<
typename realT>
830 return constants::a_PSD<realT>()*pow(m_r_0, -math::five_thirds<realT>());;
838 template<
typename realT>
841 m_nonKolmogorov =
true;
845 template<
typename realT>
851 template<
typename realT>
864 template<
typename realT>
867 m_nonKolmogorov =
true;
871 template<
typename realT>
877 template<
typename realT>
880 if(m_nonKolmogorov)
return m_alpha.size();
881 else return m_layer_Cn2.size();
884 template<
typename realT>
890 template<
typename realT>
894 m_z_mean_updated =
false;
897 template<
typename realT>
903 template<
typename realT>
909 template<
typename realT>
915 template<
typename realT>
921 template<
typename realT>
927 template<
typename realT>
930 return m_layer_v_wind[n];
933 template<
typename realT>
936 return m_layer_v_wind;
939 template<
typename realT>
943 m_v_wind_updated =
false;
946 template<
typename realT>
949 return m_layer_dir[n];
952 template<
typename realT>
958 template<
typename realT>
962 m_v_wind_updated =
false;
966 template<
typename realT>
969 if(m_v_wind_updated ==
false) update_v_wind();
973 template<
typename realT>
976 if(m_v_wind_updated ==
false) update_v_wind();
980 template<
typename realT>
984 if( m_layer_v_wind.size() == 0 || m_layer_Cn2.size() == 0)
988 m_v_wind_updated =
true;
997 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
999 m_v_wind += m_layer_Cn2[i] * pow(m_layer_v_wind[i], math::five_thirds<realT>() );
1000 s += pow(m_layer_v_wind[i], math::five_thirds<realT>())*sin(m_layer_dir[i]) ;
1001 c += pow(m_layer_v_wind[i], math::five_thirds<realT>())*cos(m_layer_dir[i]) ;
1004 m_v_wind = pow(m_v_wind, math::three_fifths<realT>());
1007 m_dir_wind = atan( s /
c);
1008 if(m_dir_wind < 0) m_dir_wind += math::pi<realT>();
1010 m_v_wind_updated =
true;
1014 template<
typename realT>
1017 if(m_v_wind_updated ==
false) update_v_wind();
1019 realT vw_old = m_v_wind;
1024 if( m_layer_v_wind.size() > 0)
1026 for(
size_t i=0; i< m_layer_v_wind.size(); ++i)
1028 m_layer_v_wind[i] = m_layer_v_wind[i]*(vw/vw_old);
1033 template<
typename realT>
1036 if(m_z_mean_updated ==
false) update_z_mean();
1040 template<
typename realT>
1043 if(m_layer_z.size() == 0 || m_layer_Cn2.size() == 0)
1046 m_z_mean_updated =
true;
1052 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
1054 m_z_mean += m_layer_Cn2[i] * pow(m_layer_z[i], math::five_thirds<realT>() );
1057 m_z_mean = pow(m_z_mean, math::three_fifths<realT>());
1059 m_z_mean_updated =
true;
1063 template<
typename realT>
1066 if(m_z_mean_updated ==
false) update_z_mean();
1068 realT zh_old = m_z_mean;
1073 if(m_layer_z.size() > 0)
1075 for(
size_t i=0; i<m_layer_z.size(); ++i)
1077 m_layer_z[i] =m_layer_z[i]*(zm/zh_old);
1087 template<
typename realT>
1094 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
1096 c += m_layer_Cn2[i] * pow( cos(math::pi<realT>()*
k*
k*lam_sci *m_layer_z[i] * secZ), 2);
1102 template<
typename realT>
1107 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
1109 c += m_layer_Cn2[i]* pow((cos( math::pi<realT>()*f*f*lam_sci *m_layer_z[i]) - cos( math::pi<realT>()*f*f*lam_wfs *m_layer_z[i])), 2);
1115 template<
typename realT>
1123 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
1125 c += m_layer_Cn2[i]*pow(sin( math::pi<realT>()*
k*
k*lam_sci *m_layer_z[i] * secZ), 2);
1130 template<
typename realT>
1135 for(
size_t i=0;i<m_layer_Cn2.size(); ++i)
1137 c += m_layer_Cn2[i]*pow( (sin(math::pi<realT>()*f*f*lam_sci *m_layer_z[i]) - sin( math::pi<realT>()*f*f*lam_wfs *m_layer_z[i])), 2);
1143 template<
typename realT>
1146 realT ll2 =
static_cast<realT>(1)/pow(lambda/1e-6, 2);
1148 return 1.0 + 8.34213e-5 + 0.0240603/(130.0 - ll2) + 0.00015997/(38.9 - ll2);
1151 template<
typename realT>
1155 realT sinZ = sqrt(1.0 - pow(1.0/secZ,2));
1156 realT tanZ = sinZ*secZ;
1157 realT x0 = (n_air(lambda_wfs) - n_air(lambda_i)) * m_H*tanZ*secZ;
1160 for(
size_t i = 0; i < m_layer_Cn2.size(); ++i)
1162 x = x0*(1-exp((m_layer_z[i]+m_h_obs)/m_H));
1163 c += m_layer_Cn2[i] * pow( cos(math::pi<realT>()*
k*
k*lambda_i *m_layer_z[i]*secZ), 2) * pow( sin(math::pi<realT>()*x*
k*cos(0.*3.14/180.)), 2);
1169 template<
typename realT>
1172 realT r0lam = r_0(lam_sci);
1174 realT fwhm = 0.98*(lam_sci/r0lam);
1180 template<
typename realT>
1183 realT r0lam = r_0(lam_sci);
1185 realT fwhm = 0.98*(lam_sci/r0lam);
1188 if( L_0(0) > 0) fwhm *= sqrt( 1 - 2.183*pow(r0lam/L_0(0), 0.356));
1193 template<
typename realT>
1196 return 0.428*v_wind()/m_r_0;
1199 template<
typename realT>
1202 return 0.428*pow(m_lam_0/lam_sci, math::six_fifths<realT>())*v_wind()/m_r_0;
1205 template<
typename realT>
1211 template<
typename realT>
1214 return 0.134/f_g(lam_sci);
1217 template<
typename realT>
1222 realT vw = (0.134/tau_0) / 0.428 * m_r_0* pow(lam_sci/m_lam_0, math::six_fifths<realT>());
1226 template<
typename realT>
1229 layer_Cn2({0.2283, 0.0883, 0.0666, 0.1458, 0.3350, 0.1350});
1230 layer_z({500, 1000, 2000, 4000, 8000, 16000});
1231 layer_v_wind({10., 10., 10., 10., 10., 10.});
1232 layer_dir({0.0, 0.0, 0.0, 0.0, 0.0, 0.0});
1239 template<
typename realT>
1242 layer_Cn2( {0.42, 0.029, 0.062, 0.16, 0.11, 0.10, 0.12});
1243 layer_z( {250., 500., 1000., 2000., 4000., 8000., 16000. });
1244 layer_v_wind( {10.0, 10.0, 20.0, 20.0, 25.0, 30.0, 25.0});
1245 layer_dir( {1.05, 1.05, 1.31, 1.31, 1.75, 1.92, 1.75});
1249 L_0({25.0,25.0,25.0,25.0, 25.0, 25.0, 25.0});
1250 l_0({0.0,0,0,0,0,0,0});
1255 template<
typename realT>
1266 L_0(std::vector<realT>({L0}));
1267 l_0(std::vector<realT>({l0}));
1268 layer_Cn2(std::vector<realT>({1}));
1269 layer_z(std::vector<realT>({lz}));
1270 layer_v_wind(std::vector<realT>({vw}));
1271 layer_dir(std::vector<realT>({dir}));
1274 template<
typename realT>
1275 template<
typename iosT>
1278 ios <<
"# Atmosphere Parameters:\n";
1279 ios <<
"# nonKolmogorov = " << std::boolalpha << nonKolmogorov() <<
'\n';
1280 ios <<
"# n_layers = " << n_layers() <<
'\n';
1282 if(!m_nonKolmogorov)
1284 ios <<
"# r_0 = " << r_0() <<
'\n';
1285 ios <<
"# lam_0 = " << lam_0() <<
'\n';
1286 ios <<
"# tau_0 = " << tau_0(lam_0()) <<
'\n';
1287 ios <<
"# FWHM = " << fwhm(lam_0()) <<
'\n';
1288 ios <<
"# layer_Cn2 = ";
1289 for(
size_t i=0;i< n_layers()-1;++i) ios << layer_Cn2()[i] <<
", ";
1290 ios << layer_Cn2()[n_layers()-1] <<
'\n';
1294 ios <<
"# alpha = ";
1295 for(
size_t i=0;i < n_layers()-1;++i) ios << alpha()[i] <<
", ";
1296 ios << alpha()[n_layers()-1] <<
'\n';
1298 for(
size_t i=0;i < n_layers()-1;++i) ios << beta()[i] <<
", ";
1299 ios << beta()[n_layers()-1] <<
'\n';
1300 ios <<
"# beta_0 = ";
1301 for(
size_t i=0;i < n_layers()-1;++i) ios << beta_0()[i] <<
", ";
1302 ios << beta_0()[n_layers()-1] <<
'\n';
1306 for(
size_t i=0;i < n_layers()-1;++i) ios << L_0()[i] <<
", ";
1307 ios << L_0()[n_layers()-1] <<
'\n';
1309 for(
size_t i=0;i < n_layers()-1;++i) ios << l_0()[i] <<
", ";
1310 ios << l_0()[n_layers()-1] <<
'\n';
1312 ios <<
"# layer_v_wind = ";
1313 for(
size_t i=0;i< n_layers()-1;++i) ios << layer_v_wind()[i] <<
", ";
1314 ios << layer_v_wind()[ n_layers()-1] <<
'\n';
1315 ios <<
"# layer_dir = ";
1316 for(
size_t i=0;i< n_layers()-1;++i) ios << layer_dir()[i] <<
", ";
1317 ios << layer_dir()[ n_layers()-1] <<
'\n';
1318 ios <<
"# mean v_wind = " << v_wind() <<
'\n';
1319 ios <<
"# mean dir_wind = " << dir_wind() <<
'\n';
1321 if(!m_nonKolmogorov)
1323 ios <<
"# layer_z = ";
1324 for(
size_t i=0;i < n_layers()-1;++i) ios << layer_z()[i] <<
", ";
1325 ios << layer_z()[ n_layers()-1] <<
'\n';
1326 ios <<
"# mean z = " << z_mean() <<
'\n';
1327 ios <<
"# h_obs = " << h_obs() <<
'\n';
1328 ios <<
"# H = " << H() <<
'\n';
1334 template<
typename realT>
1337 using namespace mx::app;
1339 config.
add(
"atm.r_0" ,
"",
"atm.r_0" , argType::Required,
"atm",
"r_0",
false,
"real" ,
"Fried's parameter [m]");
1340 config.
add(
"atm.lam_0" ,
"",
"atm.lam_0" , argType::Required,
"atm",
"lam_0",
false,
"real" ,
"The reference wavlength for r_0 [m]");
1341 config.
add(
"atm.L_0" ,
"",
"atm.L_0" , argType::Required,
"atm",
"L_0",
false,
"vector<real>",
"Layer outer scales [m]");
1342 config.
add(
"atm.l_0" ,
"",
"atm.l_0" , argType::Required,
"atm",
"l_0",
false,
"vector<real>",
"Layer inner scales [m]");
1343 config.
add(
"atm.layer_z" ,
"",
"atm.layer_z" , argType::Required,
"atm",
"layer_z",
false,
"vector<real>",
"layer heights [m]");
1344 config.
add(
"atm.h_obs" ,
"",
"atm.h_obs" , argType::Required,
"atm",
"h_obs",
false,
"real" ,
"height of observatory [m]");
1345 config.
add(
"atm.H" ,
"",
"atm.H" , argType::Required,
"atm",
"H",
false,
"real" ,
"atmospheric scale heights [m]");
1346 config.
add(
"atm.layer_Cn2" ,
"",
"atm.layer_Cn2" , argType::Required,
"atm",
"layer_Cn2",
false,
"vector<real>",
"Layer Cn^2. Note that this does not set r_0.");
1347 config.
add(
"atm.layer_v_wind" ,
"",
"atm.layer_v_wind" , argType::Required,
"atm",
"layer_v_wind",
false,
"vector<real>",
"Layer wind speeds [m/s]");
1348 config.
add(
"atm.layer_dir" ,
"",
"atm.layer_dir" , argType::Required,
"atm",
"layer_dir",
false,
"vector<real>",
"Layer wind directions [rad]");
1349 config.
add(
"atm.v_wind" ,
"",
"atm.v_wind" , argType::Required,
"atm",
"v_wind",
false,
"real" ,
"Mean windspeed (5/3 momement), rescales layers [m/s]");
1350 config.
add(
"atm.z_mean" ,
"",
"atm.z_mean" , argType::Required,
"atm",
"z_mean",
false,
"real" ,
"Mean layer height (5/3 momemnt), rescales layers [m/s]");
1351 config.
add(
"atm.nonKolmogorov",
"",
"atm.nonKolmogorov", argType::Required,
"atm",
"nonKolmogorov",
false,
"bool" ,
"Set to use a non-Kolmogorov PSD. See alpha and beta.");
1352 config.
add(
"atm.alpha" ,
"",
"atm.alpha" , argType::Required,
"atm",
"alpha" ,
false,
"vector<real>",
"Non-kolmogorov PSD exponent.");
1353 config.
add(
"atm.beta" ,
"",
"atm.beta" , argType::Required,
"atm",
"beta" ,
false,
"vector<real>",
"Non-kolmogorov PSD normalization.");
1354 config.
add(
"atm.beta_0" ,
"",
"atm.beta_0" , argType::Required,
"atm",
"beta_0" ,
false,
"vector<real>",
"Non-kolmogorov PSD constant.");
1357 template<
typename realT>
1366 config(m_lam_0,
"atm.lam_0");
1369 std::vector<realT> lcn2 = m_layer_Cn2;
1370 config(lcn2,
"atm.layer_Cn2");
1371 if(config.
isSet(
"atm.layer_Cn2")) layer_Cn2(lcn2);
1374 config(r0,
"atm.r_0");
1375 if(config.
isSet(
"atm.r_0")) r_0(r0, m_lam_0);
1377 config(m_L_0,
"atm.L_0");
1379 config(m_l_0,
"atm.l_0");
1382 std::vector<realT> layz = m_layer_z;
1383 config(layz,
"atm.layer_z");
1384 if(config.
isSet(
"atm.layer_z")) layer_z(layz);
1386 config(m_h_obs,
"atm.h_obs");
1387 config(m_H,
"atm.H");
1390 std::vector<realT> lvw = m_layer_v_wind;
1391 config(lvw,
"atm.layer_v_wind");
1392 if(config.
isSet(
"atm.layer_v_wind")) layer_v_wind(lvw);
1395 std::vector<realT> ld = m_layer_dir;
1396 config(ld,
"atm.layer_dir");
1397 if(config.
isSet(
"atm.layer_dir")) layer_dir(ld);
1399 realT vw = m_v_wind;
1400 config(vw,
"atm.v_wind");
1401 if(config.
isSet(
"atm.v_wind")) v_wind(vw);
1403 realT zm = m_z_mean;
1404 config(zm,
"atm.z_mean");
1405 if(config.
isSet(
"atm.z_mean")) z_mean(zm);
1407 config(m_nonKolmogorov,
"atm.nonKolmogorov");
1409 std::vector<realT> a = m_alpha;
1410 config(a,
"atm.alpha");
1411 if(config.
isSet(
"atm.alpha")) alpha(a);
1413 std::vector<realT> b = m_beta;
1414 config(b,
"atm.beta");
1415 if(config.
isSet(
"atm.beta")) beta(b);
1417 std::vector<realT> b0 = m_beta_0;
1418 config(b0,
"atm.beta_0");
1419 if(config.
isSet(
"atm.beta_0")) beta_0(b0);
Calculate and provide constants related to adaptive optics.
A class to specify atmosphere parameters and perform related calculations.
void beta(const std::vector< realT > &bet)
Set the vector of layer PSD normalizations.
std::vector< realT > m_beta_0
The PSD constant when in non-Kolmogorov mode.
realT r_0(const realT &lam)
Get the value of Fried's parameter r_0 at the specified wavelength.
realT dir_wind()
Get the weighted mean wind direction.
std::vector< realT > alpha()
Get the vector of PSD indices.
realT lam_0()
Get the current value of the reference wavelength.
std::vector< realT > l_0()
Get the vector of inner scales.
void loadLCO()
Load parameters corresponding to the median atmosphere of the GMT site survey at LCO.
void layer_z(const std::vector< realT > &layz)
Set the vector of layer heights.
std::vector< realT > layer_v_wind()
Get the vector of layer windspeeds.
realT v_wind_mean2()
Get the mean-squared wind speed.
realT X(realT k, realT lam_sci, realT secZ)
The fraction of the turbulence PSD in phase after Fresnel propagation.
std::vector< realT > m_beta
The PSD normalization when in non-Kolmogorov mode.
iosT & dumpAtmosphere(iosT &ios)
Output current parameters to a stream.
realT h_obs()
Get the height of the observatory.
realT l_0(const size_t &n)
Get the value of the inner scale for a single layer.
realT m_z_mean
averaged layer height
realT layer_dir(const int n)
Get the wind direction of a single layer.
realT m_v_wind
averaged windspeed
void beta_0(const std::vector< realT > &bet)
Set the vector of layer PSD constants.
realT L_0(const size_t &n)
Get the value of the outer scale for a single layer.
realT m_dir_wind
averaged direction
std::vector< realT > m_alpha
The PSD exponent when in non-Kolmogorov mode.
std::vector< realT > beta()
Get the vector of PSD normalizations.
realT dY(realT k, realT lam_sci, realT lam_wfs)
The differential fraction of the turbulence PSD in amplitude after Fresnel propagation.
realT tau_0()
Get tau_0 at the reference wavelength.
std::vector< realT > L_0()
Get the vector of outer scales.
void layer_v_wind(const std::vector< realT > &spd)
Set the vector of layer windspeeds.
std::vector< realT > layer_dir()
Get the vector of layer wind directions.
void h_obs(realT nh)
Set the height of the observatory.
void loadGuyon2005()
Load the default atmosphere model from Guyon (2005).
void nonKolmogorov(const bool &nk)
Set the value of m_nonKolmogorov.
void layer_dir(const std::vector< realT > &d)
Set the vector of layer wind directions.
realT m_H
The atmospheric scale height, in m.
void L_0(const std::vector< realT > &L0)
Set the vector of layer outer scales.
void loadConfig(app::appConfigurator &config)
Load the configuration of this class from a configurator.
void update_z_mean()
Recalculate m_z_mean.
realT fwhm(realT lam_sci)
Calculate the full-width at half-maximum of a seeing limited image for this atmosphere for a large te...
_realT realT
The real floating type in which all calculations are performed.
bool m_nonKolmogorov
Flag indicating if non-Kolmogorov PSD parameters are used.
void alpha(const std::vector< realT > &alph)
Set the vector of layer PSD indices.
realT beta_0(const size_t &n)
Return the PSD constant for a single layer.
realT beta(const size_t &n)
Return the PSD normalization for a single layer.
realT fwhm0(realT lam_sci)
Calculate the full-width at half-maximum of a seeing limited image for this atmosphere for a small te...
realT X_Z(realT k, realT lambda_sci, realT lambda_wfs, realT secZ)
void setupConfig(app::appConfigurator &config)
Setup the configurator to configure this class.
std::vector< realT > m_L_0
The outer scale, in m.
void r_0(const realT &r0, const realT &l0)
Set the value of Fried's parameter and the reference wavelength.
void H(realT nH)
Set the atmospheric scale height.
aoAtmosphere()
Constructor.
std::vector< realT > m_layer_dir
Vector of layer wind directions, in radians.
std::vector< realT > layer_Cn2()
Get the vector of layer strengths.
void l_0(const std::vector< realT > &l0)
Set the vector of layer inner scales.
realT f_g(realT lam_sci)
Get the greenwood frequency at a specified wavelength.
realT m_r_0
Fried's parameter, in m.
void tau_0(realT tau_0, realT lam_sci)
Scale v_wind so that tau_0 has the specified value at the specified wavelength.
realT H()
Get the atmospheric scale height.
bool nonKolmogorov()
Return the value of m_nonKolmogorov.
void setSingleLayer(realT r0, realT lam0, realT L0, realT l0, realT lz, realT vw, realT dir)
Set a single layer model.
realT v_wind()
Get the 5/3 moment weighted mean wind speed.
std::vector< realT > layer_z()
Get the vector layer heights.
void layer_Cn2(const std::vector< realT > &cn2, const realT l0=0)
Set the vector layer strengths, possibly calculating r_0.
realT layer_Cn2(const int n)
Get the strength of a single layer.
realT m_h_obs
Height of the observatory above sea level, in m.
realT alpha(const size_t &n)
Return the PSD index for a single layer.
std::vector< realT > m_l_0
The inner scale of each layer, in m.
realT Y(realT k, realT lam_sci, realT secZ)
The fraction of the turbulence PSD in amplitude after Fresnel propagation.
realT layer_v_wind(const int n)
Get the wind speed of a single layer.
realT f_g()
Get the greenwood frequency at the reference wavelength.
realT z_mean()
Get the weighted mean layer height.
int checkLayers()
Checks if layer vectors have consistent length.
std::vector< realT > m_layer_Cn2
Vector of layer strengths.
std::vector< realT > m_layer_z
Vector of layer heights, in m, above the observatory.
size_t n_layers()
Get the number of layers.
std::vector< realT > beta_0()
Get the vector of PSD constants.
bool m_v_wind_updated
whether or not m_v_wind has been updated after changes
realT r_0()
Get the value of Fried's parameter r_0 at the reference wavelength lam_0.
std::vector< realT > m_layer_v_wind
Vector of layer wind speeds, in m/s.
realT v_wind_mean()
Get the mean wind speed.
void z_mean(const realT &zm)
Set the weighted mean m_z_mean and renormalize the layer heights.
realT tau_0(realT lam_sci)
Get tau_0 at a specified wavelength.
void v_wind(const realT &vw)
Set the weighted mean m_v_wind and renormalize the layer wind speeds.
realT m_lam_0
Wavelength of Fried's parameter, in m.
bool m_z_mean_updated
whether or not m_z_mean has been updated after changes
realT dX(realT k, realT lam_sci, realT lam_wfs)
The differential fraction of the turbulence PSD in phase after Fresnel propagation.
realT layer_z(const size_t n)
Get the height of a single layer.
void update_v_wind()
Recalculate m_v_wind.
constexpr units::realT c()
The speed of light.
constexpr units::realT k()
Boltzmann Constant.
Class to manage a set of configurable values, and read their values from config/ini files and the com...
void add(const configTarget &tgt)
Add a configTarget.
bool isSet(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Check if a target has been set by the configuration.