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