/** * @file test/models.hpp * @author See the AUTHORS file */ /* * Copyright (C) 2012-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 TEST_MODELS_HPP #define TEST_MODELS_HPP #include #include #include #include struct GlobalParameters { }; struct ModelParameters { }; using Model = artis::kernel::AbstractModel; using Models = artis::kernel::AbstractModels; using Trace = artis::utils::Trace; using TraceElement = artis::utils::TraceElement; template using AtomicModel = artis::kernel::AbstractAtomicModel; template using CoupledModel = artis::kernel::AbstractCoupledModel; class AModel : public AtomicModel { public: enum externals { }; enum internals { DX, BX, IX }; AModel(const Models& = Models()) :_ix(0), _bx(false), _dx(0.0) { // internals Internal(IX, &AModel::_ix); Internal(BX, &AModel::_bx); Internal(DX, &AModel::_dx); } ~AModel() override = default; void compute(double t, bool /* update */) override { Trace::trace() << TraceElement("A", t, artis::utils::COMPUTE) << "Start"; Trace::trace().flush(); ++_ix; _bx = not _bx; ++_dx; Trace::trace() << TraceElement("A", t, artis::utils::COMPUTE) << "Stop"; Trace::trace().flush(); } void init(double /* t */, const ModelParameters& /* parameters */) override { _ix = 0; _bx = false; _dx = 0.; } //private: int _ix; bool _bx; double _dx; }; class BModel : public AtomicModel { public: enum externals { IX, BX, DX }; enum internals { IY, IZ, BY, DY }; enum states { N }; BModel(const Models& = Models()) :_ix(0), _bx(false), _dx(0.0), _iy(0), _by(false), _dy(0.0), _iz(0), _n(0) { // externals Externals(int, ((IX, &BModel::_ix))); External(BX, &BModel::_bx); External(DX, &BModel::_dx); // internals Internals(int, ((IY, &BModel::_iy), (IZ, &BModel::_iz))); Internal(BY, &BModel::_by); Internal(DY, &BModel::_dy); States(int, ((N, &BModel::_n))); } ~BModel() override = default; void compute(double t, bool /* update */) override { Trace::trace() << TraceElement("B", t, artis::utils::COMPUTE) << "Start"; Trace::trace().flush(); _iy = _ix + 1; _by = not _bx; _dy = _dx + 1; ++_n; Trace::trace() << TraceElement("B", t, artis::utils::COMPUTE) << "Stop"; Trace::trace().flush(); } void init(double /* t */, const ModelParameters& /* parameters */) override { _iy = 0; _by = false; _dy = 0.; _iz = 0; _n = 0; } private: // externals int _ix; bool _bx; double _dx; // internals int _iy; bool _by; double _dy; int _iz; // states int _n; }; class RootModel : public CoupledModel { public: enum submodels { A, B }; enum internals { IY, BY, DY, IZ, DX }; enum states { N }; RootModel(Models submodels) : _a(dynamic_cast < AModel* >(submodels[0])), _b(dynamic_cast < BModel* >(submodels[1])), _dx(0.0), _n(0) { // submodels Submodels(((A, _a), (B, _b))); // internals Internal(DX, &RootModel::_dx); InternalsS(((IY, _b, BModel::IY), (IZ, _b, BModel::IZ))); InternalS(BY, _b, BModel::BY); // states States(int, ((N, &RootModel::_n))); // State(N, &RootModel::_n); } RootModel() :_a(new AModel), _b(new BModel), _dx(0.0), _n(0) { // submodels Submodels(((A, _a), (B, _b))); // internals Internal(DX, &RootModel::_dx); InternalsS(((IY, _b, BModel::IY), (IZ, _b, BModel::IZ))); InternalS(BY, _b, BModel::BY); // states States(int, ((N, &RootModel::_n))); } ~RootModel() override { delete _a; delete _b; } void compute(double t, bool /* update */) override { Trace::trace() << TraceElement(this->path(this), t, artis::utils::COMPUTE) << "Start"; Trace::trace().flush(); (*_a)(t); _b->put(t, BModel::DX, _a->get(t, AModel::DX)); _b->put(t, BModel::IX, _a->get(t, AModel::IX)); _b->put(t, BModel::BX, _a->get(t, AModel::BX)); (*_b)(t); ++_n; Trace::trace() << TraceElement(this->path(this), t, artis::utils::COMPUTE) << "Stop"; Trace::trace().flush(); } void init(double t, const ModelParameters& parameters) override { _a->init(t, parameters); _b->init(t, parameters); _n = 0; _dx = 0; } private: // submodels AModel* _a; BModel* _b; //internals double _dx; // states int _n; }; #endif