Write tally info to statepoint from C++

This commit is contained in:
Sterling Harper 2019-02-12 15:50:54 -05:00
parent b350e7dcd6
commit 558259e4a0
3 changed files with 130 additions and 171 deletions

View file

@ -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))

View file

@ -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)

View file

@ -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<int32_t> 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<int32_t> 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<int32_t> 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<std::string> 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<std::string> 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