29#ifndef mx_AO_sim_turbLayer_hpp
30#define mx_AO_sim_turbLayer_hpp
36#include "../../improc/imageTransforms.hpp"
45template <
typename _aoSystemT,
class _verboseT>
54template <
typename _aoSystemT,
class _verboseT = mx::verbose::d>
57 typedef _aoSystemT aoSystemT;
58 typedef _verboseT verboseT;
60 typedef typename aoSystemT::realT realT;
61 typedef Eigen::Array<realT, -1, -1> imageT;
82 imageT m_shiftPhaseWP;
84 imageT m_shiftPhaseWork;
103 void shift( realT dt );
124template <
typename aoSystemT,
class verboseT>
134 if( m_parent ==
nullptr )
139 if( m_parent->aosys() ==
nullptr )
144 realT vwind = m_parent->aosys()->atm.layer_v_wind( m_layerNo );
145 realT dwind = m_parent->aosys()->atm.layer_dir( m_layerNo );
146 realT pupD = m_parent->aosys()->D();
147 uint32_t wfSz = m_parent->wfSz();
149 m_dx = vwind * cos( dwind ) / ( pupD / wfSz );
150 m_dy = vwind * sin( dwind ) / ( pupD / wfSz );
155template <
typename aoSystemT,
class verboseT>
156uint32_t turbLayer<aoSystemT, verboseT>::layerNo()
161template <
typename aoSystemT,
class verboseT>
162uint32_t turbLayer<aoSystemT, verboseT>::scrnSz()
167template <
typename aoSystemT,
class verboseT>
168void turbLayer<aoSystemT, verboseT>::alloc()
170 if( m_parent ==
nullptr )
175 if( m_parent->aosys() ==
nullptr )
180 m_phase.resize( m_scrnSz, m_scrnSz );
182 uint32_t wfSz = m_parent->wfSz();
184 uint32_t buffSz = m_parent->buffSz();
186 m_shiftPhaseWP.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
188 m_shiftPhase.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
190 m_shiftPhaseWork.resize( wfSz + 2 * buffSz, wfSz + 2 * buffSz );
196 m_last_wdx = m_scrnSz + 1;
197 m_last_wdy = m_scrnSz + 1;
200 realT r0 = m_parent->aosys()->atm.r_0( m_parent->aosys()->lam_sci() );
201 realT L0 = m_parent->aosys()->atm.L_0( m_layerNo );
202 realT l0 = m_parent->aosys()->atm.l_0( m_layerNo );
204 m_psd.resize( m_scrnSz, m_scrnSz );
206 m_freq.resize( m_scrnSz, m_scrnSz );
207 sigproc::frequencyGrid<imageT>( m_freq, m_parent->aosys()->D() / wfSz );
209 realT beta = 0.0218 / pow( r0, 5. / 3. );
210 realT sqrt_alpha = 0.5 * 11. / 3.;
215 L02 = 1.0 / ( L0 * L0 );
223 #pragma omp parallel for
224 for(
size_t jj = 0; jj < m_scrnSz; ++jj )
226 for(
size_t ii = 0; ii < m_scrnSz; ++ii )
229 if( m_freq( ii, jj ) == 0 && L02 == 0 )
235 p = beta / pow( pow( m_freq( ii, jj ), 2 ) + L02, sqrt_alpha );
238 p *= exp( -1 * pow( m_freq( ii, jj ) * l0, 2 ) );
244 if( m_parent->aosys()->psd.subPiston() )
249 if( m_parent->aosys()->psd.subTipTilt() )
255 m_psd( ii, jj ) = sqrt( p * ( 1.0 - Ppiston - Ptiptilt ) );
259 if( m_parent->shLevel() > 0 )
262 if( m_parent->outerSubHarmonics() )
268 m_psd( 0, 1 ) *= 0.5 * 0.5 * onoff;
269 m_psd( 1, 0 ) *= 0.5 * 0.5 * onoff;
270 m_psd( m_psd.rows() - 1, 0 ) *= 0.5 * 0.5 * onoff;
271 m_psd( 0, m_psd.cols() - 1 ) *= 0.5 * 0.5 * onoff;
273 m_psd( 1, 1 ) *= 0.75 * 0.75 * onoff;
274 m_psd( m_psd.rows() - 1, m_psd.cols() - 1 ) *= 0.75 * 0.75 * onoff;
275 m_psd( m_psd.rows() - 1, 1 ) *= 0.75 * 0.75 * onoff;
276 m_psd( 1, m_psd.cols() - 1 ) *= 0.75 * 0.75 * onoff;
280template <
typename aoSystemT,
class verboseT>
283 m_freq.resize( 0, 0 );
284 m_psd.resize( 0, 0 );
287template <
typename aoSystemT,
class verboseT>
293 ddx = m_x0 + m_dx * dt;
294 ddy = m_y0 + m_dy * dt;
296 wdx = (int)trunc( ddx );
299 wdy = (int)trunc( ddy );
307 m_shiftPhase = m_phase;
312 if( wdx != m_last_wdx || wdy != m_last_wdy )
326template <
typename aoSystemT,
class verboseT>
332template <
typename aoSystemT,
class verboseT>
338 ddx = uniVar * ( m_scrnSz );
339 ddy = uniVar * ( m_scrnSz );
341 wdx = (int)trunc( ddx );
343 wdy = (int)trunc( ddy );
354 if( ddx != 0 || ddy != 0 )
360 m_shiftPhase = m_shiftPhaseWP;
Augments an exception with the source file and line.
A random number type, which functions like any other arithmetic type.
@ 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 floatT six_fifths()
Return 6/5 in the specified precision.
A turbulent atmosphere simulator.
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.