/**
* @file artis/kernel/AbstractModel.hpp
* @author See the AUTHORS file
*/
/*
* Copyright (C) 2012-2016 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 __ARTIS_KERNEL_ABSTRACT_ATOMIC_MODEL_HPP
#define __ARTIS_KERNEL_ABSTRACT_ATOMIC_MODEL_HPP
#include
#include
#include
#include
#include
#include
namespace artis { namespace kernel {
template < typename T, typename U, typename V >
class AbstractAtomicModel : public AbstractModel < U, V >,
public States < T, U >,
public Internals < T, U >,
public Externals < T, U >
{
typedef AbstractModel < U, V > type;
public:
AbstractAtomicModel()
{ }
virtual ~AbstractAtomicModel()
{ }
virtual bool check(typename U::type t) const
{ return Externals < T, U >::check(t); }
virtual void compute(typename U::type t, bool update) = 0;
virtual double get(typename U::type t, unsigned int index) const
{
if (type::last_time != t) {
throw utils::InvalidGet("Variable not computed");
}
return static_cast < const T* >(this)->*(
Internals < T, U >::get(index));
}
virtual int getI(typename U::type t, unsigned int index) const
{
if (type::last_time != t) {
throw utils::InvalidGet("Variable not computed");
}
return static_cast < const T* >(this)->*(
Internals < T, U >::getI(index));
}
virtual bool getB(typename U::type t, unsigned int index) const
{
if (type::last_time != t) {
throw utils::InvalidGet("Variable not computed");
}
return static_cast < const T* >(this)->*(
Internals < T, U >::getB(index));
}
virtual void init(typename U::type t, const V& parameters) = 0;
bool is_computed(typename U::type t, unsigned int /* index */) const
{ return type::last_time == t; }
// bool is_ready(typename U::type t, unsigned int index) const
// { return type::externalDates.at(index) == t; }
// bool is_readyV(typename U::type t, unsigned int index) const
// { return type::externalDatesV.at(index) == t; }
bool is_stable(typename U::type t) const
{ return type::last_time == t; }
virtual bool is_updated() const
{ return Externals < T, U >::updated; }
// void put(typename U::type t, unsigned int index, double value)
// {
// if (type::externalDates.at(index) != t) {
// static_cast < T* >(this)->*externals.at(index) = value;
// type::externalDates.at(index) = t;
// type::updated = true;
// } else {
// if (static_cast < T* >(this)->*externals.at(index) != value) {
// static_cast < T* >(this)->*externals.at(index) = value;
// type::updated = true;
// }
// }
// }
// void put(typename U::type t, unsigned int index,
// const std::vector < double >& value)
// {
// if (type::externalDatesV.at(index) != t) {
// static_cast < T* >(this)->*externalsV.at(index) = value;
// type::externalDatesV.at(index) = t;
// type::updated = true;
// } else {
// if (static_cast < T* >(this)->*externalsV.at(index) != value) {
// static_cast < T* >(this)->*externalsV.at(index) = value;
// type::updated = true;
// }
// }
// }
virtual void restore(const State < U >& state)
{
States < T, U >::restore(state);
Internals < T, U >::restore(state);
type::last_time = state.last_time();
}
virtual void save(State < U >& state) const
{
States < T, U >::save(state);
Internals < T, U >::save(state);
state.last_time(type::last_time);
}
virtual void stable()
{ Externals < T, U >::updated = false; }
protected:
// void external(unsigned int index, double T::* var)
// {
// if (externals.size() <= index) {
// externals.resize(index + 1);
// type::externalDates.resize(index + 1);
// }
// externals[index] = var;
// type::externalDates[index] = -1;
// }
// void externalV(unsigned int index, std::vector < double > T::* var)
// {
// if (externalsV.size() <= index) {
// externalsV.resize(index + 1);
// type::externalDatesV.resize(index + 1);
// }
// externalsV[index] = var;
// type::externalDatesV[index] = -1;
// }
private:
// std::vector < double T::* > externals;
// std::vector < std::vector < double > T::* > externalsV;
};
template < typename T, typename U, typename V >
struct OUT_SA_t
{
OUT_SA_t(double t, AbstractAtomicModel < T, U, V >* model,
unsigned int index) : t(t), model(model), index(index)
{ }
double t;
AbstractAtomicModel < T, U, V >* model;
unsigned int index;
};
template < typename T, typename U, typename V >
OUT_SA_t < T, U, V > OUT(double t,
AbstractAtomicModel < T, U, V >* model,
unsigned int index)
{ return OUT_SA_t < T, U, V >(t, model, index); }
template < typename T1, typename U1, typename V1, typename W1,
typename T2, typename U2, typename V2 >
void operator>>(OUT_SA_t < T2, U2, V2 > out, IN_t < T1, U1, V1, W1 > in)
{
if (out.model->is_computed(out.t, out.index)) {
in.model->put(out.t, in.index, out.model->get(out.t, out.index));
}
}
} }
#endif