diff --git a/src/output/WriterBase.cpp b/src/output/WriterBase.cpp index 83d890c2ab8bf31e60d7ed09e4e2da7770ebbfb8..b5cbee4c412d485fcdd12d6497e4b1fec20706f1 100644 --- a/src/output/WriterBase.cpp +++ b/src/output/WriterBase.cpp @@ -70,6 +70,63 @@ WriterBase::_checkConnectivity( } } +void +WriterBase::_checkSignature( + const std::vector<std::shared_ptr<const INamedDiscreteData>>& named_discrete_data_list) const +{ + using NameTypeMap = std::map<std::string, std::string>; + NameTypeMap name_type_map; + + for (auto named_discrete_data : named_discrete_data_list) { + switch (named_discrete_data->type()) { + case INamedDiscreteData::Type::item_value: { + const NamedItemValueVariant& named_item_value = dynamic_cast<const NamedItemValueVariant&>(*named_discrete_data); + std::visit( + [&](auto&& item_value) { + using ItemValueT = std::decay_t<decltype(item_value)>; + using DataType = std::decay_t<typename ItemValueT::data_type>; + + std::ostringstream type_name; + type_name << "item_value(" << dataTypeName(ast_node_data_type_from<DataType>) << ')'; + + name_type_map[named_discrete_data->name()] = type_name.str(); + }, + named_item_value.itemValueVariant()->itemValue()); + break; + } + case INamedDiscreteData::Type::discrete_function: { + const NamedDiscreteFunction& named_discrete_function = + dynamic_cast<const NamedDiscreteFunction&>(*named_discrete_data); + std::visit( + [&](auto&& discrete_function) { + std::ostringstream type_name; + type_name << "Vh(" << dataTypeName(discrete_function.dataType()) << ')'; + + name_type_map[named_discrete_data->name()] = type_name.str(); + }, + named_discrete_function.discreteFunctionVariant()->discreteFunction()); + break; + } + default: { + throw UnexpectedError("unexpected discrete data type"); + } + } + } + + std::string signature{"|"}; + for (auto&& [name, type_name] : name_type_map) { + signature += name + std::string{"-"} + type_name + std::string{"|"}; + } + + if (m_signature.has_value()) { + if (m_signature.value() != signature) { + throw NormalError("output variable list changed"); + } + } else { + m_signature = signature; + } +} + void WriterBase::_checkMesh(const std::shared_ptr<const IMesh>& mesh, const std::vector<std::shared_ptr<const INamedDiscreteData>>& named_discrete_data_list) const @@ -223,10 +280,10 @@ WriterBase::_getOutputNamedItemDataSet( } WriterBase::WriterBase(const std::string& base_filename, const double& time_period) - : m_base_filename{base_filename}, m_period_manager(time_period) + : m_base_filename{base_filename}, m_period_manager(time_period), m_signature(std::nullopt) {} -WriterBase::WriterBase(const std::string& base_filename) : m_base_filename{base_filename} {} +WriterBase::WriterBase(const std::string& base_filename) : m_base_filename{base_filename}, m_signature(std::nullopt) {} void WriterBase::write(const std::vector<std::shared_ptr<const INamedDiscreteData>>& named_discrete_data_list) const @@ -250,6 +307,7 @@ WriterBase::writeIfNeeded(const std::vector<std::shared_ptr<const INamedDiscrete if (time >= m_period_manager->nextTime()) { std::shared_ptr<const IMesh> mesh = _getMesh(named_discrete_data_list); + this->_checkSignature(named_discrete_data_list); this->_writeAtTime(*mesh, named_discrete_data_list, time); m_period_manager->setSaveTime(time); } @@ -265,7 +323,9 @@ WriterBase::writeForced(const std::vector<std::shared_ptr<const INamedDiscreteDa if (m_period_manager.has_value()) { if (time == m_period_manager->getLastTime()) return; // output already performed + std::shared_ptr<const IMesh> mesh = _getMesh(named_discrete_data_list); + this->_checkSignature(named_discrete_data_list); this->_writeAtTime(*mesh, named_discrete_data_list, time); m_period_manager->setSaveTime(time); } else { diff --git a/src/output/WriterBase.hpp b/src/output/WriterBase.hpp index 7fae994d78ed0e97be8f10d63097464280c739fc..707ac52d3a3c69c749c46047bd594b0be46c408b 100644 --- a/src/output/WriterBase.hpp +++ b/src/output/WriterBase.hpp @@ -85,7 +85,11 @@ class WriterBase : public IWriter std::optional<PeriodManager> m_period_manager; + mutable std::optional<std::string> m_signature; + private: + void _checkSignature(const std::vector<std::shared_ptr<const INamedDiscreteData>>& named_discrete_data_list) const; + template <typename DiscreteFunctionType> static void _registerDiscreteFunction(const std::string& name, const DiscreteFunctionType&, OutputNamedItemDataSet&);