diff --git a/ProcessLib/Output/IntegrationPointWriter.cpp b/ProcessLib/Output/IntegrationPointWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc4249e864e8f75031f6646379af9788757ef442 --- /dev/null +++ b/ProcessLib/Output/IntegrationPointWriter.cpp @@ -0,0 +1,91 @@ +/** + * \file + * + * \copyright + * Copyright (c) 2012-2018, 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 <nlohmann/json.hpp> + +#include "MeshLib/Mesh.h" + +#include "IntegrationPointWriter.h" + +using nlohmann::json; + +/// Adds the integration point data and creates meta data for it. +/// +/// Returns meta data for the written integration point data. +static ProcessLib::IntegrationPointMetaData addIntegrationPointData( + MeshLib::Mesh& mesh, ProcessLib::IntegrationPointWriter const& writer) +{ + auto const& ip_values = writer.values(/*t, x, dof_table*/); + assert(ip_values.size() == mesh.getNumberOfElements()); + + // create field data and fill it with nodal values, and an offsets cell + // array indicating where the cell's integration point data starts. + auto& field_data = *MeshLib::getOrCreateMeshProperty<double>( + mesh, writer.name(), MeshLib::MeshItemType::IntegrationPoint, + writer.numberOfComponents()); + field_data.clear(); + + for (std::size_t e = 0; e < ip_values.size(); ++e) + { + auto const& element_ip_values = ip_values[e]; + std::copy(element_ip_values.begin(), element_ip_values.end(), + std::back_inserter(field_data)); + } + + return {writer.name(), writer.numberOfComponents(), + writer.integrationOrder()}; +} + +/// Adds integration point meta data as char mesh property encoded in JSON +/// format, which is then stored as VTK's field data. +static void addIntegrationPointMetaData( + MeshLib::Mesh& mesh, + std::vector<ProcessLib::IntegrationPointMetaData> const& meta_data) +{ + json json_meta_data; + json_meta_data["integration_point_arrays"] = json::array(); + + for (auto const& md : meta_data) + { + json_meta_data["integration_point_arrays"].push_back( + {{"name", md.name}, + {"number_of_components", md.n_components}, + {"integration_order", md.integration_order}}); + } + + // Store the field data. + std::string const json_string = json_meta_data.dump(); + auto& dictionary = *MeshLib::getOrCreateMeshProperty<char>( + mesh, "IntegrationPointMetaData", + MeshLib::MeshItemType::IntegrationPoint, 1); + dictionary.clear(); + std::copy(json_string.begin(), json_string.end(), + std::back_inserter(dictionary)); +} + +namespace ProcessLib +{ +void addIntegrationPointWriter( + MeshLib::Mesh& mesh, + std::vector<std::unique_ptr<IntegrationPointWriter>> const& + integration_point_writer) +{ + std::vector<IntegrationPointMetaData> meta_data; + for (auto const& ip_writer : integration_point_writer) + { + meta_data.push_back(addIntegrationPointData(mesh, *ip_writer)); + } + if (!meta_data.empty()) + { + addIntegrationPointMetaData(mesh, meta_data); + } +} +} // namespace ProcessLib diff --git a/ProcessLib/Output/IntegrationPointWriter.h b/ProcessLib/Output/IntegrationPointWriter.h index b442d107f8df9efda4e2a23a6c7629e1ce1a8ae8..da772e81186b23070cc4f1d606f23e901a345dbc 100644 --- a/ProcessLib/Output/IntegrationPointWriter.h +++ b/ProcessLib/Output/IntegrationPointWriter.h @@ -1,4 +1,6 @@ /** + * \file + * * \copyright * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. @@ -6,9 +8,16 @@ * http://www.opengeosys.org/project/license * */ +#include <memory> +#include <vector> #pragma once +namespace MeshLib +{ +class Mesh; +} + namespace ProcessLib { struct IntegrationPointWriter @@ -21,4 +30,25 @@ struct IntegrationPointWriter virtual std::vector<std::vector<double>> values() const = 0; }; +/// Add integration point data the the mesh's properties. +/// +/// Adds all integration point data arrays given by the input vector and the +/// corresponding meta data as VTK's field data. +/// Integration point data stored as field data (contrary to point or cell +/// data), as plain double arrays. The data is supplemented with information in +/// JSON format, which is stored as array of characters. +void addIntegrationPointWriter( + MeshLib::Mesh& mesh, + std::vector<std::unique_ptr<IntegrationPointWriter>> const& + integration_point_writer); + +/// Description of the stored integration point data providing additional +/// information for reconstruction and post-processing. +struct IntegrationPointMetaData +{ + std::string const name; + int const n_components; + int const integration_order; +}; + } // namespace ProcessLib diff --git a/ProcessLib/Output/ProcessOutput.cpp b/ProcessLib/Output/ProcessOutput.cpp index 65d13c59d6e0eb25d4a5ff8e44f5a0f641f30755..df6fac6affc9d39f92c41d4c9dddc333dc1cd535 100644 --- a/ProcessLib/Output/ProcessOutput.cpp +++ b/ProcessLib/Output/ProcessOutput.cpp @@ -239,6 +239,8 @@ void processOutputData( (void)secondary_variables; (void)t; #endif // USE_PETSC + + addIntegrationPointWriter(mesh, integration_point_writer); } void makeOutput(std::string const& file_name, MeshLib::Mesh& mesh,