...
 
Commits (2)
  • Philipp Schäfer's avatar
    ART - Simulation Engine · 869d3a92
    Philipp Schäfer authored
    - now stores interface to external watcher as shared ptr
    
    ART - Eigenray Engine
    - worker now hold an external watcher instead of being derived from it
    869d3a92
  • Philipp Schäfer's avatar
    ART - Eigenray Engine · 726d36fe
    Philipp Schäfer authored
    - Simulation watcher now works with pointers to receiver positions
    
    ART - Simulation::IExternalWatcher
    - now works with shared_ptr and not references to shared_ptr
    726d36fe
......@@ -43,11 +43,15 @@ namespace ITAPropagationPathSim
class ITA_PROPAGATION_PATH_SIM_API CEngine
{
public:
IExternalWatcher& externalWatcher; //!< Reference to externally defined abort criterion.
std::shared_ptr<IExternalWatcher> pExternalWatcher; //!< Reference to externally defined abort criterion.
Simulation::Settings settings;
public:
CEngine(IExternalWatcher& watcher = CAbortAtMaxTime()): externalWatcher(watcher) {}
inline CEngine()
{
pExternalWatcher = std::make_shared<CAbortAtMaxTime>();
};
inline CEngine(std::shared_ptr<IExternalWatcher> pWatcher) : pExternalWatcher(pWatcher) {};
public:
std::vector<std::shared_ptr<CRay>> Run(const ITAGeo::CStratifiedAtmosphere& atmosphere, const VistaVector3D& v3SourcePosition, const std::vector<VistaVector3D>& v3RayDirections) const;
......
......@@ -36,21 +36,21 @@ namespace ITAPropagationPathSim
{
public:
//! Returns true if the abort criterion for tracing the given ray is reached
virtual bool AbortRequested(const std::shared_ptr<CRay>& pRay) const = 0;
virtual bool AbortRequested(const std::shared_ptr<CRay> pRay) const = 0;
//! Allows additional proecssing of the ray at the end of each time step.
virtual void ProcessRay(std::shared_ptr<CRay>&) const = 0;
virtual void ProcessRay(std::shared_ptr<CRay>) const = 0;
//! This is called after the tracing of a ray is finished.
virtual void FinalizeRay(std::shared_ptr<CRay>&) const = 0;
virtual void FinalizeRay(std::shared_ptr<CRay>) const = 0;
};
class ITA_PROPAGATION_PATH_SIM_API CAbortAtMaxTime : public IExternalWatcher
{
private:
double dTMax;
public:
inline CAbortAtMaxTime(double tMax = 30) : dTMax(tMax) {}
inline bool AbortRequested(const std::shared_ptr<CRay>& pRay) const { return pRay->LastTimeStamp() >= dTMax; }
inline virtual void ProcessRay(std::shared_ptr<CRay>&) const {}
inline virtual void FinalizeRay(std::shared_ptr<CRay>&) const {}
inline CAbortAtMaxTime(double tMax = 30) : dTMax(tMax) {};
inline bool AbortRequested(const std::shared_ptr<CRay> pRay) const { return pRay->LastTimeStamp() >= dTMax; };
inline virtual void ProcessRay(std::shared_ptr<CRay>) const {};
inline virtual void FinalizeRay(std::shared_ptr<CRay>) const {};
};
enum ITA_PROPAGATION_PATH_SIM_API SolverMethod
......
#include "Worker.h"
// ITA includes
// Vista includes
//#include <VistaInterProcComm/Concurrency/VistaThread.h>
// STD
#include <algorithm>
using namespace ITAPropagationPathSim::AtmosphericRayTracing;
#pragma region WORKERBASE
EigenraySearch::CWorkerBase::CWorkerBase(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings)
: v3SourcePosition(sourcePosition), v3ReceiverPosition(receiverPosition), rayTracingAbortSettings(abortSettings), v3MirroredReceiverPosition(receiverPosition), simulationEngine(Simulation::CEngine(*this))
#pragma region EigenraySearchWatcher
EigenraySearch::CEigenraySearchWatcher::CEigenraySearchWatcher(const V3DConstPtrVector& vv3ReceiverPositions, const double& tMax, const int& maxReflOrder)
: m_vpReceiverPositions(vv3ReceiverPositions)
, m_dTMax(tMax)
, m_iMaxReflectionOrder(maxReflOrder)
{
simulationEngine.settings = simSettings;
v3MirroredReceiverPosition[Vista::Z] = -v3MirroredReceiverPosition[Vista::Z];
}
void EigenraySearch::CWorkerBase::ProcessRay(RayPtr& pRay) const
bool EigenraySearch::CEigenraySearchWatcher::AbortRequested(const std::shared_ptr<CRay> pRay) const
{
UpdateMinimumReceiverDistance(pRay);
//TODO: For CAdaptiveWorker: Track whether distance increased and use this for abortion
return pRay->LastTimeStamp() >= m_dTMax || pRay->ReflectionOrder() > m_iMaxReflectionOrder;
}
void EigenraySearch::CWorkerBase::FinalizeRay(RayPtr& pRay) const
void EigenraySearch::CEigenraySearchWatcher::ProcessRay(std::shared_ptr<CRay> pRay) const
{
for each (const VistaVector3D* pReceiverPos in m_vpReceiverPositions)
pRay->UpdateMinimumReceiverDistance(*pReceiverPos);
}
void EigenraySearch::CEigenraySearchWatcher::FinalizeRay(std::shared_ptr<CRay> pRay) const
{
pRay->FinalizeMinimumReceiverDistances();
}
#pragma endregion
#pragma region WORKERBASE
EigenraySearch::CWorkerBase::CWorkerBase(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings)
: v3SourcePosition(sourcePosition)
, v3ReceiverPosition(receiverPosition)
, rayTracingAbortSettings(abortSettings)
, v3MirroredReceiverPosition(receiverPosition)
{
simulationEngine.settings = simSettings;
v3MirroredReceiverPosition[Vista::Z] = -v3MirroredReceiverPosition[Vista::Z];
}
const VistaVector3D& EigenraySearch::CWorkerBase::VirtualReceiverPosition(const int reflectionOrder) const
{
......@@ -36,10 +52,10 @@ const VistaVector3D& EigenraySearch::CWorkerBase::VirtualReceiverPosition(const
}
EigenraySearch::RayPtr EigenraySearch::CWorkerBase::FindMinimumDistanceRay(const std::set<RayPtr>& rays, const int reflectionOrder)
{
float dMin = _FMAX;
float dMin = FLT_MAX;
const VistaVector3D& receiverPos = VirtualReceiverPosition(reflectionOrder);
RayPtr pMinRay = nullptr;
for each (const RayPtr & pRay in rays)
for each (const RayPtr& pRay in rays)
{
const CRayReceiverData* distanceData = pRay->ReceiverDistanceData(receiverPos);
if (distanceData && distanceData->distance < dMin)
......@@ -55,21 +71,15 @@ EigenraySearch::RayPtr EigenraySearch::CWorkerBase::FindMinimumDistanceRay(const
#pragma region INITIAL WORKER
bool EigenraySearch::CInitialWorker::AbortRequested(const RayPtr& pRay) const
{
return pRay->LastTimeStamp() >= rayTracingAbortSettings.maxTime || pRay->ReflectionOrder() > rayTracingAbortSettings.maxReflectionOrder+1;
}
void EigenraySearch::CInitialWorker::UpdateMinimumReceiverDistance(RayPtr& pRay) const
EigenraySearch::CInitialWorker::CInitialWorker(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings)
: CWorkerBase(sourcePosition, receiverPosition, simSettings, abortSettings)
{
pRay->UpdateMinimumReceiverDistance( ReceiverPosition() );
pRay->UpdateMinimumReceiverDistance( MirroredReceiverPosition() );
V3DConstPtrVector receiverPositions = { &ReceiverPosition(), &MirroredReceiverPosition() };
m_pSimulationWatcher = std::make_shared<CEigenraySearchWatcher>(receiverPositions, rayTracingAbortSettings.maxTime, rayTracingAbortSettings.maxReflectionOrder + 1);
simulationEngine.pExternalWatcher = m_pSimulationWatcher;
}
EigenraySearch::CInitialWorker::CInitialWorker(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings)
: CWorkerBase(sourcePosition, receiverPosition, simSettings, abortSettings) {}
std::vector<CRayGrid> EigenraySearch::CInitialWorker::Run(const ITAGeo::CStratifiedAtmosphere& atmosphere)
{
CRayGrid rayGrid = InitRayGrid(atmosphere);
......@@ -116,18 +126,18 @@ std::vector<CRayGrid> EigenraySearch::CInitialWorker::FinalizeResult(const CRayG
#pragma region ADAPTIVE WORKER
bool EigenraySearch::CAdaptiveWorker::AbortRequested(const RayPtr& pRay) const
{
return pRay->LastTimeStamp() >= rayTracingAbortSettings.maxTime || pRay->ReflectionOrder() > iActiveReflexionOrder+1;
}
EigenraySearch::CAdaptiveWorker::CAdaptiveWorker(const CRayGrid& rayGrid, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const Settings& eigenraySettings, const int activeReflectionOrder)
: CWorkerBase(rayGrid.SourcePosition(), receiverPosition, simSettings, eigenraySettings.rayTracing),
adaptiveRayGrid(rayGrid), iActiveReflexionOrder(activeReflectionOrder), rayAdaptationSettings(eigenraySettings.rayAdaptation)
{
const float sourceReceiverDistance = (VirtualReceiverPosition() - rayGrid.SourcePosition()).GetLength();
fReceiverRadius = tan(rayAdaptationSettings.accuracy.maxSourceReceiverAngle) * sourceReceiverDistance;
fReceiverRadius = tan(rayAdaptationSettings.accuracy.maxSourceReceiverAngle * M_PI/180.0) * sourceReceiverDistance;
fReceiverRadius = fmin(rayAdaptationSettings.accuracy.maxReceiverRadius, fReceiverRadius);
//TODO: Track whether distance increased and use this for abortion
V3DConstPtrVector receiverPositions = { &VirtualReceiverPosition() };
m_pSimulationWatcher = std::make_shared<CEigenraySearchWatcher>(receiverPositions, rayTracingAbortSettings.maxTime, iActiveReflexionOrder + 1);
simulationEngine.pExternalWatcher = m_pSimulationWatcher;
}
EigenraySearch::RayPtr EigenraySearch::CAdaptiveWorker::Run(const ITAGeo::CStratifiedAtmosphere& atmosphere)
......@@ -147,12 +157,6 @@ EigenraySearch::RayPtr EigenraySearch::CAdaptiveWorker::Run(const ITAGeo::CStrat
//TODO: Postprocessing: Calculate spreading loss factor
}
void EigenraySearch::CAdaptiveWorker::UpdateMinimumReceiverDistance(RayPtr& pRay) const
{
pRay->UpdateMinimumReceiverDistance( VirtualReceiverPosition() );
//TODO: Track whether distance increased and use this for abortion
}
bool EigenraySearch::CAdaptiveWorker::EigenrayAccuracyReached()
{
......@@ -163,9 +167,7 @@ bool EigenraySearch::CAdaptiveWorker::EigenrayAccuracyReached()
bool abort = nAdaptations > rayAdaptationSettings.abort.maxNAdaptations
|| adaptiveRayGrid.MaxAngularResolution() < rayAdaptationSettings.abort.minAngleResolutionDeg;
if (abort)
{
//TODO: Warning: Abort criterion reached!
}
std::cout << "WARNING: EigenraySearch::Engine: Could not find eigenray with proper accuracy. Abort criterion reached." << std::endl;
return abort;
}
void EigenraySearch::CAdaptiveWorker::PostProcessEigenray(const ITAGeo::CStratifiedAtmosphere& atmosphere)
......@@ -199,8 +201,9 @@ void EigenraySearch::CAdaptiveWorker::CalculateEigenraySpreadingLoss(const ITAGe
if (adaptiveRayGrid.MaxAngularResolution() > rayAdaptationSettings.accuracy.maxAngleForGeomSpreading || !adaptiveRayGrid.Is2D())
{
adaptiveRayGrid.ZoomIntoRay(pMinDistanceRay, rayAdaptationSettings.accuracy.maxAngleForGeomSpreading, rayAdaptationSettings.accuracy.maxAngleForGeomSpreading);
simulationEngine.externalWatcher = Simulation::CAbortAtMaxTime(time);
simulationEngine.Run(atmosphere, adaptiveRayGrid.NewRaysOfLastAdaptation());
auto tmpSimulationEngine = Simulation::CEngine( std::make_shared<Simulation::CAbortAtMaxTime>(time) );
tmpSimulationEngine.settings = simulationEngine.settings;
tmpSimulationEngine.Run(atmosphere, adaptiveRayGrid.NewRaysOfLastAdaptation());
}
else
adaptiveRayGrid.SetToSurroundingGrid(pMinDistanceRay);
......@@ -212,4 +215,4 @@ void EigenraySearch::CAdaptiveWorker::CalculateEigenraySpreadingLoss(const ITAGe
pMinDistanceRay->SetSpreadingLoss( surfaceRef/surfaceReceiver * cReceiver/cRef );
}
#pragma endregion
#pragma endregion
\ No newline at end of file
......@@ -50,10 +50,29 @@ namespace ITAPropagationPathSim
typedef std::shared_ptr<CRay> RayPtr;
typedef std::vector< RayPtr > RayVector;
typedef std::vector<const VistaVector3D* > V3DConstPtrVector;
class CEigenraySearchWatcher : public Simulation::IExternalWatcher
{
private:
V3DConstPtrVector m_vpReceiverPositions;
const double m_dTMax;
const int m_iMaxReflectionOrder;
public:
CEigenraySearchWatcher(const V3DConstPtrVector& vv3ReceiverPositions, const double& tMax, const int& maxReflOrder);
public:
virtual bool AbortRequested(const std::shared_ptr<CRay> pRay) const;
//! Interface function to Simulation::Engine: Updates the minimum receiver distance of the ray after each processing step
virtual void ProcessRay(std::shared_ptr<CRay>) const;
//! Interface function to Simulation::Engine: Called after tracing a ray is finished.
virtual void FinalizeRay(std::shared_ptr<CRay>) const;
};
//! Basis for a worker which tracks the distance between rays and a receiver to find eigenrays
class CWorkerBase : public Simulation::IExternalWatcher
class CWorkerBase
{
protected:
std::shared_ptr<CEigenraySearchWatcher> m_pSimulationWatcher;
Simulation::CEngine simulationEngine;
RayTracingAbortSettings rayTracingAbortSettings;
VistaVector3D v3SourcePosition;
......@@ -64,16 +83,9 @@ namespace ITAPropagationPathSim
public:
CWorkerBase(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings);
public:
//! Interface function to Simulation::Engine: Updates the minimum receiver distance of the ray after each processing step
virtual void ProcessRay(RayPtr& pRay) const;
//! Interface function to Simulation::Engine: Called after tracing a ray is finished.
virtual void FinalizeRay(RayPtr& pRay) const;
protected:
virtual void UpdateMinimumReceiverDistance(RayPtr& pRay) const = 0;
const VistaVector3D& ReceiverPosition() const { return v3ReceiverPosition; }
const VistaVector3D& MirroredReceiverPosition() const { return v3MirroredReceiverPosition; }
inline const VistaVector3D& ReceiverPosition() const { return v3ReceiverPosition; };
inline const VistaVector3D& MirroredReceiverPosition() const { return v3MirroredReceiverPosition; };
const VistaVector3D& VirtualReceiverPosition(const int reflectionOrder) const;
RayPtr FindMinimumDistanceRay(const std::set<RayPtr>& rays, const int reflectionOrder);
......@@ -85,12 +97,6 @@ namespace ITAPropagationPathSim
private:
RayVector vpMinDistanceRays; //< Vector containing the current ray of minimum receiver distance for each reflection order
public:
//! Interface function to Simulation::Engine: Checks whether ray does not have to be traced anymore.
virtual bool AbortRequested(const RayPtr& pRay) const;
private:
virtual void UpdateMinimumReceiverDistance(RayPtr& pRay) const;
public:
CInitialWorker(const VistaVector3D& sourcePosition, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const RayTracingAbortSettings& abortSettings);
......@@ -113,17 +119,12 @@ namespace ITAPropagationPathSim
RayPtr pMinDistanceRay;
int nAdaptations = 0;
public:
//! Interface function to Simulation::Engine: Checks whether ray does not have to be traced anymore.
virtual bool AbortRequested(const RayPtr& pRay) const;
public:
CAdaptiveWorker(const CRayGrid& rayGrid, const VistaVector3D& receiverPosition, const Simulation::Settings& simSettings, const Settings& eigenraySettings, const int activeReflectionOrder);
RayPtr Run(const ITAGeo::CStratifiedAtmosphere& atmosphere);
private:
virtual void UpdateMinimumReceiverDistance(RayPtr& pRay) const;
inline const VistaVector3D& VirtualReceiverPosition() const { return CWorkerBase::VirtualReceiverPosition(iActiveReflexionOrder); }
inline const VistaVector3D& VirtualReceiverPosition() const { return CWorkerBase::VirtualReceiverPosition(iActiveReflexionOrder); };
bool EigenrayAccuracyReached();
void PostProcessEigenray(const ITAGeo::CStratifiedAtmosphere& atmosphere);
......
......@@ -21,10 +21,10 @@ class CWorker
{
private:
std::shared_ptr<CRay> pRay;
IExternalWatcher& rExternalWatcher; //!< Reference to externally defined abort criterion.
const IExternalWatcher& rExternalWatcher; //!< Reference to externally defined abort criterion.
CAdaptiveSolver solver;
public:
CWorker(std::shared_ptr<CRay> ray, const Settings& simSettings, IExternalWatcher& externalWatcher) :
CWorker(std::shared_ptr<CRay> ray, const Settings& simSettings, const IExternalWatcher& externalWatcher) :
pRay(ray), rExternalWatcher(externalWatcher), solver(CAdaptiveSolver(simSettings)) {}
private:
......@@ -151,13 +151,17 @@ void CEngine::Run(const ITAGeo::CStratifiedAtmosphere& atmosphere, const std::se
void 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.");
#pragma omp parallel for schedule(static)
for (int idx = 0; idx < rays.size(); idx++)
{
if (rays[idx] == nullptr)
continue;
auto worker = CWorker(rays[idx], settings, externalWatcher);
auto worker = CWorker(rays[idx], settings, *simulationWatcher);
worker.TraceRay(atmosphere);
}
}
......@@ -48,7 +48,7 @@ using namespace ITAPropagationPathSim::AtmosphericRayTracing::Utils;
void runTest(const CStratifiedAtmosphere& atmosphere, const double& sourceAltitude, const VistaVector3D& rayDirection, const string& fileSuffix)
{
double tMax = 15;
auto engine = Simulation::CEngine(CAbortAtMaxTime(tMax));
auto engine = Simulation::CEngine( std::make_shared<CAbortAtMaxTime>(tMax) );
double dt = 0.01;
engine.settings.adaptiveIntegration.bActive = true;
......