diff --git a/src/weight_windows.cpp b/src/weight_windows.cpp index 5d938240896..dcdf13abe97 100644 --- a/src/weight_windows.cpp +++ b/src/weight_windows.cpp @@ -695,431 +695,421 @@ void WeightWindows::check_tally_update_compatibility(const Tally* tally) } } - void WeightWindows::to_hdf5(hid_t group) const - { - hid_t ww_group = - create_group(group, fmt::format("weight_windows_{}", id())); - - write_dataset(ww_group, "mesh", this->mesh()->id()); - write_dataset( - ww_group, "particle_type", openmc::particle_type_to_str(particle_type_)); - write_dataset(ww_group, "energy_bounds", energy_bounds_); - write_dataset(ww_group, "lower_ww_bounds", lower_ww_); - write_dataset(ww_group, "upper_ww_bounds", upper_ww_); - write_dataset(ww_group, "survival_ratio", survival_ratio_); - write_dataset(ww_group, "max_lower_bound_ratio", max_lb_ratio_); - write_dataset(ww_group, "max_split", max_split_); - write_dataset(ww_group, "weight_cutoff", weight_cutoff_); - - close_group(ww_group); - } +void WeightWindows::to_hdf5(hid_t group) const +{ + hid_t ww_group = create_group(group, fmt::format("weight_windows_{}", id())); + + write_dataset(ww_group, "mesh", this->mesh()->id()); + write_dataset( + ww_group, "particle_type", openmc::particle_type_to_str(particle_type_)); + write_dataset(ww_group, "energy_bounds", energy_bounds_); + write_dataset(ww_group, "lower_ww_bounds", lower_ww_); + write_dataset(ww_group, "upper_ww_bounds", upper_ww_); + write_dataset(ww_group, "survival_ratio", survival_ratio_); + write_dataset(ww_group, "max_lower_bound_ratio", max_lb_ratio_); + write_dataset(ww_group, "max_split", max_split_); + write_dataset(ww_group, "weight_cutoff", weight_cutoff_); + + close_group(ww_group); +} - WeightWindowsGenerator::WeightWindowsGenerator(pugi::xml_node node) - { - // read information from the XML node - int32_t mesh_id = std::stoi(get_node_value(node, "mesh")); - int32_t mesh_idx = model::mesh_map[mesh_id]; - max_realizations_ = std::stoi(get_node_value(node, "max_realizations")); - - int active_batches = settings::n_batches - settings::n_inactive; - if (max_realizations_ > active_batches) { - auto msg = fmt::format( - "The maximum number of specified tally realizations ({}) is " - "greater than the number of active batches ({}).", +WeightWindowsGenerator::WeightWindowsGenerator(pugi::xml_node node) +{ + // read information from the XML node + int32_t mesh_id = std::stoi(get_node_value(node, "mesh")); + int32_t mesh_idx = model::mesh_map[mesh_id]; + max_realizations_ = std::stoi(get_node_value(node, "max_realizations")); + + int active_batches = settings::n_batches - settings::n_inactive; + if (max_realizations_ > active_batches) { + auto msg = + fmt::format("The maximum number of specified tally realizations ({}) is " + "greater than the number of active batches ({}).", max_realizations_, active_batches); - warning(msg); - } - auto tmp_str = get_node_value(node, "particle_type", true, true); - auto particle_type = str_to_particle_type(tmp_str); - - update_interval_ = std::stoi(get_node_value(node, "update_interval")); - on_the_fly_ = get_node_value_bool(node, "on_the_fly"); - - std::vector e_bounds; - if (check_for_node(node, "energy_bounds")) { - e_bounds = get_node_array(node, "energy_bounds"); - } else { - int p_type = static_cast(particle_type); - e_bounds.push_back(data::energy_min[p_type]); - e_bounds.push_back(data::energy_max[p_type]); - } + warning(msg); + } + auto tmp_str = get_node_value(node, "particle_type", true, true); + auto particle_type = str_to_particle_type(tmp_str); + + update_interval_ = std::stoi(get_node_value(node, "update_interval")); + on_the_fly_ = get_node_value_bool(node, "on_the_fly"); + + std::vector e_bounds; + if (check_for_node(node, "energy_bounds")) { + e_bounds = get_node_array(node, "energy_bounds"); + } else { + int p_type = static_cast(particle_type); + e_bounds.push_back(data::energy_min[p_type]); + e_bounds.push_back(data::energy_max[p_type]); + } - // create a tally based on the WWG information - Tally* ww_tally = Tally::create(); - tally_idx_ = model::tally_map[ww_tally->id()]; - ww_tally->set_scores({"flux"}); - - // see if there's already a mesh filter using this mesh - bool found_mesh_filter = false; - for (const auto& f : model::tally_filters) { - if (f->type() == FilterType::MESH) { - const auto* mesh_filter = dynamic_cast(f.get()); - if (mesh_filter->mesh() == mesh_idx && !mesh_filter->translated()) { - ww_tally->add_filter(f.get()); - found_mesh_filter = true; - break; - } + // create a tally based on the WWG information + Tally* ww_tally = Tally::create(); + tally_idx_ = model::tally_map[ww_tally->id()]; + ww_tally->set_scores({"flux"}); + + // see if there's already a mesh filter using this mesh + bool found_mesh_filter = false; + for (const auto& f : model::tally_filters) { + if (f->type() == FilterType::MESH) { + const auto* mesh_filter = dynamic_cast(f.get()); + if (mesh_filter->mesh() == mesh_idx && !mesh_filter->translated()) { + ww_tally->add_filter(f.get()); + found_mesh_filter = true; + break; } } + } - if (!found_mesh_filter) { - auto mesh_filter = Filter::create("mesh"); - openmc_mesh_filter_set_mesh( - mesh_filter->index(), model::mesh_map[mesh_id]); - ww_tally->add_filter(mesh_filter); - } + if (!found_mesh_filter) { + auto mesh_filter = Filter::create("mesh"); + openmc_mesh_filter_set_mesh(mesh_filter->index(), model::mesh_map[mesh_id]); + ww_tally->add_filter(mesh_filter); + } - if (e_bounds.size() > 0) { - auto energy_filter = Filter::create("energy"); - openmc_energy_filter_set_bins( - energy_filter->index(), e_bounds.size(), e_bounds.data()); - ww_tally->add_filter(energy_filter); - } + if (e_bounds.size() > 0) { + auto energy_filter = Filter::create("energy"); + openmc_energy_filter_set_bins( + energy_filter->index(), e_bounds.size(), e_bounds.data()); + ww_tally->add_filter(energy_filter); + } - // add a particle filter - auto particle_filter = Filter::create("particle"); - auto pf = dynamic_cast(particle_filter); - pf->set_particles({&particle_type, 1}); - ww_tally->add_filter(particle_filter); - - // set method and parameters for updates - method_ = get_node_value(node, "method"); - if (method_ == "magic") { - // parse non-default update parameters if specified - if (check_for_node(node, "update_parameters")) { - pugi::xml_node params_node = node.child("update_parameters"); - if (check_for_node(params_node, "value")) - tally_value_ = get_node_value(params_node, "value"); - if (check_for_node(params_node, "threshold")) - threshold_ = std::stod(get_node_value(params_node, "threshold")); - if (check_for_node(params_node, "ratio")) { - ratio_ = std::stod(get_node_value(params_node, "ratio")); - } - } - // check update parameter values - if (tally_value_ != "mean" && tally_value_ != "rel_err") { - fatal_error(fmt::format("Unsupported tally value '{}' specified for " - "weight window generation.", - tally_value_)); + // add a particle filter + auto particle_filter = Filter::create("particle"); + auto pf = dynamic_cast(particle_filter); + pf->set_particles({&particle_type, 1}); + ww_tally->add_filter(particle_filter); + + // set method and parameters for updates + method_ = get_node_value(node, "method"); + if (method_ == "magic") { + // parse non-default update parameters if specified + if (check_for_node(node, "update_parameters")) { + pugi::xml_node params_node = node.child("update_parameters"); + if (check_for_node(params_node, "value")) + tally_value_ = get_node_value(params_node, "value"); + if (check_for_node(params_node, "threshold")) + threshold_ = std::stod(get_node_value(params_node, "threshold")); + if (check_for_node(params_node, "ratio")) { + ratio_ = std::stod(get_node_value(params_node, "ratio")); } - if (threshold_ <= 0.0) - fatal_error( - fmt::format("Invalid relative error threshold '{}' (<= 0.0) " - "specified for weight window generation", - ratio_)); - if (ratio_ <= 1.0) - fatal_error(fmt::format("Invalid weight window ratio '{}' (<= 1.0) " - "specified for weight window generation")); - } else { - fatal_error(fmt::format( - "Unknown weight window update method '{}' specified", method_)); } - - // create a matching weight windows object - auto wws = WeightWindows::create(); - ww_idx_ = wws->index(); - if (e_bounds.size() > 0) - wws->set_energy_bounds(e_bounds); - wws->set_mesh(model::mesh_map[mesh_id]); - wws->set_particle_type(particle_type); - wws->set_defaults(); + // check update parameter values + if (tally_value_ != "mean" && tally_value_ != "rel_err") { + fatal_error(fmt::format("Unsupported tally value '{}' specified for " + "weight window generation.", + tally_value_)); + } + if (threshold_ <= 0.0) + fatal_error(fmt::format("Invalid relative error threshold '{}' (<= 0.0) " + "specified for weight window generation", + ratio_)); + if (ratio_ <= 1.0) + fatal_error(fmt::format("Invalid weight window ratio '{}' (<= 1.0) " + "specified for weight window generation")); + } else { + fatal_error(fmt::format( + "Unknown weight window update method '{}' specified", method_)); } - void WeightWindowsGenerator::update() const - { - const auto& wws = variance_reduction::weight_windows[ww_idx_]; - - Tally* tally = model::tallies[tally_idx_].get(); + // create a matching weight windows object + auto wws = WeightWindows::create(); + ww_idx_ = wws->index(); + if (e_bounds.size() > 0) + wws->set_energy_bounds(e_bounds); + wws->set_mesh(model::mesh_map[mesh_id]); + wws->set_particle_type(particle_type); + wws->set_defaults(); +} - // if we're beyond the number of max realizations or not at the corrrect - // update interval, skip the update - if (max_realizations_ < tally->n_realizations_ || - tally->n_realizations_ % update_interval_ != 0) - return; +void WeightWindowsGenerator::update() const +{ + const auto& wws = variance_reduction::weight_windows[ww_idx_]; - wws->update_magic(tally, tally_value_, threshold_, ratio_); + Tally* tally = model::tallies[tally_idx_].get(); - // if we're not doing on the fly generation, reset the tally results once - // we're done with the update - if (!on_the_fly_) - tally->reset(); + // if we're beyond the number of max realizations or not at the corrrect + // update interval, skip the update + if (max_realizations_ < tally->n_realizations_ || + tally->n_realizations_ % update_interval_ != 0) + return; - // TODO: deactivate or remove tally once weight window generation is - // complete - } + wws->update_magic(tally, tally_value_, threshold_, ratio_); - //============================================================================== - // C API - //============================================================================== + // if we're not doing on the fly generation, reset the tally results once + // we're done with the update + if (!on_the_fly_) + tally->reset(); - int verify_ww_index(int32_t index) - { - if (index < 0 || index >= variance_reduction::weight_windows.size()) { - set_errmsg( - fmt::format("Index '{}' for weight windows is invalid", index)); - return OPENMC_E_OUT_OF_BOUNDS; - } - return 0; - } + // TODO: deactivate or remove tally once weight window generation is + // complete +} - extern "C" int openmc_get_weight_windows_index(int32_t id, int32_t * idx) - { - auto it = variance_reduction::ww_map.find(id); - if (it == variance_reduction::ww_map.end()) { - set_errmsg(fmt::format("No weight windows exist with ID={}", id)); - return OPENMC_E_INVALID_ID; - } +//============================================================================== +// C API +//============================================================================== - *idx = it->second; - return 0; +int verify_ww_index(int32_t index) +{ + if (index < 0 || index >= variance_reduction::weight_windows.size()) { + set_errmsg(fmt::format("Index '{}' for weight windows is invalid", index)); + return OPENMC_E_OUT_OF_BOUNDS; } + return 0; +} - extern "C" int openmc_weight_windows_get_id(int32_t index, int32_t * id) - { - if (int err = verify_ww_index(index)) - return err; - - const auto& wws = variance_reduction::weight_windows.at(index); - *id = wws->id(); - return 0; +extern "C" int openmc_get_weight_windows_index(int32_t id, int32_t* idx) +{ + auto it = variance_reduction::ww_map.find(id); + if (it == variance_reduction::ww_map.end()) { + set_errmsg(fmt::format("No weight windows exist with ID={}", id)); + return OPENMC_E_INVALID_ID; } - extern "C" int openmc_weight_windows_set_id(int32_t index, int32_t id) - { - if (int err = verify_ww_index(index)) - return err; - - const auto& wws = variance_reduction::weight_windows.at(index); - wws->set_id(id); - return 0; - } + *idx = it->second; + return 0; +} - extern "C" int openmc_weight_windows_update_magic(int32_t ww_idx, - int32_t tally_idx, const char* value, double threshold, double ratio) - { - if (int err = verify_ww_index(ww_idx)) - return err; +extern "C" int openmc_weight_windows_get_id(int32_t index, int32_t* id) +{ + if (int err = verify_ww_index(index)) + return err; - if (tally_idx < 0 || tally_idx >= model::tallies.size()) { - set_errmsg(fmt::format("Index '{}' for tally is invalid", tally_idx)); - return OPENMC_E_OUT_OF_BOUNDS; - } + const auto& wws = variance_reduction::weight_windows.at(index); + *id = wws->id(); + return 0; +} - // get the requested tally - const Tally* tally = model::tallies.at(tally_idx).get(); +extern "C" int openmc_weight_windows_set_id(int32_t index, int32_t id) +{ + if (int err = verify_ww_index(index)) + return err; - // get the WeightWindows object - const auto& wws = variance_reduction::weight_windows.at(ww_idx); + const auto& wws = variance_reduction::weight_windows.at(index); + wws->set_id(id); + return 0; +} - wws->update_magic(tally, value, threshold, ratio); +extern "C" int openmc_weight_windows_update_magic(int32_t ww_idx, + int32_t tally_idx, const char* value, double threshold, double ratio) +{ + if (int err = verify_ww_index(ww_idx)) + return err; - return 0; + if (tally_idx < 0 || tally_idx >= model::tallies.size()) { + set_errmsg(fmt::format("Index '{}' for tally is invalid", tally_idx)); + return OPENMC_E_OUT_OF_BOUNDS; } - extern "C" int openmc_weight_windows_set_mesh( - int32_t ww_idx, int32_t mesh_idx) - { - if (int err = verify_ww_index(ww_idx)) - return err; - const auto& wws = variance_reduction::weight_windows.at(ww_idx); - wws->set_mesh(mesh_idx); - return 0; - } + // get the requested tally + const Tally* tally = model::tallies.at(tally_idx).get(); - extern "C" int openmc_weight_windows_get_mesh( - int32_t ww_idx, int32_t * mesh_idx) - { - if (int err = verify_ww_index(ww_idx)) - return err; - const auto& wws = variance_reduction::weight_windows.at(ww_idx); - *mesh_idx = model::mesh_map.at(wws->mesh()->id()); - return 0; - } + // get the WeightWindows object + const auto& wws = variance_reduction::weight_windows.at(ww_idx); - extern "C" int openmc_weight_windows_set_energy_bounds( - int32_t ww_idx, double* e_bounds, size_t e_bounds_size) - { - if (int err = verify_ww_index(ww_idx)) - return err; - const auto& wws = variance_reduction::weight_windows.at(ww_idx); - wws->set_energy_bounds({e_bounds, e_bounds_size}); - return 0; - } + wws->update_magic(tally, value, threshold, ratio); - extern "C" int openmc_weight_windows_get_energy_bounds( - int32_t ww_idx, const double** e_bounds, size_t* e_bounds_size) - { - if (int err = verify_ww_index(ww_idx)) - return err; - const auto& wws = variance_reduction::weight_windows[ww_idx].get(); - *e_bounds = wws->energy_bounds().data(); - *e_bounds_size = wws->energy_bounds().size(); - return 0; - } - - extern "C" int openmc_weight_windows_set_particle(int32_t index, int particle) - { - if (int err = verify_ww_index(index)) - return err; + return 0; +} - const auto& wws = variance_reduction::weight_windows.at(index); - wws->set_particle_type(static_cast(particle)); - return 0; - } +extern "C" int openmc_weight_windows_set_mesh(int32_t ww_idx, int32_t mesh_idx) +{ + if (int err = verify_ww_index(ww_idx)) + return err; + const auto& wws = variance_reduction::weight_windows.at(ww_idx); + wws->set_mesh(mesh_idx); + return 0; +} - extern "C" int openmc_weight_windows_get_particle( - int32_t index, int* particle) - { - if (int err = verify_ww_index(index)) - return err; +extern "C" int openmc_weight_windows_get_mesh(int32_t ww_idx, int32_t* mesh_idx) +{ + if (int err = verify_ww_index(ww_idx)) + return err; + const auto& wws = variance_reduction::weight_windows.at(ww_idx); + *mesh_idx = model::mesh_map.at(wws->mesh()->id()); + return 0; +} - const auto& wws = variance_reduction::weight_windows.at(index); - *particle = static_cast(wws->particle_type()); - return 0; - } +extern "C" int openmc_weight_windows_set_energy_bounds( + int32_t ww_idx, double* e_bounds, size_t e_bounds_size) +{ + if (int err = verify_ww_index(ww_idx)) + return err; + const auto& wws = variance_reduction::weight_windows.at(ww_idx); + wws->set_energy_bounds({e_bounds, e_bounds_size}); + return 0; +} - extern "C" int openmc_weight_windows_get_bounds(int32_t index, - const double** lower_bounds, const double** upper_bounds, size_t* size) - { - if (int err = verify_ww_index(index)) - return err; +extern "C" int openmc_weight_windows_get_energy_bounds( + int32_t ww_idx, const double** e_bounds, size_t* e_bounds_size) +{ + if (int err = verify_ww_index(ww_idx)) + return err; + const auto& wws = variance_reduction::weight_windows[ww_idx].get(); + *e_bounds = wws->energy_bounds().data(); + *e_bounds_size = wws->energy_bounds().size(); + return 0; +} - const auto& wws = variance_reduction::weight_windows[index]; - *size = wws->lower_ww_bounds().size(); - *lower_bounds = wws->lower_ww_bounds().data(); - *upper_bounds = wws->upper_ww_bounds().data(); - return 0; - } +extern "C" int openmc_weight_windows_set_particle(int32_t index, int particle) +{ + if (int err = verify_ww_index(index)) + return err; - extern "C" int openmc_weight_windows_set_bounds(int32_t index, - const double* lower_bounds, const double* upper_bounds, size_t size) - { - if (int err = verify_ww_index(index)) - return err; + const auto& wws = variance_reduction::weight_windows.at(index); + wws->set_particle_type(static_cast(particle)); + return 0; +} - const auto& wws = variance_reduction::weight_windows[index]; - wws->set_bounds({lower_bounds, size}, {upper_bounds, size}); - return 0; - } +extern "C" int openmc_weight_windows_get_particle(int32_t index, int* particle) +{ + if (int err = verify_ww_index(index)) + return err; - extern "C" int openmc_extend_weight_windows( - int32_t n, int32_t * index_start, int32_t * index_end) - { - if (index_start) - *index_start = variance_reduction::weight_windows.size(); - if (index_end) - *index_end = variance_reduction::weight_windows.size() + n - 1; - for (int i = 0; i < n; ++i) - variance_reduction::weight_windows.push_back( - make_unique()); - return 0; - } + const auto& wws = variance_reduction::weight_windows.at(index); + *particle = static_cast(wws->particle_type()); + return 0; +} - extern "C" size_t openmc_weight_windows_size() - { - return variance_reduction::weight_windows.size(); - } +extern "C" int openmc_weight_windows_get_bounds(int32_t index, + const double** lower_bounds, const double** upper_bounds, size_t* size) +{ + if (int err = verify_ww_index(index)) + return err; + + const auto& wws = variance_reduction::weight_windows[index]; + *size = wws->lower_ww_bounds().size(); + *lower_bounds = wws->lower_ww_bounds().data(); + *upper_bounds = wws->upper_ww_bounds().data(); + return 0; +} - extern "C" int openmc_weight_windows_export(const char* filename) - { +extern "C" int openmc_weight_windows_set_bounds(int32_t index, + const double* lower_bounds, const double* upper_bounds, size_t size) +{ + if (int err = verify_ww_index(index)) + return err; - if (!mpi::master) - return 0; + const auto& wws = variance_reduction::weight_windows[index]; + wws->set_bounds({lower_bounds, size}, {upper_bounds, size}); + return 0; +} - std::string name = filename ? filename : "weight_windows.h5"; +extern "C" int openmc_extend_weight_windows( + int32_t n, int32_t* index_start, int32_t* index_end) +{ + if (index_start) + *index_start = variance_reduction::weight_windows.size(); + if (index_end) + *index_end = variance_reduction::weight_windows.size() + n - 1; + for (int i = 0; i < n; ++i) + variance_reduction::weight_windows.push_back(make_unique()); + return 0; +} - write_message(fmt::format("Exporting weight windows to {}...", name), 5); +extern "C" size_t openmc_weight_windows_size() +{ + return variance_reduction::weight_windows.size(); +} - hid_t ww_file = file_open(name, 'w'); +extern "C" int openmc_weight_windows_export(const char* filename) +{ - // Write file type - write_attribute(ww_file, "filetype", "weight_windows"); + if (!mpi::master) + return 0; - // Write revisiion number for state point file - write_attribute(ww_file, "version", VERSION_WEIGHT_WINDOWS); + std::string name = filename ? filename : "weight_windows.h5"; - hid_t weight_windows_group = create_group(ww_file, "weight_windows"); + write_message(fmt::format("Exporting weight windows to {}...", name), 5); - hid_t mesh_group = create_group(ww_file, "meshes"); + hid_t ww_file = file_open(name, 'w'); - std::vector mesh_ids; - std::vector ww_ids; - for (const auto& ww : variance_reduction::weight_windows) { + // Write file type + write_attribute(ww_file, "filetype", "weight_windows"); - ww->to_hdf5(weight_windows_group); - ww_ids.push_back(ww->id()); + // Write revisiion number for state point file + write_attribute(ww_file, "version", VERSION_WEIGHT_WINDOWS); - // if the mesh has already been written, move on - int32_t mesh_id = ww->mesh()->id(); - if (std::find(mesh_ids.begin(), mesh_ids.end(), mesh_id) != - mesh_ids.end()) - continue; + hid_t weight_windows_group = create_group(ww_file, "weight_windows"); - mesh_ids.push_back(mesh_id); - ww->mesh()->to_hdf5(mesh_group); - } + hid_t mesh_group = create_group(ww_file, "meshes"); - write_attribute(mesh_group, "n_meshes", mesh_ids.size()); - write_attribute(mesh_group, "ids", mesh_ids); - close_group(mesh_group); + std::vector mesh_ids; + std::vector ww_ids; + for (const auto& ww : variance_reduction::weight_windows) { - write_attribute(weight_windows_group, "n_weight_windows", ww_ids.size()); - write_attribute(weight_windows_group, "ids", ww_ids); - close_group(weight_windows_group); + ww->to_hdf5(weight_windows_group); + ww_ids.push_back(ww->id()); - file_close(ww_file); + // if the mesh has already been written, move on + int32_t mesh_id = ww->mesh()->id(); + if (std::find(mesh_ids.begin(), mesh_ids.end(), mesh_id) != mesh_ids.end()) + continue; - return 0; + mesh_ids.push_back(mesh_id); + ww->mesh()->to_hdf5(mesh_group); } - extern "C" int openmc_weight_windows_import(const char* filename) - { - std::string name = filename ? filename : "weight_windows.h5"; + write_attribute(mesh_group, "n_meshes", mesh_ids.size()); + write_attribute(mesh_group, "ids", mesh_ids); + close_group(mesh_group); - if (mpi::master) - write_message( - fmt::format("Importing weight windows from {}...", name), 5); + write_attribute(weight_windows_group, "n_weight_windows", ww_ids.size()); + write_attribute(weight_windows_group, "ids", ww_ids); + close_group(weight_windows_group); - if (!file_exists(name)) { - set_errmsg(fmt::format("File '{}' does not exist", name)); - } + file_close(ww_file); - hid_t ww_file = file_open(name, 'r'); + return 0; +} - // Check that filetype is correct - std::string filetype; - read_attribute(ww_file, "filetype", filetype); - if (filetype != "weight_windows") { - file_close(ww_file); - set_errmsg(fmt::format("File '{}' is not a weight windows file.", name)); - return OPENMC_E_INVALID_ARGUMENT; - } +extern "C" int openmc_weight_windows_import(const char* filename) +{ + std::string name = filename ? filename : "weight_windows.h5"; - // Check that the file version is compatible - std::array file_version; - read_attribute(ww_file, "version", file_version); - if (file_version[0] != VERSION_WEIGHT_WINDOWS[0]) { - std::string err_msg = - fmt::format("File '{}' has version {} which is incompatible with the " - "expected version ({}).", - name, file_version, VERSION_WEIGHT_WINDOWS); - set_errmsg(err_msg); - return OPENMC_E_INVALID_ARGUMENT; - } + if (mpi::master) + write_message(fmt::format("Importing weight windows from {}...", name), 5); - hid_t weight_windows_group = open_group(ww_file, "weight_windows"); + if (!file_exists(name)) { + set_errmsg(fmt::format("File '{}' does not exist", name)); + } - std::vector names = group_names(weight_windows_group); + hid_t ww_file = file_open(name, 'r'); - for (const auto& name : names) { - WeightWindows::from_hdf5(weight_windows_group, name); - } + // Check that filetype is correct + std::string filetype; + read_attribute(ww_file, "filetype", filetype); + if (filetype != "weight_windows") { + file_close(ww_file); + set_errmsg(fmt::format("File '{}' is not a weight windows file.", name)); + return OPENMC_E_INVALID_ARGUMENT; + } + + // Check that the file version is compatible + std::array file_version; + read_attribute(ww_file, "version", file_version); + if (file_version[0] != VERSION_WEIGHT_WINDOWS[0]) { + std::string err_msg = + fmt::format("File '{}' has version {} which is incompatible with the " + "expected version ({}).", + name, file_version, VERSION_WEIGHT_WINDOWS); + set_errmsg(err_msg); + return OPENMC_E_INVALID_ARGUMENT; + } - close_group(weight_windows_group); + hid_t weight_windows_group = open_group(ww_file, "weight_windows"); - file_close(ww_file); + std::vector names = group_names(weight_windows_group); - return 0; + for (const auto& name : names) { + WeightWindows::from_hdf5(weight_windows_group, name); } + close_group(weight_windows_group); + + file_close(ww_file); + + return 0; +} + } // namespace openmc