/**
* @file tests/qss/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 .
*/
#ifndef TESTS_QSS_MODELS_HPP
#define TESTS_QSS_MODELS_HPP
#include
#include
#include
namespace artis {
namespace tests {
namespace qss {
class Constant : public artis::pdevs::qss::Derivative {
public:
Constant(const std::string& name,
const artis::pdevs::Context& context)
:
artis::pdevs::qss::Derivative(name,
context) { }
~Constant() override = default;
double compute() const override { return 0.5; }
};
struct ParabolaParameters {
double alpha;
};
class Parabola
: public artis::pdevs::qss::Derivative {
public:
Parabola(const std::string& name,
const artis::pdevs::Context& context)
:
artis::pdevs::qss::Derivative(
name,
context), _alpha(context.parameters().alpha)
{
internal("X", &Parabola::_x);
}
~Parabola() override = default;
double compute() const override { return _alpha * _x; }
private:
double _alpha;
double _x;
};
struct PreyPredatorParameters {
double a;
double b;
double d;
double e;
};
class Predator
: public artis::pdevs::qss::Derivative {
public:
unsigned int IN_X;
Predator(const std::string& name,
const artis::pdevs::Context& context)
:
artis::pdevs::qss::Derivative(
name,
context), _b(context.parameters().b), _d(context.parameters().d),
_e(context.parameters().e)
{
internal("Y", &Predator::_y);
IN_X = external("X", &Predator::_x);
}
~Predator() override = default;
double compute() const override { return _b * _d * _x * _y - _e * _y; }
private:
// parameters
double _b;
double _d;
double _e;
// state
double _x;
double _y;
};
class Prey
: public artis::pdevs::qss::Derivative {
public:
unsigned int IN_Y;
Prey(const std::string& name,
const artis::pdevs::Context& context)
:
artis::pdevs::qss::Derivative(
name,
context), _a(context.parameters().a), _b(context.parameters().b)
{
internal("X", &Prey::_x);
IN_Y = external("Y", &Prey::_y);
}
~Prey() override = default;
double compute() const override { return _a * _x - _b * _y * _x; }
private:
// parameters
double _a;
double _b;
// state
double _x;
double _y;
};
struct SmartGardenerParameters {
double threshold;
double prey_proportion;
double predator_proportion;
double delay;
};
class SmartGardener
: public artis::pdevs::Dynamics {
public:
enum inputs {
IN_X, IN_Y
};
enum outputs {
OUT_X, OUT_Y
};
SmartGardener(const std::string& name,
const artis::pdevs::Context& context)
:
artis::pdevs::Dynamics(
name, context),
_threshold(context.parameters().threshold),
_prey_proportion(context.parameters().prey_proportion),
_predator_proportion(context.parameters().predator_proportion),
_delay(context.parameters().delay)
{
input_ports({{IN_X, "in_x"},
{IN_Y, "in_y"}});
output_ports({{OUT_X, "out_x"},
{OUT_Y, "out_y"}});
}
~SmartGardener() override = default;
void dint(typename common::DoubleTime::type /* t */) override
{
switch (_phase) {
case INIT:
_phase = IDLE;
_sigma = _delay;
break;
case IDLE:
if (_prey_amount > _threshold) {
_phase = PEST;
} else {
_phase = IDLE;
_sigma = _delay;
}
break;
case PEST:
_phase = IDLE;
_sigma = _delay;
break;
}
}
void
dext(typename common::DoubleTime::type /* t */, typename common::DoubleTime::type e,
const common::Bag& bag) override
{
std::for_each(bag.begin(), bag.end(),
[this](const common::ExternalEvent& event) {
artis::pdevs::qss::IntegratorData data;
event.data()(data);
if (event.on_port(IN_X)) {
_prey_amount = data.value;
} else if (event.on_port(IN_Y)) {
_predator_amount = data.value;
}
});
_sigma -= e;
}
void start(typename common::DoubleTime::type /* t */) override { _phase = INIT; }
typename common::DoubleTime::type
ta(typename common::DoubleTime::type /* t */) const override
{
switch (_phase) {
case INIT:
return 0.0;
case IDLE:
return _sigma;
case PEST:
return 0.0;
}
return common::DoubleTime::infinity;
}
common::Bag
lambda(typename common::DoubleTime::type /* t */) const override
{
common::Bag bag;
if (_phase == PEST) {
artis::pdevs::qss::IntegratorData data = {_prey_amount * _prey_proportion};
bag.push_back(common::ExternalEvent(OUT_X, data));
data = {_predator_amount * _predator_proportion};
bag.push_back(common::ExternalEvent(OUT_Y, data));
}
return bag;
}
private:
enum Phase {
INIT, IDLE, PEST
};
// parameters
double _threshold;
double _prey_proportion;
double _predator_proportion;
double _delay;
// state
Phase _phase;
common::DoubleTime::type _sigma;
double _prey_amount;
double _predator_amount;
};
}
}
} // namespace artis tests qss
#endif