/** * @file kernel/qss/Derivative.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-2022 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 . */ #ifndef QSS_DERIVATIVE #define QSS_DERIVATIVE #include #include namespace artis::qss { template class Derivative : public artis::pdevs::Dynamics { public: struct input { enum values { RESET = 0, IN }; }; struct output { enum values { OUT = 0 }; }; struct var { enum values { VALUE }; }; typedef Derivative type; Derivative(const std::string &name, const artis::pdevs::Context &context) : artis::pdevs::Dynamics(name, context), _external_number(0), _internal_number(0) { DECLARE_STATES(int, ((state::PHASE, &type::_phase))); DECLARE_STATES(unsigned int, ((state::INPUT_NUMBER, &type::_input_number))); DECLARE_STATES(double, ((state::OUTPUT_VALUE, &type::_output_value), (state::LAST_OUTPUT, &type::_last_output))); this->input_ports({{input::RESET, "reset"}, {input::IN, "in"}}); this->output_port({output::OUT, "out"}); this->observable({var::VALUE, "value"}); } virtual ~Derivative() {} int external(const std::string &name, double Dyn::* var) { ++_external_number; this->state_(state::LAST_OUTPUT + _external_number + 1, name, var); this->input_port({input::IN + _external_number, name}); return input::IN + _external_number; } void internal(const std::string &name, double Dyn::* var) { assert(_internal_number == 0); ++_internal_number; this->state_(state::LAST_OUTPUT + 1, name, var); } virtual double compute() const = 0; virtual void dconf(const typename Time::type &t, typename Time::type e, const common::event::Bag