diff --git a/include/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.h b/include/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.h
index e72f1c81e119b700727be7d66b57118f6da5f08c..fb3027c4559df55235ea0dbef5ad7a2470924e71 100644
--- a/include/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.h
+++ b/include/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.h
@@ -47,16 +47,22 @@ namespace ITAPropagationPathSim
 				Simulation::Settings settings;
 
 			public:
-				inline CEngine( ) { pExternalWatcher = std::make_shared<CAbortAtMaxTime>( ); };
-				inline CEngine( std::shared_ptr<IExternalWatcher> pWatcher ) : pExternalWatcher( pWatcher ) { };
+				CEngine( bool bSuppressWarnings = false );
+				CEngine( std::shared_ptr<IExternalWatcher> pWatcher, bool bSuppressWarnings = false );
 
 			public:
+				// Initializes rays with given source position and initial direction, traces and returns them
 				std::vector<std::shared_ptr<CRay>> Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const VistaVector3D& m_v3SourcePosition,
 				                                        const std::vector<VistaVector3D>& v3RayDirections ) const;
-				void Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::set<std::shared_ptr<CRay>>& rays ) const;
+				// Traces given rays and returns true if all rays were inside valid bounds of atmosphere
+				bool Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::set<std::shared_ptr<CRay>>& rays ) const;
 
 			private:
-				void TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::vector<std::shared_ptr<CRay>>& rays ) const;
+				// Traces rays and returns true if all rays were inside valid bounds of atmosphere
+				bool TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::vector<std::shared_ptr<CRay>>& rays ) const;
+
+				bool m_bSuppressWarnings;              // If set to true, suppresses out of atmosphere bounds warning
+				bool m_bOutOfAtmosphereBounds = false; // Indicates whether last Run() call used data above the specified limit of the atmosphere
 			};
 		} // namespace Simulation
 	}     // namespace AtmosphericRayTracing
diff --git a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/EigenrayEngine.cpp b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/EigenrayEngine.cpp
index ddb63f4464c18f2ff2426c76445b89250667d219..5864361dcf62b795903a2f71076128a2f870cf24 100644
--- a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/EigenrayEngine.cpp
+++ b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/EigenrayEngine.cpp
@@ -34,16 +34,20 @@ std::vector<std::shared_ptr<CRay>> ITAPropagationPathSim::AtmosphericRayTracing:
 
 	RayVector eigenrays;
 	bool bAccuracyReached = true;
+	bool bRaysInsideAtmosphereBounds = true;
 	for( int reflectionOrder = 0; reflectionOrder < initialRayGrids.size( ); reflectionOrder++ )
 	{
 		CAdaptiveWorker worker( initialRayGrids[reflectionOrder], receiverPosition, simulationSettings, eigenraySettings, reflectionOrder );
 		eigenrays.push_back( worker.Run( atmosphere ) );
 		viTotalNumRaysTraced.push_back( worker.TotalNumRaysTraced( ) );
 		bAccuracyReached &= eigenrays.back( )->ReceiverHit( );
+		bRaysInsideAtmosphereBounds &= worker.RaysInsideAtmosphereBounds( );
 	}
 
 	if( !bAccuracyReached )
 		ART_WARN( "EigenraySearch::Engine: Could not find eigenray(s) with proper accuracy. Abort criterion reached." );
+	if( !bRaysInsideAtmosphereBounds )
+		ART_WARN( "EigenraySearch::Engine: Maximum altitude of atmosphere exceeded for at least one ray during eigenray search. Results should be treated with care." );
 
 	return eigenrays;
 }
