diff --git a/src/propagation/examples/main-propagation-loss.cc b/src/propagation/examples/main-propagation-loss.cc index 8a29331ae..0666a5166 100644 --- a/src/propagation/examples/main-propagation-loss.cc +++ b/src/propagation/examples/main-propagation-loss.cc @@ -53,7 +53,7 @@ static double dround (double number, double precision) } static Gnuplot -TestDeterministic (Ptr model) +TestDeterministic (Ptr model, double targetDistance, double step) { Ptr a = CreateObject (); Ptr b = CreateObject (); @@ -73,7 +73,7 @@ TestDeterministic (Ptr model) { a->SetPosition (Vector (0.0, 0.0, 0.0)); - for (double distance = 0.0; distance < 2500.0; distance += 10.0) + for (double distance = 0.0; distance < targetDistance; distance += step) { b->SetPosition (Vector (distance, 0.0, 0.0)); @@ -99,7 +99,7 @@ TestDeterministic (Ptr model) } static Gnuplot -TestProbabilistic (Ptr model, unsigned int samples = 100000) +TestProbabilistic (Ptr model, double targetDistance, double step, unsigned int samples) { Ptr a = CreateObject (); Ptr b = CreateObject (); @@ -131,7 +131,7 @@ TestProbabilistic (Ptr model, unsigned int samples = 10000 { a->SetPosition (Vector (0.0, 0.0, 0.0)); - for (double distance = 100.0; distance < 2500.0; distance += 100.0) + for (double distance = 100.0; distance < targetDistance; distance += step) { b->SetPosition (Vector (distance, 0.0, 0.0)); @@ -169,9 +169,9 @@ TestProbabilistic (Ptr model, unsigned int samples = 10000 static Gnuplot TestDeterministicByTime (Ptr model, - Time timeStep = Seconds (0.001), - Time timeTotal = Seconds (1.0), - double distance = 100.0) + Time timeStep, + Time timeTotal, + double distance) { Ptr a = CreateObject (); Ptr b = CreateObject (); @@ -219,15 +219,32 @@ TestDeterministicByTime (Ptr model, int main (int argc, char *argv[]) { + bool test = false; CommandLine cmd (__FILE__); + cmd.AddValue ("test", "Run as a test, sample the models only once", test); cmd.Parse (argc, argv); + double testDeterministicDistance = 2500.0; + double testProbabilisticDistance = 2500.0; + unsigned int testProbabilisticSamples = 100000; + Time testJakesTimeOneMsRes = Seconds (1.0); + Time testJakesTimeZeroDotOneMsRes = Seconds (0.1); + + if (test) + { + testDeterministicDistance = 10; + testProbabilisticDistance = 200; + testProbabilisticSamples = 1; + testJakesTimeOneMsRes = Seconds (0.001); + testJakesTimeZeroDotOneMsRes = Seconds (0.0001); + } + GnuplotCollection gnuplots ("main-propagation-loss.pdf"); { Ptr friis = CreateObject (); - Gnuplot plot = TestDeterministic (friis); + Gnuplot plot = TestDeterministic (friis, testDeterministicDistance, 10.0); plot.SetTitle ("ns3::FriisPropagationLossModel (Default Parameters)"); gnuplots.AddPlot (plot); } @@ -236,7 +253,7 @@ int main (int argc, char *argv[]) Ptr log = CreateObject (); log->SetAttribute ("Exponent", DoubleValue (2.5)); - Gnuplot plot = TestDeterministic (log); + Gnuplot plot = TestDeterministic (log, testDeterministicDistance, 10.0); plot.SetTitle ("ns3::LogDistancePropagationLossModel (Exponent = 2.5)"); gnuplots.AddPlot (plot); } @@ -246,7 +263,7 @@ int main (int argc, char *argv[]) Ptr expVar = CreateObjectWithAttributes ("Mean", DoubleValue (50.0)); random->SetAttribute ("Variable", PointerValue (expVar)); - Gnuplot plot = TestDeterministic (random); + Gnuplot plot = TestDeterministic (random, testDeterministicDistance, 10.0); plot.SetTitle ("ns3::RandomPropagationLossModel with Exponential Distribution"); gnuplots.AddPlot (plot); } @@ -257,9 +274,13 @@ int main (int argc, char *argv[]) // doppler frequency shift for 5.15 GHz at 100 km/h Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9)); - Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.001), Seconds (1.0)); + Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.001), testJakesTimeOneMsRes, 100.0); plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 1 millisec resolution)"); gnuplots.AddPlot (plot); + // Usually objects are aggregated either to a Node or a Channel, and this aggregation ensures + // a proper call to Dispose. + // Here we must call it manually, since the PropagationLossModel is not aggregated to anything. + jakes->Dispose (); } { @@ -268,15 +289,19 @@ int main (int argc, char *argv[]) // doppler frequency shift for 5.15 GHz at 100 km/h Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9)); - Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.0001), Seconds (0.1)); + Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.0001), testJakesTimeZeroDotOneMsRes, 100.0); plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 0.1 millisec resolution)"); gnuplots.AddPlot (plot); - } + // Usually objects are aggregated either to a Node or a Channel, and this aggregation ensures + // a proper call to Dispose. + // Here we must call it manually, since the PropagationLossModel is not aggregated to anything. + jakes->Dispose (); + } { Ptr log3 = CreateObject (); - Gnuplot plot = TestDeterministic (log3); + Gnuplot plot = TestDeterministic (log3, testDeterministicDistance, 10.0); plot.SetTitle ("ns3::ThreeLogDistancePropagationLossModel (Defaults)"); gnuplots.AddPlot (plot); } @@ -288,7 +313,7 @@ int main (int argc, char *argv[]) log3->SetAttribute ("Exponent1", DoubleValue (3.0)); log3->SetAttribute ("Exponent2", DoubleValue (10.0)); - Gnuplot plot = TestDeterministic (log3); + Gnuplot plot = TestDeterministic (log3, testDeterministicDistance, 10.0); plot.SetTitle ("ns3::ThreeLogDistancePropagationLossModel (Exponents 1.0, 3.0 and 10.0)"); gnuplots.AddPlot (plot); } @@ -296,7 +321,7 @@ int main (int argc, char *argv[]) { Ptr nak = CreateObject (); - Gnuplot plot = TestProbabilistic (nak); + Gnuplot plot = TestProbabilistic (nak, testProbabilisticDistance, 100.0, testProbabilisticSamples); plot.SetTitle ("ns3::NakagamiPropagationLossModel (Default Parameters)"); gnuplots.AddPlot (plot); } @@ -307,7 +332,7 @@ int main (int argc, char *argv[]) Ptr nak = CreateObject (); log3->SetNext (nak); - Gnuplot plot = TestProbabilistic (log3); + Gnuplot plot = TestProbabilistic (log3, testProbabilisticDistance, 100.0, testProbabilisticSamples); plot.SetTitle ("ns3::ThreeLogDistancePropagationLossModel and ns3::NakagamiPropagationLossModel (Default Parameters)"); gnuplots.AddPlot (plot); } diff --git a/src/propagation/model/jakes-process.cc b/src/propagation/model/jakes-process.cc index 824e24682..3dd0439a0 100644 --- a/src/propagation/model/jakes-process.cc +++ b/src/propagation/model/jakes-process.cc @@ -68,7 +68,7 @@ void JakesProcess::SetPropagationLossModel (Ptr propagationModel) { Ptr jakes = propagationModel->GetObject (); - NS_ASSERT_MSG (jakes != 0, "Jakes Process can work only with JakesPropagationLossModel!"); + NS_ASSERT_MSG (jakes != nullptr, "Jakes Process can work only with JakesPropagationLossModel!"); m_jakes = jakes; NS_ASSERT (m_nOscillators != 0); @@ -127,7 +127,8 @@ JakesProcess::~JakesProcess() void JakesProcess::DoDispose () { - m_jakes = 0; + m_uniformVariable = nullptr; + m_jakes = nullptr; } std::complex diff --git a/src/propagation/model/jakes-process.h b/src/propagation/model/jakes-process.h index 0ff760488..03a2916da 100644 --- a/src/propagation/model/jakes-process.h +++ b/src/propagation/model/jakes-process.h @@ -62,7 +62,6 @@ public: static TypeId GetTypeId (void); JakesProcess (); virtual ~JakesProcess(); - virtual void DoDispose (); /** * Get the channel complex gain @@ -80,6 +79,10 @@ public: * \param model the propagation model using this class */ void SetPropagationLossModel (Ptr model); + +protected: + virtual void DoDispose (); + private: /** * This class Represents a single oscillator @@ -119,7 +122,7 @@ private: void SetDopplerFrequencyHz (double dopplerFrequencyHz); /** - * + * Builds the object Oscillators */ void ConstructOscillators (); private: diff --git a/src/propagation/model/jakes-propagation-loss-model.cc b/src/propagation/model/jakes-propagation-loss-model.cc index 091bceba3..b08ce0891 100644 --- a/src/propagation/model/jakes-propagation-loss-model.cc +++ b/src/propagation/model/jakes-propagation-loss-model.cc @@ -51,13 +51,20 @@ JakesPropagationLossModel::GetTypeId () return tid; } +void +JakesPropagationLossModel::DoDispose () +{ + m_uniformVariable = nullptr; + m_propagationCache.Cleanup (); +} + double JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm, Ptr a, Ptr b) const { Ptr pathData = m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/); - if (pathData == 0) + if (!pathData) { pathData = CreateObject (); pathData->SetPropagationLossModel (this); diff --git a/src/propagation/model/jakes-propagation-loss-model.h b/src/propagation/model/jakes-propagation-loss-model.h index 2e2e24f87..bf1b8e1c6 100644 --- a/src/propagation/model/jakes-propagation-loss-model.h +++ b/src/propagation/model/jakes-propagation-loss-model.h @@ -48,6 +48,9 @@ public: JakesPropagationLossModel (const JakesPropagationLossModel &) = delete; JakesPropagationLossModel & operator = (const JakesPropagationLossModel &) = delete; +protected: + virtual void DoDispose () override; + private: friend class JakesProcess; diff --git a/src/propagation/model/propagation-cache.h b/src/propagation/model/propagation-cache.h index 6c933eb98..fdd4a3879 100644 --- a/src/propagation/model/propagation-cache.h +++ b/src/propagation/model/propagation-cache.h @@ -69,6 +69,19 @@ public: NS_ASSERT (m_pathCache.find (key) == m_pathCache.end ()); m_pathCache.insert (std::make_pair (key, data)); }; + + /** + * Clean the cache + */ + void Cleanup () + { + for (auto i : m_pathCache) + { + i.second->Dispose (); + } + m_pathCache.clear (); + } + private: /// Each path is identified by struct PropagationPathIdentifier diff --git a/src/propagation/test/examples-to-run.py b/src/propagation/test/examples-to-run.py index 1d2fcd9dc..5a3700533 100644 --- a/src/propagation/test/examples-to-run.py +++ b/src/propagation/test/examples-to-run.py @@ -8,7 +8,7 @@ # # See test.py for more information. cpp_examples = [ - ("main-propagation-loss", "True", "False"), + ("main-propagation-loss --test", "True", "True"), ] # A list of Python examples to run in order to ensure that they remain