Parcourir la source

Add new unit tests for DEVS formalism

Eric Ramat il y a 5 ans
Parent
commit
7214db5619

+ 1 - 0
src/tests/CMakeLists.txt

@@ -1,4 +1,5 @@
 ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(devs)
 ADD_SUBDIRECTORY(dsde)
 ADD_SUBDIRECTORY(dtss)
 ADD_SUBDIRECTORY(fddevs)

+ 12 - 0
src/tests/devs/CMakeLists.txt

@@ -0,0 +1,12 @@
+add_definitions(-DWITH_TRACE)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/src
+        ${ARTIS_INCLUDE_DIRS}
+        ${Boost_INCLUDE_DIRS})
+
+LINK_DIRECTORIES()
+
+ADD_EXECUTABLE(devs-tests graph_manager.hpp models.hpp tests.cpp)
+
+TARGET_LINK_LIBRARIES(devs-tests)

+ 89 - 0
src/tests/devs/graph_manager.hpp

@@ -0,0 +1,89 @@
+/**
+ * @file tests/devs/graph_manager.cpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TESTS_DEVS_GRAPH_MANAGER_HPP
+#define TESTS_DEVS_GRAPH_MANAGER_HPP
+
+#include <tests/devs/models.hpp>
+
+#include <artis-star/kernel/devs/Coordinator.hpp>
+#include <artis-star/kernel/devs/GraphManager.hpp>
+#include <artis-star/kernel/devs/Simulator.hpp>
+
+namespace artis {
+    namespace tests {
+        namespace devs {
+
+            class FlatGraphManager :
+                    public artis::devs::GraphManager<common::DoubleTime> {
+            public:
+                enum submodels {
+                    FirstA, SecondA,
+                    FirstB, SecondB
+                };
+
+                FlatGraphManager(common::Coordinator<common::DoubleTime>* coordinator,
+                        const artis::common::NoParameters& parameters,
+                        const artis::common::NoParameters& graph_parameters)
+                        :
+                        artis::devs::GraphManager<common::DoubleTime>(coordinator, parameters,
+                                graph_parameters),
+                        a1("a1", parameters), b1("b1", parameters),
+                        a2("a2", parameters), b2("b2", parameters)
+                {
+                    add_child(FirstA, &a1);
+                    add_child(FirstB, &b1);
+                    add_child(SecondA, &a2);
+                    add_child(SecondB, &b2);
+
+                    add_link(&a1, &b1);
+                    add_link(&b1, &a2);
+                    add_link(&a2, &b2);
+                }
+
+                ~FlatGraphManager() override = default;
+
+            private:
+                artis::devs::Simulator<common::DoubleTime, A> a1;
+                artis::devs::Simulator<common::DoubleTime, B> b1;
+                artis::devs::Simulator<common::DoubleTime, A> a2;
+                artis::devs::Simulator<common::DoubleTime, B> b2;
+            };
+
+            class Select {
+            public:
+                Select() = default;
+
+                common::Model<common::DoubleTime>*
+                operator()(const common::Models<common::DoubleTime>& list) const
+                { return list.at(0); }
+            };
+
+        }
+    }
+} // namespace artis tests devs
+
+#endif

+ 333 - 0
src/tests/devs/models.hpp

@@ -0,0 +1,333 @@
+/**
+ * @file tests/devs/models.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TESTS_DEVS_MODELS_HPP
+#define TESTS_DEVS_MODELS_HPP
+
+#include <artis-star/common/time/DoubleTime.hpp>
+#include <artis-star/common/utils/Trace.hpp>
+
+#include <artis-star/kernel/devs/Dynamics.hpp>
+
+#include <chrono>
+#include <iostream>
+
+namespace artis {
+    namespace tests {
+        namespace devs {
+
+            struct data {
+                double x;
+                double y;
+
+                data()
+                        :x(0), y(0) { }
+
+                data(double _x, double _y)
+                        :x(_x), y(_y) { }
+            };
+
+            class A : public artis::devs::Dynamics<common::DoubleTime, A> {
+            public:
+                A(const std::string& name,
+                        const artis::devs::Context<common::DoubleTime, A, artis::common::NoParameters>& context)
+                        :
+                        artis::devs::Dynamics<common::DoubleTime, A>(name, context)
+                {
+                }
+
+                ~A() override = default;
+
+                void dint(typename common::DoubleTime::type t) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::DELTA_INT,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    if (_phase == WAIT) {
+                        ++_value.x;
+                        --_value.y;
+                        _phase = SEND;
+                    } else if (_phase == SEND) {
+                        _phase = WAIT;
+                    }
+                }
+
+                void
+                dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
+                        const common::ExternalEvent<common::DoubleTime>& msg) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+                    (void)msgs;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::DELTA_EXT,
+                                    common::LevelType::USER)
+                            << "event = " << msg.to_string();
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    _phase = SEND;
+                }
+
+                void start(typename common::DoubleTime::type t) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::START,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    _phase = SEND;
+                }
+
+                typename common::DoubleTime::type
+                ta(typename common::DoubleTime::type t) const override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::TA,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    if (_phase == WAIT) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                }
+
+                common::ExternalEvent<common::DoubleTime>
+                lambda(typename common::DoubleTime::type t) const override
+                {
+#ifndef WITH_TRACE
+                    (void)t;
+#endif
+
+                    if (_phase == SEND) {
+                        artis::common::ExternalEvent<common::DoubleTime> msg(_value);
+
+#ifdef WITH_TRACE
+                        common::Trace<common::DoubleTime>::trace()
+                                << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                        common::FormalismType::DEVS,
+                                        common::FunctionType::LAMBDA,
+                                        common::LevelType::USER)
+                                << "event = " << msg.to_string();
+                        common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                        return msg;
+                    } else {
+
+#ifdef WITH_TRACE
+                        common::Trace<common::DoubleTime>::trace()
+                                << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                        common::FormalismType::DEVS,
+                                        common::FunctionType::LAMBDA,
+                                        common::LevelType::USER)
+                                << "no event";
+                        common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                        return artis::common::ExternalEvent<common::DoubleTime>::Void;
+                    }
+                }
+
+            private:
+                enum Phase {
+                    WAIT, SEND
+                };
+
+                Phase _phase;
+                data _value;
+            };
+
+            class B : public artis::devs::Dynamics<common::DoubleTime, B> {
+            public:
+                B(const std::string& name,
+                        const artis::devs::Context<common::DoubleTime, B, artis::common::NoParameters>& context)
+                        :
+                        artis::devs::Dynamics<common::DoubleTime, B>(name, context),
+                        _value(0)
+                {
+                }
+
+                ~B() override = default;
+
+                void dint(typename common::DoubleTime::type t) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::DELTA_INT,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    if (_phase == SEND) {
+                        _phase = WAIT;
+                    }
+                }
+
+                void
+                dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
+                        const common::ExternalEvent<common::DoubleTime>& msg) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+                    (void)msgs;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::DELTA_EXT,
+                                    common::LevelType::USER)
+                            << "event = " << msg.to_string();
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    _phase = SEND;
+                }
+
+                void start(typename common::DoubleTime::type t) override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::START,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    _phase = WAIT;
+                }
+
+                typename common::DoubleTime::type ta(
+                        typename common::DoubleTime::type t) const override
+                {
+
+#ifndef WITH_TRACE
+                    (void)t;
+#else
+                    common::Trace<common::DoubleTime>::trace()
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::FormalismType::DEVS,
+                                    common::FunctionType::TA,
+                                    common::LevelType::USER);
+                    common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                    if (_phase == WAIT) {
+                        return common::DoubleTime::infinity;
+                    } else {
+                        return 0;
+                    }
+                }
+
+                common::ExternalEvent<common::DoubleTime> lambda(
+                        typename common::DoubleTime::type t) const override
+                {
+#ifndef WITH_TRACE
+                    (void)t;
+#endif
+                    if (_phase == SEND) {
+                        artis::common::ExternalEvent<common::DoubleTime> msg(_value);
+
+#ifdef WITH_TRACE
+                        common::Trace<common::DoubleTime>::trace()
+                                << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                        common::FormalismType::DEVS,
+                                        common::FunctionType::LAMBDA,
+                                        common::LevelType::USER)
+                                << "event = " << msg.to_string();
+                        common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                        return msg;
+                    } else {
+
+#ifdef WITH_TRACE
+                        common::Trace<common::DoubleTime>::trace()
+                                << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                        common::FormalismType::DEVS,
+                                        common::FunctionType::LAMBDA,
+                                        common::LevelType::USER)
+                                << "no event";
+                        common::Trace<common::DoubleTime>::trace().flush();
+#endif
+
+                        return artis::common::ExternalEvent<common::DoubleTime>::Void;
+                    }
+                }
+
+            private:
+                enum Phase {
+                    WAIT, SEND
+                };
+
+                Phase _phase;
+                double _value;
+            };
+
+        }
+    }
+} // namespace artis tests devs
+
+#endif

+ 170 - 0
src/tests/devs/tests.cpp

@@ -0,0 +1,170 @@
+/**
+ * @file tests/devs/tests.cpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <tests/devs/graph_manager.hpp>
+#include <tests/devs/models.hpp>
+
+#include <artis-star/common/RootCoordinator.hpp>
+
+#define CATCH_CONFIG_MAIN
+
+#include <tests/catch.hpp>
+
+using namespace artis::tests::devs;
+using namespace artis::common;
+
+TEST_CASE("devs/flat", "run")
+{
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
+    artis::common::RootCoordinator<
+            DoubleTime, artis::devs::Coordinator<
+                    DoubleTime,
+                    FlatGraphManager,
+                    Select>
+    > rc(context, "root", artis::common::NoParameters(), artis::common::NoParameters());
+
+    artis::common::Trace<DoubleTime>::trace().clear();
+    rc.run(context);
+
+    std::cout << artis::common::Trace<DoubleTime>::trace().elements().filter_level_type(
+            LevelType::USER).to_string() << std::endl;
+
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").
+            filter_function_type(artis::common::FunctionType::START).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("b1").
+            filter_function_type(artis::common::FunctionType::START).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").
+            filter_function_type(artis::common::FunctionType::START).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("b2").
+            filter_function_type(artis::common::FunctionType::START).size() == 1);
+
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").
+            filter_function_type(artis::common::FunctionType::DELTA_EXT).empty());
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::TA).size() == 2);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::LAMBDA).size() == 1);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 3);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 2);
+        }
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
+    }
+
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_function_type(
+            artis::common::FunctionType::DELTA_CONF).empty());
+
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 4);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::LAMBDA).size() == 3);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 3);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 5);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        }
+        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 2);
+    }
+}

+ 6 - 14
src/tests/pdevs/models.hpp

@@ -142,8 +142,7 @@ namespace artis {
 
                 }
 
-                typename common::DoubleTime::type
-                start(typename common::DoubleTime::type t) override
+                void start(typename common::DoubleTime::type t) override
                 {
 
 #ifndef WITH_TRACE
@@ -159,8 +158,7 @@ namespace artis {
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
-                    _phase = WAIT;
-                    return 0;
+                    _phase = SEND;
                 }
 
                 typename common::DoubleTime::type
@@ -311,8 +309,7 @@ namespace artis {
 
                 }
 
-                typename common::DoubleTime::type
-                start(typename common::DoubleTime::type t) override
+                void start(typename common::DoubleTime::type t) override
                 {
 
 #ifndef WITH_TRACE
@@ -329,7 +326,6 @@ namespace artis {
 #endif
 
                     _phase = WAIT;
-                    return common::DoubleTime::infinity;
                 }
 
                 typename common::DoubleTime::type ta(
@@ -410,12 +406,10 @@ namespace artis {
                     _last_time = t;
                 }
 
-                typename common::DoubleTime::type
-                start(typename common::DoubleTime::type t) override
+                void start(typename common::DoubleTime::type t) override
                 {
                     _phase = S1;
                     _last_time = t;
-                    return ta(t);
                 }
 
                 typename common::DoubleTime::type
@@ -519,17 +513,15 @@ namespace artis {
                     compute();
                 }
 
-                typename common::DoubleTime::type
-                start(typename common::DoubleTime::type t) override
+                void start(typename common::DoubleTime::type t) override
                 {
                     heights = {0, 0, 0, 0, 0};
                     speeds = {0.21, 0.3, 0.7, 0.56, 0.14};
                     scales = {1, 1, 1, 1, 1};
                     index = 0;
                     n = 0;
-                    sigma = 1;
+                    sigma = 0;
                     _last_time = t;
-                    return 0;
                 }
 
                 typename common::DoubleTime::type

+ 119 - 23
src/tests/pdevs/tests.cpp

@@ -57,7 +57,20 @@ TEST_CASE("pdevs/only_one", "run")
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a").
             filter_function_type(artis::common::FunctionType::DELTA_CONF).empty());
-    for (unsigned int t = 0; t <= 10; ++t) {
+
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
@@ -82,6 +95,9 @@ TEST_CASE("pdevs/flat", "run")
     artis::common::Trace<DoubleTime>::trace().clear();
     rc.run(context);
 
+    std::cout << artis::common::Trace<DoubleTime>::trace().elements().filter_level_type(
+            LevelType::USER).to_string() << std::endl;
+
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").
             filter_function_type(artis::common::FunctionType::START).size() == 1);
@@ -98,7 +114,19 @@ TEST_CASE("pdevs/flat", "run")
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").
             filter_function_type(artis::common::FunctionType::DELTA_EXT).empty());
-    for (unsigned int t = 0; t <= 10; ++t) {
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
@@ -117,15 +145,40 @@ TEST_CASE("pdevs/flat", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("b1").filter_time(t).
-                filter_function_type(artis::common::FunctionType::TA).size() == 2);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 3);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 2);
+        }
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
     }
 
-    for (unsigned int t = 0; t <= 10; ++t) {
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_function_type(
+            artis::common::FunctionType::DELTA_CONF).empty());
+
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 4);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::LAMBDA).size() == 3);
@@ -138,9 +191,6 @@ TEST_CASE("pdevs/flat", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("a2").filter_time(t).
-                filter_function_type(artis::common::FunctionType::DELTA_CONF).empty());
     }
 
     for (unsigned int t = 0; t <= 10; ++t) {
@@ -150,9 +200,15 @@ TEST_CASE("pdevs/flat", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("b2").filter_time(t).
-                filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 5);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        }
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 2);
@@ -187,7 +243,19 @@ TEST_CASE("pdevs/hierachical", "run")
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").
             filter_function_type(artis::common::FunctionType::DELTA_EXT).empty());
-    for (unsigned int t = 0; t <= 10; ++t) {
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a1").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
@@ -206,15 +274,40 @@ TEST_CASE("pdevs/hierachical", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 1);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("b1").filter_time(t).
-                filter_function_type(artis::common::FunctionType::TA).size() == 2);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 3);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b1").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 2);
+        }
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b1").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
     }
 
-    for (unsigned int t = 0; t <= 10; ++t) {
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_function_type(
+            artis::common::FunctionType::DELTA_CONF).empty());
+
+    // at t = 0
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::LAMBDA).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::TA).size() == 4);
+    REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+            filter_model_name("a2").filter_time(0).
+            filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
+
+    // at t > 0
+    for (unsigned int t = 1; t <= 10; ++t) {
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::LAMBDA).size() == 3);
@@ -227,9 +320,6 @@ TEST_CASE("pdevs/hierachical", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("a2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 1);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("a2").filter_time(t).
-                filter_function_type(artis::common::FunctionType::DELTA_CONF).empty());
     }
 
     for (unsigned int t = 0; t <= 10; ++t) {
@@ -239,9 +329,15 @@ TEST_CASE("pdevs/hierachical", "run")
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_INT).size() == 2);
-        REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
-                filter_model_name("b2").filter_time(t).
-                filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        if (t == 0) {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 5);
+        } else {
+            REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
+                    filter_model_name("b2").filter_time(t).
+                    filter_function_type(artis::common::FunctionType::TA).size() == 4);
+        }
         REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
                 filter_model_name("b2").filter_time(t).
                 filter_function_type(artis::common::FunctionType::DELTA_EXT).size() == 2);