Page MenuHomec4science

component_libmultiscale.hh
No OneTemporary

File Metadata

Created
Fri, Jun 7, 22:10

component_libmultiscale.hh

/**
* @file component_libmultiscale.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This describe the root objects to be combined into valid LM
* components
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_HH__
#define __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_HH__
/* -------------------------------------------------------------------------- */
#include "auto_arguments.hh"
#include "container.hh"
#include "lm_common.hh"
#include "lm_object.hh"
/* -------------------------------------------------------------------------- */
#include <cmath>
#include <limits>
#include <map>
#include <memory>
#include <stdexcept>
#include <tuple>
#include <typeindex>
#include <typeinfo>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
class Component;
/* -------------------------------------------------------------------------- */
using dispatch = AutoDispatch::dispatch;
template <typename T, typename... Ts>
using enable_if_type = AutoDispatch::enable_if_type<T, Ts...>;
/* -------------------------------------------------------------------------- */
template <typename T1>
std::enable_if_t<std::is_base_of<ContainerInterface, std::decay_t<T1>>::value>
_copyContainerInfo_casted(T1 &value, ContainerInterface &a) {
value.copyContainerInfo(a);
}
template <typename T1>
std::enable_if_t<!std::is_base_of<ContainerInterface, std::decay_t<T1>>::value>
_copyContainerInfo_casted(T1 &, ContainerInterface &) {}
template <typename T1>
void _copyContainerInfo_casted(std::shared_ptr<T1> value,
ContainerInterface &a) {
T1 &v = *value;
_copyContainerInfo_casted<T1>(v, a);
}
template <typename T1>
std::enable_if_t<std::is_base_of<LMObject, std::decay_t<T1>>::value>
_setCommGroup(T1 &value, CommGroup &c) {
value.setCommGroup(c);
}
template <typename T1>
std::enable_if_t<!std::is_base_of<LMObject, std::decay_t<T1>>::value>
_setCommGroup(T1 &, CommGroup &) {}
template <typename T1>
void _setCommGroup(std::shared_ptr<T1> value, CommGroup &comm_group) {
T1 &v = *value;
_setCommGroup(v, comm_group);
}
/* -------------------------------------------------------------------------- */
// Output Container
/* -------------------------------------------------------------------------- */
class OutputContainer : public AutoDispatch::ArgumentAny {
public:
OutputContainer() : component(nullptr){};
OutputContainer(Component &component) : component(&component){};
OutputContainer(OutputContainer &&other) = default;
OutputContainer(const OutputContainer &other) = default;
inline OutputContainer &operator=(OutputContainer &&arg) = default;
inline OutputContainer &operator=(OutputContainer &arg) = default;
template <typename T = ReleasedObject> decltype(auto) get() {
return AutoDispatch::ArgumentAny::get<T>();
}
template <typename T = ReleasedObject> decltype(auto) get() const {
return AutoDispatch::ArgumentAny::get<T>();
}
inline ReleasedObject *operator->() { return &this->get(); }
inline ReleasedObject &operator*() { return this->get(); }
inline const ReleasedObject *operator->() const { return &this->get(); }
inline const ReleasedObject &operator*() const { return this->get(); }
template <typename T> inline OutputContainer &operator=(T &&v) {
AutoDispatch::ArgumentAny::operator=(std::forward<T>(v));
return *this;
}
friend class InputContainer;
UInt getRelease() const;
inline void setRelease(UInt release);
protected:
Component *component;
};
/* --------------------------------------------------------------------- */
// InputContainer
/* --------------------------------------------------------------------- */
class InputContainer {
public:
inline InputContainer() = default;
inline InputContainer(InputContainer &&v) = default;
inline InputContainer(const InputContainer &v) = default;
inline InputContainer &operator=(InputContainer &&v) = default;
inline InputContainer &operator=(OutputContainer &v);
inline InputContainer &operator=(OutputContainer &&v);
template <typename T> inline InputContainer &operator=(T &&v);
inline bool has_value() const { return output_reference.has_value(); }
inline UInt getRelease() const;
inline OutputContainer &get() const;
template <typename T> inline decltype(auto) get();
template <typename T> inline decltype(auto) get() const;
protected:
private:
std::any output_reference;
};
/* --------------------------------------------------------------------- */
// Component
/* --------------------------------------------------------------------- */
class Component : public ReleasedObject, public virtual LMObject {
public:
Component();
virtual ~Component(){};
////////////////////////////////////////////////////////////////
// meta-data of component
////////////////////////////////////////////////////////////////
public:
template <typename T = Real> void setCommGroup(CommGroup &group);
inline void printself(std::ostream &os) const;
protected:
template <typename T>
std::enable_if_t<std::is_base_of<ContainerInterface, T>::value>
_copyContainerInfo(T &a);
struct UnconnectedInput : public std::runtime_error {
using std::runtime_error::runtime_error;
};
struct NotInCommGroup : public std::runtime_error {
using std::runtime_error::runtime_error;
};
void acquireRelease();
bool checkDependency();
void propagateRelease();
////////////////////////////////////////////////////////////////
// input management
////////////////////////////////////////////////////////////////
public:
template <typename T> void connect(const std::string &input, T &&arg);
inline void connect(const std::string &input, Component &comp,
const std::string &output = "");
inline const auto &getInputs() const { return inputs; }
protected:
void clear_inputs() { inputs.clear(); }
inline InputContainer &getInput(const std::string &requested_input = "");
inline InputContainer &createInput(const std::string &input);
////////////////////////////////////////////////////////////////
// output management
////////////////////////////////////////////////////////////////
public:
template <typename T = Real>
inline decltype(auto) evalArrayOutput(const std::string &output_name = "");
template <typename T>
inline decltype(auto) evalOutput(const std::string &output_name = "");
inline OutputContainer &evalOutput(const std::string &output_name = "");
inline const auto &getOutputs();
protected:
template <typename T = Real>
ContainerArray<T> &getOutputAsArray(const std::string &output_name = "");
inline OutputContainer &createOutput(const std::string &output);
template <typename T>
inline decltype(auto) getOutput(const std::string &output_name = "");
inline OutputContainer &getOutput(const std::string &output_name = "");
template <typename Names> void createArrayOutputs(Names &&output_names);
template <typename T = Real> void createArrayOutput(const std::string &name);
template <typename Cont, typename... T>
auto &allocOutput(const std::string &output_name,
T &&... construction_parameters);
inline void removeInput(const std::string &input);
////////////////////////////////////////////////////////////////
// compute management
////////////////////////////////////////////////////////////////
public:
virtual void compute_make_call() = 0;
virtual void compute();
private:
template <typename ContMap>
decltype(auto) getContainer(const std::string &name, ContMap &cont);
protected:
std::map<std::string, InputContainer> inputs;
std::map<std::string, OutputContainer> outputs;
bool calculated_once;
CommGroup *comm_group;
};
/* --------------------------------------------------------------------- */
template <typename Output, typename Component>
class SingleOutputComponent : public Component {
public:
using Component::Component;
SingleOutputComponent(const LMID &name) : LMObject(name), Component(name) {}
operator Output &() {
return this->getOutputs().begin()->second.get().template cast<Output>();
}
auto begin() { return (*this)->begin(); }
auto end() { return (*this)->end(); }
Output *operator->() { return &static_cast<Output &>(*this); }
Output &operator*() { return *this; }
};
template <typename T> struct casted_component {
template <typename CastT> using cast = SingleOutputComponent<CastT, T>;
};
/* --------------------------------------------------------------------- */
__END_LIBMULTISCALE__
/* --------------------------------------------------------------------- */
#include "component_libmultiscale_inline_impl.hh"
#include "possible_types.hh"
/* --------------------------------------------------------------------- */
#endif /* __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_HH__ */

Event Timeline