/** * @file test/models.hpp * @author See the AUTHORS file */ /* * Copyright (C) 2012-2017 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 < artis::utils::DoubleTime, ModelParameters >; using Trace = artis::utils::Trace < artis::utils::DoubleTime >; using TraceElement = artis::utils::TraceElement < artis::utils::DoubleTime >; template < typename T > using AtomicModel = artis::kernel::AbstractAtomicModel < T, artis::utils::DoubleTime, ModelParameters >; template < typename T > using CoupledModel = artis::kernel::AbstractCoupledModel < T, artis::utils::DoubleTime, ModelParameters, GlobalParameters >; class AModel : public AtomicModel < AModel > { public: enum externals { }; enum internals { DX, BX, IX }; AModel() { Internal(IX, &AModel::_ix); Internal(BX, &AModel::_bx); Internal(DX, &AModel::_dx); } virtual ~AModel() { } void compute(double t, bool /* update */) { ++_ix; _bx = not _bx; ++_dx; ::Trace::trace() << ::TraceElement("A", t, artis::utils::COMPUTE); ::Trace::trace().flush(); } void init(double /* t */, const ModelParameters& /* parameters */) { _ix = 0; _bx = false; _dx = 0.; } //private: int _ix; bool _bx; double _dx; }; class BModel : public AtomicModel < BModel > { public: enum externals { IX, BX, DX }; enum internals { IY, BY, DY, IZ }; enum states { N }; BModel() { // external(IX, &BModel::_ix); Externals(int, (( IX, &BModel::_ix ))); External(BX, &BModel::_bx); External(DX, &BModel::_dx); // internal(IY, &BModel::_iy); Internals(int, ( ( IY, &BModel::_iy ), ( IZ, &BModel::_iz ) ) ); Internal(BY, &BModel::_by); Internal(DY, &BModel::_dy); States(int, ((N, &BModel::_n))); } virtual ~BModel() { } void compute(double t, bool /* update */) { _iy = _ix + 1; _by = not _bx; _dy = _dx + 1; ++_n; ::Trace::trace() << ::TraceElement("B", t, artis::utils::COMPUTE); ::Trace::trace().flush(); } void init(double /* t */, const ModelParameters& /* parameters */) { _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 < RootModel > { public: enum submodels { A, B }; enum internals { IY, BY, DY, IZ, DX }; enum states { N }; RootModel() : _a(new AModel), _b(new BModel) { // submodels Submodels(((A, _a.get()), (B, _b.get()))); // internals Internal(DX, &RootModel::_dx); InternalsS(((IY, _b.get(), BModel::IY), (IZ, _b.get(), BModel::IZ))); InternalS(BY, _b.get(), BModel::BY); // states States(int, ((N, &RootModel::_n))); // State(N, &RootModel::_n); } virtual ~RootModel() { } void compute(double t, bool /* update */) { (*_a)(t); _b->put < double >(t, BModel::DX, _a->get < double >(t, AModel::DX)); _b->put < int >(t, BModel::IX, _a->get < int >(t, AModel::IX)); _b->put < bool >(t, BModel::BX, _a->get < bool >(t, AModel::BX)); (*_b)(t); ++_n; ::Trace::trace() << ::TraceElement("ROOT", t, artis::utils::COMPUTE); ::Trace::trace().flush(); } void init(double t, const ModelParameters& parameters) { _a->init(t, parameters); _b->init(t, parameters); _n = 0; } private: // submodels std::unique_ptr < AModel > _a; std::unique_ptr < BModel > _b; //internals double _dx; // states int _n; }; #endif