From 8c24f29d297b0da48b72c6284c93c62a5b2a2f46 Mon Sep 17 00:00:00 2001 From: Tobias Meisel <tobias.meisel@ufz.de> Date: Tue, 20 Jul 2021 15:19:34 +0200 Subject: [PATCH] [MeL/IO] XDMF: Use new xdmf writer --- MeshLib/IO/XDMF/MeshPropertyDataType.h | 5 +- MeshLib/IO/XDMF/Xdmf3Writer.cpp | 182 ------------------------- MeshLib/IO/XDMF/Xdmf3Writer.h | 77 ----------- MeshLib/IO/XDMF/XdmfData.cpp | 41 +----- MeshLib/IO/XDMF/XdmfData.h | 12 +- MeshLib/IO/XDMF/XdmfHdfWriter.cpp | 42 ++++-- MeshLib/IO/XDMF/XdmfHdfWriter.h | 14 +- MeshLib/IO/XDMF/transformData.cpp | 124 +++++++++-------- MeshLib/IO/writeMeshToFile.cpp | 6 +- MeshLib/MeshEnums.h | 3 +- ProcessLib/Output/Output.cpp | 2 +- 11 files changed, 125 insertions(+), 383 deletions(-) delete mode 100644 MeshLib/IO/XDMF/Xdmf3Writer.cpp delete mode 100644 MeshLib/IO/XDMF/Xdmf3Writer.h diff --git a/MeshLib/IO/XDMF/MeshPropertyDataType.h b/MeshLib/IO/XDMF/MeshPropertyDataType.h index 35d32bf1fa2..e792809d962 100644 --- a/MeshLib/IO/XDMF/MeshPropertyDataType.h +++ b/MeshLib/IO/XDMF/MeshPropertyDataType.h @@ -15,7 +15,7 @@ // TODO (tm) If used on several other places move definition of propertyVector enum class MeshPropertyDataType { - unknown, + unknown=0, float64, float32, int32, @@ -23,5 +23,6 @@ enum class MeshPropertyDataType uint32, uint64, int8, - uint8 + uint8, + enum_length }; \ No newline at end of file diff --git a/MeshLib/IO/XDMF/Xdmf3Writer.cpp b/MeshLib/IO/XDMF/Xdmf3Writer.cpp deleted file mode 100644 index 91556c378c9..00000000000 --- a/MeshLib/IO/XDMF/Xdmf3Writer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/** - * \file - * \copyright - * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - */ - -#include "Xdmf3Writer.h" - -#include <Xdmf.hpp> -#include <XdmfAttribute.hpp> -#include <XdmfDomain.hpp> -#include <XdmfGeometryType.hpp> -#include <XdmfGridCollection.hpp> -#include <XdmfGridCollectionType.hpp> -#include <XdmfHDF5Controller.hpp> -#include <XdmfHeavyDataDescription.hpp> -#include <XdmfInformation.hpp> -#include <XdmfTopologyType.hpp> -#include <XdmfUnstructuredGrid.hpp> -#include <XdmfWriter.hpp> -#include <string> - -#include "InfoLib/GitInfo.h" - -using namespace MeshLib::IO; -using namespace std::string_literals; - -boost::shared_ptr<const XdmfAttributeCenter> elemTypeOGS2XDMF( - MeshLib::MeshItemType const elem_type) -{ - std::map<MeshLib::MeshItemType, - boost::shared_ptr<const XdmfAttributeCenter>> - mesh_item_type_ogs2xdmf = { - {MeshLib::MeshItemType::Cell, XdmfAttributeCenter::Cell()}, - {MeshLib::MeshItemType::Edge, XdmfAttributeCenter::Edge()}, - {MeshLib::MeshItemType::Face, XdmfAttributeCenter::Face()}, - {MeshLib::MeshItemType::Node, XdmfAttributeCenter::Node()}, - {MeshLib::MeshItemType::IntegrationPoint, - XdmfAttributeCenter::Other()}}; - - return mesh_item_type_ogs2xdmf.at(elem_type); -} - -static std::string getDataSection(std::string const& name) -{ - return "data/"s + name; -} - -static std::vector<XdmfDimType> prependDimension( - XdmfDimType const prepend_value, std::vector<XdmfDimType> const& dimensions) -{ - std::vector<XdmfDimType> dims = {prepend_value}; - dims.insert(dims.end(), dimensions.begin(), dimensions.end()); - return dims; -} - -static boost::shared_ptr<XdmfGeometry> getLightGeometry( - std::string const& hdf5filename, XdmfData const& geometry) -{ - auto xdmf_geometry = XdmfGeometry::New(); - xdmf_geometry->setType(XdmfGeometryType::XYZ()); - boost::shared_ptr<XdmfHDF5Controller> geometry_controller = - XdmfHDF5Controller::New(hdf5filename, - getDataSection("geometry"), - XdmfArrayType::Float64(), - geometry.starts, - geometry.strides, - geometry.global_block_dims, - geometry.global_block_dims); - xdmf_geometry->setHeavyDataController(geometry_controller); - return xdmf_geometry; -} - -static boost::shared_ptr<XdmfTopology> getLightTopology( - std::string const& hdf5filename, XdmfData const& topology) -{ - auto xdmf_topology = XdmfTopology::New(); - xdmf_topology->setType(XdmfTopologyType::Mixed()); - auto topology_controller = - XdmfHDF5Controller::New(hdf5filename, - getDataSection("topology"), - XdmfArrayType::Int32(), - topology.starts, - topology.strides, - topology.global_block_dims, - topology.global_block_dims); - xdmf_topology->setHeavyDataController(topology_controller); - return xdmf_topology; -} - -static boost::shared_ptr<XdmfAttribute> getLightAttribute( - std::string const& hdf5filename, int const step, XdmfData const& attribute) -{ - std::vector<XdmfDimType> starts = prependDimension(step, attribute.starts); - std::vector<XdmfDimType> strides = prependDimension(1, attribute.strides); - std::vector<XdmfDimType> global_block_dims = - prependDimension(1, attribute.global_block_dims); - std::vector<XdmfDimType> all_global_block_dims = - prependDimension(step + 1, attribute.global_block_dims); - - auto const attribute_controller = - XdmfHDF5Controller::New(hdf5filename, - getDataSection(attribute.name), - attribute.data_type, - starts, - strides, - global_block_dims, - all_global_block_dims); - - auto const xdmf_attribute = XdmfAttribute::New(); - auto const center = elemTypeOGS2XDMF(*(attribute.attribute_center)); - xdmf_attribute->setCenter(center); - xdmf_attribute->setName(attribute.name); - xdmf_attribute->setHeavyDataController(attribute_controller); - return xdmf_attribute; -} - -namespace MeshLib::IO -{ -Xdmf3Writer::Xdmf3Writer(XdmfData const& geometry, XdmfData const& topology, - std::vector<XdmfData> constant_attributes, - std::vector<XdmfData> variable_attributes, - std::filesystem::path const& filepath, - int const time_step) - : _variable_attributes(std::move(variable_attributes)), - _hdf5filename(filepath.stem().string() + ".h5") -{ - _initial_geometry = getLightGeometry(_hdf5filename, geometry); - _initial_topology = getLightTopology(_hdf5filename, topology); - - std::transform( - constant_attributes.begin(), constant_attributes.end(), - std::back_inserter(_constant_attributes), - [&](XdmfData const& attribute) -> boost::shared_ptr<XdmfAttribute> { - return getLightAttribute(_hdf5filename, time_step, attribute); - }); - - _writer = XdmfWriter::New(filepath.string()); - _writer->setMode(XdmfWriter::DistributedHeavyData); - - auto version = XdmfInformation::New(); - version->setKey(GitInfoLib::GitInfo::OGS_VERSION); - version->setValue(GitInfoLib::GitInfo::ogs_version); - - auto grid_collection = XdmfGridCollection::New(); - grid_collection->setType(XdmfGridCollectionType::Temporal()); - - _root = XdmfDomain::New(); - _root->insert(version); - _root->insert(grid_collection); -} - -Xdmf3Writer::~Xdmf3Writer() -{ - _root->accept(_writer); -} - -void Xdmf3Writer::writeStep(int const time_step, double const time) -{ - auto grid = XdmfUnstructuredGrid::New(); - grid->setGeometry(_initial_geometry); - grid->setTopology(_initial_topology); - - for (auto const& constant_attribute : _constant_attributes) - { - grid->insert(constant_attribute); - } - - grid->setTime(XdmfTime::New(time)); - - for (auto const& attribute : _variable_attributes) - { - grid->insert(getLightAttribute(_hdf5filename, time_step, attribute)); - } - - auto grid_collection = _root->getGridCollection(0); - grid_collection->insert(grid); -} -} // namespace MeshLib::IO diff --git a/MeshLib/IO/XDMF/Xdmf3Writer.h b/MeshLib/IO/XDMF/Xdmf3Writer.h deleted file mode 100644 index 5489609d5fc..00000000000 --- a/MeshLib/IO/XDMF/Xdmf3Writer.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * \file - * \author Tobias Meisel - * \date 2020-11-13 - * \brief XdmfWriter which takes contiguous data and writes 1 xdmf + 1 hdf file - * \copyright - * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - */ - -#pragma once - -#include <filesystem.h> - -#include <boost/shared_ptr.hpp> - -#include "MeshLib/Mesh.h" -#include "XdmfData.h" - -class XdmfAttribute; -class XdmfGridCollection; -class XdmfTopology; -class XdmfGeometry; -class XdmfWriter; -class XdmfDomain; - -namespace MeshLib::IO -{ -struct Geometry; -struct Topology; -} // namespace MeshLib::IO - -namespace MeshLib::IO -{ -class Xdmf3Writer final -{ -public: - /** - * \brief Write xdmf and h5 file with geometry and topology data. - * The data itself is held by a structure outside of this class. - * The writer assumes a constant data holder (data itself can change, memory - * address is the same) - * @param geometry contains meta data to coordinates - * @param topology contains meta data cells - * @param constant_attributes vector of constant attributes (each attribute - * is a OGS mesh property) - * @param variable_attributes vector of variable attributes (each attribute - * is a OGS mesh property - * @param filepath absolute or relative filepath to the hdf5 file - * @param time_step number of the step (temporal collection) - */ - Xdmf3Writer(XdmfData const& geometry, XdmfData const& topology, - std::vector<XdmfData> constant_attributes, - std::vector<XdmfData> variable_attributes, - std::filesystem::path const& filepath, int time_step); - /** - * \brief Write attribute data that has modified to previous time step or - * initial - * @param time_step number of the step (temporal collection) - * @param time time value of the current time_step - */ - void writeStep(int time_step, double time); - ~Xdmf3Writer(); - -private: - boost::shared_ptr<XdmfGridCollection> _gridCollection; - boost::shared_ptr<XdmfTopology> _initial_topology; - boost::shared_ptr<XdmfGeometry> _initial_geometry; - std::vector<boost::shared_ptr<XdmfAttribute>> _constant_attributes; - std::vector<XdmfData> const _variable_attributes; - boost::shared_ptr<XdmfWriter> _writer; - boost::shared_ptr<XdmfDomain> _root; - std::string const _hdf5filename; -}; -} // namespace MeshLib::IO diff --git a/MeshLib/IO/XDMF/XdmfData.cpp b/MeshLib/IO/XDMF/XdmfData.cpp index a2e0462e48e..2aa9bf64cb2 100644 --- a/MeshLib/IO/XDMF/XdmfData.cpp +++ b/MeshLib/IO/XDMF/XdmfData.cpp @@ -9,9 +9,6 @@ #include "XdmfData.h" -#include <XdmfArrayType.hpp> -#include <XdmfAttributeCenter.hpp> -#include <XdmfTopologyType.hpp> #include <cassert> #include <map> @@ -20,38 +17,13 @@ #include "partition.h" namespace MeshLib::IO - -{ -static boost::shared_ptr<XdmfArrayType const> MeshPropertyDataType2XdmfType( - MeshPropertyDataType const ogs_data_type) { - std::map<MeshPropertyDataType, boost::shared_ptr<XdmfArrayType const>> const - ogs_to_xdmf_type = { - {MeshPropertyDataType::float64, XdmfArrayType::Float64()}, - {MeshPropertyDataType::float32, XdmfArrayType::Float32()}, - {MeshPropertyDataType::int32, XdmfArrayType::Int32()}, - // TODO (tm) XdmfLib does not support 64 bit data types so far - //{MeshPropertyDataType::int64, XdmfArrayType::Int64()}, - {MeshPropertyDataType::uint32, XdmfArrayType::UInt32()}, - // TODO (tm) XdmfLib does not support 64 bit data types so far - //{MeshPropertyDataType::uint64, XdmfArrayType::UInt64}, - {MeshPropertyDataType::int8, XdmfArrayType::Int8()}, - {MeshPropertyDataType::uint8, XdmfArrayType::UInt8()}}; - try - { - return ogs_to_xdmf_type.at(ogs_data_type); - } - catch (const std::exception& e) - { - OGS_FATAL("No known HDF5 type for XDMF type. {:s}", e.what()); - } -} - XdmfData::XdmfData(std::size_t const size_partitioned_dim, std::size_t const size_tuple, MeshPropertyDataType const mesh_property_data_type, std::string const& name, - std::optional<MeshLib::MeshItemType> const attribute_center) + std::optional<MeshLib::MeshItemType> const attribute_center, + unsigned int const index) : starts([&size_tuple]() { if (size_tuple > 1) { @@ -65,15 +37,17 @@ XdmfData::XdmfData(std::size_t const size_partitioned_dim, strides([&size_tuple]() { if (size_tuple > 1) { - return std::vector<XdmfDimType>{1}; + return std::vector<XdmfDimType>{1, 1}; } else { - return std::vector<XdmfDimType>{1, 1}; + return std::vector<XdmfDimType>{1}; } }()), + data_type(mesh_property_data_type), name(name), - attribute_center(attribute_center) + attribute_center(attribute_center), + index(index) { auto partition_info = getPartitionInfo(size_partitioned_dim); // TODO (tm) XdmfLib does not support 64 bit data types so far @@ -92,7 +66,6 @@ XdmfData::XdmfData(std::size_t const size_partitioned_dim, global_block_dims = {ui_global_components, ui_tuple_size}; } - data_type = MeshPropertyDataType2XdmfType(mesh_property_data_type); DBUG( "XDMF: dataset name: {:s}, offset: {:d} " "global_blocks: {:d}, tuples: {:d}", diff --git a/MeshLib/IO/XDMF/XdmfData.h b/MeshLib/IO/XDMF/XdmfData.h index 959e7d1536b..b6a826eeed8 100644 --- a/MeshLib/IO/XDMF/XdmfData.h +++ b/MeshLib/IO/XDMF/XdmfData.h @@ -26,7 +26,7 @@ namespace MeshLib::IO { using XdmfDimType = unsigned int; -struct XdmfData +struct XdmfData final { /** * \brief XdmfData contains meta data to be passed to the XdmfWriter - it @@ -43,19 +43,25 @@ struct XdmfData * @param attribute_center XdmfData is used for topology, geometry and * attributes. Geometry and topology have never a attribute_center. * Attributes have always an attribute_center + * @param index The position of the DataItem parents in a grid + * (representing a single step). Convention is: 1=Time, 2= + * Geometry, 3=Topology, 4>=Attribute + * */ XdmfData(std::size_t size_partitioned_dim, std::size_t size_tuple, MeshPropertyDataType mesh_property_data_type, std::string const& name, - std::optional<MeshLib::MeshItemType> attribute_center); + std::optional<MeshLib::MeshItemType> attribute_center, + unsigned int const index); // a hyperslab is defined by starts and strides see // https://www.xdmf.org/index.php/XDMF_Model_and_Format#HyperSlab std::vector<XdmfDimType> const starts; std::vector<XdmfDimType> const strides; std::vector<XdmfDimType> global_block_dims; - boost::shared_ptr<const XdmfArrayType> data_type; + MeshPropertyDataType const data_type; std::string const name; std::optional<MeshLib::MeshItemType> const attribute_center; + unsigned int index; }; } // namespace MeshLib::IO diff --git a/MeshLib/IO/XDMF/XdmfHdfWriter.cpp b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp index a33354b118f..7ec87403806 100644 --- a/MeshLib/IO/XDMF/XdmfHdfWriter.cpp +++ b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp @@ -12,16 +12,17 @@ #include <algorithm> #include <functional> +#include "InfoLib/GitInfo.h" #include "partition.h" #include "transformData.h" +#include "writeXdmf.h" namespace MeshLib::IO { XdmfHdfWriter::XdmfHdfWriter(MeshLib::Mesh const& mesh, std::filesystem::path const& filepath, - int const time_step, - std::set<std::string> - variable_output_names, + int const time_step, double const initial_time, + std::set<std::string> const& variable_output_names, bool const use_compression) { // transform Data into contiguous data and collect meta data @@ -87,7 +88,13 @@ XdmfHdfWriter::XdmfHdfWriter(MeshLib::Mesh const& mesh, std::vector<XdmfData> xdmf_attributes; std::transform(attributes.begin(), attributes.end(), std::back_inserter(xdmf_attributes), - [](AttributeMeta att) -> XdmfData { return att.xdmf; }); + [&attributes](AttributeMeta& att) -> XdmfData { + size_t const i = &att - &attributes.front(); + // index 1 geo, index 2 topology, attributes start at + // index 3 + att.xdmf.index = i + 4; + return att.xdmf; + }); std::function<bool(XdmfData)> is_variable_xdmf_attribute = [&variable_output_names](XdmfData data) -> bool { @@ -100,28 +107,33 @@ XdmfHdfWriter::XdmfHdfWriter(MeshLib::Mesh const& mesh, std::copy_if(xdmf_attributes.begin(), xdmf_attributes.end(), back_inserter(xdmf_variable_attributes), is_variable_xdmf_attribute); - std::vector<XdmfData> xdmf_constant_attributes; std::copy_if(xdmf_attributes.begin(), xdmf_attributes.end(), back_inserter(xdmf_constant_attributes), std::not_fn(is_variable_xdmf_attribute)); - _xdmf_writer = std::make_unique<Xdmf3Writer>( - geometry.xdmf, topology.xdmf, std::move(xdmf_constant_attributes), - std::move(xdmf_variable_attributes), xdmf_filepath, time_step); + if (isFileManager()) + { + auto xdmf_writer_fn = + write_xdmf(geometry.xdmf, topology.xdmf, xdmf_constant_attributes, + xdmf_variable_attributes, hdf_filepath.string(), + GitInfoLib::GitInfo::ogs_version); + _xdmf_writer = std::make_unique<XdmfWriter>(xdmf_filepath.string(), + xdmf_writer_fn); + _xdmf_writer->addTimeStep(initial_time); + } } -void XdmfHdfWriter::writeStep(int const time_step, double const time) const +void XdmfHdfWriter::writeStep([[maybe_unused]] int const& time_step, + double const& time) { - _hdf_writer->writeStep(time_step); - - // XDMF + // ToDo (tm) time_step will be used for simulation continuation (restart) + _hdf_writer->writeStep(); // The light data is only written by just one process - if (!_xdmf_writer) + if (isFileManager()) { - return; + _xdmf_writer->addTimeStep(time); } - _xdmf_writer->writeStep(time_step, time); } } // namespace MeshLib::IO diff --git a/MeshLib/IO/XDMF/XdmfHdfWriter.h b/MeshLib/IO/XDMF/XdmfHdfWriter.h index 311821c098b..d4301f0b7ab 100644 --- a/MeshLib/IO/XDMF/XdmfHdfWriter.h +++ b/MeshLib/IO/XDMF/XdmfHdfWriter.h @@ -19,7 +19,7 @@ #include "HdfWriter.h" #include "MeshLib/Mesh.h" -#include "Xdmf3Writer.h" +#include "XdmfWriter.h" namespace MeshLib::IO { @@ -31,6 +31,7 @@ public: * @param mesh Mesh or NodePartitionedMesh to be written to file(s) * @param filepath absolute or relative filepath to the hdf5 file * @param time_step number of the step (temporal collection) + * @param initial_time time in seconds of the first time step * @param variable_output_names names of all process variables (attributes) * that change over time * @param use_compression if true, zlib compression in HDFWriter component @@ -38,19 +39,20 @@ public: */ XdmfHdfWriter(MeshLib::Mesh const& mesh, std::filesystem::path const& filepath, int time_step, - std::set<std::string> variable_output_names, + double initial_time, + std::set<std::string> const& variable_output_names, bool use_compression); + /** - * \brief Write attribute data that has modified to previous time step or - * initial + * \brief Adds data for either lazy (xdmf) or eager (hdf) writing algorithm * @param time_step number of the step (temporal collection) * @param time time value of the current time_step */ - void writeStep(int time_step, double time) const; + void writeStep(int const& time_step, double const& time); private: // hdf_writer must be destructed before xdmf_writer - std::unique_ptr<Xdmf3Writer> _xdmf_writer; std::unique_ptr<HdfWriter> _hdf_writer; + std::unique_ptr<XdmfWriter> _xdmf_writer; }; } // namespace MeshLib::IO \ No newline at end of file diff --git a/MeshLib/IO/XDMF/transformData.cpp b/MeshLib/IO/XDMF/transformData.cpp index 10244d1bb93..33ac0e59859 100644 --- a/MeshLib/IO/XDMF/transformData.cpp +++ b/MeshLib/IO/XDMF/transformData.cpp @@ -11,11 +11,13 @@ #include "transformData.h" -#include <XdmfTopologyType.hpp> #include <algorithm> +#include <array> #include <optional> #include <string> + +#include "BaseLib/cpp23.h" #include "InfoLib/GitInfo.h" #include "MeshLib/Elements/Element.h" #include "MeshLib/Mesh.h" @@ -24,37 +26,47 @@ #include "MeshPropertyDataType.h" #include "partition.h" + +using namespace BaseLib; namespace MeshLib::IO { -// \TODO (tm) constexpr by other function signature can not be transformed to -// constexpr shared_ptr is not literal type / has non trivial destructor -boost::shared_ptr<const XdmfTopologyType> cellTypeOGS2XDMF( - MeshLib::CellType const cell_type) +struct XdmfTopology +{ + // https://www.xdmf.org/index.php/XDMF_Model_and_Format#Topology, Section + // Arbitrary + unsigned int id; + unsigned int number_of_nodes; +}; + +constexpr auto elemOGSTypeToXDMFType() +{ + std::array<XdmfTopology, to_underlying(MeshLib::CellType::enum_length)> elem_type{}; + elem_type[to_underlying(MeshLib::CellType::POINT1)] = {0x1, 1}; + elem_type[to_underlying(MeshLib::CellType::LINE2)] = {0x2, 2}; + elem_type[to_underlying(MeshLib::CellType::LINE3)] = {0x2, 3}; + elem_type[to_underlying(MeshLib::CellType::TRI3)] = {0x4, 3}; + elem_type[to_underlying(MeshLib::CellType::TRI6)] = {0x24, 6}; + elem_type[to_underlying(MeshLib::CellType::QUAD4)] = {0x5, 4}; + elem_type[to_underlying(MeshLib::CellType::QUAD8)] = {0x25, 8}; + elem_type[to_underlying(MeshLib::CellType::QUAD9)] = {0x23, 9}; + elem_type[to_underlying(MeshLib::CellType::TET4)] = {0x6, 4}; + elem_type[to_underlying(MeshLib::CellType::TET10)] = {0x26, 10}; + elem_type[to_underlying(MeshLib::CellType::HEX8)] = {0x9, 8}; + elem_type[to_underlying(MeshLib::CellType::HEX20)] = {0x30, 20}; + elem_type[to_underlying(MeshLib::CellType::HEX27)] = {0x32, 27}; + elem_type[to_underlying(MeshLib::CellType::PRISM6)] = { + 0x8, 6}; // parallel triangle wedge + elem_type[to_underlying(MeshLib::CellType::PRISM15)] = {0x28, 15}; + elem_type[to_underlying(MeshLib::CellType::PRISM18)] = {0x29, 18}; + elem_type[to_underlying(MeshLib::CellType::PYRAMID5)] = {0x7, 5}; + elem_type[to_underlying(MeshLib::CellType::PYRAMID13)] = {0x27, 13}; + return elem_type; +} + +auto cellTypeOGS2XDMF(MeshLib::CellType const& cell_type) { - static std::map<MeshLib::CellType const, - boost::shared_ptr<const XdmfTopologyType> const> - elem_type_ogs2xdmf = { - {MeshLib::CellType::POINT1, XdmfTopologyType::Polyvertex()}, - {MeshLib::CellType::LINE2, XdmfTopologyType::Polyline(2)}, - {MeshLib::CellType::LINE3, XdmfTopologyType::Polyline(3)}, - {MeshLib::CellType::QUAD4, XdmfTopologyType::Quadrilateral()}, - {MeshLib::CellType::QUAD8, XdmfTopologyType::Quadrilateral_8()}, - {MeshLib::CellType::QUAD9, XdmfTopologyType::Quadrilateral_9()}, - {MeshLib::CellType::TET4, XdmfTopologyType::Tetrahedron()}, - {MeshLib::CellType::TET10, XdmfTopologyType::Tetrahedron_10()}, - {MeshLib::CellType::TRI3, XdmfTopologyType::Triangle()}, - {MeshLib::CellType::TRI6, XdmfTopologyType::Triangle_6()}, - {MeshLib::CellType::PRISM6, - XdmfTopologyType::Wedge()}, // parallel triangle wedge - {MeshLib::CellType::PRISM15, XdmfTopologyType::Wedge_15()}, - {MeshLib::CellType::PRISM18, XdmfTopologyType::Wedge_18()}, - {MeshLib::CellType::PYRAMID13, XdmfTopologyType::Pyramid_13()}, - {MeshLib::CellType::PYRAMID5, XdmfTopologyType::Pyramid()}, - {MeshLib::CellType::HEX20, XdmfTopologyType::Hexahedron_20()}, - {MeshLib::CellType::HEX27, XdmfTopologyType::Hexahedron_27()}, - {MeshLib::CellType::HEX8, XdmfTopologyType::Hexahedron()}}; - - return elem_type_ogs2xdmf.at(cell_type); + constexpr auto elem_type_ogs2xdmf = elemOGSTypeToXDMFType(); + return elem_type_ogs2xdmf[to_underlying(cell_type)]; } std::optional<AttributeMeta> transformAttribute( @@ -106,33 +118,31 @@ std::optional<AttributeMeta> transformAttribute( "Signed int has 32-1 bits"); data_type = MeshPropertyDataType::int32; } - // \TODO (tm) Reimplement size checks + // ToDo (tm) These tests are platform specific and currently fail on Windows // else if constexpr (std::is_same_v<long, decltype(basic_type)>) - // { - // static_assert((std::numeric_limits<long>::digits == 63), - // "Signed int has 64-1 bits"); - // data_type = XdmfArrayType::Int64(); - // } + //{ + // static_assert((std::numeric_limits<long>::digits == 63), + // "Signed int has 64-1 bits"); + // data_type = MeshPropertyDataType::int64; + //} + // else if constexpr (std::is_same_v<unsigned long, + // decltype(basic_type)>) + //{ + // static_assert((std::numeric_limits<unsigned long>::digits == 64), + // "Unsigned long has 64 bits"); + // data_type = MeshPropertyDataType::uint64; + //} else if constexpr (std::is_same_v<unsigned int, decltype(basic_type)>) { static_assert((std::numeric_limits<unsigned int>::digits == 32), "Unsigned int has 32 bits"); data_type = MeshPropertyDataType::uint32; } - // else if constexpr (std::is_same_v<unsigned long, - // decltype(basic_type)>) - // { - // static_assert((std::numeric_limits<unsigned long>::digits == 64), - // "Unsigned long has 64 bits"); - // // \TODO (tm) Extend XdmfLibrary with 64bit data types - // data_type = XdmfArrayType::UInt32(); - // } else if constexpr (std::is_same_v<std::size_t, decltype(basic_type)>) { static_assert((std::numeric_limits<std::size_t>::digits == 64), "size_t has 64 bits"); - // \TODO (tm) Extend XdmfLibrary with 64bit data types - data_type = MeshPropertyDataType::uint32; + data_type = MeshPropertyDataType::uint64; } else if constexpr (std::is_same_v<char, decltype(basic_type)>) { @@ -182,7 +192,7 @@ std::optional<AttributeMeta> transformAttribute( HdfData(data_ptr, num_of_tuples, ui_global_components, name, data_type); XdmfData xdmf = XdmfData(num_of_tuples, ui_global_components, data_type, - name, mesh_item_type); + name, mesh_item_type, 0); return AttributeMeta{std::move(hdf), std::move(xdmf)}; } @@ -234,11 +244,9 @@ Geometry transformGeometry(MeshLib::Mesh const& mesh) point_size, name, MeshPropertyDataType::float64); - XdmfData xdmf = XdmfData(partition_dim, - point_size, - MeshPropertyDataType::float64, - name, - std::nullopt); + XdmfData xdmf = + XdmfData(partition_dim, point_size, MeshPropertyDataType::float64, name, + std::nullopt, 2); return Geometry{std::move(values), std::move(hdf), std::move(xdmf)}; } @@ -247,18 +255,18 @@ Topology transformTopology(MeshLib::Mesh const& mesh, std::size_t const offset) { std::string const name = "topology"; std::vector<MeshLib::Element*> const& elements = mesh.getElements(); - // \TODO (tm) Precalculate exact size std::vector<int> values; values.reserve(elements.size()); for (auto const& cell : elements) { - auto const cell_type = cellTypeOGS2XDMF(cell->getCellType()); - auto const cell_type_id = cell_type->getID(); - values.push_back(cell_type_id); - if (cell_type_id == 2 || cell_type_id == 3) + auto const ogs_cell_type = cell->getCellType(); + auto const xdmf_cell_id = cellTypeOGS2XDMF(ogs_cell_type).id; + values.push_back(xdmf_cell_id); + if (ogs_cell_type == MeshLib::CellType::LINE2 || + ogs_cell_type == MeshLib::CellType::LINE3) { - values.push_back(cell_type->getNodesPerElement()); + values.push_back(cellTypeOGS2XDMF(ogs_cell_type).number_of_nodes); } for (std::size_t i = 0; i < cell->getNumberOfNodes(); ++i) @@ -271,7 +279,7 @@ Topology transformTopology(MeshLib::Mesh const& mesh, std::size_t const offset) HdfData hdf = HdfData(values.data(), values.size(), 1, name, MeshPropertyDataType::int32); XdmfData xdmf = XdmfData(values.size(), 1, MeshPropertyDataType::int32, - name, std::nullopt); + name, std::nullopt, 3); return Topology{std::move(values), std::move(hdf), std::move(xdmf)}; } diff --git a/MeshLib/IO/writeMeshToFile.cpp b/MeshLib/IO/writeMeshToFile.cpp index 81d9eb6d839..53fab4f321c 100644 --- a/MeshLib/IO/writeMeshToFile.cpp +++ b/MeshLib/IO/writeMeshToFile.cpp @@ -48,9 +48,8 @@ int writeMeshToFile(const MeshLib::Mesh& mesh, #ifdef OGS_USE_XDMF if (file_path.extension().string() == ".xdmf") { - MeshLib::IO::XdmfHdfWriter( - mesh, file_path, 0, variable_output_names, true); - + MeshLib::IO::XdmfHdfWriter(mesh, file_path, 0, 0.0, + variable_output_names, true); return 0; } #endif @@ -58,5 +57,4 @@ int writeMeshToFile(const MeshLib::Mesh& mesh, file_path.string()); return -1; } - } // namespace MeshLib::IO diff --git a/MeshLib/MeshEnums.h b/MeshLib/MeshEnums.h index 9a137657584..658b9d93faa 100644 --- a/MeshLib/MeshEnums.h +++ b/MeshLib/MeshEnums.h @@ -59,7 +59,8 @@ enum class CellType PRISM15 = 15, PRISM18 = 16, PYRAMID5 = 17, - PYRAMID13 = 18 + PYRAMID13 = 18, + enum_length }; /** diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp index 790bae18b58..cc2ac5b9ec4 100644 --- a/ProcessLib/Output/Output.cpp +++ b/ProcessLib/Output/Output.cpp @@ -245,7 +245,7 @@ void Output::outputMeshXdmf(OutputFile const& output_file, std::filesystem::path path(output_file.path); _mesh_xdmf_hdf_writer = std::make_unique<MeshLib::IO::XdmfHdfWriter>( MeshLib::IO::XdmfHdfWriter( - mesh, path, timestep, + mesh, path, timestep, t, _output_data_specification.output_variables, output_file.compression)); } _mesh_xdmf_hdf_writer->writeStep(timestep, t); -- GitLab