diff --git a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.cpp b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.cpp
index 70c4a7d53dc1ba8ff161e91952845a59e05dc5ce..180fd3d0acb6ff4d3e34776241079bf0374be93e 100644
--- a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.cpp
+++ b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.cpp
@@ -62,6 +62,7 @@ EigenraySearch::CWorkerBase::CWorkerBase( const VistaVector3D& sourcePosition, c
     , m_v3ReceiverPosition( receiverPosition )
     , m_rayTracingAbortSettings( abortSettings )
     , m_v3MirroredReceiverPosition( receiverPosition )
+    , m_simulationEngine( Simulation::CEngine(true) ) //Suppress warnings in simulation engine to catch them in this one
 {
 	m_simulationEngine.settings            = simSettings;
 	m_v3MirroredReceiverPosition[Vista::Z] = -m_v3MirroredReceiverPosition[Vista::Z];
@@ -76,7 +77,7 @@ const VistaVector3D& EigenraySearch::CWorkerBase::VirtualReceiverPosition( const
 void EigenraySearch::CWorkerBase::RunRayTracing( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::set<RayPtr>& rays )
 {
 	m_pSimulationWatcher->InitRayReceiverDistances( rays );
-	m_simulationEngine.Run( atmosphere, rays );
+	m_bRaysInsideAtmosphereBounds &= m_simulationEngine.Run( atmosphere, rays );
 	m_iTotalNumRaysTraced += int( rays.size( ) );
 }
 EigenraySearch::RayPtr EigenraySearch::CWorkerBase::FindMinimumDistanceRay( const std::set<RayPtr>& rays, const int reflectionOrder ) const
@@ -265,7 +266,7 @@ void EigenraySearch::CAdaptiveWorker::CalculateEigenraySpreadingLoss( const ITAG
 			dDeltaPhi *= 10;
 
 		m_adaptiveRayGrid.ZoomIntoRay( m_pMinDistanceRay, m_rayAdaptationSettings.accuracy.maxAngleForGeomSpreading, dDeltaPhi );
-		auto tmpSimulationEngine     = Simulation::CEngine( std::make_shared<Simulation::CAbortAtMaxTime>( time ) );
+		auto tmpSimulationEngine     = Simulation::CEngine( std::make_shared<Simulation::CAbortAtMaxTime>( time ), true );
 		tmpSimulationEngine.settings = m_simulationEngine.settings;
 		tmpSimulationEngine.Run( atmosphere, m_adaptiveRayGrid.NewRaysOfLastAdaptation( ) );
 	}
diff --git a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.h b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.h
index 4be890aef4f24c8579ea34ffdae3eaa6aa434e2a..5487e7e12d69a667e0554809ebbfa4af63dc5406 100644
--- a/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.h
+++ b/src/ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/Worker.h
@@ -93,6 +93,7 @@ namespace ITAPropagationPathSim
 				RayTracingAbortSettings m_rayTracingAbortSettings;
 				VistaVector3D m_v3SourcePosition;
 				int m_iTotalNumRaysTraced = 0;
+				bool m_bRaysInsideAtmosphereBounds = true;
 
 			private:
 				VistaVector3D m_v3ReceiverPosition;
@@ -103,6 +104,7 @@ namespace ITAPropagationPathSim
 				             const RayTracingAbortSettings& abortSettings );
 				// Returns the total number of rays traced by this worker
 				inline int TotalNumRaysTraced( ) { return m_iTotalNumRaysTraced; };
+				inline bool RaysInsideAtmosphereBounds( ) { return m_bRaysInsideAtmosphereBounds; };
 
 			protected:
 				inline const VistaVector3D& ReceiverPosition( ) const { return m_v3ReceiverPosition; };
diff --git a/src/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.cpp b/src/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.cpp
index 2cec7428430efaed4988e4156257768a6bd842c1..9e0f672560dc8add54f0680849762d1171837ac4 100644
--- a/src/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.cpp
+++ b/src/ITAPropagationPathSim/AtmosphericRayTracing/Simulation/ARTEngine.cpp
@@ -3,9 +3,11 @@
 // ITA includes
 #include "AdaptiveSolver.h"
 
+#include <ART_instrumentation.h>
 #include <ITAPropagationPathSim/AtmosphericRayTracing/ODESolver/ODESolver.h>
 
 // STD
+#include <algorithm>
 #include <cmath>
 
 // OMP
@@ -90,7 +92,8 @@ namespace ITAPropagationPathSim
 					while( !rExternalWatcher.AbortRequested( pRay ) )
 						ExtendRayByOnePeriod( );
 				};
-				inline void CalculateRay( const ITAGeo::CStratifiedAtmosphere& atmosphere )
+				//Calculates the path using given atmosphere for initialized ray and returns its maximum altitude
+				inline double CalculateRay( const ITAGeo::CStratifiedAtmosphere& atmosphere )
 				{
 					VistaVector3D r = pRay->LastPoint( );
 					double rz       = r[Vista::Z];
@@ -100,6 +103,7 @@ namespace ITAPropagationPathSim
 					VistaVector3D s = ODESolver::NormalToSlowness( n, rz, atmosphere );
 
 					VistaVector3D rNew, sNew;
+					double rzMax = rz;
 					while( !rExternalWatcher.AbortRequested( pRay ) )
 					{
 						solver.Process( r, s, atmosphere, rNew, sNew );
@@ -121,12 +125,12 @@ namespace ITAPropagationPathSim
 							}
 
 							if( rExternalWatcher.AbortRequested( pRay ) )
-								return;
+								return rzMax;
 
 							if( pRay->ReflectionOrder( ) >= 2 ) // Ray is periodic
 							{
 								ExtendRayPeriodically( );
-								return;
+								return rzMax;
 							}
 						}
 
@@ -135,14 +139,18 @@ namespace ITAPropagationPathSim
 						time += dt;
 						pRay->Append( r, n, time );
 						rExternalWatcher.ProcessRay( pRay );
+
+						rzMax = std::max( rzMax, (double)r[Vista::Z] );
 					}
