From 558259e4a09f54ac31ff8136add6e4e21df610c8 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 12 Feb 2019 15:50:54 -0500 Subject: [PATCH] Write tally info to statepoint from C++ --- src/simulation.F90 | 2 - src/state_point.F90 | 168 +------------------------------------------- src/state_point.cpp | 131 +++++++++++++++++++++++++++++++++- 3 files changed, 130 insertions(+), 171 deletions(-) diff --git a/src/simulation.F90 b/src/simulation.F90 index 54cd9e6d51..f088481dd6 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -16,8 +16,6 @@ contains subroutine simulation_init_f() bind(C) - integer :: i - !$omp parallel ! Allocate array for microscopic cross section cache allocate(micro_xs(n_nuclides)) diff --git a/src/state_point.F90 b/src/state_point.F90 index 5baf1d7cf4..33daef4c33 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -13,19 +13,10 @@ module state_point use, intrinsic :: ISO_C_BINDING - use constants - use endf, only: reaction_name - use error, only: fatal_error, warning, write_message use hdf5_interface - use message_passing - use mgxs_interface - use nuclide_header, only: nuclides use settings - use simulation_header use string, only: to_str use tally_header - use tally_filter_header - use tally_derivative_header implicit none @@ -38,167 +29,12 @@ contains subroutine statepoint_write_f(file_id) bind(C) integer(HID_T), value :: file_id - integer :: i, j - integer :: i_xs - integer, allocatable :: id_array(:) - integer(HID_T) :: tallies_group, tally_group, & - filters_group, filter_group, derivs_group, & - deriv_group - character(MAX_WORD_LEN), allocatable :: str_array(:) - character(MAX_WORD_LEN, kind=C_CHAR) :: temp_name - type(TallyDerivative), pointer :: deriv + integer :: i + integer(HID_T) :: tallies_group, tally_group ! Open tallies group tallies_group = open_group(file_id, "tallies") - ! Write information for derivatives. - if (n_tally_derivs() > 0) then - derivs_group = create_group(tallies_group, "derivatives") - do i = 0, n_tally_derivs() - 1 - deriv => tally_deriv_c(i) - deriv_group = create_group(derivs_group, "derivative " & - // trim(to_str(deriv % id))) - select case (deriv % variable) - case (DIFF_DENSITY) - call write_dataset(deriv_group, "independent variable", "density") - call write_dataset(deriv_group, "material", deriv % diff_material) - case (DIFF_NUCLIDE_DENSITY) - call write_dataset(deriv_group, "independent variable", & - "nuclide_density") - call write_dataset(deriv_group, "material", deriv % diff_material) - call write_dataset(deriv_group, "nuclide", & - nuclides(deriv % diff_nuclide) % name) - case (DIFF_TEMPERATURE) - call write_dataset(deriv_group, "independent variable", & - "temperature") - call write_dataset(deriv_group, "material", deriv % diff_material) - case default - call fatal_error("Independent variable for derivative " & - // trim(to_str(deriv % id)) // " not defined in & - &state_point.F90.") - end select - call close_group(deriv_group) - end do - call close_group(derivs_group) - end if - - ! Write number of filters - filters_group = create_group(tallies_group, "filters") - call write_attribute(filters_group, "n_filters", n_filters) - - if (n_filters > 0) then - ! Write IDs of filters - allocate(id_array(n_filters)) - do i = 1, n_filters - id_array(i) = filters(i) % obj % id() - end do - call write_attribute(filters_group, "ids", id_array) - deallocate(id_array) - - ! Write filter information - FILTER_LOOP: do i = 1, n_filters - filter_group = create_group(filters_group, "filter " // & - trim(to_str(filters(i) % obj % id()))) - call filters(i) % obj % to_statepoint(filter_group) - call close_group(filter_group) - end do FILTER_LOOP - end if - - call close_group(filters_group) - - ! Write number of tallies - call write_attribute(tallies_group, "n_tallies", n_tallies) - - if (n_tallies > 0) then - ! Write array of tally IDs - allocate(id_array(n_tallies)) - do i = 1, n_tallies - id_array(i) = tallies(i) % obj % id() - end do - call write_attribute(tallies_group, "ids", id_array) - deallocate(id_array) - - ! Write all tally information except results - TALLY_METADATA: do i = 1, n_tallies - - ! Get pointer to tally - associate (tally => tallies(i) % obj) - tally_group = create_group(tallies_group, "tally " // & - trim(to_str(tally % id()))) - - ! Write the name for this tally - call write_dataset(tally_group, "name", tally % name) - - select case(tally % estimator()) - case (ESTIMATOR_ANALOG) - call write_dataset(tally_group, "estimator", "analog") - case (ESTIMATOR_TRACKLENGTH) - call write_dataset(tally_group, "estimator", "tracklength") - case (ESTIMATOR_COLLISION) - call write_dataset(tally_group, "estimator", "collision") - end select - call write_dataset(tally_group, "n_realizations", & - tally % n_realizations) - - call write_dataset(tally_group, "n_filters", tally % n_filters()) - if (tally % n_filters() > 0) then - ! Write IDs of filters - allocate(id_array(tally % n_filters())) - do j = 1, tally % n_filters() - id_array(j) = filters(tally % filter(j) + 1) % obj % id() - end do - call write_dataset(tally_group, "filters", id_array) - deallocate(id_array) - end if - - ! Set up nuclide bin array and then write - allocate(str_array(tally % n_nuclide_bins())) - NUCLIDE_LOOP: do j = 1, tally % n_nuclide_bins() - if (tally % nuclide_bins(j) >= 0) then - if (run_CE) then - i_xs = index(nuclides(tally % nuclide_bins(j)+1) % name, '.') - if (i_xs > 0) then - str_array(j) = nuclides(tally % nuclide_bins(j)+1) % name(1 : i_xs-1) - else - str_array(j) = nuclides(tally % nuclide_bins(j)+1) % name - end if - else - call get_name_c(tally % nuclide_bins(j)+1, len(temp_name), & - temp_name) - i_xs = index(temp_name, '.') - if (i_xs > 0) then - str_array(j) = trim(temp_name(1 : i_xs-1)) - else - str_array(j) = trim(temp_name) - end if - end if - else - str_array(j) = 'total' - end if - end do NUCLIDE_LOOP - call write_dataset(tally_group, "nuclides", str_array) - deallocate(str_array) - - ! Write derivative information. - if (tally % deriv() /= C_NONE) then - deriv => tally_deriv_c(tally % deriv()) - call write_dataset(tally_group, "derivative", deriv % id) - end if - - ! Write scores. - call write_dataset(tally_group, "n_score_bins", tally % n_score_bins()) - allocate(str_array(tally % n_score_bins())) - do j = 1, tally % n_score_bins() - str_array(j) = reaction_name(tally % score_bins(j)) - end do - call write_dataset(tally_group, "score_bins", str_array) - deallocate(str_array) - - call close_group(tally_group) - end associate - end do TALLY_METADATA - end if - if (reduce_tallies) then ! Write global tallies call write_dataset(file_id, "global_tallies", global_tallies) diff --git a/src/state_point.cpp b/src/state_point.cpp index 107ecdaaf9..f86a7b1312 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -17,9 +17,12 @@ #include "openmc/hdf5_interface.h" #include "openmc/mesh.h" #include "openmc/message_passing.h" +#include "openmc/mgxs_interface.h" +#include "openmc/nuclide.h" #include "openmc/output.h" #include "openmc/settings.h" #include "openmc/simulation.h" +#include "openmc/tallies/derivative.h" #include "openmc/tallies/filter.h" #include "openmc/tallies/tally.h" #include "openmc/timer.h" @@ -101,13 +104,135 @@ openmc_statepoint_write(const char* filename, bool* write_source) write_attribute(file_id, "source_present", write_source_); // Write out information for eigenvalue run - if (settings::run_mode == RUN_MODE_EIGENVALUE) write_eigenvalue_hdf5(file_id); + if (settings::run_mode == RUN_MODE_EIGENVALUE) + write_eigenvalue_hdf5(file_id); - // Write tally-related data hid_t tallies_group = create_group(file_id, "tallies"); + + // Write meshes meshes_to_hdf5(tallies_group); - statepoint_write_f(file_id); + + // Write information for derivatives + if (!model::tally_derivs.empty()) { + hid_t derivs_group = create_group(tallies_group, "derivatives"); + for (const auto& deriv : model::tally_derivs) { + hid_t deriv_group = create_group(derivs_group, + "derivative " + std::to_string(deriv.id)); + write_dataset(deriv_group, "material", deriv.diff_material); + if (deriv.variable == DIFF_DENSITY) { + write_dataset(deriv_group, "independent variable", "density"); + } else if (deriv.variable == DIFF_NUCLIDE_DENSITY) { + write_dataset(deriv_group, "independent variable", "nuclide_density"); + //TODO: off-by-one + write_dataset(deriv_group, "nuclide", + data::nuclides[deriv.diff_nuclide-1]->name_); + } else if (deriv.variable == DIFF_TEMPERATURE) { + write_dataset(deriv_group, "independent variable", "temperature"); + } else { + fatal_error("Independent variable for derivative " + + std::to_string(deriv.id) + " not defined in state_point.cpp"); + } + close_group(deriv_group); + } + close_group(derivs_group); + } + + // Write information for filters + hid_t filters_group = create_group(tallies_group, "filters"); + write_attribute(filters_group, "n_filters", model::tally_filters.size()); + if (!model::tally_filters.empty()) { + // Write filter IDs + std::vector filter_ids; + filter_ids.reserve(model::tally_filters.size()); + for (const auto& filt : model::tally_filters) + filter_ids.push_back(filt->id_); + write_attribute(filters_group, "ids", filter_ids); + + // Write info for each filter + for (const auto& filt : model::tally_filters) { + hid_t filter_group = create_group(filters_group, + "filter " + std::to_string(filt->id_)); + filt->to_statepoint(filter_group); + close_group(filter_group); + } + } + close_group(filters_group); + + // Write information for tallies + write_attribute(tallies_group, "n_tallies", model::tallies.size()); + if (!model::tallies.empty()) { + // Write tally IDs + std::vector tally_ids; + tally_ids.reserve(model::tallies.size()); + for (const auto& tally : model::tallies) + tally_ids.push_back(tally->id_); + write_attribute(tallies_group, "ids", tally_ids); + + // Write all tally information except results + //TODO: use these two lines when openmc_get_n_realizations isn't needed + //for (const auto& tally_ptr : model::tallies) { + // const auto& tally {*tally_ptr}; + for (auto i_tally = 0; i_tally < model::tallies.size(); ++i_tally) { + const auto& tally {*model::tallies[i_tally]}; + hid_t tally_group = create_group(tallies_group, + "tally " + std::to_string(tally.id_)); + + write_dataset(tally_group, "name", tally.name_); + + if (tally.estimator_ == ESTIMATOR_ANALOG) { + write_dataset(tally_group, "estimator", "analog"); + } else if (tally.estimator_ == ESTIMATOR_TRACKLENGTH) { + write_dataset(tally_group, "estimator", "tracklength"); + } else if (tally.estimator_ == ESTIMATOR_COLLISION) { + write_dataset(tally_group, "estimator", "collision"); + } + + // TODO: get this directly from the tally object when it's moved to C++ + int32_t n_realizations; + auto err = openmc_tally_get_n_realizations(i_tally+1, &n_realizations); + write_dataset(tally_group, "n_realizations", n_realizations); + + // Write the ID of each filter attached to this tally + write_dataset(tally_group, "n_filters", tally.filters().size()); + if (!tally.filters().empty()) { + std::vector filter_ids; + filter_ids.reserve(tally.filters().size()); + for (auto i_filt : tally.filters()) + filter_ids.push_back(model::tally_filters[i_filt]->id_); + write_dataset(tally_group, "filters", filter_ids); + } + + // Write the nuclides this tally scores + std::vector nuclides; + for (auto i_nuclide : tally.nuclides_) { + if (i_nuclide == -1) { + nuclides.push_back("total"); + } else { + if (settings::run_CE) { + nuclides.push_back(data::nuclides[i_nuclide]->name_); + } else { + nuclides.push_back(data::nuclides_MG[i_nuclide].name); + } + } + } + write_dataset(tally_group, "nuclides", nuclides); + + if (tally.deriv_ != C_NONE) write_dataset(tally_group, "derivative", + model::tally_derivs[tally.deriv_].id); + + // Write the tally score bins + std::vector scores; + for (auto sc : tally.scores_) scores.push_back(reaction_name(sc)); + write_dataset(tally_group, "n_score_bins", scores.size()); + write_dataset(tally_group, "score_bins", scores); + + close_group(tally_group); + } + + } + close_group(tallies_group); + statepoint_write_f(file_id); } // Check for the no-tally-reduction method