/** * @file kernel/qss/MultiDerivative.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_MULTI_DERIVATIVE #define QSS_MULTI_DERIVATIVE #include namespace artis::qss { template class MultiDerivative : public artis::pdevs::Dynamics { public: struct input { enum values { RESET = 0, INTERNAL = 1, EXTERNAL = 1000 }; }; struct var { enum values { VALUE }; }; typedef MultiDerivative type; MultiDerivative(const std::string &name, const artis::pdevs::Context &context) : artis::pdevs::Dynamics(name, context), _external_number(0), _internal_number(0), _variable_number(0) { DECLARE_STATES(int, ((state::PHASE, &type::_phase))); DECLARE_STATES(unsigned int, ((state::INPUT_NUMBER, &type::_input_number))); DECLARE_STATES(std::vector < double > , ((state::OUTPUT_VALUES, &type::_output_values), (state::LAST_OUTPUTS, &type::_last_outputs))); this->input_port({input::RESET, "reset"}); } virtual ~MultiDerivative() {} int external(const std::string &name, double Dyn::* var) { this->state_(state::LAST_OUTPUTS + _variable_number + 1, name, var); this->input_port({input::EXTERNAL + _external_number, name}); ++_variable_number; ++_external_number; return input::EXTERNAL + _external_number - 1; } void internal(const std::string &name, double Dyn::* var) { assert(_external_number == 0); this->state_(state::LAST_OUTPUTS + _variable_number + 1, name, var); this->input_port({input::INTERNAL + _internal_number, name}); this->output_port({_internal_number, name}); this->observable({var::VALUE + _internal_number, name}); ++_variable_number; ++_internal_number; } virtual std::vector compute() = 0; virtual void dconf(const typename Time::type &t, typename Time::type e, const common::event::Bag