+					return rzMax;
 				};
 
 			public:
-				inline void TraceRay( const ITAGeo::CStratifiedAtmosphere& atmosphere )
+				inline double TraceRay( const ITAGeo::CStratifiedAtmosphere& atmosphere )
 				{
-					CalculateRay( atmosphere );
+					const double rzMax = CalculateRay( atmosphere );
 					rExternalWatcher.FinalizeRay( pRay );
+					return rzMax;
 				};
 			};
 		} // namespace Simulation
@@ -150,6 +158,17 @@ namespace ITAPropagationPathSim
 } // namespace ITAPropagationPathSim
 
 
+CEngine::CEngine( bool bSuppressWarnings ) : m_bSuppressWarnings( bSuppressWarnings )
+{
+	pExternalWatcher = std::make_shared<CAbortAtMaxTime>( );
+}
+
+CEngine::CEngine( std::shared_ptr<IExternalWatcher> pWatcher, bool bSuppressWarnings )
+    : pExternalWatcher( pWatcher )
+    , m_bSuppressWarnings( bSuppressWarnings )
+{
+}
+
 std::vector<std::shared_ptr<CRay>> CEngine::Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const VistaVector3D& m_v3SourcePosition,
                                                  const std::vector<VistaVector3D>& v3RayDirections ) const
 {
@@ -161,17 +180,18 @@ std::vector<std::shared_ptr<CRay>> CEngine::Run( const ITAGeo::CStratifiedAtmosp
 	TraceRays( atmosphere, rays );
 	return rays;
 }
-void CEngine::Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::set<std::shared_ptr<CRay>>& rays ) const
+bool CEngine::Run( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::set<std::shared_ptr<CRay>>& rays ) const
 {
-	TraceRays( atmosphere, std::vector<std::shared_ptr<CRay>>( rays.begin( ), rays.end( ) ) );
+	return TraceRays( atmosphere, std::vector<std::shared_ptr<CRay>>( rays.begin( ), rays.end( ) ) );
 }
 
-void CEngine::TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::vector<std::shared_ptr<CRay>>& rays ) const
+bool CEngine::TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::vector<std::shared_ptr<CRay>>& rays ) const
 {
 	std::shared_ptr<IExternalWatcher> simulationWatcher = pExternalWatcher;
 	if( !simulationWatcher )
 		ITA_EXCEPT_INVALID_PARAMETER( "Simulation-Engine: Interface to external watcher is not set. Cannot run simulation." );
 
+	std::vector<double> vdMaxRayAltitude( rays.size( ) );
 	if( settings.bMultiThreading )
 	{
 #pragma omp parallel for schedule( static )
@@ -181,7 +201,7 @@ void CEngine::TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const
 				continue;
 
 			auto worker = CWorker( rays[idx], settings, *simulationWatcher );
-			worker.TraceRay( atmosphere );
+			vdMaxRayAltitude[idx] = worker.TraceRay( atmosphere );
 		}
 	}
 	else
@@ -192,7 +212,12 @@ void CEngine::TraceRays( const ITAGeo::CStratifiedAtmosphere& atmosphere, const
 				continue;
 
 			auto worker = CWorker( rays[idx], settings, *simulationWatcher );
-			worker.TraceRay( atmosphere );
+			vdMaxRayAltitude[idx] = worker.TraceRay( atmosphere );
 		}
 	}
+	const double dMaxRayAltitude = *std::max_element( vdMaxRayAltitude.begin( ), vdMaxRayAltitude.end( ) );
+	const bool bInsideBounds     = atmosphere.InsideBounds( dMaxRayAltitude );
+	if( !m_bSuppressWarnings && !bInsideBounds )
+		ART_WARN( "Simulation::Engine: Maximum altitude of atmosphere exceeded for at least one ray. Results should be treated with care." );
+	return bInsideBounds;
 }