/**
* @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