diff --git a/.github/workflows/build_docker_images_for_ci.yml b/.github/workflows/build_docker_images_for_ci.yml index 4d1b04fd..aaf8fbf6 100644 --- a/.github/workflows/build_docker_images_for_ci.yml +++ b/.github/workflows/build_docker_images_for_ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build the Docker image run: docker build . --file .github/docker_files/docker_file_ci_ubuntu_20_04/DockerFile --tag kratosmultiphysics/co-sim-io-image-ci-ubuntu-20-04 - name: Docker Login diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38b4b91c..0231e242 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install dependencies run: | @@ -132,7 +132,7 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Intel compiler if: ${{ matrix.compiler == 'ICC' }} @@ -153,7 +153,7 @@ jobs: sudo apt-get install libopenmpi-dev openmpi-bin - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -198,7 +198,7 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build CoSimIO run: | @@ -225,10 +225,10 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -257,7 +257,7 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build CoSimIO shell: cmd @@ -301,10 +301,10 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -355,7 +355,7 @@ jobs: image: kratosmultiphysics/kratos-image-ci-centos7:latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build CoSimIO run: | @@ -398,7 +398,7 @@ jobs: sudo apt-get update sudo apt-get install libopenmpi-dev openmpi-bin - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build CoSimIO run: | diff --git a/co_sim_io/c/co_sim_io_c.h b/co_sim_io/c/co_sim_io_c.h index 221baea9..1a9444b8 100644 --- a/co_sim_io/c/co_sim_io_c.h +++ b/co_sim_io/c/co_sim_io_c.h @@ -35,7 +35,7 @@ enum CoSimIO_ConnectionStatus CoSimIO_DisconnectionError }; -CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_Hello(); +CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_Hello(void); CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_Connect( const CoSimIO_Info I_Settings); diff --git a/co_sim_io/c/co_sim_io_c_info.h b/co_sim_io/c/co_sim_io_c_info.h index d9cfd770..98998bd2 100644 --- a/co_sim_io/c/co_sim_io_c_info.h +++ b/co_sim_io/c/co_sim_io_c_info.h @@ -22,7 +22,7 @@ typedef struct CoSimIO_Info } CoSimIO_Info; -CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_CreateInfo(); +CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_CreateInfo(void); CO_SIM_IO_NODISCARD CoSimIO_Info CoSimIO_CopyInfo(const CoSimIO_Info I_Info); diff --git a/co_sim_io/includes/vtk_utilities.hpp b/co_sim_io/includes/vtk_utilities.hpp index 0f7d2d72..38e6600e 100644 --- a/co_sim_io/includes/vtk_utilities.hpp +++ b/co_sim_io/includes/vtk_utilities.hpp @@ -43,7 +43,13 @@ enum class VtkCellType { VtkCellType CO_SIM_IO_API GetVtkCellTypeForElementType(ElementType I_ElementType); -void CO_SIM_IO_API WriteVtk(const Info& I_Settings, const ModelPart& I_ModelPart); +void CO_SIM_IO_API WriteVtk( + const Info& I_Settings, + const ModelPart& I_ModelPart, + const std::unordered_map>& I_NodalScalarData={}, + const std::unordered_map>>& I_NodalVectorData={}, + const std::unordered_map>& I_ElementalScalarData={}, + const std::unordered_map>>& I_ElementalVectorData={}); void CO_SIM_IO_API ReadVtk(const Info& I_Settings, ModelPart& O_ModelPart); diff --git a/co_sim_io/sources/vtk_utilities.cpp b/co_sim_io/sources/vtk_utilities.cpp index 22fe097e..410dc7b7 100644 --- a/co_sim_io/sources/vtk_utilities.cpp +++ b/co_sim_io/sources/vtk_utilities.cpp @@ -53,12 +53,39 @@ VtkCellType GetVtkCellTypeForElementType(ElementType I_ElementType) return type_iter->second; } -void WriteVtk(const Info& I_Settings, const ModelPart& I_ModelPart) +void WriteVtk( + const Info& I_Settings, + const ModelPart& I_ModelPart, + const std::unordered_map>& I_NodalScalarData, + const std::unordered_map>>& I_NodalVectorData, + const std::unordered_map>& I_ElementalScalarData, + const std::unordered_map>>& I_ElementalVectorData) { const std::string file_name = I_Settings.Get("file_name"); const int precision = I_Settings.Get("precision", 12); + // check sizes of data + for (const auto& r_data : I_NodalScalarData) { + CO_SIM_IO_ERROR_IF(r_data.first == "") << "No data name defined for nodal scalar data!" << std::endl; + CO_SIM_IO_ERROR_IF(r_data.second.size() != I_ModelPart.NumberOfNodes()) << "Size of scalar nodal data \"" << r_data.first << "\"(" << r_data.second.size() << ") does not match number of nodes (" << I_ModelPart.NumberOfNodes() << ")!" << std::endl; + } + + for (const auto& r_data : I_NodalVectorData) { + CO_SIM_IO_ERROR_IF(r_data.first == "") << "No data name defined for nodal vector data!" << std::endl; + CO_SIM_IO_ERROR_IF(r_data.second.size() != I_ModelPart.NumberOfNodes()) << "Size of vector nodal data \"" << r_data.first << "\"(" << r_data.second.size() << ") does not match number of nodes (" << I_ModelPart.NumberOfNodes() << ")!" << std::endl; + } + + for (const auto& r_data : I_ElementalScalarData) { + CO_SIM_IO_ERROR_IF(r_data.first == "") << "No data name defined for elemental scalar data!" << std::endl; + CO_SIM_IO_ERROR_IF(r_data.second.size() != I_ModelPart.NumberOfNodes()) << "Size of scalar elemental data \"" << r_data.first << "\"(" << r_data.second.size() << ") does not match number of elements (" << I_ModelPart.NumberOfElements() << ")!" << std::endl; + } + + for (const auto& r_data : I_ElementalVectorData) { + CO_SIM_IO_ERROR_IF(r_data.first == "") << "No data name defined for elemental vector data!" << std::endl; + CO_SIM_IO_ERROR_IF(r_data.second.size() != I_ModelPart.NumberOfNodes()) << "Size of vector elemental data \"" << r_data.first << "\"(" << r_data.second.size() << ") does not match number of elements (" << I_ModelPart.NumberOfElements() << ")!" << std::endl; + } + std::ofstream output_file; output_file.open(file_name); Utilities::CheckStream(output_file, file_name); @@ -112,18 +139,39 @@ void WriteVtk(const Info& I_Settings, const ModelPart& I_ModelPart) } output_file << "\n"; + const std::size_t num_point_data = 1 + I_NodalScalarData.size() + I_NodalVectorData.size(); + const std::size_t num_cell_data = 2 + I_ElementalScalarData.size() + I_ElementalVectorData.size(); + // writing node Ids output_file << "POINT_DATA " << I_ModelPart.NumberOfNodes() << "\n"; - output_file << "FIELD FieldData 1" << "\n"; + output_file << "FIELD FieldData " << num_point_data << "\n"; output_file << "NODE_ID 1 " << I_ModelPart.NumberOfNodes() << " int\n"; for (const auto& r_node : I_ModelPart.Nodes()) { output_file << r_node.Id() << "\n"; } output_file << "\n"; + // writing nodal scalar data + for (const auto& r_data : I_NodalScalarData) { + output_file << r_data.first << " 1 " << I_ModelPart.NumberOfNodes() << " float\n"; + for (const auto& v : r_data.second) { + output_file << v << "\n"; + } + output_file << "\n"; + } + + // writing nodal vector data + for (const auto& r_data : I_NodalVectorData) { + output_file << r_data.first << " 3 " << I_ModelPart.NumberOfNodes() << " float\n"; + for (const auto& v : r_data.second) { + output_file << v[0] << " " << v[1] << " " << v[2] << "\n"; + } + output_file << "\n"; + } + // writing element Ids output_file << "CELL_DATA " << I_ModelPart.NumberOfElements() << "\n"; - output_file << "FIELD FieldData 1" << "\n"; + output_file << "FIELD FieldData " << num_cell_data << "\n"; output_file << "ELEMENT_ID 1 " << I_ModelPart.NumberOfElements() << " int\n"; for (const auto& r_elem : I_ModelPart.Elements()) { output_file << r_elem.Id() << "\n"; @@ -131,13 +179,29 @@ void WriteVtk(const Info& I_Settings, const ModelPart& I_ModelPart) output_file << "\n"; // writing element types - output_file << "CELL_DATA " << I_ModelPart.NumberOfElements() << "\n"; - output_file << "FIELD FieldData 1" << "\n"; output_file << "ELEMENT_TYPE 1 " << I_ModelPart.NumberOfElements() << " int\n"; for (const auto& r_elem : I_ModelPart.Elements()) { output_file << static_cast(r_elem.Type()) << "\n"; } + // writing elemental scalar data + for (const auto& r_data : I_ElementalScalarData) { + output_file << r_data.first << " 1 " << I_ModelPart.NumberOfElements() << " float\n"; + for (const auto& v : r_data.second) { + output_file << v << "\n"; + } + output_file << "\n"; + } + + // writing elemental vector data + for (const auto& r_data : I_ElementalVectorData) { + output_file << r_data.first << " 3 " << I_ModelPart.NumberOfElements() << " float\n"; + for (const auto& v : r_data.second) { + output_file << v[0] << " " << v[1] << " " << v[2] << "\n"; + } + output_file << "\n"; + } + output_file.close(); } diff --git a/tests/co_sim_io/cpp/test_vtk_utilities.cpp b/tests/co_sim_io/cpp/test_vtk_utilities.cpp index 10d86090..20ade4c1 100644 --- a/tests/co_sim_io/cpp/test_vtk_utilities.cpp +++ b/tests/co_sim_io/cpp/test_vtk_utilities.cpp @@ -43,10 +43,17 @@ TEST_CASE("write_read_vtk") Info info_vtk; info_vtk.Set("file_name", file_name); - CoSimIO::VtkUtilities::WriteVtk(info_vtk, model_part_write); + CoSimIO::VtkUtilities::WriteVtk( + info_vtk, + model_part_write, + {{std::string("pressure"),{1,2.5,3}}}, // nodal scalar data + {{std::string("Disp"),{{1,2.5,3}, {0,0,2}, {-215, 456, 98}}}}, // nodal vector data + {{std::string("AREA"),{1.02,25.5,-3}}}, // elemental scalar data + {{std::string("gradient"),{{1,2.5,3},{1,3,974},{0,0,0}}}} // elemental vector data + ); CoSimIO::VtkUtilities::ReadVtk(info_vtk, model_part_read); - fs::remove(file_name); + // fs::remove(file_name); CheckModelPartsAreEqual(model_part_write, model_part_read); }