29#ifndef mx_AO_sim_turbLayer_hpp
30#define mx_AO_sim_turbLayer_hpp
39#include "../../math/constants.hpp"
52template <
typename _aoSystemT,
class _verboseT>
61template <
typename _aoSystemT,
class _verboseT = mx::verbose::d>
64 typedef _aoSystemT aoSystemT;
65 typedef _verboseT verboseT;
67 typedef typename aoSystemT::realT realT;
68 typedef Eigen::Array<realT, -1, -1> imageT;
89 imageT m_shiftPhaseWP;
91 imageT m_shiftPhaseWork;
110 void shift( realT dt );
131template <
typename aoSystemT,
class verboseT>
141 if( m_parent ==
nullptr )
146 if( m_parent->aosys() ==
nullptr )
151 realT vwind = m_parent->
aosys()->atm.layer_v_wind( m_layerNo );
152 realT dwind = m_parent->aosys()->atm.layer_dir( m_layerNo );
153 realT pupD = m_parent->aosys()->D();
154 uint32_t wfSz = m_parent->wfSz();
156 m_dx = vwind * cos( dwind ) / ( pupD / wfSz );
157 m_dy = vwind * sin( dwind ) / ( pupD / wfSz );
162template <
typename aoSystemT,
class verboseT>
163uint32_t turbLayer<aoSystemT, verboseT>::layerNo()
168template <
typename aoSystemT,
class verboseT>
169uint32_t turbLayer<aoSystemT, verboseT>::scrnSz()
174template <
typename aoSystemT,
class verboseT>
175void turbLayer<aoSystemT, verboseT>::alloc()
177 if( m_parent ==
nullptr )
182 if( m_parent->aosys() ==
nullptr )
187 m_phase.resize( m_scrnSz, m_scrnSz );
189 uint32_t wfSz = m_parent->wfSz();
191 uint32_t buffSz = m_parent->buffSz();
193 m_shiftPhaseWP.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
195 m_shiftPhase.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
197 m_shiftPhaseWork.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
203 m_last_wdx = m_scrnSz + 1;
204 m_last_wdy = m_scrnSz + 1;
207 realT r0 = m_parent->aosys()->atm.r_0( m_parent->aosys()->lam_sci() );
208 realT L0 = m_parent->aosys()->atm.L_0( m_layerNo );
209 realT l0 = m_parent->aosys()->atm.l_0( m_layerNo );
211 m_psd.resize( m_scrnSz, m_scrnSz );
213 m_freq.resize( m_scrnSz, m_scrnSz );
216 realT beta = 0.0218 / pow( r0, 5. / 3. );
217 realT sqrt_alpha = 0.5 * 11. / 3.;
222 L02 = 1.0 / ( L0 * L0 );
230 #pragma omp parallel for
231 for(
size_t jj = 0; jj < m_scrnSz; ++jj )
233 for(
size_t ii = 0; ii < m_scrnSz; ++ii )
236 if( m_freq( ii, jj ) == 0 && L02 == 0 )
242 p = beta / pow( pow( m_freq( ii, jj ), 2 ) + L02, sqrt_alpha );
245 p *= exp( -1 * pow( m_freq( ii, jj ) * l0, 2 ) );
251 if( m_parent->aosys()->psd.subPiston() )
256 if( m_parent->aosys()->psd.subTipTilt() )
262 m_psd( ii, jj ) = sqrt( p * ( 1.0 - Ppiston - Ptiptilt ) );
266 if( m_parent->shLevel() > 0 )
269 if( m_parent->outerSubHarmonics() )
275 m_psd( 0, 1 ) *= 0.5 * 0.5 * onoff;
276 m_psd( 1, 0 ) *= 0.5 * 0.5 * onoff;
277 m_psd( m_psd.rows() - 1, 0 ) *= 0.5 * 0.5 * onoff;
278 m_psd( 0, m_psd.cols() - 1 ) *= 0.5 * 0.5 * onoff;
280 m_psd( 1, 1 ) *= 0.75 * 0.75 * onoff;
281 m_psd( m_psd.rows() - 1, m_psd.cols() - 1 ) *= 0.75 * 0.75 * onoff;
282 m_psd( m_psd.rows() - 1, 1 ) *= 0.75 * 0.75 * onoff;
283 m_psd( 1, m_psd.cols() - 1 ) *= 0.75 * 0.75 * onoff;
287template <
typename aoSystemT,
class verboseT>
290 m_freq.resize( 0, 0 );
291 m_psd.resize( 0, 0 );
294template <
typename aoSystemT,
class verboseT>
300 ddx = m_x0 + m_dx * dt;
301 ddy = m_y0 + m_dy * dt;
303 wdx =
static_cast<int>( std::floor( ddx ) );
306 wdy =
static_cast<int>( std::floor( ddy ) );
309 wdx %=
static_cast<int>( m_scrnSz );
310 wdy %=
static_cast<int>( m_scrnSz );
319 m_shiftPhase = m_phase;
323 m_shiftPhase = m_shiftPhaseWP;
328 if( wdx != m_last_wdx || wdy != m_last_wdy || m_last_wdx == m_scrnSz + 1 || m_last_wdy == m_scrnSz + 1 )
342template <
typename aoSystemT,
class verboseT>
348template <
typename aoSystemT,
class verboseT>
354 ddx =
uniVar * ( m_scrnSz );
355 ddy =
uniVar * ( m_scrnSz );
357 wdx = (int)trunc( ddx );
359 wdy = (int)trunc( ddy );
370 if( ddx != 0 || ddy != 0 )
376 m_shiftPhase = m_shiftPhaseWP;
The mxlib error reporting system.
The mxlib exception class.
@ exception
An exception was thrown.
@ paramnotset
A parameter was not set.
T2 jincN(const T1 &v, const T2 &x)
The JincN function.
T jinc(const T &x)
The Jinc function.
constexpr T pi()
Get the value of pi.
int frequencyGrid(std::vector< realT > &vec, realParamT dt, bool fftOrder=true)
Create a 1-D frequency grid.
randomT< realT, std::mt19937_64, std::uniform_real_distribution< realT > > uniDistT
Alias for a uniform random variate.
Declares and defines the Jinc and Jinc2 functions.
Declares and defines a class for filtering with PSDs.
Tools for working with PSDs.
Defines a random number type.
A turbulent atmosphere simulator.
void aosys(aoSystemT *aos)
Set the pointer to an AO system object.
Simulation of a single turbulent layer.
void genDealloc()
Deallocate memory necessary for phase screen generation.
mx::math::uniDistT< realT > uniVar
Uniform deviate, used in shiftRandom.
void shift(realT dt)
Shift to a timestep.
void shiftRandom(bool nofract=false)
Shift by a random amount using the uniform distribution.
void initRandom()
Seed the uniform deviation. Call this if you intend to use shiftRandom.