OpenMC/tests/cpp_unit_tests/test_mesh.cpp
GuySten c31032cf25
load mesh objects from weight_windows.h5 file (#3598)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-10-21 23:03:27 +00:00

257 lines
6.1 KiB
C++

#include <cstdio>
#include <iostream>
#include <string>
#include <catch2/catch_test_macros.hpp>
#include <pugixml.hpp>
#include "openmc/hdf5_interface.h"
#include "openmc/mesh.h"
using namespace openmc;
TEST_CASE("Test mesh hdf5 roundtrip - regular")
{
// The XML data as a string
std::string xml_string = R"(
<mesh id="1">
<dimension>3 4 5</dimension>
<lower_left>-2 -3 -5</lower_left>
<upper_right>2 3 5</upper_right>
</mesh>
)";
// Create a pugixml document object
pugi::xml_document doc;
// Load the XML from the string
pugi::xml_parse_result result = doc.load_string(xml_string.c_str());
pugi::xml_node root = doc.child("mesh");
auto mesh = RegularMesh(root);
hid_t file_id = file_open("mesh.h5", 'w');
mesh.to_hdf5(file_id);
file_close(file_id);
hid_t file_id2 = file_open("mesh.h5", 'r');
hid_t group = open_group(file_id2, "mesh 1");
auto mesh2 = RegularMesh(group);
file_close(file_id2);
remove("mesh.h5");
REQUIRE(mesh2.shape_ == mesh.shape_);
REQUIRE(mesh2.lower_left() == mesh.lower_left());
REQUIRE(mesh2.upper_right() == mesh.upper_right());
}
TEST_CASE("Test mesh hdf5 roundtrip - rectilinear")
{
// The XML data as a string
std::string xml_string = R"(
<mesh id="1" type="rectilinear">
<x_grid>0.0 1.0 5.0 10.0</x_grid>
<y_grid>-10.0 -5.0 0.0</y_grid>
<z_grid>-100.0 0.0 100.0</z_grid>
</mesh>
)";
// Create a pugixml document object
pugi::xml_document doc;
// Load the XML from the string
pugi::xml_parse_result result = doc.load_string(xml_string.c_str());
pugi::xml_node root = doc.child("mesh");
auto mesh = RectilinearMesh(root);
hid_t file_id = file_open("mesh.h5", 'w');
mesh.to_hdf5(file_id);
file_close(file_id);
hid_t file_id2 = file_open("mesh.h5", 'r');
hid_t group = open_group(file_id2, "mesh 1");
auto mesh2 = RectilinearMesh(group);
file_close(file_id2);
remove("mesh.h5");
REQUIRE(mesh2.shape_ == mesh.shape_);
REQUIRE(mesh2.grid_ == mesh.grid_);
}
TEST_CASE("Test mesh hdf5 roundtrip - cylindrical")
{
// The XML data as a string
std::string xml_string = R"(
<mesh id="1" type="cylindrical">
<r_grid>0.1 0.2 0.5 1.0</r_grid>
<phi_grid>0.0 6.283185307179586</phi_grid>
<z_grid>0.1 0.2 0.4 0.6 1.0</z_grid>
<origin>0 0 0</origin>
</mesh>
)";
// Create a pugixml document object
pugi::xml_document doc;
// Load the XML from the string
pugi::xml_parse_result result = doc.load_string(xml_string.c_str());
pugi::xml_node root = doc.child("mesh");
auto mesh = CylindricalMesh(root);
hid_t file_id = file_open("mesh.h5", 'w');
mesh.to_hdf5(file_id);
file_close(file_id);
hid_t file_id2 = file_open("mesh.h5", 'r');
hid_t group = open_group(file_id2, "mesh 1");
auto mesh2 = CylindricalMesh(group);
file_close(file_id2);
remove("mesh.h5");
REQUIRE(mesh2.shape_ == mesh.shape_);
REQUIRE(mesh2.grid_ == mesh.grid_);
}
TEST_CASE("Test mesh hdf5 roundtrip - spherical")
{
// The XML data as a string
std::string xml_string = R"(
<mesh id="1" type="spherical">
<r_grid>0.1 0.2 0.5 1.0</r_grid>
<theta_grid>0.0 3.141592653589793</theta_grid>
<phi_grid>0.0 6.283185307179586</phi_grid>
<origin>0.0 0.0 0.0</origin>
</mesh>'
)";
// Create a pugixml document object
pugi::xml_document doc;
// Load the XML from the string
pugi::xml_parse_result result = doc.load_string(xml_string.c_str());
pugi::xml_node root = doc.child("mesh");
auto mesh = SphericalMesh(root);
hid_t file_id = file_open("mesh.h5", 'w');
mesh.to_hdf5(file_id);
file_close(file_id);
hid_t file_id2 = file_open("mesh.h5", 'r');
hid_t group = open_group(file_id2, "mesh 1");
auto mesh2 = SphericalMesh(group);
file_close(file_id2);
remove("mesh.h5");
REQUIRE(mesh2.shape_ == mesh.shape_);
REQUIRE(mesh2.grid_ == mesh.grid_);
}
TEST_CASE("Test multiple meshes HDF5 roundtrip - spherical")
{
// The XML data as a string
std::string xml_string = R"(
<meshes>
<mesh id="1" type="spherical">
<r_grid>0.1 0.2 0.5 1.0</r_grid>
<theta_grid>0.0 3.141592653589793</theta_grid>
<phi_grid>0.0 6.283185307179586</phi_grid>
<origin>0.0 0.0 0.0</origin>
</mesh>
<mesh id="2">
<dimension>3 4 5</dimension>
<lower_left>-2 -3 -5</lower_left>
<upper_right>2 3 5</upper_right>
</mesh>
</meshes>
)";
// Create a pugixml document object
pugi::xml_document doc;
// Load the XML from the string
pugi::xml_parse_result result = doc.load_string(xml_string.c_str());
pugi::xml_node root = doc.child("meshes");
read_meshes(root);
const auto spherical_mesh_xml =
dynamic_cast<SphericalMesh*>(model::meshes[0].get());
const auto regular_mesh_xml =
dynamic_cast<RegularMesh*>(model::meshes[1].get());
hid_t file_id = file_open("meshes.h5", 'w');
hid_t root_group = create_group(file_id, "root");
open_group(file_id, "root");
meshes_to_hdf5(root_group);
close_group(root_group);
file_close(file_id);
hid_t file_id2 = file_open("meshes.h5", 'r');
hid_t root_group_read = open_group(file_id2, "root");
hid_t mesh_group_read = open_group(root_group_read, "meshes");
read_meshes(mesh_group_read);
// increment mesh IDs to avoid collision during read
for (auto& mesh : model::meshes) {
mesh->set_id(mesh->id() + 10);
}
const auto spherical_mesh_hdf5 = dynamic_cast<SphericalMesh*>(
model::meshes[model::mesh_map[spherical_mesh_xml->id_]].get());
const auto regular_mesh_hdf5 = dynamic_cast<RegularMesh*>(
model::meshes[model::mesh_map[regular_mesh_xml->id_]].get());
remove("meshes.h5");
REQUIRE(spherical_mesh_hdf5->shape_ == spherical_mesh_xml->shape_);
REQUIRE(spherical_mesh_hdf5->grid_ == spherical_mesh_xml->grid_);
REQUIRE(regular_mesh_hdf5->shape_ == regular_mesh_xml->shape_);
REQUIRE(regular_mesh_hdf5->lower_left() == regular_mesh_xml->lower_left());
REQUIRE(regular_mesh_hdf5->upper_right() == regular_mesh_xml->upper_right());
}