From a043699d8db39e7c9fa6f7fbd5bbcc89dec4032b Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 25 Aug 2018 10:30:03 -0400 Subject: [PATCH 01/45] Access FilterMatch bins and weights via procedures --- src/cmfd_data.F90 | 50 ++++----- src/output.F90 | 18 ++-- src/tallies/tally.F90 | 118 ++++++++++----------- src/tallies/tally_filter.cpp | 21 ++++ src/tallies/tally_filter_azimuthal.F90 | 4 +- src/tallies/tally_filter_cell.F90 | 4 +- src/tallies/tally_filter_cellborn.F90 | 4 +- src/tallies/tally_filter_cellfrom.F90 | 4 +- src/tallies/tally_filter_delayedgroup.F90 | 4 +- src/tallies/tally_filter_distribcell.F90 | 4 +- src/tallies/tally_filter_energy.F90 | 20 ++-- src/tallies/tally_filter_energyfunc.F90 | 4 +- src/tallies/tally_filter_header.F90 | 66 +++++++++++- src/tallies/tally_filter_legendre.F90 | 4 +- src/tallies/tally_filter_material.F90 | 4 +- src/tallies/tally_filter_mesh.F90 | 8 +- src/tallies/tally_filter_meshsurface.F90 | 16 +-- src/tallies/tally_filter_mu.F90 | 4 +- src/tallies/tally_filter_particle.F90 | 4 +- src/tallies/tally_filter_polar.F90 | 4 +- src/tallies/tally_filter_sph_harm.F90 | 4 +- src/tallies/tally_filter_sptl_legendre.F90 | 4 +- src/tallies/tally_filter_surface.F90 | 6 +- src/tallies/tally_filter_universe.F90 | 4 +- src/tallies/tally_filter_zernike.F90 | 8 +- src/tallies/trigger.F90 | 36 +++---- 26 files changed, 255 insertions(+), 172 deletions(-) create mode 100644 src/tallies/tally_filter.cpp diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index ce4825426..410b6b32e 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -154,27 +154,27 @@ contains ! Reset all bins to 1 do l = 1, size(t % filter) - call filter_matches(t % filter(l)) % bins % clear() - call filter_matches(t % filter(l)) % bins % push_back(1) + call filter_matches(t % filter(l)) % bins_clear() + call filter_matches(t % filter(l)) % bins_push_back(1) end do ! Set ijk as mesh indices ijk = (/ i, j, k /) ! Get bin number for mesh indices - filter_matches(i_filter_mesh) % bins % data(1) = & - m % get_bin_from_indices(ijk) + call filter_matches(i_filter_mesh) & + % bins_set_data(1, m % get_bin_from_indices(ijk)) ! Apply energy in filter if (energy_filters) then - filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 + call filter_matches(i_filter_ein) % bins_set_data(1, ng - h + 1) end if ! Calculate score index from bins score_index = 1 do l = 1, size(t % filter) score_index = score_index + (filter_matches(t % filter(l)) & - % bins % data(1) - 1) * t % stride(l) + % bins_data(1) - 1) * t % stride(l) end do ! Get flux @@ -198,30 +198,30 @@ contains ! Reset all bins to 1 do l = 1, size(t % filter) - call filter_matches(t % filter(l)) % bins % clear() - call filter_matches(t % filter(l)) % bins % push_back(1) + call filter_matches(t % filter(l)) % bins_clear() + call filter_matches(t % filter(l)) % bins_push_back(1) end do ! Set ijk as mesh indices ijk = (/ i, j, k /) ! Get bin number for mesh indices - filter_matches(i_filter_mesh) % bins % data(1) = & - m % get_bin_from_indices(ijk) + call filter_matches(i_filter_mesh) & + % bins_set_data(1, m % get_bin_from_indices(ijk)) if (energy_filters) then ! Apply energy in filter - filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 + call filter_matches(i_filter_ein) % bins_set_data(1, ng - h + 1) ! Set energy out bin - filter_matches(i_filter_eout) % bins % data(1) = ng - g + 1 + call filter_matches(i_filter_eout) % bins_set_data(1, ng - g + 1) end if ! Calculate score index from bins score_index = 1 do l = 1, size(t % filter) score_index = score_index + (filter_matches(t % filter(l)) & - % bins % data(1) - 1) * t % stride(l) + % bins_data(1) - 1) * t % stride(l) end do ! Get scattering @@ -244,23 +244,23 @@ contains ! Initialize and filter for energy do l = 1, size(t % filter) - call filter_matches(t % filter(l)) % bins % clear() - call filter_matches(t % filter(l)) % bins % push_back(1) + call filter_matches(t % filter(l)) % bins_clear() + call filter_matches(t % filter(l)) % bins_push_back(1) end do ! Set the bin for this mesh cell i_mesh = m % get_bin_from_indices([ i, j, k ]) - filter_matches(i_filter_mesh) % bins % data(1) = 12*(i_mesh - 1) + 1 + call filter_matches(i_filter_mesh) % bins_set_data(1, 12*(i_mesh - 1) + 1) ! Set the energy bin if needed if (energy_filters) then - filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 + call filter_matches(i_filter_ein) % bins_set_data(1, ng - h + 1) end if score_index = 0 do l = 1, size(t % filter) score_index = score_index + (filter_matches(t % filter(l)) & - % bins % data(1) - 1) * t % stride(l) + % bins_data(1) - 1) * t % stride(l) end do ! Left surface @@ -303,30 +303,30 @@ contains ! Reset all bins to 1 do l = 1, size(t % filter) - call filter_matches(t % filter(l)) % bins % clear() - call filter_matches(t % filter(l)) % bins % push_back(1) + call filter_matches(t % filter(l)) % bins_clear() + call filter_matches(t % filter(l)) % bins_push_back(1) end do ! Set ijk as mesh indices ijk = (/ i, j, k /) ! Get bin number for mesh indices - filter_matches(i_filter_mesh) % bins % data(1) = & - m % get_bin_from_indices(ijk) + call filter_matches(i_filter_mesh) & + % bins_set_data(1, m % get_bin_from_indices(ijk)) ! Apply energy in filter if (energy_filters) then - filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 + call filter_matches(i_filter_ein) % bins_set_data(1, ng - h + 1) end if ! Apply Legendre filter - filter_matches(i_filter_legendre) % bins % data(1) = 2 + call filter_matches(i_filter_legendre) % bins_set_data(1, 2) ! Calculate score index from bins score_index = 1 do l = 1, size(t % filter) score_index = score_index + (filter_matches(t % filter(l)) & - % bins % data(1) - 1) * t % stride(l) + % bins_data(1) - 1) * t % stride(l) end do ! Get p1 scatter rr and convert to p1 scatter xs diff --git a/src/output.F90 b/src/output.F90 index 49dc380a9..f956c44f2 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -773,8 +773,8 @@ contains ! Initialize bins, filter level, and indentation do h = 1, size(t % filter) - call matches(t % filter(h)) % bins % clear() - call matches(t % filter(h)) % bins % push_back(0) + call matches(t % filter(h)) % bins_clear() + call matches(t % filter(h)) % bins_push_back(0) end do j = 1 indent = 0 @@ -785,18 +785,18 @@ contains if (size(t % filter) == 0) exit find_bin ! Increment bin combination - matches(t % filter(j)) % bins % data(1) = & - matches(t % filter(j)) % bins % data(1) + 1 + call matches(t % filter(j)) % bins_set_data(1, & + matches(t % filter(j)) % bins_data(1) + 1) ! ================================================================= ! REACHED END OF BINS FOR THIS FILTER, MOVE TO NEXT FILTER - if (matches(t % filter(j)) % bins % data(1) > & + if (matches(t % filter(j)) % bins_data(1) > & filters(t % filter(j)) % obj % n_bins) then ! If this is the first filter, then exit if (j == 1) exit print_bin - matches(t % filter(j)) % bins % data(1) = 0 + call matches(t % filter(j)) % bins_set_data(1, 0) j = j - 1 indent = indent - 2 @@ -810,7 +810,7 @@ contains ! Print current filter information write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & trim(filters(t % filter(j)) % obj % & - text_label(matches(t % filter(j)) % bins % data(1))) + text_label(matches(t % filter(j)) % bins_data(1))) indent = indent + 2 j = j + 1 end if @@ -821,7 +821,7 @@ contains if (size(t % filter) > 0) then write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & trim(filters(t % filter(j)) % obj % & - text_label(matches(t % filter(j)) % bins % data(1))) + text_label(matches(t % filter(j)) % bins_data(1))) end if ! Determine scoring index for this bin combination -- note that unlike @@ -831,7 +831,7 @@ contains filter_index = 1 do h = 1, size(t % filter) filter_index = filter_index + (max(matches(t % filter(h)) & - % bins % data(1),1) - 1) * t % stride(h) + % bins_data(1),1) - 1) * t % stride(h) end do ! Write results for this filter bin combination diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 9967606d1..6bc670da0 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -2080,15 +2080,15 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) if (.not. filter_matches(i_filt) % bins_present) then - call filter_matches(i_filt) % bins % clear() - call filter_matches(i_filt) % weights % clear() + call filter_matches(i_filt) % bins_clear() + call filter_matches(i_filt) % weights_clear() call filters(i_filt) % obj % get_all_bins(p, t % estimator, & filter_matches(i_filt)) filter_matches(i_filt) % bins_present = .true. end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins_size() == 0) cycle TALLY_LOOP ! Set the index of the bin used in the first filter combination filter_matches(i_filt) % i_bin = 1 @@ -2107,10 +2107,10 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) i_bin = filter_matches(i_filt) % i_bin - filter_index = filter_index + (filter_matches(i_filt) % bins % & - data(i_bin) - 1) * t % stride(j) - filter_weight = filter_weight * filter_matches(i_filt) % weights % & - data(i_bin) + filter_index = filter_index + (filter_matches(i_filt) & + % bins_data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) & + % weights_data(i_bin) end do ! ====================================================================== @@ -2167,7 +2167,7 @@ contains do j = size(t % filter), 1, -1 i_filt = t % filter(j) if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & - bins % size()) then + bins_size()) then filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 finished = .false. exit @@ -2226,15 +2226,15 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) if (.not. filter_matches(i_filt) % bins_present) then - call filter_matches(i_filt) % bins % clear() - call filter_matches(i_filt) % weights % clear() + call filter_matches(i_filt) % bins_clear() + call filter_matches(i_filt) % weights_clear() call filters(i_filt) % obj % get_all_bins(p, t % estimator, & filter_matches(i_filt)) filter_matches(i_filt) % bins_present = .true. end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins_size() == 0) cycle TALLY_LOOP ! Set the index of the bin used in the first filter combination filter_matches(i_filt) % i_bin = 1 @@ -2253,10 +2253,10 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) i_bin = filter_matches(i_filt) % i_bin - filter_index = filter_index + (filter_matches(i_filt) % bins % & - data(i_bin) - 1) * t % stride(j) - filter_weight = filter_weight * filter_matches(i_filt) % weights % & - data(i_bin) + filter_index = filter_index + (filter_matches(i_filt) & + % bins_data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) & + % weights_data(i_bin) end do ! ====================================================================== @@ -2296,7 +2296,7 @@ contains do j = size(t % filter), 1, -1 i_filt = t % filter(j) if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & - bins % size()) then + bins_size()) then filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 finished = .false. exit @@ -2361,7 +2361,7 @@ contains ! save original outgoing energy bin and score index i = t % filter(t % find_filter(FILTER_ENERGYOUT)) i_bin = filter_matches(i) % i_bin - bin_energyout = filter_matches(i) % bins % data(i_bin) + bin_energyout = filter_matches(i) % bins_data(i_bin) ! declare the energyout filter type select type(eo_filt => filters(i) % obj) @@ -2401,7 +2401,7 @@ contains g_out = size(eo_filt % bins) - g_out ! change outgoing energy bin - filter_matches(i) % bins % data(i_bin) = g_out + call filter_matches(i) % bins_set_data(i_bin, g_out) else @@ -2417,8 +2417,8 @@ contains if (E_out < eo_filt % bins(1) .or. E_out > eo_filt % bins(n)) cycle ! change outgoing energy bin - filter_matches(i) % bins % data(i_bin) = & - binary_search(eo_filt % bins, n, E_out) + call filter_matches(i) % bins_set_data(i_bin, & + binary_search(eo_filt % bins, n, E_out)) end if @@ -2429,8 +2429,8 @@ contains ! determine scoring index and weight for this filter combination i_filter = 1 do l = 1, size(t % filter) - i_filter = i_filter + (filter_matches(t % filter(l)) % bins % & - data(filter_matches(t % filter(l)) % i_bin) - 1) * & + i_filter = i_filter + (filter_matches(t % filter(l)) & + % bins_data(filter_matches(t % filter(l)) % i_bin) - 1) * & t % stride(l) end do @@ -2471,10 +2471,10 @@ contains do l = 1, size(t % filter) f = t % filter(l) b = filter_matches(f) % i_bin - i_filter = i_filter + (filter_matches(f) % bins % & - data(b) - 1) * t % stride(l) - filter_weight = filter_weight * filter_matches(f) % & - weights % data(b) + i_filter = i_filter + (filter_matches(f) & + % bins_data(b) - 1) * t % stride(l) + filter_weight = filter_weight * filter_matches(f) & + % weights_data(b) end do call score_fission_delayed_dg(t, d_bin, & @@ -2494,10 +2494,10 @@ contains do l = 1, size(t % filter) f = t % filter(l) b = filter_matches(f) % i_bin - i_filter = i_filter + (filter_matches(f) % bins % data(b) - 1) & + i_filter = i_filter + (filter_matches(f) % bins_data(b) - 1) & * t % stride(l) - filter_weight = filter_weight * filter_matches(f) % weights % & - data(b) + filter_weight = filter_weight * filter_matches(f) & + % weights_data(b) end do ! Add score to tally @@ -2510,7 +2510,7 @@ contains end select ! reset outgoing energy bin and score index - filter_matches(i) % bins % data(i_bin) = bin_energyout + call filter_matches(i) % bins_set_data(i_bin, bin_energyout) end subroutine score_fission_eout @@ -2535,14 +2535,14 @@ contains ! save original delayed group bin i_filt = t % filter(t % find_filter(FILTER_DELAYEDGROUP)) i_bin = filter_matches(i_filt) % i_bin - bin_original = filter_matches(i_filt) % bins % data(i_bin) - filter_matches(i_filt) % bins % data(i_bin) = d_bin + bin_original = filter_matches(i_filt) % bins_data(i_bin) + call filter_matches(i_filt) % bins_set_data(i_bin, d_bin) ! determine scoring index and weight on the modified matching bins filter_index = 1 do i = 1, size(t % filter) - filter_index = filter_index + (filter_matches(t % filter(i)) % bins % & - data(filter_matches(t % filter(i)) % i_bin) - 1) * t % stride(i) + filter_index = filter_index + (filter_matches(t % filter(i)) % & + bins_data(filter_matches(t % filter(i)) % i_bin) - 1) * t % stride(i) end do !$omp atomic @@ -2550,7 +2550,7 @@ contains t % results(RESULT_VALUE, score_index, filter_index) + score ! reset original delayed group bin - filter_matches(i_filt) % bins % data(i_bin) = bin_original + call filter_matches(i_filt) % bins_set_data(i_bin, bin_original) end subroutine score_fission_delayed_dg @@ -2596,15 +2596,15 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) if (.not. filter_matches(i_filt) % bins_present) then - call filter_matches(i_filt) % bins % clear() - call filter_matches(i_filt) % weights % clear() + call filter_matches(i_filt) % bins_clear() + call filter_matches(i_filt) % weights_clear() call filters(i_filt) % obj % get_all_bins(p, t % estimator, & filter_matches(i_filt)) filter_matches(i_filt) % bins_present = .true. end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins_size() == 0) cycle TALLY_LOOP ! Set the index of the bin used in the first filter combination filter_matches(i_filt) % i_bin = 1 @@ -2623,10 +2623,10 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) i_bin = filter_matches(i_filt) % i_bin - filter_index = filter_index + (filter_matches(i_filt) % bins % & - data(i_bin) - 1) * t % stride(j) - filter_weight = filter_weight * filter_matches(i_filt) % weights % & - data(i_bin) + filter_index = filter_index + (filter_matches(i_filt) & + % bins_data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) & + % weights_data(i_bin) end do ! ====================================================================== @@ -2675,7 +2675,7 @@ contains do j = size(t % filter), 1, -1 i_filt = t % filter(j) if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & - bins % size()) then + bins_size()) then filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 finished = .false. exit @@ -2753,15 +2753,15 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) if (.not. filter_matches(i_filt) % bins_present) then - call filter_matches(i_filt) % bins % clear() - call filter_matches(i_filt) % weights % clear() + call filter_matches(i_filt) % bins_clear() + call filter_matches(i_filt) % weights_clear() call filters(i_filt) % obj % get_all_bins(p, t % estimator, & filter_matches(i_filt)) filter_matches(i_filt) % bins_present = .true. end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins_size() == 0) cycle TALLY_LOOP ! Set the index of the bin used in the first filter combination filter_matches(i_filt) % i_bin = 1 @@ -2780,10 +2780,10 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) i_bin = filter_matches(i_filt) % i_bin - filter_index = filter_index + (filter_matches(i_filt) % bins % & - data(i_bin) - 1) * t % stride(j) - filter_weight = filter_weight * filter_matches(i_filt) % weights % & - data(i_bin) + filter_index = filter_index + (filter_matches(i_filt) & + % bins_data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) & + % weights_data(i_bin) end do ! ====================================================================== @@ -2832,7 +2832,7 @@ contains do j = size(t % filter), 1, -1 i_filt = t % filter(j) if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & - bins % size()) then + bins_size()) then filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 finished = .false. exit @@ -2899,15 +2899,15 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) if (.not. filter_matches(i_filt) % bins_present) then - call filter_matches(i_filt) % bins % clear() - call filter_matches(i_filt) % weights % clear() + call filter_matches(i_filt) % bins_clear() + call filter_matches(i_filt) % weights_clear() call filters(i_filt) % obj % get_all_bins(p, t % estimator, & filter_matches(i_filt)) filter_matches(i_filt) % bins_present = .true. end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins_size() == 0) cycle TALLY_LOOP ! Set the index of the bin used in the first filter combination filter_matches(i_filt) % i_bin = 1 @@ -2926,10 +2926,10 @@ contains do j = 1, size(t % filter) i_filt = t % filter(j) i_bin = filter_matches(i_filt) % i_bin - filter_index = filter_index + (filter_matches(i_filt) % bins % & - data(i_bin) - 1) * t % stride(j) - filter_weight = filter_weight * filter_matches(i_filt) % weights % & - data(i_bin) + filter_index = filter_index + (filter_matches(i_filt) & + % bins_data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) & + % weights_data(i_bin) end do ! Determine score @@ -2962,7 +2962,7 @@ contains do j = size(t % filter), 1, -1 i_filt = t % filter(j) if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & - bins % size()) then + bins_size()) then filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 finished = .false. exit diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp new file mode 100644 index 000000000..dcd499c10 --- /dev/null +++ b/src/tallies/tally_filter.cpp @@ -0,0 +1,21 @@ +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +//============================================================================== +// Global variables +//============================================================================== + +std::vector filter_matches; + +//============================================================================== +// Fortran compatibility functions +//============================================================================== + +extern "C" { + TallyFilterMatch* filter_match_pointer(int indx) + {return &filter_matches[indx];} +} + +} // namespace openmc diff --git a/src/tallies/tally_filter_azimuthal.F90 b/src/tallies/tally_filter_azimuthal.F90 index fc7f15a17..5dc5f9e2c 100644 --- a/src/tallies/tally_filter_azimuthal.F90 +++ b/src/tallies/tally_filter_azimuthal.F90 @@ -89,8 +89,8 @@ contains ! Search to find azimuthal angle bin. bin = binary_search(this % bins, n + 1, phi) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if end subroutine get_all_bins_azimuthal diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index be3746707..eced3873b 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -61,8 +61,8 @@ contains do i = 1, p % n_coord val = this % map % get(p % coord(i) % cell) if (val /= EMPTY) then - call match % bins % push_back(val) - call match % weights % push_back(ONE) + call match % bins_push_back(val) + call match % weights_push_back(ONE) end if end do diff --git a/src/tallies/tally_filter_cellborn.F90 b/src/tallies/tally_filter_cellborn.F90 index a373c2d4e..474176565 100644 --- a/src/tallies/tally_filter_cellborn.F90 +++ b/src/tallies/tally_filter_cellborn.F90 @@ -57,8 +57,8 @@ contains val = this % map % get(p % cell_born) if (val /= EMPTY) then - call match % bins % push_back(val) - call match % weights % push_back(ONE) + call match % bins_push_back(val) + call match % weights_push_back(ONE) end if end subroutine get_all_bins_cellborn diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index 83a3179d2..de2beca39 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -44,8 +44,8 @@ contains do i = 1, p % last_n_coord val = this % map % get(p % last_cell(i)) if (val /= EMPTY) then - call match % bins % push_back(val) - call match % weights % push_back(ONE) + call match % bins_push_back(val) + call match % weights_push_back(ONE) exit end if end do diff --git a/src/tallies/tally_filter_delayedgroup.F90 b/src/tallies/tally_filter_delayedgroup.F90 index 1a662005b..130469a71 100644 --- a/src/tallies/tally_filter_delayedgroup.F90 +++ b/src/tallies/tally_filter_delayedgroup.F90 @@ -62,8 +62,8 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - call match % bins % push_back(1) - call match % weights % push_back(ONE) + call match % bins_push_back(1) + call match % weights_push_back(ONE) end subroutine get_all_bins_dg subroutine to_statepoint_dg(this, filter_group) diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index c9564083d..0b773710b 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -74,8 +74,8 @@ contains end if end if if (this % cell == p % coord(i) % cell) then - call match % bins % push_back(offset + 1) - call match % weights % push_back(ONE) + call match % bins_push_back(offset + 1) + call match % weights_push_back(ONE) return end if end do diff --git a/src/tallies/tally_filter_energy.F90 b/src/tallies/tally_filter_energy.F90 index f230d438e..70142156e 100644 --- a/src/tallies/tally_filter_energy.F90 +++ b/src/tallies/tally_filter_energy.F90 @@ -95,11 +95,11 @@ contains if (p % g /= NONE .and. this % matches_transport_groups) then if (estimator == ESTIMATOR_TRACKLENGTH) then - call match % bins % push_back(num_energy_groups - p % g + 1) - call match % weights % push_back(ONE) + call match % bins_push_back(num_energy_groups - p % g + 1) + call match % weights_push_back(ONE) else - call match % bins % push_back(num_energy_groups - p % last_g + 1) - call match % weights % push_back(ONE) + call match % bins_push_back(num_energy_groups - p % last_g + 1) + call match % weights_push_back(ONE) end if else @@ -109,8 +109,8 @@ contains ! Search to find incoming energy bin. bin = binary_search(this % bins, n + 1, E) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if end if end subroutine get_all_bins_energy @@ -155,16 +155,16 @@ contains if (p % g /= NONE .and. this % matches_transport_groups) then ! Tallies are ordered in increasing groups, group indices ! however are the opposite, so switch - call match % bins % push_back(num_energy_groups - p % g + 1) - call match % weights % push_back(ONE) + call match % bins_push_back(num_energy_groups - p % g + 1) + call match % weights_push_back(ONE) else ! Search to find incoming energy bin. bin = binary_search(this % bins, n + 1, p % E) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if end if end subroutine get_all_bins_energyout diff --git a/src/tallies/tally_filter_energyfunc.F90 b/src/tallies/tally_filter_energyfunc.F90 index 1402707b4..0581fdacc 100644 --- a/src/tallies/tally_filter_energyfunc.F90 +++ b/src/tallies/tally_filter_energyfunc.F90 @@ -89,9 +89,9 @@ contains / (this % energy(indx+1) - this % energy(indx)) ! Interpolate on the lin-lin grid. - call match % bins % push_back(1) + call match % bins_push_back(1) weight = (ONE - f) * this % y(indx) + f * this % y(indx+1) - call match % weights % push_back(weight) + call match % weights_push_back(weight) end select end subroutine get_all_bins_energyfunction diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index e57423ddf..57b6798bb 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -28,11 +28,21 @@ module tally_filter_header type, public :: TallyFilterMatch ! Index of the bin and weight being used in the current filter combination integer :: i_bin - type(VectorInt) :: bins - type(VectorReal) :: weights + type(VectorInt) :: bins_ + type(VectorReal) :: weights_ ! Indicates whether all valid bins for this filter have been found logical :: bins_present = .false. + + contains + procedure :: bins_push_back + procedure :: weights_push_back + procedure :: bins_clear + procedure :: weights_clear + procedure :: bins_size + procedure :: bins_data + procedure :: weights_data + procedure :: bins_set_data end type TallyFilterMatch !=============================================================================== @@ -129,6 +139,58 @@ module tally_filter_header contains +!=============================================================================== +!=============================================================================== + + subroutine bins_push_back(this, val) + class(TallyFilterMatch), intent(inout) :: this + integer, intent(in) :: val + call this % bins_ % push_back(val) + end subroutine bins_push_back + + subroutine weights_push_back(this, val) + class(TallyFilterMatch), intent(inout) :: this + real(8), intent(in) :: val + call this % weights_ % push_back(val) + end subroutine weights_push_back + + subroutine bins_clear(this) + class(TallyFilterMatch), intent(inout) :: this + call this % bins_ % clear() + end subroutine bins_clear + + subroutine weights_clear(this) + class(TallyFilterMatch), intent(inout) :: this + call this % weights_ % clear() + end subroutine weights_clear + + function bins_size(this) result(len) + class(TallyFilterMatch), intent(inout) :: this + integer :: len + len = this % bins_ % size() + end function bins_size + + function bins_data(this, indx) result(val) + class(TallyFilterMatch), intent(inout) :: this + integer, intent(in) :: indx + integer :: val + val = this % bins_ % data(indx) + end function bins_data + + function weights_data(this, indx) result(val) + class(TallyFilterMatch), intent(inout) :: this + integer, intent(in) :: indx + real(8) :: val + val = this % weights_ % data(indx) + end function weights_data + + subroutine bins_set_data(this, indx, val) + class(TallyFilterMatch), intent(inout) :: this + integer, intent(in) :: indx + integer, intent(in) :: val + this % bins_ % data(indx) = val + end subroutine bins_set_data + !=============================================================================== ! INITIALIZE sets up any internal data, as necessary. If this procedure is not ! overriden by the derived class, then it will do nothing by default. diff --git a/src/tallies/tally_filter_legendre.F90 b/src/tallies/tally_filter_legendre.F90 index 4663df651..32d1b4506 100644 --- a/src/tallies/tally_filter_legendre.F90 +++ b/src/tallies/tally_filter_legendre.F90 @@ -55,8 +55,8 @@ contains call calc_pn(this % order, p % mu, wgt) do i = 1, this % n_bins - call match % bins % push_back(i) - call match % weights % push_back(wgt(i)) + call match % bins_push_back(i) + call match % weights_push_back(wgt(i)) end do end subroutine get_all_bins diff --git a/src/tallies/tally_filter_material.F90 b/src/tallies/tally_filter_material.F90 index 51ab26594..2b9a79331 100644 --- a/src/tallies/tally_filter_material.F90 +++ b/src/tallies/tally_filter_material.F90 @@ -58,8 +58,8 @@ contains val = this % map % get(p % material) if (val /= EMPTY) then - call match % bins % push_back(val) - call match % weights % push_back(ONE) + call match % bins_push_back(val) + call match % weights_push_back(ONE) end if end subroutine get_all_bins_material diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index 486569da6..9c91f8102 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -103,8 +103,8 @@ contains ! valid mesh bin. call m % get_bin(p % coord(1) % xyz, bin) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if return end if @@ -217,8 +217,8 @@ contains ! Assign the next tally bin and the score. bin = m % get_bin_from_indices(ijk0(:n)) - call match % bins % push_back(bin) - call match % weights % push_back(distance / total_distance) + call match % bins_push_back(bin) + call match % weights_push_back(distance / total_distance) ! Find the next mesh cell that the particle enters. diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index 801d4252c..c133ac14b 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -162,8 +162,8 @@ contains i_mesh = m % get_bin_from_indices(ijk0) i_bin = 4*n_dim*(i_mesh - 1) + i_surf - call match % bins % push_back(i_bin) - call match % weights % push_back(ONE) + call match % bins_push_back(i_bin) + call match % weights_push_back(ONE) end if ! Advance position @@ -178,8 +178,8 @@ contains i_mesh = m % get_bin_from_indices(ijk0) i_bin = 4*n_dim*(i_mesh - 1) + i_surf - call match % bins % push_back(i_bin) - call match % weights % push_back(ONE) + call match % bins_push_back(i_bin) + call match % weights_push_back(ONE) end if else @@ -192,8 +192,8 @@ contains i_mesh = m % get_bin_from_indices(ijk0) i_bin = 4*n_dim*(i_mesh - 1) + i_surf - call match % bins % push_back(i_bin) - call match % weights % push_back(ONE) + call match % bins_push_back(i_bin) + call match % weights_push_back(ONE) end if ! Advance position @@ -208,8 +208,8 @@ contains i_mesh = m % get_bin_from_indices(ijk0) i_bin = 4*n_dim*(i_mesh - 1) + i_surf - call match % bins % push_back(i_bin) - call match % weights % push_back(ONE) + call match % bins_push_back(i_bin) + call match % weights_push_back(ONE) end if end if end if diff --git a/src/tallies/tally_filter_mu.F90 b/src/tallies/tally_filter_mu.F90 index 7f8bde923..ecd0a75af 100644 --- a/src/tallies/tally_filter_mu.F90 +++ b/src/tallies/tally_filter_mu.F90 @@ -80,8 +80,8 @@ contains ! Search to find incoming energy bin. bin = binary_search(this % bins, n + 1, p % mu) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if end subroutine get_all_bins_mu diff --git a/src/tallies/tally_filter_particle.F90 b/src/tallies/tally_filter_particle.F90 index 5ac846310..665ea5cf3 100644 --- a/src/tallies/tally_filter_particle.F90 +++ b/src/tallies/tally_filter_particle.F90 @@ -52,8 +52,8 @@ contains do i = 1, this % n_bins if (this % particles(i) == p % type) then - call match % bins % push_back(i) - call match % weights % push_back(ONE) + call match % bins_push_back(i) + call match % weights_push_back(ONE) end if end do end subroutine get_all_bins diff --git a/src/tallies/tally_filter_polar.F90 b/src/tallies/tally_filter_polar.F90 index 7cbb55f8b..46627230a 100644 --- a/src/tallies/tally_filter_polar.F90 +++ b/src/tallies/tally_filter_polar.F90 @@ -88,8 +88,8 @@ contains ! Search to find polar angle bin. bin = binary_search(this % bins, n + 1, theta) if (bin /= NO_BIN_FOUND) then - call match % bins % push_back(bin) - call match % weights % push_back(ONE) + call match % bins_push_back(bin) + call match % weights_push_back(ONE) end if end subroutine get_all_bins_polar diff --git a/src/tallies/tally_filter_sph_harm.F90 b/src/tallies/tally_filter_sph_harm.F90 index 4a1f43273..8fba71564 100644 --- a/src/tallies/tally_filter_sph_harm.F90 +++ b/src/tallies/tally_filter_sph_harm.F90 @@ -95,8 +95,8 @@ contains ! Append matching (bin,weight) for each moment do i = 1, num_nm j = j + 1 - call match % bins % push_back(j) - call match % weights % push_back(wgt(n + 1) * rn(j)) + call match % bins_push_back(j) + call match % weights_push_back(wgt(n + 1) * rn(j)) end do end do diff --git a/src/tallies/tally_filter_sptl_legendre.F90 b/src/tallies/tally_filter_sptl_legendre.F90 index 1bfbd0e3b..ba2a25b7a 100644 --- a/src/tallies/tally_filter_sptl_legendre.F90 +++ b/src/tallies/tally_filter_sptl_legendre.F90 @@ -86,8 +86,8 @@ contains call calc_pn(this % order, x_norm, wgt) do i = 1, this % n_bins - call match % bins % push_back(i) - call match % weights % push_back(wgt(i)) + call match % bins_push_back(i) + call match % weights_push_back(wgt(i)) end do end if end subroutine get_all_bins diff --git a/src/tallies/tally_filter_surface.F90 b/src/tallies/tally_filter_surface.F90 index ec642bc8d..d545d4672 100644 --- a/src/tallies/tally_filter_surface.F90 +++ b/src/tallies/tally_filter_surface.F90 @@ -58,11 +58,11 @@ contains do i = 1, this % n_bins if (abs(p % surface) == this % surfaces(i)) then - call match % bins % push_back(i) + call match % bins_push_back(i) if (p % surface < 0) then - call match % weights % push_back(-ONE) + call match % weights_push_back(-ONE) else - call match % weights % push_back(ONE) + call match % weights_push_back(ONE) end if exit end if diff --git a/src/tallies/tally_filter_universe.F90 b/src/tallies/tally_filter_universe.F90 index 0dc5aefe1..71e266394 100644 --- a/src/tallies/tally_filter_universe.F90 +++ b/src/tallies/tally_filter_universe.F90 @@ -59,8 +59,8 @@ contains do i = 1, p % n_coord val = this % map % get(p % coord(i) % universe) if (val /= EMPTY) then - call match % bins % push_back(val) - call match % weights % push_back(ONE) + call match % bins_push_back(val) + call match % weights_push_back(ONE) end if end do diff --git a/src/tallies/tally_filter_zernike.F90 b/src/tallies/tally_filter_zernike.F90 index 04515cf31..1c6955b03 100644 --- a/src/tallies/tally_filter_zernike.F90 +++ b/src/tallies/tally_filter_zernike.F90 @@ -102,8 +102,8 @@ contains call calc_zn(this % order, r, theta, zn) do i = 1, this % n_bins - call match % bins % push_back(i) - call match % weights % push_back(zn(i)) + call match % bins_push_back(i) + call match % weights_push_back(zn(i)) end do endif end subroutine get_all_bins_zn @@ -173,8 +173,8 @@ contains call calc_zn_rad(this % order, r, zn_rad) do i = 1, this % n_bins - call match % bins % push_back(i) - call match % weights % push_back(zn_rad(i)) + call match % bins_push_back(i) + call match % weights_push_back(zn_rad(i)) end do endif end subroutine get_all_bins_zn_rad diff --git a/src/tallies/trigger.F90 b/src/tallies/trigger.F90 index 2cb3bf819..27dafd78f 100644 --- a/src/tallies/trigger.F90 +++ b/src/tallies/trigger.F90 @@ -173,8 +173,8 @@ contains ! Initialize bins, filter level do j = 1, size(t % filter) - call filter_matches(t % filter(j)) % bins % clear() - call filter_matches(t % filter(j)) % bins % push_back(0) + call filter_matches(t % filter(j)) % bins_clear() + call filter_matches(t % filter(j)) % bins_push_back(0) end do FILTER_LOOP: do filter_index = 1, t % n_filter_bins @@ -269,8 +269,8 @@ contains ! initialize bins array do j = 1, size(t % filter) - call filter_matches(t % filter(j)) % bins % clear() - call filter_matches(t % filter(j)) % bins % push_back(1) + call filter_matches(t % filter(j)) % bins_clear() + call filter_matches(t % filter(j)) % bins_push_back(1) end do ! determine how many energyin bins there are @@ -293,20 +293,20 @@ contains ! Get the indices for this cell call m % get_indices_from_bin(i, ijk) - filter_matches(i_filter_mesh) % bins % data(1) = i + call filter_matches(i_filter_mesh) % bins_set_data(1, i) do l = 1, n if (print_ebin) then - filter_matches(i_filter_ein) % bins % data(1) = l + call filter_matches(i_filter_ein) % bins_set_data(1, l) end if ! Left Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_LEFT + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_LEFT) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then @@ -318,11 +318,11 @@ contains trigger % variance = std_dev**2 ! Right Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_RIGHT + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_RIGHT) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then @@ -334,11 +334,11 @@ contains trigger % variance = trigger % std_dev**2 ! Back Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_BACK + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_BACK) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then @@ -350,11 +350,11 @@ contains trigger % variance = trigger % std_dev**2 ! Front Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_FRONT + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_FRONT) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then @@ -366,11 +366,11 @@ contains trigger % variance = trigger % std_dev**2 ! Bottom Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_BOTTOM + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_BOTTOM) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then @@ -382,11 +382,11 @@ contains trigger % variance = trigger % std_dev**2 ! Top Surface - filter_matches(i_filter_surf) % bins % data(1) = OUT_TOP + call filter_matches(i_filter_surf) % bins_set_data(1, OUT_TOP) filter_index = 1 do j = 1, size(t % filter) filter_index = filter_index + (filter_matches(t % filter(j)) % & - bins % data(1) - 1) * t % stride(j) + bins_data(1) - 1) * t % stride(j) end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then From c387bde956370a209a278160ced4c488af10d1ad Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 7 Sep 2018 17:26:57 -0400 Subject: [PATCH 02/45] Add basic C++ TallyFilterMatch class --- CMakeLists.txt | 1 + include/openmc/tallies/tally_filter.h | 34 +++++++++++++++++++++++++++ src/simulation.F90 | 19 ++++++++++++++- src/simulation.cpp | 26 +++++++++++++++++++- src/tallies/tally_filter_header.F90 | 11 +++++++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 include/openmc/tallies/tally_filter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 23a6176a8..31df21d82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -417,6 +417,7 @@ add_library(libopenmc SHARED src/state_point.cpp src/string_functions.cpp src/surface.cpp + src/tallies/tally_filter.cpp src/thermal.cpp src/xml_interface.cpp src/xsdata.cpp) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h new file mode 100644 index 000000000..85b6f8c72 --- /dev/null +++ b/include/openmc/tallies/tally_filter.h @@ -0,0 +1,34 @@ +#ifndef OPENMC_TALLY_FILTER_H +#define OPENMC_TALLY_FILTER_H + +#include +#include + + +namespace openmc { + +//============================================================================== +// Global variables +//============================================================================== + +extern "C" int32_t n_filters; + +class TallyFilterMatch; +extern std::vector filter_matches; +#pragma omp threadprivate(filter_matches) + +//============================================================================== +//! Stores bins and weights for filtered tally events +//============================================================================== + +class TallyFilterMatch +{ +public: + int i_bin; + std::vector bins; + std::vector weights; + bool bins_present; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER diff --git a/src/simulation.F90 b/src/simulation.F90 index df6bf13ba..9fa2b290d 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -36,7 +36,7 @@ module simulation use tally, only: accumulate_tallies, setup_active_tallies, & init_tally_routines use tally_header - use tally_filter_header, only: filter_matches, n_filters + use tally_filter_header, only: filter_matches, n_filters, filter_match_pointer use tally_derivative_header, only: tally_derivs use timer_header use trigger, only: check_triggers @@ -420,6 +420,11 @@ contains integer :: i + interface + subroutine openmc_simulation_init_c() bind(C) + end subroutine openmc_simulation_init_c + end interface + err = 0 ! Skip if simulation has already been initialized @@ -453,6 +458,9 @@ contains ! Allocate array for matching filter bins allocate(filter_matches(n_filters)) + do i = 1, n_filters + filter_matches(i) % ptr = filter_match_pointer(i - 1) + end do !$omp end parallel ! Reset global variables -- this is done before loading state point (as that @@ -493,6 +501,8 @@ contains end if end if + call openmc_simulation_init_c() + ! Set flag indicating initialization is done simulation_initialized = .true. @@ -520,6 +530,11 @@ contains #endif #endif + interface + subroutine openmc_simulation_finalize_c() bind(C) + end subroutine openmc_simulation_finalize_c + end interface + err = 0 ! Skip if simulation was never run @@ -590,6 +605,8 @@ contains end do end if + call openmc_simulation_finalize_c() + ! Stop timers and show timing statistics call time_finalize%stop() call time_total%stop() diff --git a/src/simulation.cpp b/src/simulation.cpp index e1dd0ac93..e9cb971cf 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -1,10 +1,12 @@ #include "openmc/capi.h" +#include "openmc/tallies/tally_filter.h" // OPENMC_RUN encompasses all the main logic where iterations are performed // over the batches, generations, and histories in a fixed source or k-eigenvalue // calculation. -int openmc_run() { +int openmc_run() +{ openmc_simulation_init(); int err = 0; @@ -16,3 +18,25 @@ int openmc_run() { openmc_simulation_finalize(); return err; } + +namespace openmc { + +extern "C" void +openmc_simulation_init_c() +{ + #pragma omp parallel + { + filter_matches.resize(n_filters); + } +} + +extern "C" void +openmc_simulation_finalize_c() +{ + #pragma omp parallel + { + filter_matches.clear(); + } +} + +} // namespace openmc diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 57b6798bb..38de7a5ad 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -20,12 +20,23 @@ module tally_filter_header public :: openmc_filter_set_id public :: openmc_get_filter_index public :: openmc_get_filter_next_id + public :: filter_match_pointer + + interface + function filter_match_pointer(indx) bind(C) result(ptr) + import C_PTR, C_INT + integer(C_INT), intent(in), value :: indx + type(C_PTR) :: ptr + end function filter_match_pointer + end interface !=============================================================================== ! TALLYFILTERMATCH stores every valid bin and weight for a filter !=============================================================================== type, public :: TallyFilterMatch + type(C_PTR) :: ptr + ! Index of the bin and weight being used in the current filter combination integer :: i_bin type(VectorInt) :: bins_ From dce001fae35e6d3b1769eaa58bbff2c44e32f7de Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 10 Sep 2018 15:37:30 -0400 Subject: [PATCH 03/45] Move TallyFilterMatch bins and weights to C++ --- src/output.F90 | 22 ++++----- src/simulation.F90 | 14 +++--- src/tallies/tally_filter.cpp | 32 ++++++++++++ src/tallies/tally_filter_header.F90 | 75 +++++++++++++++++++++++++---- 4 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/output.F90 b/src/output.F90 index f956c44f2..10ce6614e 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -683,13 +683,13 @@ contains character(36) :: score_names(N_SCORE_TYPES) ! names of scoring function character(36) :: score_name ! names of scoring function ! to be applied at write-time - type(TallyFilterMatch), allocatable :: matches(:) + integer, allocatable :: filter_bins(:) character(MAX_WORD_LEN) :: temp_name ! Skip if there are no tallies if (n_tallies == 0) return - allocate(matches(n_filters)) + allocate(filter_bins(n_filters)) ! Initialize names for scores score_names(abs(SCORE_FLUX)) = "Flux" @@ -773,8 +773,7 @@ contains ! Initialize bins, filter level, and indentation do h = 1, size(t % filter) - call matches(t % filter(h)) % bins_clear() - call matches(t % filter(h)) % bins_push_back(0) + filter_bins(t % filter(h)) = 0 end do j = 1 indent = 0 @@ -785,18 +784,17 @@ contains if (size(t % filter) == 0) exit find_bin ! Increment bin combination - call matches(t % filter(j)) % bins_set_data(1, & - matches(t % filter(j)) % bins_data(1) + 1) + filter_bins(t % filter(j)) = filter_bins(t % filter(j)) + 1 ! ================================================================= ! REACHED END OF BINS FOR THIS FILTER, MOVE TO NEXT FILTER - if (matches(t % filter(j)) % bins_data(1) > & + if (filter_bins(t % filter(j)) > & filters(t % filter(j)) % obj % n_bins) then ! If this is the first filter, then exit if (j == 1) exit print_bin - call matches(t % filter(j)) % bins_set_data(1, 0) + filter_bins(t % filter(j)) = 0 j = j - 1 indent = indent - 2 @@ -810,7 +808,7 @@ contains ! Print current filter information write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & trim(filters(t % filter(j)) % obj % & - text_label(matches(t % filter(j)) % bins_data(1))) + text_label(filter_bins(t % filter(j)))) indent = indent + 2 j = j + 1 end if @@ -821,7 +819,7 @@ contains if (size(t % filter) > 0) then write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & trim(filters(t % filter(j)) % obj % & - text_label(matches(t % filter(j)) % bins_data(1))) + text_label(filter_bins(t % filter(j)))) end if ! Determine scoring index for this bin combination -- note that unlike @@ -830,8 +828,8 @@ contains filter_index = 1 do h = 1, size(t % filter) - filter_index = filter_index + (max(matches(t % filter(h)) & - % bins_data(1),1) - 1) * t % stride(h) + filter_index = filter_index & + + (max(filter_bins(t % filter(h)) ,1) - 1) * t % stride(h) end do ! Write results for this filter bin combination diff --git a/src/simulation.F90 b/src/simulation.F90 index 9fa2b290d..9be64ed5d 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -455,12 +455,6 @@ contains ! Allocate array for microscopic cross section cache allocate(micro_xs(n_nuclides)) allocate(micro_photon_xs(n_elements)) - - ! Allocate array for matching filter bins - allocate(filter_matches(n_filters)) - do i = 1, n_filters - filter_matches(i) % ptr = filter_match_pointer(i - 1) - end do !$omp end parallel ! Reset global variables -- this is done before loading state point (as that @@ -503,6 +497,14 @@ contains call openmc_simulation_init_c() +!$omp parallel + ! Allocate array for matching filter bins + allocate(filter_matches(n_filters)) + do i = 1, n_filters + filter_matches(i) % ptr = filter_match_pointer(i - 1) + end do +!$omp end parallel + ! Set flag indicating initialization is done simulation_initialized = .true. diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index dcd499c10..42589a579 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -16,6 +16,38 @@ std::vector filter_matches; extern "C" { TallyFilterMatch* filter_match_pointer(int indx) {return &filter_matches[indx];} + + void + filter_match_bins_push_back(TallyFilterMatch* match, int val) + {match->bins.push_back(val);} + + void + filter_match_weights_push_back(TallyFilterMatch* match, double val) + {match->weights.push_back(val);} + + void + filter_match_bins_clear(TallyFilterMatch* match) + {match->bins.clear();} + + void + filter_match_weights_clear(TallyFilterMatch* match) + {match->weights.clear();} + + int + filter_match_bins_size(TallyFilterMatch* match) + {return match->bins.size();} + + int + filter_match_bins_data(TallyFilterMatch* match, int indx) + {return match->bins.at(indx-1);} + + double + filter_match_weights_data(TallyFilterMatch* match, int indx) + {return match->weights.at(indx-1);} + + void + filter_match_bins_set_data(TallyFilterMatch* match, int indx, int val) + {match->bins.at(indx-1) = val;} } } // namespace openmc diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 38de7a5ad..5f37b33ce 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -39,8 +39,6 @@ module tally_filter_header ! Index of the bin and weight being used in the current filter combination integer :: i_bin - type(VectorInt) :: bins_ - type(VectorReal) :: weights_ ! Indicates whether all valid bins for this filter have been found logical :: bins_present = .false. @@ -156,50 +154,107 @@ contains subroutine bins_push_back(this, val) class(TallyFilterMatch), intent(inout) :: this integer, intent(in) :: val - call this % bins_ % push_back(val) + interface + subroutine filter_match_bins_push_back(ptr, val) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: ptr + integer(C_INT), intent(in), value :: val + end subroutine + end interface + call filter_match_bins_push_back(this % ptr, val) end subroutine bins_push_back subroutine weights_push_back(this, val) class(TallyFilterMatch), intent(inout) :: this real(8), intent(in) :: val - call this % weights_ % push_back(val) + interface + subroutine filter_match_weights_push_back(ptr, val) bind(C) + import C_PTR, C_DOUBLE + type(C_PTR), value :: ptr + real(C_DOUBLE), intent(in), value :: val + end subroutine + end interface + call filter_match_weights_push_back(this % ptr, val) end subroutine weights_push_back subroutine bins_clear(this) class(TallyFilterMatch), intent(inout) :: this - call this % bins_ % clear() + interface + subroutine filter_match_bins_clear(ptr) bind(C) + import C_PTR + type(C_PTR), value :: ptr + end subroutine + end interface + call filter_match_bins_clear(this % ptr) end subroutine bins_clear subroutine weights_clear(this) class(TallyFilterMatch), intent(inout) :: this - call this % weights_ % clear() + interface + subroutine filter_match_weights_clear(ptr) bind(C) + import C_PTR + type(C_PTR), value :: ptr + end subroutine + end interface + call filter_match_weights_clear(this % ptr) end subroutine weights_clear function bins_size(this) result(len) class(TallyFilterMatch), intent(inout) :: this integer :: len - len = this % bins_ % size() + interface + function filter_match_bins_size(ptr) bind(C) result(len) + import C_PTR, C_INT + type(C_PTR), value :: ptr + integer(C_INT) :: len + end function + end interface + len = filter_match_bins_size(this % ptr) end function bins_size function bins_data(this, indx) result(val) class(TallyFilterMatch), intent(inout) :: this integer, intent(in) :: indx integer :: val - val = this % bins_ % data(indx) + interface + function filter_match_bins_data(ptr, indx) bind(C) result(val) + import C_PTR, C_INT + type(C_PTR), value :: ptr + integer(C_INT), intent(in), value :: indx + integer(C_INT) :: val + end function + end interface + val = filter_match_bins_data(this % ptr, indx) end function bins_data function weights_data(this, indx) result(val) class(TallyFilterMatch), intent(inout) :: this integer, intent(in) :: indx real(8) :: val - val = this % weights_ % data(indx) + interface + function filter_match_weights_data(ptr, indx) bind(C) result(val) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), value :: ptr + integer(C_INT), intent(in), value :: indx + real(C_DOUBLE) :: val + end function + end interface + val = filter_match_weights_data(this % ptr, indx) end function weights_data subroutine bins_set_data(this, indx, val) class(TallyFilterMatch), intent(inout) :: this integer, intent(in) :: indx integer, intent(in) :: val - this % bins_ % data(indx) = val + interface + subroutine filter_match_bins_set_data(ptr, indx, val) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: ptr + integer(C_INT), value, intent(in) :: indx + integer(C_INT), value, intent(in) :: val + end subroutine + end interface + call filter_match_bins_set_data(this % ptr, indx, val) end subroutine bins_set_data !=============================================================================== From 1cc0271f4c3ef541b809585088cbeba99e2e9dbb Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 19 Sep 2018 10:52:07 -0400 Subject: [PATCH 04/45] Add framework for calling C++ filters from F90 --- include/openmc/tallies/tally_filter.h | 20 +++++++++- include/openmc/tallies/tally_filter_cell.h | 46 ++++++++++++++++++++++ src/cell.cpp | 14 +++++++ src/tallies/tally_filter.F90 | 16 ++++++++ src/tallies/tally_filter.cpp | 22 +++++++++++ src/tallies/tally_filter_cell.F90 | 6 ++- src/tallies/tally_filter_header.F90 | 36 +++++++++++++++++ 7 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_cell.h diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 85b6f8c72..190045ee8 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -4,6 +4,8 @@ #include #include +#include "openmc/xml_interface.h" + namespace openmc { @@ -17,8 +19,11 @@ class TallyFilterMatch; extern std::vector filter_matches; #pragma omp threadprivate(filter_matches) +class TallyFilter; +extern std::vector tally_filters; + //============================================================================== -//! Stores bins and weights for filtered tally events +//! Stores bins and weights for filtered tally events. //============================================================================== class TallyFilterMatch @@ -30,5 +35,16 @@ public: bool bins_present; }; +//============================================================================== +//! Modifies tally score events. +//============================================================================== + +class TallyFilter +{ +public: + virtual void from_xml(pugi::xml_node node) = 0; + virtual void initialize() = 0; +}; + } // namespace openmc -#endif // OPENMC_TALLY_FILTER +#endif // OPENMC_TALLY_FILTER_H diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h new file mode 100644 index 000000000..f0a4bb430 --- /dev/null +++ b/include/openmc/tallies/tally_filter_cell.h @@ -0,0 +1,46 @@ +#ifndef OPENMC_TALLY_FILTER_CELL_H +#define OPENMC_TALLY_FILTER_CELL_H + +#include +#include +#include + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class CellFilter : public TallyFilter +{ +public: + virtual void + from_xml(pugi::xml_node node) + { + cells_ = get_node_array(node, "bins"); + } + + virtual void + initialize() + { + for (auto& c : cells_) { + auto search = cell_map.find(c); + if (search != cell_map.end()) { + c = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find cell " << c << " specified on tally filter."; + fatal_error(err_msg); + } + } + + //TODO: mapping + } + +protected: + std::vector cells_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_CELL_H diff --git a/src/cell.cpp b/src/cell.cpp index e579b9db4..3d81a577e 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -604,6 +604,20 @@ read_cells(pugi::xml_node* node) cells.push_back(new Cell(cell_node)); } + // Fill the cell map. + // TODO: update this map when openmc_extend_cells is called + for (int i = 0; i < cells.size(); i++) { + int32_t id = cells[i]->id_; + auto search = cell_map.find(id); + if (search == cell_map.end()) { + cell_map[id] = i; + } else { + std::stringstream err_msg; + err_msg << "Two or more cells use the same unique ID: " << id; + fatal_error(err_msg); + } + } + // Populate the Universe vector and map. for (int i = 0; i < cells.size(); i++) { int32_t uid = cells[i]->universe_; diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index 81b195816..caa088e5a 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -114,6 +114,14 @@ contains character(:), allocatable :: type_ + interface + function allocate_filter(type) result(ptr) bind(C) + import C_CHAR, C_PTR + character(kind=C_CHAR), intent(in) :: type(*) + type(C_PTR) :: ptr + end function allocate_filter + end interface + ! Convert C string to Fortran string type_ = to_f_string(type) @@ -128,6 +136,14 @@ contains allocate(AzimuthalFilter :: filters(index) % obj) case ('cell') allocate(CellFilter :: filters(index) % obj) + select type(filt => filters(index) % obj) + type is (CellFilter) + filt % ptr = allocate_filter(type) + if (.not. c_associated(filt % ptr)) then + err = E_UNASSIGNED + call set_errmsg("Could not allocate C++ tally filter") + end if + end select case ('cellborn') allocate(CellbornFilter :: filters(index) % obj) case ('cellfrom') diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 42589a579..d869f6cc6 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -1,5 +1,9 @@ #include "openmc/tallies/tally_filter.h" +#include + +#include "openmc/tallies/tally_filter_cell.h" + namespace openmc { @@ -8,6 +12,7 @@ namespace openmc { //============================================================================== std::vector filter_matches; +std::vector tally_filters; //============================================================================== // Fortran compatibility functions @@ -48,6 +53,23 @@ extern "C" { void filter_match_bins_set_data(TallyFilterMatch* match, int indx, int val) {match->bins.at(indx-1) = val;} + + TallyFilter* + allocate_filter(const char* type) + { + std::string type_ {type}; + if (type_ == "cell") { + tally_filters.push_back(new CellFilter()); + return tally_filters.back(); + } else { + return nullptr; + } + } + + void filter_from_xml(TallyFilter* filt, pugi::xml_node* node) + {filt->from_xml(*node);} + + void filter_initialize(TallyFilter* filt) {filt->initialize();} } } // namespace openmc diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index dae870e1f..3f3706621 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -20,7 +20,7 @@ module tally_filter_cell ! CELLFILTER specifies which geometric cells tally events reside in. !=============================================================================== - type, public, extends(TallyFilter) :: CellFilter + type, public, extends(CppTallyFilter) :: CellFilter integer(C_INT32_T), allocatable :: cells(:) type(DictIntInt) :: map contains @@ -39,6 +39,8 @@ contains integer :: n + call this % from_xml_c(node) + ! Determine how many bins were given n = node_word_count(node, "bins") @@ -91,6 +93,8 @@ contains integer :: i, id integer :: val + call this % initialize_c() + ! Convert ids to indices. do i = 1, this % n_bins id = this % cells(i) diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 5f37b33ce..b1686235c 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -124,6 +124,16 @@ module tally_filter_header end interface +!=============================================================================== +!=============================================================================== + + type, public, abstract, extends(TallyFilter) :: CppTallyFilter + type(C_PTR) :: ptr + contains + procedure :: from_xml_c + procedure :: initialize_c + end type CppTallyFilter + !=============================================================================== ! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of ! TallyFilters @@ -265,6 +275,32 @@ contains class(TallyFilter), intent(inout) :: this end subroutine filter_initialize +!=============================================================================== + + subroutine from_xml_c(this, node) + class(CppTallyFilter), intent(inout) :: this + class(XMLNode), intent(in) :: node + interface + subroutine filter_from_xml(filt, node) bind(C) + import C_PTR + type(C_PTR), value :: filt + type(C_PTR) :: node + end subroutine filter_from_xml + end interface + call filter_from_xml(this % ptr, node % ptr) + end subroutine from_xml_c + + subroutine initialize_c(this) + class(CppTallyFilter), intent(inout) :: this + interface + subroutine filter_initialize(filt) bind(C) + import C_PTR + type(C_PTR), value :: filt + end subroutine filter_initialize + end interface + call filter_initialize(this % ptr) + end subroutine initialize_c + !=============================================================================== ! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module !=============================================================================== From 0084ae613b9ac6ddcdf098a76a1257fc35ee91e3 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 19 Sep 2018 11:37:06 -0400 Subject: [PATCH 05/45] Move cell filter get_all_bins to C++ --- include/openmc/tallies/tally_filter.h | 5 +++++ include/openmc/tallies/tally_filter_cell.h | 19 ++++++++++++++++++- src/tallies/tally_filter.cpp | 7 +++++++ src/tallies/tally_filter_cell.F90 | 12 +----------- src/tallies/tally_filter_header.F90 | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 190045ee8..d6cf72cd9 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -4,6 +4,7 @@ #include #include +#include "openmc/particle.h" #include "openmc/xml_interface.h" @@ -43,6 +44,10 @@ class TallyFilter { public: virtual void from_xml(pugi::xml_node node) = 0; + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; + virtual void initialize() = 0; }; diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index f0a4bb430..21da79102 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "openmc/cell.h" @@ -35,11 +36,27 @@ public: } } - //TODO: mapping + for (int i = 0; i < cells_.size(); i++) { + map_[cells_[i]] = i; + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const + { + for (int i = 0; i < p->n_coord; i++) { + auto search = map_.find(p->coord[i].cell); + if (search != map_.end()) { + // TODO: off-by-one + match.bins.push_back(search->second + 1); + match.weights.push_back(1); + } + } } protected: std::vector cells_; + std::unordered_map map_; }; } // namespace openmc diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index d869f6cc6..e936e8d50 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -69,6 +69,13 @@ extern "C" { void filter_from_xml(TallyFilter* filt, pugi::xml_node* node) {filt->from_xml(*node);} + void + filter_get_all_bins(TallyFilter* filt, Particle* p, int estimator, + TallyFilterMatch* match) + { + filt->get_all_bins(p, estimator, *match); + } + void filter_initialize(TallyFilter* filt) {filt->initialize();} } diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index 3f3706621..5bf594f2f 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -56,17 +56,7 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - integer :: i - integer :: val - - ! Iterate over coordinate levels to see with cells match - do i = 1, p % n_coord - val = this % map % get(p % coord(i) % cell + 1) - if (val /= EMPTY) then - call match % bins_push_back(val) - call match % weights_push_back(ONE) - end if - end do + call this % get_all_bins_c(p , estimator, match) end subroutine get_all_bins_cell diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index b1686235c..1d0688bb1 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -131,6 +131,7 @@ module tally_filter_header type(C_PTR) :: ptr contains procedure :: from_xml_c + procedure :: get_all_bins_c procedure :: initialize_c end type CppTallyFilter @@ -290,6 +291,23 @@ contains call filter_from_xml(this % ptr, node % ptr) end subroutine from_xml_c + subroutine get_all_bins_c(this, p, estimator, match) + class(CppTallyFilter), intent(in) :: this + type(Particle), intent(in) :: p + integer, intent(in) :: estimator + type(TallyFilterMatch), intent(inout) :: match + interface + subroutine filter_get_all_bins(filt, p, estimator, match) bind(C) + import C_PTR, Particle, C_INT + type(C_PTR), value :: filt + type(Particle), intent(in) :: p + integer(C_INT), intent(in), value :: estimator + type(C_PTR), value :: match + end subroutine filter_get_all_bins + end interface + call filter_get_all_bins(this % ptr, p, estimator, match % ptr) + end subroutine get_all_bins_c + subroutine initialize_c(this) class(CppTallyFilter), intent(inout) :: this interface From b27242e726efd2f4d681824e31578f167690ea6a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 2 Oct 2018 22:11:55 -0400 Subject: [PATCH 06/45] Add C++ CellFromFilter --- .../openmc/tallies/tally_filter_cellfrom.h | 27 +++++++++++++++++++ src/tallies/tally_filter.F90 | 20 +++++++------- src/tallies/tally_filter.cpp | 5 +++- src/tallies/tally_filter_cellfrom.F90 | 13 +-------- 4 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_cellfrom.h diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h new file mode 100644 index 000000000..ad9d54a5f --- /dev/null +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -0,0 +1,27 @@ +#ifndef OPENMC_TALLY_FILTER_CELLFROM_H +#define OPENMC_TALLY_FILTER_CELLFROM_H + +#include "openmc/tallies/tally_filter_cell.h" + + +namespace openmc { + +class CellFromFilter : public CellFilter +{ +public: + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const + { + for (int i = 0; i < p->last_n_coord; i++) { + auto search = map_.find(p->last_cell[i]); + if (search != map_.end()) { + // TODO: off-by-one + match.bins.push_back(search->second + 1); + match.weights.push_back(1); + } + } + } +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_CELLFROM_H diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index caa088e5a..6a699e2e6 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -136,18 +136,10 @@ contains allocate(AzimuthalFilter :: filters(index) % obj) case ('cell') allocate(CellFilter :: filters(index) % obj) - select type(filt => filters(index) % obj) - type is (CellFilter) - filt % ptr = allocate_filter(type) - if (.not. c_associated(filt % ptr)) then - err = E_UNASSIGNED - call set_errmsg("Could not allocate C++ tally filter") - end if - end select case ('cellborn') allocate(CellbornFilter :: filters(index) % obj) case ('cellfrom') - allocate(CellfromFilter :: filters(index) % obj) + allocate(CellFromFilter :: filters(index) % obj) case ('delayedgroup') allocate(DelayedGroupFilter :: filters(index) % obj) case ('distribcell') @@ -188,6 +180,16 @@ contains err = E_UNASSIGNED call set_errmsg("Unknown filter type: " // trim(type_)) end select + + select type(filt => filters(index) % obj) + class is (CppTallyFilter) + filt % ptr = allocate_filter(type) + if (.not. c_associated(filt % ptr)) then + err = E_UNASSIGNED + call set_errmsg("Could not allocate C++ tally filter") + end if + end select + end if else err = E_OUT_OF_BOUNDS diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index e936e8d50..660178cbf 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -3,6 +3,7 @@ #include #include "openmc/tallies/tally_filter_cell.h" +#include "openmc/tallies/tally_filter_cellfrom.h" namespace openmc { @@ -60,10 +61,12 @@ extern "C" { std::string type_ {type}; if (type_ == "cell") { tally_filters.push_back(new CellFilter()); - return tally_filters.back(); + } else if (type_ == "cellfrom") { + tally_filters.push_back(new CellFromFilter()); } else { return nullptr; } + return tally_filters.back(); } void filter_from_xml(TallyFilter* filt, pugi::xml_node* node) diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index e8048ecbe..999a55bfd 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -37,18 +37,7 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - integer :: i - integer :: val - - ! Starting one coordinate level deeper, find the next bin. - do i = 1, p % last_n_coord - val = this % map % get(p % last_cell(i) + 1) - if (val /= EMPTY) then - call match % bins_push_back(val) - call match % weights_push_back(ONE) - exit - end if - end do + call this % get_all_bins_c(p, estimator, match) end subroutine get_all_bins_cell_from From 3e953ef7cf37084dd26df968b945ed35fc2fa08d Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 2 Oct 2018 22:19:35 -0400 Subject: [PATCH 07/45] Free C++ tally filter memory --- include/openmc/tallies/tally_filter.h | 4 ++++ src/tallies/tally_filter.cpp | 16 ++++++++++++++++ src/tallies/tally_header.F90 | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index d6cf72cd9..f6118f92f 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -51,5 +51,9 @@ public: virtual void initialize() = 0; }; +//============================================================================== + +extern "C" void free_memory_tally_c(); + } // namespace openmc #endif // OPENMC_TALLY_FILTER_H diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 660178cbf..65ba03076 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -15,6 +15,22 @@ namespace openmc { std::vector filter_matches; std::vector tally_filters; +//============================================================================== +// Non-member functions +//============================================================================== + +void +free_memory_tally_c() +{ + #pragma omp parallel + { + filter_matches.clear(); + } + + for (TallyFilter* filt : tally_filters) {delete filt;} + tally_filters.clear(); +} + //============================================================================== // Fortran compatibility functions //============================================================================== diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 367214a93..b0532a40c 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -412,6 +412,13 @@ contains !=============================================================================== subroutine free_memory_tally() + interface + subroutine free_memory_tally_c() bind(C) + end subroutine free_memory_tally_c + end interface + + call free_memory_tally_c() + n_tallies = 0 if (allocated(tallies)) deallocate(tallies) call tally_dict % clear() From 2626f62ad14ed344434df106861fed7e57e903d6 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 2 Oct 2018 23:25:59 -0400 Subject: [PATCH 08/45] Add MeshFilter and MeshSurfaceFilter to C++ --- include/openmc/tallies/tally_filter.h | 2 +- include/openmc/tallies/tally_filter_cell.h | 7 ++- .../openmc/tallies/tally_filter_cellfrom.h | 3 +- include/openmc/tallies/tally_filter_mesh.h | 55 +++++++++++++++++++ .../openmc/tallies/tally_filter_meshsurface.h | 48 ++++++++++++++++ src/mesh.cpp | 19 ------- src/tallies/tally_filter.cpp | 6 ++ src/tallies/tally_filter_cell.F90 | 2 +- src/tallies/tally_filter_mesh.F90 | 32 ++--------- src/tallies/tally_filter_meshsurface.F90 | 21 ++----- 10 files changed, 125 insertions(+), 70 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_mesh.h create mode 100644 include/openmc/tallies/tally_filter_meshsurface.h diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index f6118f92f..89ede592c 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -48,7 +48,7 @@ public: virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; - virtual void initialize() = 0; + virtual void initialize() {} }; //============================================================================== diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index 21da79102..c70fcbe30 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -17,13 +17,13 @@ class CellFilter : public TallyFilter { public: virtual void - from_xml(pugi::xml_node node) + from_xml(pugi::xml_node node) override { cells_ = get_node_array(node, "bins"); } virtual void - initialize() + initialize() override { for (auto& c : cells_) { auto search = cell_map.find(c); @@ -42,7 +42,8 @@ public: } virtual void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override { for (int i = 0; i < p->n_coord; i++) { auto search = map_.find(p->coord[i].cell); diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index ad9d54a5f..ed7518bfe 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -10,7 +10,8 @@ class CellFromFilter : public CellFilter { public: virtual void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override { for (int i = 0; i < p->last_n_coord; i++) { auto search = map_.find(p->last_cell[i]); diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h new file mode 100644 index 000000000..3ef457093 --- /dev/null +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -0,0 +1,55 @@ +#ifndef OPENMC_TALLY_FILTER_MESH_H +#define OPENMC_TALLY_FILTER_MESH_H + +#include +#include + +#include "openmc/error.h" +#include "openmc/mesh.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class MeshFilter : public TallyFilter +{ +public: + virtual void + from_xml(pugi::xml_node node) override + { + auto bins_ = get_node_array(node, "bins"); + if (bins_.size() != 1) + fatal_error("Only one mesh can be specified per mesh filter."); + + auto id = bins_[0]; + auto search = mesh_map.find(id); + if (search != mesh_map.end()) { + mesh_ = search->second; + } else{ + std::stringstream err_msg; + err_msg << "Could not find cell " << id << " specified on tally filter."; + fatal_error(err_msg); + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + if (estimator != ESTIMATOR_TRACKLENGTH) { + auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); + if (bin >= 0) { + match.bins.push_back(bin); + match.weights.push_back(1.0); + } + } else { + meshes[mesh_]->bins_crossed(p, match.bins, match.weights); + } + } + +protected: + int32_t mesh_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_MESH_H diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h new file mode 100644 index 000000000..9a69d60bd --- /dev/null +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -0,0 +1,48 @@ +#ifndef OPENMC_TALLY_FILTER_MESHSURFACE_H +#define OPENMC_TALLY_FILTER_MESHSURFACE_H + +#include +#include + +#include "openmc/error.h" +#include "openmc/mesh.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class MeshSurfaceFilter : public TallyFilter +{ +public: + virtual void + from_xml(pugi::xml_node node) override + { + auto bins_ = get_node_array(node, "bins"); + if (bins_.size() != 1) + fatal_error("Only one mesh can be specified per mesh filter."); + + auto id = bins_[0]; + auto search = mesh_map.find(id); + if (search != mesh_map.end()) { + mesh_ = search->second; + } else{ + std::stringstream err_msg; + err_msg << "Could not find cell " << id << " specified on tally filter."; + fatal_error(err_msg); + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + meshes[mesh_]->surface_bins_crossed(p, match.bins); + for (auto b : match.bins) match.weights.push_back(1.0); + } + +protected: + int32_t mesh_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_MESHSURFACE_H diff --git a/src/mesh.cpp b/src/mesh.cpp index fd05cf6ca..59679525f 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -933,25 +933,6 @@ extern "C" { m->get_indices_from_bin(bin, ijk); } - void mesh_bins_crossed(RegularMesh* m, const Particle* p, - TallyFilterMatch* match) - { - match->bins.clear(); - match->weights.clear(); - m->bins_crossed(p, match->bins, match->weights); - } - - void mesh_surface_bins_crossed(RegularMesh* m, const Particle* p, - TallyFilterMatch* match) - { - match->bins.clear(); - match->weights.clear(); - m->surface_bins_crossed(p, match->bins); - for (auto b : match->bins) { - match->weights.push_back(1.0); - } - } - void free_memory_mesh() { meshes.clear(); diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 65ba03076..1dae39782 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -4,6 +4,8 @@ #include "openmc/tallies/tally_filter_cell.h" #include "openmc/tallies/tally_filter_cellfrom.h" +#include "openmc/tallies/tally_filter_mesh.h" +#include "openmc/tallies/tally_filter_meshsurface.h" namespace openmc { @@ -79,6 +81,10 @@ extern "C" { tally_filters.push_back(new CellFilter()); } else if (type_ == "cellfrom") { tally_filters.push_back(new CellFromFilter()); + } else if (type_ == "mesh") { + tally_filters.push_back(new MeshFilter()); + } else if (type_ == "meshsurface") { + tally_filters.push_back(new MeshSurfaceFilter()); } else { return nullptr; } diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index 5bf594f2f..16d146df8 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -56,7 +56,7 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - call this % get_all_bins_c(p , estimator, match) + call this % get_all_bins_c(p, estimator, match) end subroutine get_all_bins_cell diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index e9c01d34e..abbd29657 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -23,7 +23,7 @@ module tally_filter_mesh ! will correspond to the fraction of the track length that lies in that bin. !=============================================================================== - type, public, extends(TallyFilter) :: MeshFilter + type, public, extends(CppTallyFilter) :: MeshFilter integer :: mesh contains procedure :: from_xml @@ -44,6 +44,8 @@ contains integer(C_INT) :: err type(RegularMesh) :: m + call this % from_xml_c(node) + n = node_word_count(node, "bins") if (n /= 1) call fatal_error("Only one mesh can be & @@ -73,33 +75,7 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - integer :: bin - type(RegularMesh) :: m - - interface - subroutine mesh_bins_crossed(m, p, match) bind(C) - import C_PTR, Particle - type(C_PTR), value :: m - type(Particle), intent(in) :: p - type(C_PTR), value :: match - end subroutine - end interface - - ! Get a pointer to the mesh. - m = meshes(this % mesh) - - if (estimator /= ESTIMATOR_TRACKLENGTH) then - ! If this is an analog or collision tally, then there can only be one - ! valid mesh bin. - call m % get_bin(p % coord(1) % xyz, bin) - if (bin >= 0) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - return - else - call mesh_bins_crossed(m % ptr, p, match % ptr) - end if + call this % get_all_bins_c(p, estimator, match) end subroutine get_all_bins_mesh diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index f16611d26..6a9e0de5c 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -22,7 +22,7 @@ module tally_filter_meshsurface ! will correspond to the fraction of the track length that lies in that bin. !=============================================================================== - type, public, extends(TallyFilter) :: MeshSurfaceFilter + type, public, extends(CppTallyFilter) :: MeshSurfaceFilter integer :: mesh contains procedure :: from_xml @@ -43,6 +43,8 @@ contains integer(C_INT) :: err type(RegularMesh) :: m + call this % from_xml_c(node) + n = node_word_count(node, "bins") if (n /= 1) call fatal_error("Only one mesh can be & @@ -72,22 +74,7 @@ contains integer, intent(in) :: estimator type(TallyFilterMatch), intent(inout) :: match - type(RegularMesh) :: m - type(C_PTR) :: ptr_bins, ptr_weights - - interface - subroutine mesh_surface_bins_crossed(m, p, match) bind(C) - import C_PTR, Particle - type(C_PTR), value :: m - type(Particle), intent(in) :: p - type(C_PTR), value :: match - end subroutine - end interface - - ! Get a pointer to the mesh. - m = meshes(this % mesh) - - call mesh_surface_bins_crossed(m % ptr, p, match % ptr) + call this % get_all_bins_c(p, estimator, match) end subroutine get_all_bins From 98b437924518e57c453aea8f8ad705d00e25633b Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 4 Oct 2018 22:43:54 -0400 Subject: [PATCH 09/45] Add C++ TallyFilter::to_statepoint() --- include/openmc/tallies/tally_filter.h | 3 +++ include/openmc/tallies/tally_filter_cell.h | 10 ++++++++++ include/openmc/tallies/tally_filter_cellfrom.h | 10 ++++++++++ src/tallies/tally_filter.cpp | 3 +++ src/tallies/tally_filter_cell.F90 | 11 +---------- src/tallies/tally_filter_cellfrom.F90 | 11 +---------- src/tallies/tally_filter_header.F90 | 14 ++++++++++++++ 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 89ede592c..6988ff31b 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -4,6 +4,7 @@ #include #include +#include "openmc/hdf5_interface.h" #include "openmc/particle.h" #include "openmc/xml_interface.h" @@ -48,6 +49,8 @@ public: virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; + virtual void to_statepoint(hid_t filter_group) const {} + virtual void initialize() {} }; diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index c70fcbe30..85f4cd911 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -55,6 +55,16 @@ public: } } + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "cell"); + write_dataset(filter_group, "n_bins", cells_.size()); + std::vector cell_ids; + for (auto c : cells_) cell_ids.push_back(cells[c]->id_); + write_dataset(filter_group, "bins", cell_ids); + } + protected: std::vector cells_; std::unordered_map map_; diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index ed7518bfe..8bcc9a5af 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -22,6 +22,16 @@ public: } } } + + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "cellfrom"); + write_dataset(filter_group, "n_bins", cells_.size()); + std::vector cell_ids; + for (auto c : cells_) cell_ids.push_back(cells[c]->id_); + write_dataset(filter_group, "bins", cell_ids); + } }; } // namespace openmc diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 1dae39782..8754d5880 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -101,6 +101,9 @@ extern "C" { filt->get_all_bins(p, estimator, *match); } + void filter_to_statepoint(TallyFilter* filt, hid_t group) + {filt->to_statepoint(group);} + void filter_initialize(TallyFilter* filt) {filt->initialize();} } diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index 16d146df8..647ed38e6 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -64,17 +64,8 @@ contains class(CellFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group - integer :: i - integer, allocatable :: cell_ids(:) + call this % to_statepoint_c(filter_group) - call write_dataset(filter_group, "type", "cell") - call write_dataset(filter_group, "n_bins", this % n_bins) - - allocate(cell_ids(size(this % cells))) - do i = 1, size(this % cells) - cell_ids(i) = cells(this % cells(i)) % id() - end do - call write_dataset(filter_group, "bins", cell_ids) end subroutine to_statepoint_cell subroutine initialize_cell(this) diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index 999a55bfd..ebc063ac0 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -45,17 +45,8 @@ contains class(CellFromFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group - integer :: i - integer, allocatable :: cell_ids(:) + call this % to_statepoint_c(filter_group) - call write_dataset(filter_group, "type", "cellfrom") - call write_dataset(filter_group, "n_bins", this % n_bins) - - allocate(cell_ids(size(this % cells))) - do i = 1, size(this % cells) - cell_ids(i) = cells(this % cells(i)) % id() - end do - call write_dataset(filter_group, "bins", cell_ids) end subroutine to_statepoint_cell_from function text_label_cell_from(this, bin) result(label) diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 1d0688bb1..713fc405f 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -132,6 +132,7 @@ module tally_filter_header contains procedure :: from_xml_c procedure :: get_all_bins_c + procedure :: to_statepoint_c procedure :: initialize_c end type CppTallyFilter @@ -308,6 +309,19 @@ contains call filter_get_all_bins(this % ptr, p, estimator, match % ptr) end subroutine get_all_bins_c + subroutine to_statepoint_c(this, filter_group) + class(CppTallyFilter), intent(in) :: this + integer(HID_T), intent(in) :: filter_group + interface + subroutine filter_to_statepoint(filt, filter_group) bind(C) + import C_PTR, HID_T + type(C_PTR), value :: filt + integer(HID_T), intent(in), value :: filter_group + end subroutine filter_to_statepoint + end interface + call filter_to_statepoint(this % ptr, filter_group) + end subroutine to_statepoint_c + subroutine initialize_c(this) class(CppTallyFilter), intent(inout) :: this interface From 377e9fba3d96e87bcbdc3a8cac253670a8061245 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 5 Oct 2018 23:47:55 -0400 Subject: [PATCH 10/45] Add destructors to the C++ TallyFilter classes --- include/openmc/tallies/tally_filter.h | 4 ++++ include/openmc/tallies/tally_filter_cell.h | 2 ++ include/openmc/tallies/tally_filter_mesh.h | 2 ++ include/openmc/tallies/tally_filter_meshsurface.h | 2 ++ 4 files changed, 10 insertions(+) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 6988ff31b..b4d8a6e8d 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -44,6 +44,8 @@ public: class TallyFilter { public: + virtual ~TallyFilter() = 0; + virtual void from_xml(pugi::xml_node node) = 0; virtual void @@ -54,6 +56,8 @@ public: virtual void initialize() {} }; +inline TallyFilter::~TallyFilter() {} + //============================================================================== extern "C" void free_memory_tally_c(); diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index 85f4cd911..8504a769b 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -16,6 +16,8 @@ namespace openmc { class CellFilter : public TallyFilter { public: + virtual ~CellFilter() override = default; + virtual void from_xml(pugi::xml_node node) override { diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index 3ef457093..632c123a6 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -14,6 +14,8 @@ namespace openmc { class MeshFilter : public TallyFilter { public: + virtual ~MeshFilter() override = default; + virtual void from_xml(pugi::xml_node node) override { diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 9a69d60bd..0b638d707 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -14,6 +14,8 @@ namespace openmc { class MeshSurfaceFilter : public TallyFilter { public: + virtual ~MeshSurfaceFilter() override = default; + virtual void from_xml(pugi::xml_node node) override { From 64bd9af4ced65b5a8668fc8e414af8e93653b40a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 6 Oct 2018 13:55:36 -0400 Subject: [PATCH 11/45] Add TallyFilter::text_label --- include/openmc/constants.h | 1 + include/openmc/tallies/tally_filter.h | 3 +++ include/openmc/tallies/tally_filter_cell.h | 6 +++++ .../openmc/tallies/tally_filter_cellfrom.h | 6 +++++ include/openmc/tallies/tally_filter_mesh.h | 2 ++ .../openmc/tallies/tally_filter_meshsurface.h | 2 ++ src/tallies/tally_filter.cpp | 10 ++++++++ src/tallies/tally_filter_cell.F90 | 2 +- src/tallies/tally_filter_cellfrom.F90 | 2 +- src/tallies/tally_filter_header.F90 | 23 +++++++++++++++++++ 10 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index 9c96258fb..042dd9668 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -62,6 +62,7 @@ constexpr int MAX_SAMPLE {100000}; // Maximum number of words in a single line, length of line, and length of // single word +constexpr int MAX_LINE_LEN {250}; constexpr int MAX_WORD_LEN {150}; // Maximum number of external source spatial resamples to encounter before an diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index b4d8a6e8d..4713338d9 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -2,6 +2,7 @@ #define OPENMC_TALLY_FILTER_H #include +#include #include #include "openmc/hdf5_interface.h" @@ -53,6 +54,8 @@ public: virtual void to_statepoint(hid_t filter_group) const {} + virtual std::string text_label(int bin) const = 0; + virtual void initialize() {} }; diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index 8504a769b..0d56752c7 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -67,6 +67,12 @@ public: write_dataset(filter_group, "bins", cell_ids); } + virtual std::string + text_label(int bin) const override + { + return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); + } + protected: std::vector cells_; std::unordered_map map_; diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index 8bcc9a5af..a0eca932a 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -32,6 +32,12 @@ public: for (auto c : cells_) cell_ids.push_back(cells[c]->id_); write_dataset(filter_group, "bins", cell_ids); } + + virtual std::string + text_label(int bin) const override + { + return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); + } }; } // namespace openmc diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index 632c123a6..3c13a7f24 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -49,6 +49,8 @@ public: } } + virtual std::string text_label(int bin) const {}; + protected: int32_t mesh_; }; diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 0b638d707..14eede2c7 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -42,6 +42,8 @@ public: for (auto b : match.bins) match.weights.push_back(1.0); } + virtual std::string text_label(int bin) const {}; + protected: int32_t mesh_; }; diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 8754d5880..d2d10ceb3 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -2,6 +2,7 @@ #include +#include "openmc/constants.h" // for MAX_LINE_LEN; #include "openmc/tallies/tally_filter_cell.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_mesh.h" @@ -104,6 +105,15 @@ extern "C" { void filter_to_statepoint(TallyFilter* filt, hid_t group) {filt->to_statepoint(group);} + void filter_text_label(TallyFilter* filt, int bin, char* label) + { + std::string label_str = filt->text_label(bin); + int i = 0; + for (; i < label_str.size() && i < MAX_LINE_LEN; i++) + label[i] = label_str[i]; + label[i] = '\0'; + } + void filter_initialize(TallyFilter* filt) {filt->initialize();} } diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index 647ed38e6..984385a5b 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -99,7 +99,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Cell " // to_str(cells(this % cells(bin)) % id()) + label = this % text_label_c(bin) end function text_label_cell !=============================================================================== diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index ebc063ac0..94be061f7 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -54,7 +54,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Cell from " // to_str(cells(this % cells(bin)) % id()) + label = this % text_label_c(bin) end function text_label_cell_from end module tally_filter_cellfrom diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 713fc405f..63a636076 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -133,6 +133,7 @@ module tally_filter_header procedure :: from_xml_c procedure :: get_all_bins_c procedure :: to_statepoint_c + procedure :: text_label_c procedure :: initialize_c end type CppTallyFilter @@ -322,6 +323,28 @@ contains call filter_to_statepoint(this % ptr, filter_group) end subroutine to_statepoint_c + function text_label_c(this, bin) result(label) + class(CppTallyFilter), intent(in) :: this + integer, intent(in) :: bin + character(MAX_LINE_LEN) :: label + character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1) + integer :: i + interface + subroutine filter_text_label(filt, bin, label) bind(C) + import C_PTR, C_INT, C_CHAR + type(C_PTR), value :: filt + integer(C_INT), value :: bin + character(kind=C_CHAR) :: label(*) + end subroutine filter_text_label + end interface + call filter_text_label(this % ptr, bin, label_) + label = " " + do i = 1, MAX_LINE_LEN + if (label_(i) == C_NULL_CHAR) exit + label(i:i) = label_(i) + end do + end function text_label_c + subroutine initialize_c(this) class(CppTallyFilter), intent(inout) :: this interface From cf1e9204f6e508b20e3cc3e0807771aa2c4a0cf4 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 7 Oct 2018 11:43:46 -0400 Subject: [PATCH 12/45] Call C++ code by default in F90 CppTallyFilters --- src/tallies/tally_filter_cell.F90 | 33 +----------- src/tallies/tally_filter_cellfrom.F90 | 42 --------------- src/tallies/tally_filter_header.F90 | 67 ++++++++++++++++++------ src/tallies/tally_filter_mesh.F90 | 13 +---- src/tallies/tally_filter_meshsurface.F90 | 13 +---- 5 files changed, 56 insertions(+), 112 deletions(-) diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index 984385a5b..e02fef583 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -25,9 +25,6 @@ module tally_filter_cell type(DictIntInt) :: map contains procedure :: from_xml - procedure :: get_all_bins => get_all_bins_cell - procedure :: to_statepoint => to_statepoint_cell - procedure :: text_label => text_label_cell procedure :: initialize => initialize_cell end type CellFilter @@ -39,7 +36,7 @@ contains integer :: n - call this % from_xml_c(node) + call this % from_xml_cpp_inner(node) ! Determine how many bins were given n = node_word_count(node, "bins") @@ -50,31 +47,13 @@ contains call get_node_array(node, "bins", this % cells) end subroutine from_xml - subroutine get_all_bins_cell(this, p, estimator, match) - class(CellFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - call this % get_all_bins_c(p, estimator, match) - - end subroutine get_all_bins_cell - - subroutine to_statepoint_cell(this, filter_group) - class(CellFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call this % to_statepoint_c(filter_group) - - end subroutine to_statepoint_cell - subroutine initialize_cell(this) class(CellFilter), intent(inout) :: this integer :: i, id integer :: val - call this % initialize_c() + call this % initialize_cpp_inner() ! Convert ids to indices. do i = 1, this % n_bins @@ -94,14 +73,6 @@ contains end do end subroutine initialize_cell - function text_label_cell(this, bin) result(label) - class(CellFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = this % text_label_c(bin) - end function text_label_cell - !=============================================================================== ! C API FUNCTIONS !=============================================================================== diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index 94be061f7..201f94688 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -2,16 +2,7 @@ module tally_filter_cellfrom use, intrinsic :: ISO_C_BINDING - use constants, only: ONE, MAX_LINE_LEN - use dict_header, only: EMPTY - use error, only: fatal_error - use hdf5_interface - use geometry_header - use particle_header, only: Particle - use string, only: to_str - use tally_filter_header use tally_filter_cell - use xml_interface implicit none private @@ -22,39 +13,6 @@ module tally_filter_cellfrom !=============================================================================== type, public, extends(CellFilter) :: CellFromFilter - contains - ! Inherit from_xml from CellFilter - procedure :: get_all_bins => get_all_bins_cell_from - procedure :: to_statepoint => to_statepoint_cell_from - procedure :: text_label => text_label_cell_from end type CellFromFilter -contains - - subroutine get_all_bins_cell_from(this, p, estimator, match) - class(CellFromFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - call this % get_all_bins_c(p, estimator, match) - - end subroutine get_all_bins_cell_from - - subroutine to_statepoint_cell_from(this, filter_group) - class(CellFromFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call this % to_statepoint_c(filter_group) - - end subroutine to_statepoint_cell_from - - function text_label_cell_from(this, bin) result(label) - class(CellFromFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = this % text_label_c(bin) - end function text_label_cell_from - end module tally_filter_cellfrom diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 63a636076..0744e5baf 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -130,11 +130,16 @@ module tally_filter_header type, public, abstract, extends(TallyFilter) :: CppTallyFilter type(C_PTR) :: ptr contains - procedure :: from_xml_c - procedure :: get_all_bins_c - procedure :: to_statepoint_c - procedure :: text_label_c - procedure :: initialize_c + procedure :: from_xml_cpp_inner + procedure :: get_all_bins_cpp_inner + procedure :: to_statepoint_cpp_inner + procedure :: text_label_cpp_inner + procedure :: initialize_cpp_inner + procedure :: from_xml => from_xml_cpp_default + procedure :: get_all_bins => get_all_bins_cpp_default + procedure :: to_statepoint => to_statepoint_cpp_default + procedure :: text_label => text_label_cpp_default + procedure :: initialize => initialize_cpp_default end type CppTallyFilter !=============================================================================== @@ -280,7 +285,7 @@ contains !=============================================================================== - subroutine from_xml_c(this, node) + subroutine from_xml_cpp_inner(this, node) class(CppTallyFilter), intent(inout) :: this class(XMLNode), intent(in) :: node interface @@ -291,9 +296,9 @@ contains end subroutine filter_from_xml end interface call filter_from_xml(this % ptr, node % ptr) - end subroutine from_xml_c + end subroutine from_xml_cpp_inner - subroutine get_all_bins_c(this, p, estimator, match) + subroutine get_all_bins_cpp_inner(this, p, estimator, match) class(CppTallyFilter), intent(in) :: this type(Particle), intent(in) :: p integer, intent(in) :: estimator @@ -308,9 +313,9 @@ contains end subroutine filter_get_all_bins end interface call filter_get_all_bins(this % ptr, p, estimator, match % ptr) - end subroutine get_all_bins_c + end subroutine get_all_bins_cpp_inner - subroutine to_statepoint_c(this, filter_group) + subroutine to_statepoint_cpp_inner(this, filter_group) class(CppTallyFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group interface @@ -321,9 +326,9 @@ contains end subroutine filter_to_statepoint end interface call filter_to_statepoint(this % ptr, filter_group) - end subroutine to_statepoint_c + end subroutine to_statepoint_cpp_inner - function text_label_c(this, bin) result(label) + function text_label_cpp_inner(this, bin) result(label) class(CppTallyFilter), intent(in) :: this integer, intent(in) :: bin character(MAX_LINE_LEN) :: label @@ -343,9 +348,9 @@ contains if (label_(i) == C_NULL_CHAR) exit label(i:i) = label_(i) end do - end function text_label_c + end function text_label_cpp_inner - subroutine initialize_c(this) + subroutine initialize_cpp_inner(this) class(CppTallyFilter), intent(inout) :: this interface subroutine filter_initialize(filt) bind(C) @@ -354,7 +359,39 @@ contains end subroutine filter_initialize end interface call filter_initialize(this % ptr) - end subroutine initialize_c + end subroutine initialize_cpp_inner + + subroutine from_xml_cpp_default(this, node) + class(CppTallyFilter), intent(inout) :: this + type(XMLNode), intent(in) :: node + call this % from_xml_cpp_inner(node) + end subroutine from_xml_cpp_default + + subroutine get_all_bins_cpp_default(this, p, estimator, match) + class(CppTallyFilter), intent(in) :: this + type(Particle), intent(in) :: p + integer, intent(in) :: estimator + type(TallyFilterMatch), intent(inout) :: match + call this % get_all_bins_cpp_inner(p, estimator, match) + end subroutine get_all_bins_cpp_default + + subroutine to_statepoint_cpp_default(this, filter_group) + class(CppTallyFilter), intent(in) :: this + integer(HID_T), intent(in) :: filter_group + call this % to_statepoint_cpp_inner(filter_group) + end subroutine to_statepoint_cpp_default + + function text_label_cpp_default(this, bin) result(label) + class(CppTallyFilter), intent(in) :: this + integer, intent(in) :: bin + character(MAX_LINE_LEN) :: label + label = this % text_label_cpp_inner(bin) + end function text_label_cpp_default + + subroutine initialize_cpp_default(this) + class(CppTallyFilter), intent(inout) :: this + call this % initialize_cpp_inner() + end subroutine initialize_cpp_default !=============================================================================== ! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index abbd29657..5f71f26ad 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -27,7 +27,6 @@ module tally_filter_mesh integer :: mesh contains procedure :: from_xml - procedure :: get_all_bins => get_all_bins_mesh procedure :: to_statepoint => to_statepoint_mesh procedure :: text_label => text_label_mesh end type MeshFilter @@ -44,7 +43,7 @@ contains integer(C_INT) :: err type(RegularMesh) :: m - call this % from_xml_c(node) + call this % from_xml_cpp_inner(node) n = node_word_count(node, "bins") @@ -69,16 +68,6 @@ contains end do end subroutine from_xml - subroutine get_all_bins_mesh(this, p, estimator, match) - class(MeshFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - call this % get_all_bins_c(p, estimator, match) - - end subroutine get_all_bins_mesh - subroutine to_statepoint_mesh(this, filter_group) class(MeshFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index 6a9e0de5c..62cdf60a3 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -26,7 +26,6 @@ module tally_filter_meshsurface integer :: mesh contains procedure :: from_xml - procedure :: get_all_bins procedure :: to_statepoint procedure :: text_label end type MeshSurfaceFilter @@ -43,7 +42,7 @@ contains integer(C_INT) :: err type(RegularMesh) :: m - call this % from_xml_c(node) + call this % from_xml_cpp_inner(node) n = node_word_count(node, "bins") @@ -68,16 +67,6 @@ contains end do end subroutine from_xml - subroutine get_all_bins(this, p, estimator, match) - class(MeshSurfaceFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - call this % get_all_bins_c(p, estimator, match) - - end subroutine get_all_bins - subroutine to_statepoint(this, filter_group) class(MeshSurfaceFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group From 7f2c2904e71558ca7ff8d956597f457999291d00 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 7 Oct 2018 14:08:08 -0400 Subject: [PATCH 13/45] Fix MeshFilter and MeshSurfaceFilter C-API calls --- include/openmc/tallies/tally_filter.h | 2 ++ include/openmc/tallies/tally_filter_mesh.h | 5 ++- .../openmc/tallies/tally_filter_meshsurface.h | 4 ++- src/tallies/tally_filter.cpp | 22 ++++++++++++ src/tallies/tally_filter_header.F90 | 14 ++++++++ src/tallies/tally_filter_mesh.F90 | 35 +++++++++--------- src/tallies/tally_filter_meshsurface.F90 | 36 ++++++++++--------- 7 files changed, 83 insertions(+), 35 deletions(-) diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 4713338d9..e50e70fd1 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -57,6 +57,8 @@ public: virtual std::string text_label(int bin) const = 0; virtual void initialize() {} + + int n_bins_; }; inline TallyFilter::~TallyFilter() {} diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index 3c13a7f24..d48e8e35b 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -4,6 +4,7 @@ #include #include +#include "openmc/capi.h" #include "openmc/error.h" #include "openmc/mesh.h" #include "openmc/tallies/tally_filter.h" @@ -32,6 +33,9 @@ public: err_msg << "Could not find cell " << id << " specified on tally filter."; fatal_error(err_msg); } + + n_bins_ = 1; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } virtual void @@ -51,7 +55,6 @@ public: virtual std::string text_label(int bin) const {}; -protected: int32_t mesh_; }; diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 14eede2c7..5bf06e095 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -32,6 +32,9 @@ public: err_msg << "Could not find cell " << id << " specified on tally filter."; fatal_error(err_msg); } + + n_bins_ = 4 * meshes[mesh_]->n_dimension_;; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } virtual void @@ -44,7 +47,6 @@ public: virtual std::string text_label(int bin) const {}; -protected: int32_t mesh_; }; diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index d2d10ceb3..49f5b97d1 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -115,6 +115,28 @@ extern "C" { } void filter_initialize(TallyFilter* filt) {filt->initialize();} + + int filter_n_bins(TallyFilter* filt) {return filt->n_bins_;} + + int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} + + void + mesh_filter_set_mesh(MeshFilter* filt, int mesh) + { + filt->mesh_ = mesh; + filt->n_bins_ = 1; + for (auto dim : meshes[mesh]->shape_) filt->n_bins_ *= dim; + } + + int meshsurface_filter_get_mesh(MeshSurfaceFilter* filt) {return filt->mesh_;} + + void + meshsurface_filter_set_mesh(MeshSurfaceFilter* filt, int mesh) + { + filt->mesh_ = mesh; + filt->n_bins_ = 4 * meshes[mesh]->n_dimension_; + for (auto dim : meshes[mesh]->shape_) filt->n_bins_ *= dim; + } } } // namespace openmc diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 0744e5baf..162157489 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -130,6 +130,7 @@ module tally_filter_header type, public, abstract, extends(TallyFilter) :: CppTallyFilter type(C_PTR) :: ptr contains + procedure :: n_bins_cpp procedure :: from_xml_cpp_inner procedure :: get_all_bins_cpp_inner procedure :: to_statepoint_cpp_inner @@ -285,6 +286,19 @@ contains !=============================================================================== + function n_bins_cpp(this) result(n_bins) + class(CppTallyFilter), intent(inout) :: this + integer :: n_bins + interface + function filter_n_bins(filt) result(n_bins) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: n_bins + end function filter_n_bins + end interface + n_bins = filter_n_bins(this % ptr) + end function n_bins_cpp + subroutine from_xml_cpp_inner(this, node) class(CppTallyFilter), intent(inout) :: this class(XMLNode), intent(in) :: node diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index 5f71f26ad..816a58e53 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -37,11 +37,9 @@ contains class(MeshFilter), intent(inout) :: this type(XMLNode), intent(in) :: node - integer :: i integer :: id integer :: n integer(C_INT) :: err - type(RegularMesh) :: m call this % from_xml_cpp_inner(node) @@ -61,11 +59,7 @@ contains end if ! Determine number of bins - m = meshes(this % mesh) - this % n_bins = 1 - do i = 1, m % n_dimension() - this % n_bins = this % n_bins * m % dimension(i) - end do + this % n_bins = this % n_bins_cpp() end subroutine from_xml subroutine to_statepoint_mesh(this, filter_group) @@ -112,11 +106,19 @@ contains integer(C_INT32_T), intent(out) :: index_mesh integer(C_INT) :: err + interface + function mesh_filter_get_mesh(filt) result(index_mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: index_mesh + end function mesh_filter_get_mesh + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MeshFilter) - index_mesh = f % mesh + index_mesh = mesh_filter_get_mesh(f % ptr) class default err = E_INVALID_TYPE call set_errmsg("Tried to set mesh on a non-mesh filter.") @@ -131,20 +133,21 @@ contains integer(C_INT32_T), value, intent(in) :: index_mesh integer(C_INT) :: err - type(RegularMesh) :: m - integer :: i + interface + subroutine mesh_filter_set_mesh(filt, mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: mesh + end subroutine mesh_filter_set_mesh + end interface err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MeshFilter) if (index_mesh >= 0 .and. index_mesh < n_meshes()) then - f % mesh = index_mesh - f % n_bins = 1 - m = meshes(index_mesh) - do i = 1, m % n_dimension() - f % n_bins = f % n_bins * m % dimension(i) - end do + call mesh_filter_set_mesh(f % ptr, index_mesh) + f % n_bins = f % n_bins_cpp() else err = E_OUT_OF_BOUNDS call set_errmsg("Index in 'meshes' array is out of bounds.") diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index 62cdf60a3..d2ff898b0 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -36,11 +36,9 @@ contains class(MeshSurfaceFilter), intent(inout) :: this type(XMLNode), intent(in) :: node - integer :: i integer :: id integer :: n integer(C_INT) :: err - type(RegularMesh) :: m call this % from_xml_cpp_inner(node) @@ -60,11 +58,7 @@ contains end if ! Determine number of bins - m = meshes(this % mesh) - this % n_bins = 4 * m % n_dimension() - do i = 1, m % n_dimension() - this % n_bins = this % n_bins * m % dimension(i) - end do + this % n_bins = this % n_bins_cpp() end subroutine from_xml subroutine to_statepoint(this, filter_group) @@ -149,11 +143,20 @@ contains integer(C_INT32_T), intent(out) :: index_mesh integer(C_INT) :: err + interface + function meshsurface_filter_get_mesh(filt) result(index_mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: index_mesh + end function meshsurface_filter_get_mesh + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MeshSurfaceFilter) index_mesh = f % mesh + index_mesh = meshsurface_filter_get_mesh(f % ptr) class default err = E_INVALID_TYPE call set_errmsg("Tried to set mesh on a non-mesh filter.") @@ -168,22 +171,21 @@ contains integer(C_INT32_T), value, intent(in) :: index_mesh integer(C_INT) :: err - integer :: i - integer :: n_dim - type(RegularMesh) :: m + interface + subroutine meshsurface_filter_set_mesh(filt, mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: mesh + end subroutine meshsurface_filter_set_mesh + end interface err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MeshSurfaceFilter) if (index_mesh >= 0 .and. index_mesh < n_meshes()) then - f % mesh = index_mesh - m = meshes(index_mesh) - n_dim = m % n_dimension() - f % n_bins = 4*n_dim - do i = 1, n_dim - f % n_bins = f % n_bins * m % dimension(i) - end do + call meshsurface_filter_set_mesh(f % ptr, index_mesh) + f % n_bins = f % n_bins_cpp() else err = E_OUT_OF_BOUNDS call set_errmsg("Index in 'meshes' array is out of bounds.") From 5a73710110a354fac42993a4ea2bbc6edd8b2e6f Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 7 Oct 2018 15:12:04 -0400 Subject: [PATCH 14/45] Move mesh and meshsurface filter internals to C++ --- include/openmc/tallies/tally_filter_mesh.h | 26 +++- .../openmc/tallies/tally_filter_meshsurface.h | 58 ++++++++- src/cmfd_data.F90 | 10 +- src/tallies/tally_filter_header.F90 | 1 + src/tallies/tally_filter_mesh.F90 | 94 +++------------ src/tallies/tally_filter_meshsurface.F90 | 111 ------------------ src/tallies/trigger.F90 | 2 +- 7 files changed, 107 insertions(+), 195 deletions(-) diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index d48e8e35b..01ffbae6f 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -53,7 +53,31 @@ public: } } - virtual std::string text_label(int bin) const {}; + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "mesh"); + write_dataset(filter_group, "n_bins", n_bins_); + write_dataset(filter_group, "bins", meshes[mesh_]->id_); + } + + virtual std::string + text_label(int bin) const override + { + auto& mesh = *meshes[mesh_]; + int n_dim = mesh.n_dimension_; + + int ijk[n_dim]; + mesh.get_indices_from_bin(bin, ijk); + + std::stringstream out; + out << "Mesh Index (" << ijk[0]; + if (n_dim > 1) out << ", " << ijk[1]; + if (n_dim > 2) out << ", " << ijk[2]; + out << ")"; + + return out.str(); + } int32_t mesh_; }; diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 5bf06e095..7b374b0a6 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -4,6 +4,7 @@ #include #include +#include "openmc/constants.h" #include "openmc/error.h" #include "openmc/mesh.h" #include "openmc/tallies/tally_filter.h" @@ -45,7 +46,62 @@ public: for (auto b : match.bins) match.weights.push_back(1.0); } - virtual std::string text_label(int bin) const {}; + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "meshsurface"); + write_dataset(filter_group, "n_bins", n_bins_); + write_dataset(filter_group, "bins", meshes[mesh_]->id_); + } + + virtual std::string + text_label(int bin) const override + { + auto& mesh = *meshes[mesh_]; + int n_dim = mesh.n_dimension_; + + // Get flattend mesh index and surface index. + int i_mesh = (bin - 1) / (4 * n_dim) + 1; + int i_surf = ((bin - 1) % (4 * n_dim)) + 1; + + // Get mesh index part of label. + int ijk[n_dim]; + mesh.get_indices_from_bin(i_mesh, ijk); + std::stringstream out; + out << "Mesh Index (" << ijk[0]; + if (n_dim > 1) out << ", " << ijk[1]; + if (n_dim > 2) out << ", " << ijk[2]; + out << ")"; + + // Get surface part of label. + if (i_surf == OUT_LEFT) { + out << " Outgoing, x-min"; + } else if (i_surf == IN_LEFT) { + out << " Incoming, x-min"; + } else if (i_surf == OUT_RIGHT) { + out << " Outgoing, x-max"; + } else if (i_surf == IN_RIGHT) { + out << " Incoming, x-max"; + } else if (i_surf == OUT_BACK) { + out << " Outgoing, y-min"; + } else if (i_surf == IN_BACK) { + out << " Incoming, y-min"; + } else if (i_surf == OUT_FRONT) { + out << " Outgoing, y-max"; + } else if (i_surf == IN_FRONT) { + out << " Incoming, y-max"; + } else if (i_surf == OUT_BOTTOM) { + out << " Outgoing, z-min"; + } else if (i_surf == IN_BOTTOM) { + out << " Incoming, z-min"; + } else if (i_surf == OUT_TOP) { + out << " Outgoing, z-max"; + } else if (i_surf == IN_TOP) { + out << " Incoming, z-max"; + } + + return out.str(); + } int32_t mesh_; }; diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index 07276d900..a12ca217e 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -82,6 +82,14 @@ contains real(8) :: flux ! temp variable for flux type(RegularMesh) :: m ! pointer for mesh object + interface + function mesh_filter_get_mesh(filt) result(index_mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: index_mesh + end function mesh_filter_get_mesh + end interface + ! Extract spatial and energy indices from object nx = cmfd % indices(1) ny = cmfd % indices(2) @@ -99,7 +107,7 @@ contains select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) - m = meshes(filt % mesh) + m = meshes(filt % mesh()) end select ! Set mesh widths diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 162157489..93e1a82d6 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -379,6 +379,7 @@ contains class(CppTallyFilter), intent(inout) :: this type(XMLNode), intent(in) :: node call this % from_xml_cpp_inner(node) + this % n_bins = this % n_bins_cpp() end subroutine from_xml_cpp_default subroutine get_all_bins_cpp_default(this, p, estimator, match) diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index 816a58e53..5d2307aef 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -3,14 +3,9 @@ module tally_filter_mesh use, intrinsic :: ISO_C_BINDING use constants - use dict_header, only: EMPTY use error use mesh_header - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none private @@ -24,77 +19,24 @@ module tally_filter_mesh !=============================================================================== type, public, extends(CppTallyFilter) :: MeshFilter - integer :: mesh contains - procedure :: from_xml - procedure :: to_statepoint => to_statepoint_mesh - procedure :: text_label => text_label_mesh + procedure :: mesh => get_mesh end type MeshFilter contains - subroutine from_xml(this, node) - class(MeshFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: id - integer :: n - integer(C_INT) :: err - - call this % from_xml_cpp_inner(node) - - n = node_word_count(node, "bins") - - if (n /= 1) call fatal_error("Only one mesh can be & - &specified per mesh filter.") - - ! Determine id of mesh - call get_node_value(node, "bins", id) - - ! Get pointer to mesh - err = openmc_get_mesh_index(id, this % mesh) - if (err /= 0) then - call fatal_error("Could not find mesh " // trim(to_str(id)) & - // " specified on filter.") - end if - - ! Determine number of bins - this % n_bins = this % n_bins_cpp() - end subroutine from_xml - - subroutine to_statepoint_mesh(this, filter_group) - class(MeshFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - type(RegularMesh) :: m - - m = meshes(this % mesh) - call write_dataset(filter_group, "type", "mesh") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", m % id()) - end subroutine to_statepoint_mesh - - function text_label_mesh(this, bin) result(label) - class(MeshFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - integer, allocatable :: ijk(:) - type(RegularMesh) :: m - - m = meshes(this % mesh) - allocate(ijk(m % n_dimension())) - call m % get_indices_from_bin(bin, ijk) - if (m % n_dimension() == 1) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ")" - elseif (m % n_dimension() == 2) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ", " // & - trim(to_str(ijk(2))) // ")" - elseif (m % n_dimension() == 3) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ", " // & - trim(to_str(ijk(2))) // ", " // trim(to_str(ijk(3))) // ")" - end if - end function text_label_mesh + function get_mesh(this) result(mesh) + class(MeshFilter) :: this + integer :: mesh + interface + function mesh_filter_get_mesh(filt) result(index_mesh) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: index_mesh + end function mesh_filter_get_mesh + end interface + mesh = mesh_filter_get_mesh(this % ptr) + end function get_mesh !=============================================================================== ! C API FUNCTIONS @@ -106,19 +48,11 @@ contains integer(C_INT32_T), intent(out) :: index_mesh integer(C_INT) :: err - interface - function mesh_filter_get_mesh(filt) result(index_mesh) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: index_mesh - end function mesh_filter_get_mesh - end interface - err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MeshFilter) - index_mesh = mesh_filter_get_mesh(f % ptr) + index_mesh = f % mesh() class default err = E_INVALID_TYPE call set_errmsg("Tried to set mesh on a non-mesh filter.") diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index d2ff898b0..22453a40f 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -5,11 +5,7 @@ module tally_filter_meshsurface use constants use error use mesh_header - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none private @@ -23,116 +19,10 @@ module tally_filter_meshsurface !=============================================================================== type, public, extends(CppTallyFilter) :: MeshSurfaceFilter - integer :: mesh - contains - procedure :: from_xml - procedure :: to_statepoint - procedure :: text_label end type MeshSurfaceFilter contains - subroutine from_xml(this, node) - class(MeshSurfaceFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: id - integer :: n - integer(C_INT) :: err - - call this % from_xml_cpp_inner(node) - - n = node_word_count(node, "bins") - - if (n /= 1) call fatal_error("Only one mesh can be & - &specified per meshsurface filter.") - - ! Determine id of mesh - call get_node_value(node, "bins", id) - - ! Get pointer to mesh - err = openmc_get_mesh_index(id, this % mesh) - if (err /= 0) then - call fatal_error("Could not find mesh " // trim(to_str(id)) & - // " specified on filter.") - end if - - ! Determine number of bins - this % n_bins = this % n_bins_cpp() - end subroutine from_xml - - subroutine to_statepoint(this, filter_group) - class(MeshSurfaceFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - type(RegularMesh) :: m - - m = meshes(this % mesh) - call write_dataset(filter_group, "type", "meshsurface") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", m % id()) - end subroutine to_statepoint - - function text_label(this, bin) result(label) - class(MeshSurfaceFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - integer :: i_mesh - integer :: i_surf - integer :: n_dim - integer, allocatable :: ijk(:) - type(RegularMesh) :: m - - m = meshes(this % mesh) - n_dim = m % n_dimension() - allocate(ijk(n_dim)) - - ! Get flattend mesh index and surface index - i_mesh = (bin - 1) / (4*n_dim) + 1 - i_surf = mod(bin - 1, 4*n_dim) + 1 - - ! Get mesh index part of label - call m % get_indices_from_bin(i_mesh, ijk) - if (m % n_dimension() == 1) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ")" - elseif (m % n_dimension() == 2) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ", " // & - trim(to_str(ijk(2))) // ")" - elseif (m % n_dimension() == 3) then - label = "Mesh Index (" // trim(to_str(ijk(1))) // ", " // & - trim(to_str(ijk(2))) // ", " // trim(to_str(ijk(3))) // ")" - end if - - ! Get surface part of label - select case (i_surf) - case (OUT_LEFT) - label = trim(label) // " Outgoing, x-min" - case (IN_LEFT) - label = trim(label) // " Incoming, x-min" - case (OUT_RIGHT) - label = trim(label) // " Outgoing, x-max" - case (IN_RIGHT) - label = trim(label) // " Incoming, x-max" - case (OUT_BACK) - label = trim(label) // " Outgoing, y-min" - case (IN_BACK) - label = trim(label) // " Incoming, y-min" - case (OUT_FRONT) - label = trim(label) // " Outgoing, y-max" - case (IN_FRONT) - label = trim(label) // " Incoming, y-max" - case (OUT_BOTTOM) - label = trim(label) // " Outgoing, z-min" - case (IN_BOTTOM) - label = trim(label) // " Incoming, z-min" - case (OUT_TOP) - label = trim(label) // " Outgoing, z-max" - case (IN_TOP) - label = trim(label) // " Incoming, z-max" - end select - end function text_label - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -155,7 +45,6 @@ contains if (err == 0) then select type (f => filters(index) % obj) type is (MeshSurfaceFilter) - index_mesh = f % mesh index_mesh = meshsurface_filter_get_mesh(f % ptr) class default err = E_INVALID_TYPE diff --git a/src/tallies/trigger.F90 b/src/tallies/trigger.F90 index 4450a292a..fbecaecd9 100644 --- a/src/tallies/trigger.F90 +++ b/src/tallies/trigger.F90 @@ -264,7 +264,7 @@ contains i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) - m = meshes(filt % mesh) + m = meshes(filt % mesh()) end select ! initialize bins array From e82f526771830778c5a26bf179d7f62739551466 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 11 Oct 2018 19:37:36 -0400 Subject: [PATCH 15/45] Fix DAGMC CellFilter error --- src/dagmc.cpp | 2 +- src/input_xml.F90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dagmc.cpp b/src/dagmc.cpp index 959dabd12..d4e113977 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -54,7 +54,7 @@ void load_dagmc_geometry() c->fill_ = C_NONE; // no fill, single universe cells.push_back(c); - cell_map[c->id_] = c->id_; + cell_map[c->id_] = i; // Populate the Universe vector and dict auto it = universe_map.find(dagmc_univ_id); diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 420ae5bbb..49c635235 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -363,7 +363,7 @@ contains subroutine read_geometry_dagmc() - integer :: i, j + integer :: i integer :: univ_id integer :: n_cells_in_univ logical :: file_exists From 2ce911977a40592a855e0080acc5128dbae07772 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 11 Oct 2018 20:37:07 -0400 Subject: [PATCH 16/45] Finish moving CellFilter implementation to C++ --- include/openmc/tallies/tally_filter_cell.h | 4 +- src/tallies/tally_filter.cpp | 7 +++ src/tallies/tally_filter_cell.F90 | 69 ++++------------------ 3 files changed, 20 insertions(+), 60 deletions(-) diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index 0d56752c7..972fafddb 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -22,6 +22,7 @@ public: from_xml(pugi::xml_node node) override { cells_ = get_node_array(node, "bins"); + n_bins_ = cells_.size(); } virtual void @@ -61,7 +62,7 @@ public: to_statepoint(hid_t filter_group) const override { write_dataset(filter_group, "type", "cell"); - write_dataset(filter_group, "n_bins", cells_.size()); + write_dataset(filter_group, "n_bins", n_bins_); std::vector cell_ids; for (auto c : cells_) cell_ids.push_back(cells[c]->id_); write_dataset(filter_group, "bins", cell_ids); @@ -73,7 +74,6 @@ public: return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); } -protected: std::vector cells_; std::unordered_map map_; }; diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 49f5b97d1..7df15e02f 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -118,6 +118,13 @@ extern "C" { int filter_n_bins(TallyFilter* filt) {return filt->n_bins_;} + void + cell_filter_get_bins(CellFilter* filt, int32_t** cells, int32_t* n) + { + *cells = filt->cells_.data(); + *n = filt->cells_.size(); + } + int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} void diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index e02fef583..f4201ffb7 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -2,15 +2,8 @@ module tally_filter_cell use, intrinsic :: ISO_C_BINDING - use constants, only: ONE, MAX_LINE_LEN - use dict_header, only: EMPTY - use error, only: fatal_error - use hdf5_interface - use geometry_header - use particle_header, only: Particle - use string, only: to_str + use error use tally_filter_header - use xml_interface implicit none private @@ -21,58 +14,10 @@ module tally_filter_cell !=============================================================================== type, public, extends(CppTallyFilter) :: CellFilter - integer(C_INT32_T), allocatable :: cells(:) - type(DictIntInt) :: map - contains - procedure :: from_xml - procedure :: initialize => initialize_cell end type CellFilter contains - subroutine from_xml(this, node) - class(CellFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - call this % from_xml_cpp_inner(node) - - ! Determine how many bins were given - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % cells(n)) - call get_node_array(node, "bins", this % cells) - end subroutine from_xml - - subroutine initialize_cell(this) - class(CellFilter), intent(inout) :: this - - integer :: i, id - integer :: val - - call this % initialize_cpp_inner() - - ! Convert ids to indices. - do i = 1, this % n_bins - id = this % cells(i) - val = cell_dict % get(id) - if (val /= EMPTY) then - this % cells(i) = val - else - call fatal_error("Could not find cell " // trim(to_str(id)) & - &// " specified on tally filter.") - end if - end do - - ! Generate mapping from cell indices to filter bins. - do i = 1, this % n_bins - call this % map % set(this % cells(i), i) - end do - end subroutine initialize_cell - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -84,12 +29,20 @@ contains integer(C_INT32_T), intent(out) :: n integer(C_INT) :: err + interface + subroutine cell_filter_get_bins(filt, cells, n) bind(C) + import C_PTR, C_INT + type(C_PTR), intent(in), value :: filt + type(C_PTR), intent(out) :: cells + integer(C_INT), intent(out) :: n + end subroutine cell_filter_get_bins + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (CellFilter) - cells = C_LOC(f % cells) - n = size(f % cells) + call cell_filter_get_bins(f % ptr, cells, n) class default err = E_INVALID_TYPE call set_errmsg("Tried to get cells from a non-cell filter.") From bf025edd586ff8e46a099859003597a5e5342627 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 11 Oct 2018 20:57:36 -0400 Subject: [PATCH 17/45] Move CellbornFilter to C++ --- .../openmc/tallies/tally_filter_cellborn.h | 41 +++++++ src/tallies/tally_filter.cpp | 3 + src/tallies/tally_filter_cellborn.F90 | 102 +----------------- 3 files changed, 45 insertions(+), 101 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_cellborn.h diff --git a/include/openmc/tallies/tally_filter_cellborn.h b/include/openmc/tallies/tally_filter_cellborn.h new file mode 100644 index 000000000..814b4d6b9 --- /dev/null +++ b/include/openmc/tallies/tally_filter_cellborn.h @@ -0,0 +1,41 @@ +#ifndef OPENMC_TALLY_FILTER_CELLBORN_H +#define OPENMC_TALLY_FILTER_CELLBORN_H + +#include "openmc/tallies/tally_filter_cell.h" + +namespace openmc { + +class CellbornFilter : public CellFilter +{ +public: + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + auto search = map_.find(p->cell_born); + if (search != map_.end()) { + // TODO: off-by-one + match.bins.push_back(search->second + 1); + match.weights.push_back(1); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "cellborn"); + write_dataset(filter_group, "n_bins", n_bins_); + std::vector cell_ids; + for (auto c : cells_) cell_ids.push_back(cells[c]->id_); + write_dataset(filter_group, "bins", cell_ids); + } + + virtual std::string + text_label(int bin) const override + { + return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); + } +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_CELLBORN_H diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 7df15e02f..944b15403 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -4,6 +4,7 @@ #include "openmc/constants.h" // for MAX_LINE_LEN; #include "openmc/tallies/tally_filter_cell.h" +#include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_mesh.h" #include "openmc/tallies/tally_filter_meshsurface.h" @@ -80,6 +81,8 @@ extern "C" { std::string type_ {type}; if (type_ == "cell") { tally_filters.push_back(new CellFilter()); + } else if (type_ == "cellborn") { + tally_filters.push_back(new CellbornFilter()); } else if (type_ == "cellfrom") { tally_filters.push_back(new CellFromFilter()); } else if (type_ == "mesh") { diff --git a/src/tallies/tally_filter_cellborn.F90 b/src/tallies/tally_filter_cellborn.F90 index 0a87a5046..dd7e65bf3 100644 --- a/src/tallies/tally_filter_cellborn.F90 +++ b/src/tallies/tally_filter_cellborn.F90 @@ -1,114 +1,14 @@ module tally_filter_cellborn - use, intrinsic :: ISO_C_BINDING - - use constants, only: ONE, MAX_LINE_LEN - use dict_header, only: EMPTY - use error, only: fatal_error - use hdf5_interface - use geometry_header - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! CELLBORNFILTER specifies which cell the particle was born in. !=============================================================================== - type, public, extends(TallyFilter) :: CellbornFilter - integer, allocatable :: cells(:) - type(DictIntInt) :: map - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_cellborn - procedure :: to_statepoint => to_statepoint_cellborn - procedure :: text_label => text_label_cellborn - procedure :: initialize => initialize_cellborn + type, public, extends(CppTallyFilter) :: CellbornFilter end type CellbornFilter -contains - - subroutine from_xml(this, node) - class(CellbornFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - ! Determine number of bins - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % cells(n)) - call get_node_array(node, "bins", this % cells) - end subroutine from_xml - - subroutine get_all_bins_cellborn(this, p, estimator, match) - class(CellbornFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: val - - val = this % map % get(p % cell_born + 1) - if (val /= EMPTY) then - call match % bins_push_back(val) - call match % weights_push_back(ONE) - end if - - end subroutine get_all_bins_cellborn - - subroutine to_statepoint_cellborn(this, filter_group) - class(CellbornFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - integer :: i - integer, allocatable :: cell_ids(:) - - call write_dataset(filter_group, "type", "cellborn") - call write_dataset(filter_group, "n_bins", this % n_bins) - allocate(cell_ids(size(this % cells))) - do i = 1, size(this % cells) - cell_ids(i) = cells(this % cells(i)) % id() - end do - call write_dataset(filter_group, "bins", cell_ids) - end subroutine to_statepoint_cellborn - - subroutine initialize_cellborn(this) - class(CellbornFilter), intent(inout) :: this - - integer :: i, id - integer :: val - - ! Convert ids to indices. - do i = 1, this % n_bins - id = this % cells(i) - val = cell_dict % get(id) - if (val /= EMPTY) then - this % cells(i) = val - else - call fatal_error("Could not find cell " // trim(to_str(id)) & - &// " specified on tally filter.") - end if - end do - - ! Generate mapping from cell indices to filter bins. - do i = 1, this % n_bins - call this % map % set(this % cells(i), i) - end do - end subroutine initialize_cellborn - - function text_label_cellborn(this, bin) result(label) - class(CellbornFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Birth Cell " // to_str(cells(this % cells(bin)) % id()) - end function text_label_cellborn - end module tally_filter_cellborn From f2a5e10c46ff483341bd9503e00e1a26596f8597 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 11 Oct 2018 22:27:13 -0400 Subject: [PATCH 18/45] Move DistribcellFilter to C++ --- include/openmc/geometry_aux.h | 27 +--- .../openmc/tallies/tally_filter_distribcell.h | 93 +++++++++++ src/cell.cpp | 6 - src/geometry_aux.cpp | 40 ++--- src/geometry_header.F90 | 78 --------- src/input_xml.F90 | 37 +---- src/lattice.cpp | 6 - src/tallies/tally_filter.cpp | 3 + src/tallies/tally_filter_distribcell.F90 | 148 +----------------- 9 files changed, 121 insertions(+), 317 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_distribcell.h diff --git a/include/openmc/geometry_aux.h b/include/openmc/geometry_aux.h index ac68f5b00..34ed206da 100644 --- a/include/openmc/geometry_aux.h +++ b/include/openmc/geometry_aux.h @@ -5,6 +5,7 @@ #define OPENMC_GEOMETRY_AUX_H #include +#include namespace openmc { @@ -41,7 +42,7 @@ extern "C" void neighbor_lists(); //! Populate all data structures needed for distribcells. //============================================================================== -extern "C" void prepare_distribcell(int32_t* filter_cell_list, int n); +extern "C" void prepare_distribcell(); //============================================================================== //! Recursively search through the geometry and count cell instances. @@ -65,21 +66,6 @@ extern "C" void count_cell_instances(int32_t univ_indx); extern "C" int count_universe_instances(int32_t search_univ, int32_t target_univ_id); -//============================================================================== -//! Find the length necessary for a string to contain a distribcell path. -//! @param target_cell The index of the Cell in the global Cell array. -//! @param map The index of the distribcell mapping corresponding to the target -//! cell. -//! @param target_offset An instance number for a distributed cell. -//! @param root_univ The index of the root Universe in the global Universe -//! array. -//! @return The size of a character array needed to fit the distribcell path. -//============================================================================== - -extern "C" int -distribcell_path_len(int32_t target_cell, int32_t map, int32_t target_offset, - int32_t root_univ); - //============================================================================== //! Build a character array representing the path to a distribcell instance. //! @param target_cell The index of the Cell in the global Cell array. @@ -88,13 +74,12 @@ distribcell_path_len(int32_t target_cell, int32_t map, int32_t target_offset, //! @param target_offset An instance number for a distributed cell. //! @param root_univ The index of the root Universe in the global Universe //! array. -//! @param[out] path The unique traversal through the geometry tree that leads -//! to the desired instance of the target cell. +//! @return The unique traversal through the geometry tree that leads to the +//! desired instance of the target cell. //============================================================================== -extern "C" void -distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset, - int32_t root_univ, char *path); +std::string +distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset); //============================================================================== //! Determine the maximum number of nested coordinate levels in the geometry. diff --git a/include/openmc/tallies/tally_filter_distribcell.h b/include/openmc/tallies/tally_filter_distribcell.h new file mode 100644 index 000000000..b29520caa --- /dev/null +++ b/include/openmc/tallies/tally_filter_distribcell.h @@ -0,0 +1,93 @@ +#ifndef OPENMC_TALLY_FILTER_DISTRIBCELL_H +#define OPENMC_TALLY_FILTER_DISTRIBCELL_H + +#include + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/geometry_aux.h" // For distribcell_path +#include "openmc/lattice.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class DistribcellFilter : public TallyFilter +{ +public: + virtual ~DistribcellFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + auto cells = get_node_array(node, "bins"); + if (cells.size() != 1) { + fatal_error("Only one cell can be specified per distribcell filter."); + } + cell_ = cells[0]; + } + + virtual void + initialize() override + { + auto search = cell_map.find(cell_); + if (search != cell_map.end()) { + cell_ = search->second; + n_bins_ = cells[cell_]->n_instances_; + } else { + std::stringstream err_msg; + err_msg << "Could not find cell " << cell_ + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + int offset = 0; + auto distribcell_index = cells[cell_]->distribcell_index_; + for (int i = 0; i < p->n_coord; i++) { + auto& c {*cells[p->coord[i].cell]}; + if (c.type_ == FILL_UNIVERSE) { + offset += c.offset_[distribcell_index]; + } else if (c.type_ == FILL_LATTICE) { + auto& lat {*lattices[p->coord[i+1].lattice-1]}; + int i_xyz[3] {p->coord[i+1].lattice_x, + p->coord[i+1].lattice_y, + p->coord[i+1].lattice_z}; + if (lat.are_valid_indices(i_xyz)) { + offset += lat.offset(distribcell_index, i_xyz); + } + } + if (cell_ == p->coord[i].cell) { + match.bins.push_back(offset + 1); + match.weights.push_back(1); + return; + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + write_dataset(filter_group, "type", "distribcell"); + write_dataset(filter_group, "n_bins", n_bins_); + write_dataset(filter_group, "bins", cells[cell_]->id_); + } + + virtual std::string + text_label(int bin) const override + { + auto map = cells[cell_]->distribcell_index_; + auto path = distribcell_path(cell_, map, bin-1); + + return "Distributed Cell " + path; + } + + int32_t cell_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_DISTRIBCELL_H diff --git a/src/cell.cpp b/src/cell.cpp index 41a15aefd..545bb7f58 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -803,10 +803,6 @@ extern "C" { int32_t cell_fill(Cell* c) {return c->fill_;} - int32_t cell_n_instances(Cell* c) {return c->n_instances_;} - - int cell_distribcell_index(Cell* c) {return c->distribcell_index_;} - int cell_material_size(Cell* c) {return c->material_.size();} //TODO: off-by-one @@ -821,8 +817,6 @@ extern "C" { double cell_sqrtkT(Cell* c, int i) {return c->sqrtkT_[i];} - int32_t cell_offset(Cell* c, int map) {return c->offset_[map];} - void extend_cells_c(int32_t n) { cells.reserve(cells.size() + n); diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 20f64e187..1da7bd78b 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -12,6 +12,8 @@ #include "openmc/material.h" #include "openmc/settings.h" #include "openmc/surface.h" +#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/tally_filter_distribcell.h" namespace openmc { @@ -181,12 +183,16 @@ neighbor_lists() //============================================================================== void -prepare_distribcell(int32_t* filter_cell_list, int n) +prepare_distribcell() { - // Read the list of cells contained in distribcell filters from Fortran. + // Find all cells listed in a DistribcellFilter. std::unordered_set distribcells; - for (int i = 0; i < n; i++) { - distribcells.insert(filter_cell_list[i]); + for (auto* filt : tally_filters) { + //TODO: replace this cast + auto* distrib_filt = dynamic_cast(filt); + if (distrib_filt) { + distribcells.insert(distrib_filt->cell_); + } } // Find all cells with distributed materials or temperatures. Make sure that @@ -393,29 +399,11 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, } } -//============================================================================== - -int -distribcell_path_len(int32_t target_cell, int32_t map, int32_t target_offset, - int32_t root_univ) +std::string +distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset) { - Universe& root = *universes[root_univ]; - std::string path_ {distribcell_path_inner(target_cell, map, target_offset, - root, 0)}; - return path_.size() + 1; -} - -//============================================================================== - -void -distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset, - int32_t root_univ, char* path) -{ - Universe& root = *universes[root_univ]; - std::string path_ {distribcell_path_inner(target_cell, map, target_offset, - root, 0)}; - path_.copy(path, path_.size()); - path[path_.size()] = '\0'; + auto& root_univ = *universes[openmc_root_universe]; + return distribcell_path_inner(target_cell, map, target_offset, root_univ, 0); } //============================================================================== diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index b58b5415b..89cfbcf2a 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -59,20 +59,6 @@ module geometry_header integer(C_INT32_T) :: fill end function cell_fill_c - function cell_n_instances_c(cell_ptr) bind(C, name='cell_n_instances') & - result(n_instances) - import C_PTR, C_INT32_T - type(C_PTR), intent(in), value :: cell_ptr - integer(C_INT32_T) :: n_instances - end function cell_n_instances_c - - function cell_distribcell_index_c(cell_ptr) & - bind(C, name='cell_distribcell_index') result(distribcell_index) - import C_PTR, C_INT - type(C_PTR), intent(in), value :: cell_ptr - integer(C_INT) :: distribcell_index - end function cell_distribcell_index_c - function cell_material_size_c(cell_ptr) bind(C, name='cell_material_size') & result(n) import C_PTR, C_INT @@ -103,14 +89,6 @@ module geometry_header real(C_DOUBLE) :: sqrtkT end function cell_sqrtkT_c - function cell_offset_c(cell_ptr, map) bind(C, name="cell_offset") & - result(offset) - import C_PTR, C_INT, C_INT32_T - type(C_PTR), intent(in), value :: cell_ptr - integer(C_INT), intent(in), value :: map - integer(C_INT32_T) :: offset - end function cell_offset_c - function lattice_pointer(lat_ind) bind(C) result(ptr) import C_PTR, C_INT32_T integer(C_INT32_T), intent(in), value :: lat_ind @@ -123,23 +101,6 @@ module geometry_header integer(C_INT32_T) :: id end function lattice_id_c - function lattice_are_valid_indices_c(lat_ptr, i_xyz) & - bind(C, name='lattice_are_valid_indices') result (is_valid) - import C_PTR, C_INT, C_BOOL - type(C_PTR), intent(in), value :: lat_ptr - integer(C_INT), intent(in) :: i_xyz(3) - logical(C_BOOL) :: is_valid - end function lattice_are_valid_indices_c - - function lattice_offset_c(lat_ptr, map, i_xyz) & - bind(C, name='lattice_offset') result(offset) - import C_PTR, C_INT, C_INT32_T - type(C_PTR), intent(in), value :: lat_ptr - integer(C_INT), intent(in), value :: map - integer(C_INT), intent(in) :: i_xyz(3) - integer(C_INT32_T) :: offset - end function lattice_offset_c - subroutine extend_cells_c(n) bind(C) import C_INT32_t integer(C_INT32_T), intent(in), value :: n @@ -154,8 +115,6 @@ module geometry_header type(C_PTR) :: ptr contains procedure :: id => lattice_id - procedure :: are_valid_indices => lattice_are_valid_indices - procedure :: offset => lattice_offset end type Lattice !=============================================================================== @@ -176,13 +135,10 @@ module geometry_header procedure :: type => cell_type procedure :: universe => cell_universe procedure :: fill => cell_fill - procedure :: n_instances => cell_n_instances - procedure :: distribcell_index => cell_distribcell_index procedure :: material_size => cell_material_size procedure :: material => cell_material procedure :: sqrtkT_size => cell_sqrtkT_size procedure :: sqrtkT => cell_sqrtkT - procedure :: offset => cell_offset end type Cell @@ -208,21 +164,6 @@ contains id = lattice_id_c(this % ptr) end function lattice_id - function lattice_are_valid_indices(this, i_xyz) result (is_valid) - class(Lattice), intent(in) :: this - integer(C_INT), intent(in) :: i_xyz(3) - logical(C_BOOL) :: is_valid - is_valid = lattice_are_valid_indices_c(this % ptr, i_xyz) - end function lattice_are_valid_indices - - function lattice_offset(this, map, i_xyz) result(offset) - class(Lattice), intent(in) :: this - integer(C_INT), intent(in) :: map - integer(C_INT), intent(in) :: i_xyz(3) - integer(C_INT32_T) :: offset - offset = lattice_offset_c(this % ptr, map, i_xyz) - end function lattice_offset - !=============================================================================== function cell_id(this) result(id) @@ -255,18 +196,6 @@ contains fill = cell_fill_c(this % ptr) end function cell_fill - function cell_n_instances(this) result(n_instances) - class(Cell), intent(in) :: this - integer(C_INT32_T) :: n_instances - n_instances = cell_n_instances_c(this % ptr) - end function cell_n_instances - - function cell_distribcell_index(this) result(distribcell_index) - class(Cell), intent(in) :: this - integer(C_INT) :: distribcell_index - distribcell_index = cell_distribcell_index_c(this % ptr) - end function cell_distribcell_index - function cell_material_size(this) result(n) class(Cell), intent(in) :: this integer(C_INT) :: n @@ -293,13 +222,6 @@ contains sqrtkT = cell_sqrtkT_c(this % ptr, i) end function cell_sqrtkT - function cell_offset(this, map) result(offset) - class(Cell), intent(in) :: this - integer(C_INT), intent(in) :: map - integer(C_INT32_T) :: offset - offset = cell_offset_c(this % ptr, map) - end function cell_offset - !=============================================================================== ! GET_TEMPERATURES returns a list of temperatures that each nuclide/S(a,b) table ! appears at in the model. Later, this list is used to determine the actual diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 49c635235..e6ebe3058 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -59,12 +59,8 @@ module input_xml integer(C_INT32_T), intent(in), value :: univ_indx end subroutine count_cell_instances - subroutine prepare_distribcell_c(cell_list, n) & - bind(C, name="prepare_distribcell") - import C_INT32_T, C_INT - integer(C_INT), intent(in), value :: n - integer(C_INT32_T), intent(in) :: cell_list(n) - end subroutine prepare_distribcell_c + subroutine prepare_distribcell() bind(C) + end subroutine prepare_distribcell subroutine read_surfaces(node_ptr) bind(C) import C_PTR @@ -3148,33 +3144,4 @@ contains end subroutine read_multipole_data -!=============================================================================== -! PREPARE_DISTRIBCELL initializes any distribcell filters present and sets the -! offsets for distribcells -!=============================================================================== - - subroutine prepare_distribcell() - - integer :: i, j - type(SetInt) :: cell_list ! distribcells to track - integer(C_INT32_T), allocatable :: cell_list_c(:) - - ! Find all cells listed in a distribcell filter. - do i = 1, n_tallies - do j = 1, size(tallies(i) % obj % filter) - select type(filt => filters(tallies(i) % obj % filter(j)) % obj) - type is (DistribcellFilter) - call cell_list % add(filt % cell) - end select - end do - end do - - allocate(cell_list_c(cell_list % size())) - do i = 1, cell_list % size() - cell_list_c(i) = cell_list % get_item(i) - 1 - end do - call prepare_distribcell_c(cell_list_c, cell_list % size()) - - end subroutine prepare_distribcell - end module input_xml diff --git a/src/lattice.cpp b/src/lattice.cpp index 21f476850..14b679903 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -893,12 +893,6 @@ extern "C" { Lattice* lattice_pointer(int lat_ind) {return lattices[lat_ind];} int32_t lattice_id(Lattice *lat) {return lat->id_;} - - bool lattice_are_valid_indices(Lattice *lat, const int i_xyz[3]) - {return lat->are_valid_indices(i_xyz);} - - int32_t lattice_offset(Lattice *lat, int map, const int i_xyz[3]) - {return lat->offset(map, i_xyz);} } } // namespace openmc diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 944b15403..b0f54dd1e 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -6,6 +6,7 @@ #include "openmc/tallies/tally_filter_cell.h" #include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" +#include "openmc/tallies/tally_filter_distribcell.h" #include "openmc/tallies/tally_filter_mesh.h" #include "openmc/tallies/tally_filter_meshsurface.h" @@ -85,6 +86,8 @@ extern "C" { tally_filters.push_back(new CellbornFilter()); } else if (type_ == "cellfrom") { tally_filters.push_back(new CellFromFilter()); + } else if (type_ == "distribcell") { + tally_filters.push_back(new DistribcellFilter()); } else if (type_ == "mesh") { tally_filters.push_back(new MeshFilter()); } else if (type_ == "meshsurface") { diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index b6975c8a1..4a4b28685 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -1,16 +1,6 @@ module tally_filter_distribcell - use, intrinsic :: ISO_C_BINDING - - use constants - use dict_header, only: EMPTY - use error - use geometry_header - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none private @@ -20,150 +10,18 @@ module tally_filter_distribcell ! reside in. !=============================================================================== - type, public, extends(TallyFilter) :: DistribcellFilter + type, public, extends(CppTallyFilter) :: DistribcellFilter integer :: cell contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_distribcell - procedure :: to_statepoint => to_statepoint_distribcell - procedure :: text_label => text_label_distribcell procedure :: initialize => initialize_distribcell end type DistribcellFilter contains - subroutine from_xml(this, node) - class(DistribcellFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - n = node_word_count(node, "bins") - if (n /= 1) call fatal_error("Only one cell can be & - &specified per distribcell filter.") - - ! Store bins - call get_node_value(node, "bins", this % cell) - end subroutine from_xml - - subroutine get_all_bins_distribcell(this, p, estimator, match) - class(DistribcellFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: distribcell_index, offset, i - - distribcell_index = cells(this % cell) % distribcell_index() - offset = 0 - do i = 1, p % n_coord - if (cells(p % coord(i) % cell + 1) % type() == FILL_UNIVERSE) then - offset = offset + cells(p % coord(i) % cell + 1) & - % offset(distribcell_index) - elseif (cells(p % coord(i) % cell + 1) % type() == FILL_LATTICE) then - if (lattices(p % coord(i + 1) % lattice) % are_valid_indices([& - p % coord(i + 1) % lattice_x, & - p % coord(i + 1) % lattice_y, & - p % coord(i + 1) % lattice_z])) then - offset = offset + lattices(p % coord(i + 1) % lattice) & - % offset(distribcell_index, & - [p % coord(i + 1) % lattice_x, & - p % coord(i + 1) % lattice_y, & - p % coord(i + 1) % lattice_z]) - end if - end if - if (this % cell == p % coord(i) % cell + 1) then - call match % bins_push_back(offset + 1) - call match % weights_push_back(ONE) - return - end if - end do - end subroutine get_all_bins_distribcell - - subroutine to_statepoint_distribcell(this, filter_group) - class(DistribcellFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "distribcell") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", cells(this % cell) % id()) - end subroutine to_statepoint_distribcell - subroutine initialize_distribcell(this) class(DistribcellFilter), intent(inout) :: this - - integer :: id - integer :: val - - ! Convert id to index. - id = this % cell - val = cell_dict % get(id) - if (val /= EMPTY) then - this % cell = val - this % n_bins = cells(this % cell) % n_instances() - else - call fatal_error("Could not find cell " // trim(to_str(id)) & - &// " specified on tally filter.") - end if + call this % initialize_cpp_inner() + this % n_bins = this % n_bins_cpp() end subroutine initialize_distribcell - function text_label_distribcell(this, bin) result(label) - class(DistribcellFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = '' - call find_offset(this % cell, bin-1, label) - label = "Distributed Cell " // label - end function text_label_distribcell - -!=============================================================================== -! FIND_OFFSET (for distribcell) uses a given map number, a target cell ID, and -! a target offset to build a string which is the path from the base universe to -! the target cell with the given offset -!=============================================================================== - - subroutine find_offset(i_cell, target_offset, path) - integer, intent(in) :: i_cell ! The target cell index - integer, intent(in) :: target_offset ! Target offset - character(*), intent(inout) :: path ! Path to offset - - integer :: map ! Index in maps vector - integer :: i ! Index over cells - - integer(C_INT) :: path_len - character(kind=C_CHAR), allocatable, target :: path_c(:) - - interface - function distribcell_path_len(target_cell, map, target_offset, root_univ)& - bind(C) result(len) - import C_INT32_T, C_INT - integer(C_INT32_T), intent(in), value :: target_cell, map, & - target_offset, root_univ - integer(C_INT) :: len - end function distribcell_path_len - - subroutine distribcell_path(target_cell, map, target_offset, root_univ, & - path) bind(C) - import C_INT32_T, C_CHAR - integer(C_INT32_T), intent(in), value :: target_cell, map, & - target_offset, root_univ - character(kind=C_CHAR), intent(out) :: path(*) - end subroutine distribcell_path - end interface - - ! Get the distribcell index for this cell - map = cells(i_cell) % distribcell_index() - - path_len = distribcell_path_len(i_cell-1, map, target_offset, & - root_universe) - allocate(path_c(path_len)) - call distribcell_path(i_cell-1, map, target_offset, root_universe, & - path_c) - do i = 1, min(path_len, MAX_LINE_LEN) - if (path_c(i) == C_NULL_CHAR) exit - path(i:i) = path_c(i) - end do - end subroutine find_offset - end module tally_filter_distribcell From 9d0c1ff7e2dd7a1aaadfc5ad5a3b233015bbd5f9 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 11 Oct 2018 23:06:47 -0400 Subject: [PATCH 19/45] Reduce code duplication with TallyFilter::type() --- include/openmc/hdf5_interface.h | 6 ++ include/openmc/tallies/tally_filter.h | 13 +++- include/openmc/tallies/tally_filter_cell.h | 5 +- .../openmc/tallies/tally_filter_cellborn.h | 12 +--- .../openmc/tallies/tally_filter_cellfrom.h | 12 +--- .../openmc/tallies/tally_filter_distribcell.h | 5 +- include/openmc/tallies/tally_filter_mesh.h | 11 ++-- .../openmc/tallies/tally_filter_meshsurface.h | 65 +++++-------------- src/geometry_aux.cpp | 5 +- 9 files changed, 53 insertions(+), 81 deletions(-) diff --git a/include/openmc/hdf5_interface.h b/include/openmc/hdf5_interface.h index fa6460551..d3cc558ba 100644 --- a/include/openmc/hdf5_interface.h +++ b/include/openmc/hdf5_interface.h @@ -375,5 +375,11 @@ write_dataset(hid_t obj_id, const char* name, Position r) write_dataset(obj_id, name, buffer); } +inline void +write_dataset(hid_t obj_id, const char* name, std::string buffer) +{ + write_string(obj_id, name, buffer.c_str(), false); +} + } // namespace openmc #endif // OPENMC_HDF5_INTERFACE_H diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index e50e70fd1..73b8eda64 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -32,10 +32,10 @@ extern std::vector tally_filters; class TallyFilterMatch { public: - int i_bin; + //int i_bin; std::vector bins; std::vector weights; - bool bins_present; + //bool bins_present; }; //============================================================================== @@ -45,6 +45,8 @@ public: class TallyFilter { public: + virtual std::string type() const = 0; + virtual ~TallyFilter() = 0; virtual void from_xml(pugi::xml_node node) = 0; @@ -52,7 +54,12 @@ public: virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; - virtual void to_statepoint(hid_t filter_group) const {} + virtual void + to_statepoint(hid_t filter_group) const + { + write_dataset(filter_group, "type", type()); + write_dataset(filter_group, "n_bins", n_bins_); + } virtual std::string text_label(int bin) const = 0; diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index 972fafddb..cdf9a00cf 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -16,6 +16,8 @@ namespace openmc { class CellFilter : public TallyFilter { public: + virtual std::string type() const override {return "cell";} + virtual ~CellFilter() override = default; virtual void @@ -61,8 +63,7 @@ public: virtual void to_statepoint(hid_t filter_group) const override { - write_dataset(filter_group, "type", "cell"); - write_dataset(filter_group, "n_bins", n_bins_); + TallyFilter::to_statepoint(filter_group); std::vector cell_ids; for (auto c : cells_) cell_ids.push_back(cells[c]->id_); write_dataset(filter_group, "bins", cell_ids); diff --git a/include/openmc/tallies/tally_filter_cellborn.h b/include/openmc/tallies/tally_filter_cellborn.h index 814b4d6b9..92e8721e7 100644 --- a/include/openmc/tallies/tally_filter_cellborn.h +++ b/include/openmc/tallies/tally_filter_cellborn.h @@ -8,6 +8,8 @@ namespace openmc { class CellbornFilter : public CellFilter { public: + virtual std::string type() const override {return "cellborn";} + virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override @@ -20,16 +22,6 @@ public: } } - virtual void - to_statepoint(hid_t filter_group) const override - { - write_dataset(filter_group, "type", "cellborn"); - write_dataset(filter_group, "n_bins", n_bins_); - std::vector cell_ids; - for (auto c : cells_) cell_ids.push_back(cells[c]->id_); - write_dataset(filter_group, "bins", cell_ids); - } - virtual std::string text_label(int bin) const override { diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index a0eca932a..1b7e8f6db 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -9,6 +9,8 @@ namespace openmc { class CellFromFilter : public CellFilter { public: + virtual std::string type() const override {return "cellfrom";} + virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override @@ -23,16 +25,6 @@ public: } } - virtual void - to_statepoint(hid_t filter_group) const override - { - write_dataset(filter_group, "type", "cellfrom"); - write_dataset(filter_group, "n_bins", cells_.size()); - std::vector cell_ids; - for (auto c : cells_) cell_ids.push_back(cells[c]->id_); - write_dataset(filter_group, "bins", cell_ids); - } - virtual std::string text_label(int bin) const override { diff --git a/include/openmc/tallies/tally_filter_distribcell.h b/include/openmc/tallies/tally_filter_distribcell.h index b29520caa..97a016bc4 100644 --- a/include/openmc/tallies/tally_filter_distribcell.h +++ b/include/openmc/tallies/tally_filter_distribcell.h @@ -15,6 +15,8 @@ namespace openmc { class DistribcellFilter : public TallyFilter { public: + virtual std::string type() const override {return "distribcell";} + virtual ~DistribcellFilter() override = default; virtual void @@ -72,8 +74,7 @@ public: virtual void to_statepoint(hid_t filter_group) const override { - write_dataset(filter_group, "type", "distribcell"); - write_dataset(filter_group, "n_bins", n_bins_); + TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", cells[cell_]->id_); } diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index 01ffbae6f..0fba1ca0c 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -15,14 +15,18 @@ namespace openmc { class MeshFilter : public TallyFilter { public: + virtual std::string type() const override {return "mesh";} + virtual ~MeshFilter() override = default; virtual void from_xml(pugi::xml_node node) override { auto bins_ = get_node_array(node, "bins"); - if (bins_.size() != 1) - fatal_error("Only one mesh can be specified per mesh filter."); + if (bins_.size() != 1) { + fatal_error("Only one mesh can be specified per " + type() + + " mesh filter."); + } auto id = bins_[0]; auto search = mesh_map.find(id); @@ -56,8 +60,7 @@ public: virtual void to_statepoint(hid_t filter_group) const override { - write_dataset(filter_group, "type", "mesh"); - write_dataset(filter_group, "n_bins", n_bins_); + TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", meshes[mesh_]->id_); } diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 7b374b0a6..99a748481 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -7,33 +7,20 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/mesh.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/tally_filter_mesh.h" namespace openmc { -class MeshSurfaceFilter : public TallyFilter +class MeshSurfaceFilter : public MeshFilter { public: - virtual ~MeshSurfaceFilter() override = default; + virtual std::string type() const override {return "meshsurface";} virtual void from_xml(pugi::xml_node node) override { - auto bins_ = get_node_array(node, "bins"); - if (bins_.size() != 1) - fatal_error("Only one mesh can be specified per mesh filter."); - - auto id = bins_[0]; - auto search = mesh_map.find(id); - if (search != mesh_map.end()) { - mesh_ = search->second; - } else{ - std::stringstream err_msg; - err_msg << "Could not find cell " << id << " specified on tally filter."; - fatal_error(err_msg); - } - + MeshFilter::from_xml(node); n_bins_ = 4 * meshes[mesh_]->n_dimension_;; for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } @@ -46,14 +33,6 @@ public: for (auto b : match.bins) match.weights.push_back(1.0); } - virtual void - to_statepoint(hid_t filter_group) const override - { - write_dataset(filter_group, "type", "meshsurface"); - write_dataset(filter_group, "n_bins", n_bins_); - write_dataset(filter_group, "bins", meshes[mesh_]->id_); - } - virtual std::string text_label(int bin) const override { @@ -65,45 +44,37 @@ public: int i_surf = ((bin - 1) % (4 * n_dim)) + 1; // Get mesh index part of label. - int ijk[n_dim]; - mesh.get_indices_from_bin(i_mesh, ijk); - std::stringstream out; - out << "Mesh Index (" << ijk[0]; - if (n_dim > 1) out << ", " << ijk[1]; - if (n_dim > 2) out << ", " << ijk[2]; - out << ")"; + std::string out = MeshFilter::text_label(i_mesh); // Get surface part of label. if (i_surf == OUT_LEFT) { - out << " Outgoing, x-min"; + out += " Outgoing, x-min"; } else if (i_surf == IN_LEFT) { - out << " Incoming, x-min"; + out += " Incoming, x-min"; } else if (i_surf == OUT_RIGHT) { - out << " Outgoing, x-max"; + out += " Outgoing, x-max"; } else if (i_surf == IN_RIGHT) { - out << " Incoming, x-max"; + out += " Incoming, x-max"; } else if (i_surf == OUT_BACK) { - out << " Outgoing, y-min"; + out += " Outgoing, y-min"; } else if (i_surf == IN_BACK) { - out << " Incoming, y-min"; + out += " Incoming, y-min"; } else if (i_surf == OUT_FRONT) { - out << " Outgoing, y-max"; + out += " Outgoing, y-max"; } else if (i_surf == IN_FRONT) { - out << " Incoming, y-max"; + out += " Incoming, y-max"; } else if (i_surf == OUT_BOTTOM) { - out << " Outgoing, z-min"; + out += " Outgoing, z-min"; } else if (i_surf == IN_BOTTOM) { - out << " Incoming, z-min"; + out += " Incoming, z-min"; } else if (i_surf == OUT_TOP) { - out << " Outgoing, z-max"; + out += " Outgoing, z-max"; } else if (i_surf == IN_TOP) { - out << " Incoming, z-max"; + out += " Incoming, z-max"; } - return out.str(); + return out; } - - int32_t mesh_; }; } // namespace openmc diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 1da7bd78b..ee1949788 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -188,9 +188,8 @@ prepare_distribcell() // Find all cells listed in a DistribcellFilter. std::unordered_set distribcells; for (auto* filt : tally_filters) { - //TODO: replace this cast - auto* distrib_filt = dynamic_cast(filt); - if (distrib_filt) { + if (filt->type() == "distribcell") { + auto* distrib_filt = static_cast(filt); distribcells.insert(distrib_filt->cell_); } } From 00cb9e93ae1c062e792703b4c65cf677a1797a22 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 13 Oct 2018 19:53:57 -0400 Subject: [PATCH 20/45] Move azimuthal, mu, polar filters to C++ --- .../openmc/tallies/tally_filter_azimuthal.h | 86 ++++++++++++++ include/openmc/tallies/tally_filter_mu.h | 79 +++++++++++++ include/openmc/tallies/tally_filter_polar.h | 86 ++++++++++++++ src/tallies/tally_filter.cpp | 11 +- src/tallies/tally_filter_azimuthal.F90 | 107 +----------------- src/tallies/tally_filter_distribcell.F90 | 1 - src/tallies/tally_filter_mu.F90 | 97 +--------------- src/tallies/tally_filter_polar.F90 | 105 +---------------- 8 files changed, 264 insertions(+), 308 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_azimuthal.h create mode 100644 include/openmc/tallies/tally_filter_mu.h create mode 100644 include/openmc/tallies/tally_filter_polar.h diff --git a/include/openmc/tallies/tally_filter_azimuthal.h b/include/openmc/tallies/tally_filter_azimuthal.h new file mode 100644 index 000000000..182e32bc0 --- /dev/null +++ b/include/openmc/tallies/tally_filter_azimuthal.h @@ -0,0 +1,86 @@ +#ifndef OPENMC_TALLY_FILTER_AZIMUTHAL_H +#define OPENMC_TALLY_FILTER_AZIMUTHAL_H + +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/search.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class AzimuthalFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "azimuthal";} + + virtual ~AzimuthalFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [-pi,pi) evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for azimuthal filter must " + "be greater than 1."); + + double d_angle = 2.0 * PI / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = -PI + i * d_angle; + bins_[n_angle] = PI; + } + + n_bins_ = bins_.size() - 1; + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + double phi; + if (estimator == ESTIMATOR_TRACKLENGTH) { + phi = std::atan2(p->coord[0].uvw[1], p->coord[0].uvw[0]); + } else { + phi = std::atan2(p->last_uvw[1], p->last_uvw[0]); + } + + if (phi >= bins_[0] && phi <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), phi) + 1; + match.bins.push_back(bin); + match.weights.push_back(1); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + out << "Azimuthal Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); + } + +protected: + std::vector bins_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_AZIMUTHAL_H diff --git a/include/openmc/tallies/tally_filter_mu.h b/include/openmc/tallies/tally_filter_mu.h new file mode 100644 index 000000000..e76d56e43 --- /dev/null +++ b/include/openmc/tallies/tally_filter_mu.h @@ -0,0 +1,79 @@ +#ifndef OPENMC_TALLY_FILTER_MU_H +#define OPENMC_TALLY_FILTER_MU_H + +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/search.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class MuFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "mu";} + + virtual ~MuFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [-1,1) evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for mu filter must " + "be greater than 1."); + + double d_angle = 2.0 / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = -1 + i * d_angle; + bins_[n_angle] = PI; + } + + n_bins_ = bins_.size() - 1; + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + if (p->mu >= bins_[0] && p->mu <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->mu) + 1; + match.bins.push_back(bin); + match.weights.push_back(1); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + out << "Change-in-Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); + } + +protected: + std::vector bins_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_MU_H diff --git a/include/openmc/tallies/tally_filter_polar.h b/include/openmc/tallies/tally_filter_polar.h new file mode 100644 index 000000000..d9f003330 --- /dev/null +++ b/include/openmc/tallies/tally_filter_polar.h @@ -0,0 +1,86 @@ +#ifndef OPENMC_TALLY_FILTER_POLAR_H +#define OPENMC_TALLY_FILTER_POLAR_H + +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/search.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class PolarFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "polar";} + + virtual ~PolarFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [0,pi] evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for polar filter must " + "be greater than 1."); + + double d_angle = PI / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = i * d_angle; + bins_[n_angle] = PI; + } + + n_bins_ = bins_.size() - 1; + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + double theta; + if (estimator == ESTIMATOR_TRACKLENGTH) { + theta = std::acos(p->coord[0].uvw[2]); + } else { + theta = std::acos(p->last_uvw[2]); + } + + if (theta >= bins_[0] && theta <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), theta) + 1; + match.bins.push_back(bin); + match.weights.push_back(1); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + out << "Polar Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); + } + +protected: + std::vector bins_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_POLAR_H diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index b0f54dd1e..05de1b46c 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -3,12 +3,15 @@ #include #include "openmc/constants.h" // for MAX_LINE_LEN; +#include "openmc/tallies/tally_filter_azimuthal.h" #include "openmc/tallies/tally_filter_cell.h" #include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_distribcell.h" #include "openmc/tallies/tally_filter_mesh.h" #include "openmc/tallies/tally_filter_meshsurface.h" +#include "openmc/tallies/tally_filter_mu.h" +#include "openmc/tallies/tally_filter_polar.h" namespace openmc { @@ -80,7 +83,9 @@ extern "C" { allocate_filter(const char* type) { std::string type_ {type}; - if (type_ == "cell") { + if (type_ == "azimuthal") { + tally_filters.push_back(new AzimuthalFilter()); + } else if (type_ == "cell") { tally_filters.push_back(new CellFilter()); } else if (type_ == "cellborn") { tally_filters.push_back(new CellbornFilter()); @@ -92,6 +97,10 @@ extern "C" { tally_filters.push_back(new MeshFilter()); } else if (type_ == "meshsurface") { tally_filters.push_back(new MeshSurfaceFilter()); + } else if (type_ == "mu") { + tally_filters.push_back(new MuFilter()); + } else if (type_ == "polar") { + tally_filters.push_back(new PolarFilter()); } else { return nullptr; } diff --git a/src/tallies/tally_filter_azimuthal.F90 b/src/tallies/tally_filter_azimuthal.F90 index 5dc5f9e2c..69513c26d 100644 --- a/src/tallies/tally_filter_azimuthal.F90 +++ b/src/tallies/tally_filter_azimuthal.F90 @@ -1,120 +1,15 @@ module tally_filter_azimuthal - use, intrinsic :: ISO_C_BINDING - - use algorithm, only: binary_search - use constants - use error, only: fatal_error - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! AZIMUTHALFILTER bins the incident neutron azimuthal angle (relative to the ! global xy-plane). !=============================================================================== - type, public, extends(TallyFilter) :: AzimuthalFilter - real(8), allocatable :: bins(:) - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_azimuthal - procedure :: to_statepoint => to_statepoint_azimuthal - procedure :: text_label => text_label_azimuthal + type, extends(CppTallyFilter) :: AzimuthalFilter end type AzimuthalFilter -contains - - subroutine from_xml(this, node) - class(AzimuthalFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: i - integer :: n - integer :: n_angle - real(8) :: d_angle - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - 1 - allocate(this % bins(n)) - call get_node_array(node, "bins", this % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [-pi,pi) evenly with the input being the number of - ! bins - if (n == 1) then - n_angle = int(this % bins(1)) - if (n_angle > 1) then - this % n_bins = n_angle - d_angle = TWO * PI / n_angle - deallocate(this % bins) - allocate(this % bins(n_angle + 1)) - do i = 1, n_angle - this % bins(i) = -PI + (i - 1) * d_angle - end do - this % bins(n_angle + 1) = PI - else - call fatal_error("Number of bins for azimuthal filter must be& - & greater than 1.") - end if - end if - end subroutine from_xml - - subroutine get_all_bins_azimuthal(this, p, estimator, match) - class(AzimuthalFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n - integer :: bin - real(8) :: phi - - n = this % n_bins - - ! Make sure the correct direction vector is used. - if (estimator == ESTIMATOR_TRACKLENGTH) then - phi = atan2(p % coord(1) % uvw(2), p % coord(1) % uvw(1)) - else - phi = atan2(p % last_uvw(2), p % last_uvw(1)) - end if - - ! Search to find azimuthal angle bin. - bin = binary_search(this % bins, n + 1, phi) - if (bin /= NO_BIN_FOUND) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - - end subroutine get_all_bins_azimuthal - - subroutine to_statepoint_azimuthal(this, filter_group) - class(AzimuthalFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "azimuthal") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % bins) - end subroutine to_statepoint_azimuthal - - function text_label_azimuthal(this, bin) result(label) - class(AzimuthalFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - real(8) :: E0, E1 - - E0 = this % bins(bin) - E1 = this % bins(bin + 1) - label = "Azimuthal Angle [" // trim(to_str(E0)) // ", " & - // trim(to_str(E1)) // ")" - end function text_label_azimuthal - end module tally_filter_azimuthal diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index 4a4b28685..8b25e2747 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -11,7 +11,6 @@ module tally_filter_distribcell !=============================================================================== type, public, extends(CppTallyFilter) :: DistribcellFilter - integer :: cell contains procedure :: initialize => initialize_distribcell end type DistribcellFilter diff --git a/src/tallies/tally_filter_mu.F90 b/src/tallies/tally_filter_mu.F90 index ecd0a75af..8f8d14a7d 100644 --- a/src/tallies/tally_filter_mu.F90 +++ b/src/tallies/tally_filter_mu.F90 @@ -1,110 +1,15 @@ module tally_filter_mu - use, intrinsic :: ISO_C_BINDING - - use algorithm, only: binary_search - use constants, only: ONE, TWO, MAX_LINE_LEN, NO_BIN_FOUND - use error, only: fatal_error - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! MUFILTER bins the incoming-outgoing direction cosine. This is only used for ! scatter reactions. !=============================================================================== - type, public, extends(TallyFilter) :: MuFilter - real(8), allocatable :: bins(:) - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_mu - procedure :: to_statepoint => to_statepoint_mu - procedure :: text_label => text_label_mu + type, extends(CppTallyFilter) :: MuFilter end type MuFilter -contains - - subroutine from_xml(this, node) - class(MuFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: i - integer :: n_angle - integer :: n - real(8) :: d_angle - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - 1 - allocate(this % bins(n)) - call get_node_array(node, "bins", this % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [-1,1] evenly with the input being the number of bins - if (n == 1) then - n_angle = int(this % bins(1)) - if (n_angle > 1) then - this % n_bins = n_angle - d_angle = TWO / n_angle - deallocate(this % bins) - allocate(this % bins(n_angle + 1)) - do i = 1, n_angle - this % bins(i) = -ONE + (i - 1) * d_angle - end do - this % bins(n_angle + 1) = ONE - else - call fatal_error("Number of bins for mu filter must be& - & greater than 1.") - end if - end if - end subroutine from_xml - - subroutine get_all_bins_mu(this, p, estimator, match) - class(MuFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n - integer :: bin - - n = this % n_bins - - ! Search to find incoming energy bin. - bin = binary_search(this % bins, n + 1, p % mu) - if (bin /= NO_BIN_FOUND) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - end subroutine get_all_bins_mu - - subroutine to_statepoint_mu(this, filter_group) - class(MuFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "mu") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % bins) - end subroutine to_statepoint_mu - - function text_label_mu(this, bin) result(label) - class(MuFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - real(8) :: E0, E1 - - E0 = this % bins(bin) - E1 = this % bins(bin + 1) - label = "Change-in-Angle [" // trim(to_str(E0)) // ", " & - // trim(to_str(E1)) // ")" - end function text_label_mu - end module tally_filter_mu diff --git a/src/tallies/tally_filter_polar.F90 b/src/tallies/tally_filter_polar.F90 index 46627230a..957f0f51c 100644 --- a/src/tallies/tally_filter_polar.F90 +++ b/src/tallies/tally_filter_polar.F90 @@ -1,118 +1,15 @@ module tally_filter_polar - use, intrinsic :: ISO_C_BINDING - - use algorithm, only: binary_search - use constants - use error, only: fatal_error - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! POLARFILTER bins the incident neutron polar angle (relative to the global ! z-axis). !=============================================================================== - type, public, extends(TallyFilter) :: PolarFilter - real(8), allocatable :: bins(:) - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_polar - procedure :: to_statepoint => to_statepoint_polar - procedure :: text_label => text_label_polar + type, extends(CppTallyFilter) :: PolarFilter end type PolarFilter -contains - - subroutine from_xml(this, node) - class(PolarFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: i - integer :: n_angle - integer :: n - real(8) :: d_angle - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - 1 - allocate(this % bins(n)) - call get_node_array(node, "bins", this % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [0,pi] evenly with the input being the number of bins - if (n == 1) then - n_angle = int(this % bins(1)) - if (n_angle > 1) then - this % n_bins = n_angle - d_angle = PI / real(n_angle,8) - deallocate(this % bins) - allocate(this % bins(n_angle + 1)) - do i = 1, n_angle - this % bins(i) = (i - 1) * d_angle - end do - this % bins(n_angle + 1) = PI - else - call fatal_error("Number of bins for polar filter must be& - & greater than 1.") - end if - end if - end subroutine from_xml - - subroutine get_all_bins_polar(this, p, estimator, match) - class(PolarFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n - integer :: bin - real(8) :: theta - - n = this % n_bins - - ! Make sure the correct direction vector is used. - if (estimator == ESTIMATOR_TRACKLENGTH) then - theta = acos(p % coord(1) % uvw(3)) - else - theta = acos(p % last_uvw(3)) - end if - - ! Search to find polar angle bin. - bin = binary_search(this % bins, n + 1, theta) - if (bin /= NO_BIN_FOUND) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - end subroutine get_all_bins_polar - - subroutine to_statepoint_polar(this, filter_group) - class(PolarFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "polar") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % bins) - end subroutine to_statepoint_polar - - function text_label_polar(this, bin) result(label) - class(PolarFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - real(8) :: E0, E1 - - E0 = this % bins(bin) - E1 = this % bins(bin + 1) - label = "Polar Angle [" // trim(to_str(E0)) // ", " // trim(to_str(E1)) & - // ")" - end function text_label_polar - end module tally_filter_polar From 46ea32139b092d1e164a7a40679ef439b61892f9 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 14 Oct 2018 11:56:56 -0400 Subject: [PATCH 21/45] Move MaterialFilter to C++ --- include/openmc/material.h | 2 +- .../openmc/tallies/tally_filter_material.h | 81 +++++++++++ src/cell.cpp | 2 +- src/material.cpp | 10 +- src/tallies/tally_filter.cpp | 21 +++ src/tallies/tally_filter_material.F90 | 132 +++--------------- 6 files changed, 130 insertions(+), 118 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_material.h diff --git a/include/openmc/material.h b/include/openmc/material.h index 1af6f8597..69647dec3 100644 --- a/include/openmc/material.h +++ b/include/openmc/material.h @@ -24,7 +24,7 @@ extern std::unordered_map material_map; class Material { public: - int32_t id; //!< Unique ID + int32_t id_; //!< Unique ID double volume_ {-1.0}; //!< Volume in [cm^3] //! \brief Default temperature for cells containing this material. diff --git a/include/openmc/tallies/tally_filter_material.h b/include/openmc/tallies/tally_filter_material.h new file mode 100644 index 000000000..3fd589375 --- /dev/null +++ b/include/openmc/tallies/tally_filter_material.h @@ -0,0 +1,81 @@ +#ifndef OPENMC_TALLY_FILTER_MATERIAL_H +#define OPENMC_TALLY_FILTER_MATERIAL_H + +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/material.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class MaterialFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "material";} + + virtual ~MaterialFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + materials_ = get_node_array(node, "bins"); + n_bins_ = materials_.size(); + } + + virtual void + initialize() override + { + for (auto& m : materials_) { + auto search = material_map.find(m); + if (search != material_map.end()) { + m = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find material " << m + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < materials_.size(); i++) { + map_[materials_[i]] = i; + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + auto search = map_.find(p->material - 1); + if (search != map_.end()) { + // TODO: off-by-one + match.bins.push_back(search->second + 1); + match.weights.push_back(1); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + std::vector material_ids; + for (auto c : materials_) material_ids.push_back(materials[c]->id_); + write_dataset(filter_group, "bins", material_ids); + } + + virtual std::string + text_label(int bin) const override + { + return "Material " + std::to_string(materials[materials_[bin-1]]->id_); + } + + std::vector materials_; + std::unordered_map map_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_MATERIAL_H diff --git a/src/cell.cpp b/src/cell.cpp index 545bb7f58..8896cde98 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -476,7 +476,7 @@ CSGCell::to_hdf5(hid_t cell_group) const std::vector mat_ids; for (auto i_mat : material_) { if (i_mat != MATERIAL_VOID) { - mat_ids.push_back(materials[i_mat]->id); + mat_ids.push_back(materials[i_mat]->id_); } else { mat_ids.push_back(MATERIAL_VOID); } diff --git a/src/material.cpp b/src/material.cpp index 1a0c2d207..fb52d5cd9 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -23,7 +23,7 @@ std::unordered_map material_map; Material::Material(pugi::xml_node node) { if (check_for_node(node, "id")) { - id = std::stoi(get_node_value(node, "id")); + id_ = std::stoi(get_node_value(node, "id")); } else { fatal_error("Must specify id of material in materials XML file."); } @@ -52,7 +52,7 @@ read_materials(pugi::xml_node* node) // Populate the material map. for (int i = 0; i < materials.size(); i++) { - int32_t mid = materials[i]->id; + int32_t mid = materials[i]->id_; auto search = material_map.find(mid); if (search == material_map.end()) { material_map[mid] = i; @@ -78,7 +78,7 @@ openmc_material_get_volume(int32_t index, double* volume) return 0; } else { std::stringstream msg; - msg << "Volume for material with ID=" << m->id << " not set."; + msg << "Volume for material with ID=" << m->id_ << " not set."; set_errmsg(msg); return OPENMC_E_UNASSIGNED; } @@ -113,11 +113,11 @@ openmc_material_set_volume(int32_t index, double volume) extern "C" { Material* material_pointer(int32_t indx) {return materials[indx];} - int32_t material_id(Material* mat) {return mat->id;} + int32_t material_id(Material* mat) {return mat->id_;} void material_set_id(Material* mat, int32_t id, int32_t index) { - mat->id = id; + mat->id_ = id; //TODO: off-by-one material_map[id] = index - 1; } diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 05de1b46c..dfe241cd5 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -8,6 +8,7 @@ #include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_distribcell.h" +#include "openmc/tallies/tally_filter_material.h" #include "openmc/tallies/tally_filter_mesh.h" #include "openmc/tallies/tally_filter_meshsurface.h" #include "openmc/tallies/tally_filter_mu.h" @@ -93,6 +94,8 @@ extern "C" { tally_filters.push_back(new CellFromFilter()); } else if (type_ == "distribcell") { tally_filters.push_back(new DistribcellFilter()); + } else if (type_ == "material") { + tally_filters.push_back(new MaterialFilter()); } else if (type_ == "mesh") { tally_filters.push_back(new MeshFilter()); } else if (type_ == "meshsurface") { @@ -140,6 +143,24 @@ extern "C" { *n = filt->cells_.size(); } + void + material_filter_get_bins(MaterialFilter* filt, int32_t** bins, int32_t* n) + { + *bins = filt->materials_.data(); + *n = filt->materials_.size(); + } + + void + material_filter_set_bins(MaterialFilter* filt, int32_t n, int32_t* bins) + { + filt->materials_.clear(); + filt->materials_.resize(n); + for (int i = 0; i < n; i++) filt->materials_[i] = bins[i]; + filt->n_bins_ = filt->materials_.size(); + filt->map_.clear(); + for (int i = 0; i < n; i++) filt->map_[bins[i]] = i; + } + int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} void diff --git a/src/tallies/tally_filter_material.F90 b/src/tallies/tally_filter_material.F90 index 2b9a79331..9b1b83d2d 100644 --- a/src/tallies/tally_filter_material.F90 +++ b/src/tallies/tally_filter_material.F90 @@ -2,117 +2,20 @@ module tally_filter_material use, intrinsic :: ISO_C_BINDING - use constants - use dict_header, only: DictIntInt, EMPTY use error - use hdf5_interface - use material_header, only: materials, material_dict - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private - public :: openmc_material_filter_get_bins - public :: openmc_material_filter_set_bins !=============================================================================== ! MATERIAL specifies which material tally events reside in. !=============================================================================== - type, public, extends(TallyFilter) :: MaterialFilter - integer, allocatable :: materials(:) - type(DictIntInt) :: map - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_material - procedure :: to_statepoint => to_statepoint_material - procedure :: text_label => text_label_material - procedure :: initialize => initialize_material + type, extends(CppTallyFilter) :: MaterialFilter end type MaterialFilter contains - subroutine from_xml(this, node) - class(MaterialFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % materials(n)) - call get_node_array(node, "bins", this % materials) - end subroutine from_xml - - subroutine get_all_bins_material(this, p, estimator, match) - class(MaterialFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: val - - val = this % map % get(p % material) - if (val /= EMPTY) then - call match % bins_push_back(val) - call match % weights_push_back(ONE) - end if - - end subroutine get_all_bins_material - - subroutine to_statepoint_material(this, filter_group) - class(MaterialFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - integer :: i - integer, allocatable :: material_ids(:) - - call write_dataset(filter_group, "type", "material") - call write_dataset(filter_group, "n_bins", this % n_bins) - - allocate(material_ids(size(this % materials))) - do i = 1, size(this % materials) - material_ids(i) = materials(this % materials(i)) % id() - end do - call write_dataset(filter_group, "bins", material_ids) - end subroutine to_statepoint_material - - subroutine initialize_material(this) - class(MaterialFilter), intent(inout) :: this - - integer :: i, id - integer :: val - - ! Convert ids to indices. - do i = 1, this % n_bins - id = this % materials(i) - val = material_dict % get(id) - if (val /= EMPTY) then - this % materials(i) = val - else - call fatal_error("Could not find material " // trim(to_str(id)) & - &// " specified on a tally filter.") - end if - end do - - ! Generate mapping from material indices to filter bins. - do i = 1, this % n_bins - call this % map % set(this % materials(i), i) - end do - end subroutine initialize_material - - function text_label_material(this, bin) result(label) - class(MaterialFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Material " // to_str(materials(this % materials(bin)) % id()) - end function text_label_material - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -124,12 +27,20 @@ contains integer(C_INT32_T), intent(out) :: n integer(C_INT) :: err + interface + subroutine material_filter_get_bins(filt, bins, n) bind(C) + import C_PTR, C_INT32_T + type(C_PTR), value :: filt + type(C_PTR) :: bins + integer(C_INT32_T) :: n + end subroutine material_filter_get_bins + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MaterialFilter) - bins = C_LOC(f % materials) - n = size(f % materials) + call material_filter_get_bins(f % ptr, bins, n) err = 0 class default err = E_INVALID_TYPE @@ -147,22 +58,21 @@ contains integer(C_INT32_T), intent(in) :: bins(n) integer(C_INT) :: err - integer :: i + interface + subroutine material_filter_set_bins(filt, n, bins) bind(C) + import C_PTR, C_INT32_T + type(C_PTR), value :: filt + integer(C_INT32_T), value :: n + integer(C_INT32_T) :: bins(n) + end subroutine material_filter_set_bins + end interface err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (MaterialFilter) - f % n_bins = n - if (allocated(f % materials)) deallocate(f % materials) - allocate(f % materials(n)) - f % materials(:) = bins - - ! Generate mapping from material indices to filter bins. - call f % map % clear() - do i = 1, n - call f % map % set(f % materials(i), i) - end do + call material_filter_set_bins(f % ptr, n, bins) + f % n_bins = f % n_bins_cpp() class default err = E_INVALID_TYPE From 6c4891d59187a313deaa07ef3ed9b2ff3b689c9a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 14 Oct 2018 13:01:57 -0400 Subject: [PATCH 22/45] Move UniverseFilter to C++ --- .../openmc/tallies/tally_filter_material.h | 1 + .../openmc/tallies/tally_filter_universe.h | 84 ++++++++++++++ src/geometry_header.F90 | 2 - src/input_xml.F90 | 2 - src/tallies/tally_filter.cpp | 3 + src/tallies/tally_filter_universe.F90 | 106 +----------------- 6 files changed, 89 insertions(+), 109 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_universe.h diff --git a/include/openmc/tallies/tally_filter_material.h b/include/openmc/tallies/tally_filter_material.h index 3fd589375..92f2df640 100644 --- a/include/openmc/tallies/tally_filter_material.h +++ b/include/openmc/tallies/tally_filter_material.h @@ -1,6 +1,7 @@ #ifndef OPENMC_TALLY_FILTER_MATERIAL_H #define OPENMC_TALLY_FILTER_MATERIAL_H +#include #include #include #include diff --git a/include/openmc/tallies/tally_filter_universe.h b/include/openmc/tallies/tally_filter_universe.h new file mode 100644 index 000000000..c61301c36 --- /dev/null +++ b/include/openmc/tallies/tally_filter_universe.h @@ -0,0 +1,84 @@ +#ifndef OPENMC_TALLY_FILTER_UNIVERSE_H +#define OPENMC_TALLY_FILTER_UNIVERSE_H + +#include +#include +#include +#include + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class UniverseFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "universe";} + + virtual ~UniverseFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + universes_ = get_node_array(node, "bins"); + n_bins_ = universes_.size(); + } + + virtual void + initialize() override + { + for (auto& u : universes_) { + auto search = universe_map.find(u); + if (search != universe_map.end()) { + u = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find universe " << u + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < universes_.size(); i++) { + map_[universes_[i]] = i; + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + for (int i = 0; i < p->n_coord; i++) { + auto search = map_.find(p->coord[i].universe); + if (search != map_.end()) { + // TODO: off-by-one + match.bins.push_back(search->second + 1); + match.weights.push_back(1); + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + std::vector universe_ids; + for (auto u : universes_) universe_ids.push_back(universes[u]->id_); + write_dataset(filter_group, "bins", universe_ids); + } + + virtual std::string + text_label(int bin) const override + { + return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); + } + + std::vector universes_; + std::unordered_map map_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_UNIVERSE_H diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 89cfbcf2a..9af1fcbaa 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -153,7 +153,6 @@ module geometry_header ! Dictionaries which map user IDs to indices in the global arrays type(DictIntInt) :: cell_dict - type(DictIntInt) :: universe_dict type(DictIntInt) :: lattice_dict contains @@ -305,7 +304,6 @@ contains if (allocated(lattices)) deallocate(lattices) call cell_dict % clear() - call universe_dict % clear() call lattice_dict % clear() end subroutine free_memory_geometry diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e6ebe3058..8a3682c05 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -391,7 +391,6 @@ contains if (.not. cells_in_univ_dict % has(univ_id)) then n_universes = n_universes + 1 n_cells_in_univ = 1 - call universe_dict % set(univ_id, n_universes) call univ_ids % push_back(univ_id) else n_cells_in_univ = 1 + cells_in_univ_dict % get(univ_id) @@ -561,7 +560,6 @@ contains if (.not. cells_in_univ_dict % has(univ_id)) then n_universes = n_universes + 1 n_cells_in_univ = 1 - call universe_dict % set(univ_id, n_universes - 1) call univ_ids % push_back(univ_id) else n_cells_in_univ = 1 + cells_in_univ_dict % get(univ_id) diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index dfe241cd5..c5d5600a1 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -13,6 +13,7 @@ #include "openmc/tallies/tally_filter_meshsurface.h" #include "openmc/tallies/tally_filter_mu.h" #include "openmc/tallies/tally_filter_polar.h" +#include "openmc/tallies/tally_filter_universe.h" namespace openmc { @@ -104,6 +105,8 @@ extern "C" { tally_filters.push_back(new MuFilter()); } else if (type_ == "polar") { tally_filters.push_back(new PolarFilter()); + } else if (type_ == "universe") { + tally_filters.push_back(new UniverseFilter()); } else { return nullptr; } diff --git a/src/tallies/tally_filter_universe.F90 b/src/tallies/tally_filter_universe.F90 index bd42d494a..2f3d5011c 100644 --- a/src/tallies/tally_filter_universe.F90 +++ b/src/tallies/tally_filter_universe.F90 @@ -1,118 +1,14 @@ module tally_filter_universe - use, intrinsic :: ISO_C_BINDING - - use constants, only: ONE, MAX_LINE_LEN - use dict_header, only: EMPTY - use error, only: fatal_error - use hdf5_interface - use geometry_header - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! UNIVERSEFILTER specifies which geometric universes tally events reside in. !=============================================================================== - type, public, extends(TallyFilter) :: UniverseFilter - integer, allocatable :: universes(:) - type(DictIntInt) :: map - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_universe - procedure :: to_statepoint => to_statepoint_universe - procedure :: text_label => text_label_universe - procedure :: initialize => initialize_universe + type, extends(CppTallyFilter) :: UniverseFilter end type UniverseFilter -contains - - subroutine from_xml(this, node) - class(UniverseFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % universes(n)) - call get_node_array(node, "bins", this % universes) - end subroutine from_xml - - subroutine get_all_bins_universe(this, p, estimator, match) - class(UniverseFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - integer :: val - - ! Iterate over coordinate levels to see which universes match - do i = 1, p % n_coord - val = this % map % get(p % coord(i) % universe) - if (val /= EMPTY) then - call match % bins_push_back(val) - call match % weights_push_back(ONE) - end if - end do - - end subroutine get_all_bins_universe - - subroutine to_statepoint_universe(this, filter_group) - class(UniverseFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - integer :: i - integer, allocatable :: universe_ids(:) - - call write_dataset(filter_group, "type", "universe") - call write_dataset(filter_group, "n_bins", this % n_bins) - - allocate(universe_ids(size(this % universes))) - do i = 1, size(this % universes) - universe_ids(i) = universe_id(this % universes(i)) - end do - call write_dataset(filter_group, "bins", universe_ids) - end subroutine to_statepoint_universe - - subroutine initialize_universe(this) - class(UniverseFilter), intent(inout) :: this - - integer :: i, id - integer :: val - - ! Convert ids to indices. - do i = 1, this % n_bins - id = this % universes(i) - val = universe_dict % get(id) - if (val /= EMPTY) then - this % universes(i) = val - else - call fatal_error("Could not find universe " // trim(to_str(id)) & - &// " specified on a tally filter.") - end if - end do - - ! Generate mapping from universe indices to filter bins. - do i = 1, this % n_bins - call this % map % set(this % universes(i), i) - end do - end subroutine initialize_universe - - function text_label_universe(this, bin) result(label) - class(UniverseFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Universe " // to_str(universe_id(this % universes(bin))) - end function text_label_universe - end module tally_filter_universe From ea0a91b0e6c88eacdaca7978f6a944804ec998cb Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 14 Oct 2018 13:28:03 -0400 Subject: [PATCH 23/45] Move SurfaceFilter to C++ --- include/openmc/tallies/tally_filter_surface.h | 85 +++++++++++++++++ src/input_xml.F90 | 5 - src/surface_header.F90 | 5 - src/tallies/tally_filter.cpp | 3 + src/tallies/tally_filter_surface.F90 | 95 +------------------ 5 files changed, 89 insertions(+), 104 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_surface.h diff --git a/include/openmc/tallies/tally_filter_surface.h b/include/openmc/tallies/tally_filter_surface.h new file mode 100644 index 000000000..a80fcaf12 --- /dev/null +++ b/include/openmc/tallies/tally_filter_surface.h @@ -0,0 +1,85 @@ +#ifndef OPENMC_TALLY_FILTER_SURFACE_H +#define OPENMC_TALLY_FILTER_SURFACE_H + +#include +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/surface.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class SurfaceFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "surface";} + + virtual ~SurfaceFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + surfaces_ = get_node_array(node, "bins"); + n_bins_ = surfaces_.size(); + } + + virtual void + initialize() override + { + for (auto& s : surfaces_) { + auto search = surface_map.find(s); + if (search != surface_map.end()) { + s = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find surface " << s + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < surfaces_.size(); i++) { + map_[surfaces_[i]] = i; + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + auto search = map_.find(std::abs(p->surface)-1); + if (search != map_.end()) { + match.bins.push_back(search->second + 1); + if (p->surface < 0) { + match.weights.push_back(-1); + } else { + match.weights.push_back(1); + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + std::vector surface_ids; + for (auto c : surfaces_) surface_ids.push_back(surfaces[c]->id_); + write_dataset(filter_group, "bins", surface_ids); + } + + virtual std::string + text_label(int bin) const override + { + return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); + } + + std::vector surfaces_; + std::unordered_map map_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_SURFACE_H diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8a3682c05..d4fd5dfa4 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -468,9 +468,6 @@ contains surfaces(i) % ptr = surface_pointer(i - 1); if (surfaces(i) % bc() /= BC_TRANSMIT) boundary_exists = .true. - - ! Add surface to dictionary - call surface_dict % set(surfaces(i) % id(), i) end do ! Check to make sure a boundary condition was applied to at least one @@ -628,8 +625,6 @@ contains do i = 1, n_surfaces surfaces(i) % ptr = surface_pointer(i - 1); - ! Add surface to dictionary - call surface_dict % set(surfaces(i) % id(), i) end do end subroutine allocate_surfaces diff --git a/src/surface_header.F90 b/src/surface_header.F90 index 9d7e11461..a2ef9c056 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -2,7 +2,6 @@ module surface_header use, intrinsic :: ISO_C_BINDING - use dict_header, only: DictIntInt use hdf5_interface implicit none @@ -83,9 +82,6 @@ module surface_header type(Surface), allocatable, target :: surfaces(:) - ! Dictionary that maps user IDs to indices in 'surfaces' - type(DictIntInt) :: surface_dict - contains pure function surface_id(this) result(id) @@ -128,7 +124,6 @@ contains subroutine free_memory_surfaces() if (allocated(surfaces)) deallocate(surfaces) - call surface_dict % clear() call free_memory_surfaces_c() end subroutine free_memory_surfaces diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index c5d5600a1..d66505d47 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -13,6 +13,7 @@ #include "openmc/tallies/tally_filter_meshsurface.h" #include "openmc/tallies/tally_filter_mu.h" #include "openmc/tallies/tally_filter_polar.h" +#include "openmc/tallies/tally_filter_surface.h" #include "openmc/tallies/tally_filter_universe.h" @@ -105,6 +106,8 @@ extern "C" { tally_filters.push_back(new MuFilter()); } else if (type_ == "polar") { tally_filters.push_back(new PolarFilter()); + } else if (type_ == "surface") { + tally_filters.push_back(new SurfaceFilter()); } else if (type_ == "universe") { tally_filters.push_back(new UniverseFilter()); } else { diff --git a/src/tallies/tally_filter_surface.F90 b/src/tallies/tally_filter_surface.F90 index d545d4672..1dcb56022 100644 --- a/src/tallies/tally_filter_surface.F90 +++ b/src/tallies/tally_filter_surface.F90 @@ -1,109 +1,16 @@ module tally_filter_surface - use, intrinsic :: ISO_C_BINDING - - use constants, only: ONE, MAX_LINE_LEN - use dict_header, only: EMPTY - use error, only: fatal_error - use hdf5_interface - use surface_header - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! SURFACEFILTER specifies which surface particles are crossing !=============================================================================== - type, public, extends(TallyFilter) :: SurfaceFilter - integer, allocatable :: surfaces(:) - + type, extends(CppTallyFilter) :: SurfaceFilter ! True if this filter is used for surface currents logical :: current = .false. - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_surface - procedure :: to_statepoint => to_statepoint_surface - procedure :: text_label => text_label_surface - procedure :: initialize => initialize_surface end type SurfaceFilter -contains - - subroutine from_xml(this, node) - class(SurfaceFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % surfaces(n)) - call get_node_array(node, "bins", this % surfaces) - end subroutine from_xml - - subroutine get_all_bins_surface(this, p, estimator, match) - class(SurfaceFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - - do i = 1, this % n_bins - if (abs(p % surface) == this % surfaces(i)) then - call match % bins_push_back(i) - if (p % surface < 0) then - call match % weights_push_back(-ONE) - else - call match % weights_push_back(ONE) - end if - exit - end if - end do - - end subroutine get_all_bins_surface - - subroutine to_statepoint_surface(this, filter_group) - class(SurfaceFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "surface") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % surfaces) - end subroutine to_statepoint_surface - - subroutine initialize_surface(this) - class(SurfaceFilter), intent(inout) :: this - - integer :: i, id - integer :: val - - ! Convert ids to indices. - do i = 1, this % n_bins - id = this % surfaces(i) - val = surface_dict % get(id) - if (val /= EMPTY) then - this % surfaces(i) = val - else - call fatal_error("Could not find surface " // trim(to_str(id)) & - &// " specified on tally filter.") - end if - end do - end subroutine initialize_surface - - function text_label_surface(this, bin) result(label) - class(SurfaceFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Surface " // to_str(surfaces(this % surfaces(bin)) % id()) - end function text_label_surface - end module tally_filter_surface From 77cef923b5552a86bd309caec935f238efe3bb1f Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 14 Oct 2018 14:21:37 -0400 Subject: [PATCH 24/45] Fix MaterialFilter C-API indexing error --- openmc/capi/filter.py | 6 ++++-- tests/unit_tests/test_capi.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index 8d9d794d1..5f6e74bbc 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -238,13 +238,15 @@ class MaterialFilter(Filter): materials = POINTER(c_int32)() n = c_int32() _dll.openmc_material_filter_get_bins(self._index, materials, n) - return [Material(index=materials[i]) for i in range(n.value)] + #TODO: fix this off-by-one when materials become 0-indexed + return [Material(index=materials[i]+1) for i in range(n.value)] @bins.setter def bins(self, materials): # Get material indices as int32_t[] n = len(materials) - bins = (c_int32*n)(*(m._index for m in materials)) + #TODO: fix this off-by-one when materials become 0-indexed + bins = (c_int32*n)(*(m._index-1 for m in materials)) _dll.openmc_material_filter_set_bins(self._index, n, bins) diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index ae2d92719..059557dbf 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -168,6 +168,8 @@ def test_tally(capi_init): openmc.capi.MaterialFilter(uid=1) mats = openmc.capi.materials f = openmc.capi.MaterialFilter([mats[2], mats[1]]) + assert f.bins[0] == mats[2] + assert f.bins[1] == mats[1] t.filters = [f] assert t.filters == [f] From 657773c9ebbccf7382016ec12614ce62a75a74e0 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 14 Oct 2018 18:53:13 -0400 Subject: [PATCH 25/45] Move Legendre and sph harmonics filters to C++ --- .../openmc/tallies/tally_filter_legendre.h | 57 +++++++ .../openmc/tallies/tally_filter_sph_harm.h | 106 ++++++++++++ src/tallies/tally_filter.cpp | 30 +++- src/tallies/tally_filter_legendre.F90 | 82 +++------ src/tallies/tally_filter_sph_harm.F90 | 155 +++++------------- src/tallies/tally_header.F90 | 2 +- 6 files changed, 256 insertions(+), 176 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_legendre.h create mode 100644 include/openmc/tallies/tally_filter_sph_harm.h diff --git a/include/openmc/tallies/tally_filter_legendre.h b/include/openmc/tallies/tally_filter_legendre.h new file mode 100644 index 000000000..f70cdf663 --- /dev/null +++ b/include/openmc/tallies/tally_filter_legendre.h @@ -0,0 +1,57 @@ +#ifndef OPENMC_TALLY_FILTER_LEGENDRE_H +#define OPENMC_TALLY_FILTER_LEGENDRE_H + +#include + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/math_functions.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class LegendreFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "legendre";} + + virtual ~LegendreFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + order_ = std::stoi(get_node_value(node, "order")); + n_bins_ = order_ + 1; + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + double wgt[n_bins_]; + calc_pn_c(order_, p->mu, wgt); + for (int i = 0; i < n_bins_; i++) { + match.bins.push_back(i + 1); + match.weights.push_back(wgt[i]); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + } + + virtual std::string + text_label(int bin) const override + { + return "Legendre expansion, P" + std::to_string(bin - 1); + } + + int order_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_LEGENDRE_H diff --git a/include/openmc/tallies/tally_filter_sph_harm.h b/include/openmc/tallies/tally_filter_sph_harm.h new file mode 100644 index 000000000..7c7ef00d8 --- /dev/null +++ b/include/openmc/tallies/tally_filter_sph_harm.h @@ -0,0 +1,106 @@ +#ifndef OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H +#define OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H + +#include + +#include "openmc/error.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +//TODO: those integer values are not needed when Fortran interop is removed +enum class SphericalHarmonicsCosine { + scatter = 1, particle = 2 +}; + +class SphericalHarmonicsFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "sphericalharmonics";} + + virtual ~SphericalHarmonicsFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + order_ = std::stoi(get_node_value(node, "order")); + n_bins_ = (order_ + 1) * (order_ + 1); + + if (check_for_node(node, "cosine")) { + auto cos = get_node_value(node, "cosine", true); + std::cout << cos << "\n"; + std::cout << (cos == "scatter") << " " << (cos == "particle") << "\n"; + if (cos == "scatter") { + cosine_ = SphericalHarmonicsCosine::scatter; + } else if (cos == "particle") { + cosine_ = SphericalHarmonicsCosine::particle; + } else { + std::stringstream err_msg; + err_msg << "Unrecognized cosine type, \"" << cos + << "\" in spherical harmonics filter"; + fatal_error(err_msg); + } + } + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + // Determine cosine term for scatter expansion if necessary + double wgt[order_ + 1]; + if (cosine_ == SphericalHarmonicsCosine::scatter) { + calc_pn_c(order_, p->mu, wgt); + } else { + for (int i = 0; i < order_ + 1; i++) wgt[i] = 1; + } + + // Find the Rn,m values + double rn[n_bins_]; + calc_rn_c(order_, p->last_uvw, rn); + + int j = 0; + for (int n = 0; n < order_ + 1; n++) { + // Calculate n-th order spherical harmonics for (u,v,w) + int num_nm = 2*n + 1; + + // Append the matching (bin,weight) for each moment + for (int i = 0; i < num_nm; i++) { + match.weights.push_back(wgt[n] * rn[j]); + match.bins.push_back(++j); + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + if (cosine_ == SphericalHarmonicsCosine::scatter) { + write_dataset(filter_group, "cosine", "scatter"); + } else { + write_dataset(filter_group, "cosine", "particle"); + } + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + for (int n = 0; n < order_ + 1; n++) { + if (bin <= (n + 1) * (n + 1)) { + int m = (bin - n*n - 1) - n; + out << "Spherical harmonic expansion, Y" << n << "," << m; + return out.str(); + } + } + } + + int order_; + SphericalHarmonicsCosine cosine_ {SphericalHarmonicsCosine::particle}; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index d66505d47..b3b2a7232 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -8,11 +8,13 @@ #include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_distribcell.h" +#include "openmc/tallies/tally_filter_legendre.h" #include "openmc/tallies/tally_filter_material.h" #include "openmc/tallies/tally_filter_mesh.h" #include "openmc/tallies/tally_filter_meshsurface.h" #include "openmc/tallies/tally_filter_mu.h" #include "openmc/tallies/tally_filter_polar.h" +#include "openmc/tallies/tally_filter_sph_harm.h" #include "openmc/tallies/tally_filter_surface.h" #include "openmc/tallies/tally_filter_universe.h" @@ -96,6 +98,8 @@ extern "C" { tally_filters.push_back(new CellFromFilter()); } else if (type_ == "distribcell") { tally_filters.push_back(new DistribcellFilter()); + } else if (type_ == "legendre") { + tally_filters.push_back(new LegendreFilter()); } else if (type_ == "material") { tally_filters.push_back(new MaterialFilter()); } else if (type_ == "mesh") { @@ -108,6 +112,8 @@ extern "C" { tally_filters.push_back(new PolarFilter()); } else if (type_ == "surface") { tally_filters.push_back(new SurfaceFilter()); + } else if (type_ == "sphericalharmonics") { + tally_filters.push_back(new SphericalHarmonicsFilter()); } else if (type_ == "universe") { tally_filters.push_back(new UniverseFilter()); } else { @@ -149,6 +155,12 @@ extern "C" { *n = filt->cells_.size(); } + int legendre_filter_get_order(LegendreFilter* filt) + {return filt->order_;} + + void legendre_filter_set_order(LegendreFilter* filt, int order) + {filt->order_ = order;} + void material_filter_get_bins(MaterialFilter* filt, int32_t** bins, int32_t* n) { @@ -164,7 +176,7 @@ extern "C" { for (int i = 0; i < n; i++) filt->materials_[i] = bins[i]; filt->n_bins_ = filt->materials_.size(); filt->map_.clear(); - for (int i = 0; i < n; i++) filt->map_[bins[i]] = i; + for (int i = 0; i < n; i++) filt->map_[filt->materials_[i]] = i; } int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} @@ -186,6 +198,22 @@ extern "C" { filt->n_bins_ = 4 * meshes[mesh]->n_dimension_; for (auto dim : meshes[mesh]->shape_) filt->n_bins_ *= dim; } + + int sphharm_filter_get_order(SphericalHarmonicsFilter* filt) + {return filt->order_;} + + int sphharm_filter_get_cosine(SphericalHarmonicsFilter* filt) + {return static_cast(filt->cosine_);} + + void + sphharm_filter_set_order(SphericalHarmonicsFilter* filt, int order) + { + filt->order_ = order; + filt->n_bins_ = (order + 1) * (order + 1); + } + + void sphharm_filter_set_cosine(SphericalHarmonicsFilter* filt, int cosine) + {filt->cosine_ = static_cast(cosine);} } } // namespace openmc diff --git a/src/tallies/tally_filter_legendre.F90 b/src/tallies/tally_filter_legendre.F90 index 32d1b4506..60bb59c76 100644 --- a/src/tallies/tally_filter_legendre.F90 +++ b/src/tallies/tally_filter_legendre.F90 @@ -2,14 +2,8 @@ module tally_filter_legendre use, intrinsic :: ISO_C_BINDING - use constants use error - use hdf5_interface - use math, only: calc_pn - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none private @@ -20,63 +14,11 @@ module tally_filter_legendre ! LEGENDREFILTER gives Legendre moments of the change in scattering angle !=============================================================================== - type, public, extends(TallyFilter) :: LegendreFilter - integer(C_INT) :: order - contains - procedure :: from_xml - procedure :: get_all_bins - procedure :: to_statepoint - procedure :: text_label + type, public, extends(CppTallyFilter) :: LegendreFilter end type LegendreFilter contains -!=============================================================================== -! LegendreFilter methods -!=============================================================================== - - subroutine from_xml(this, node) - class(LegendreFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - ! Get specified order - call get_node_value(node, "order", this % order) - this % n_bins = this % order + 1 - end subroutine from_xml - - subroutine get_all_bins(this, p, estimator, match) - class(LegendreFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - real(C_DOUBLE) :: wgt(this % n_bins) - - call calc_pn(this % order, p % mu, wgt) - do i = 1, this % n_bins - call match % bins_push_back(i) - call match % weights_push_back(wgt(i)) - end do - end subroutine get_all_bins - - subroutine to_statepoint(this, filter_group) - class(LegendreFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "legendre") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "order", this % order) - end subroutine to_statepoint - - function text_label(this, bin) result(label) - class(LegendreFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Legendre expansion, P" // trim(to_str(bin - 1)) - end function text_label - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -87,11 +29,19 @@ contains integer(C_INT), intent(out) :: order integer(C_INT) :: err + interface + function legendre_filter_get_order(filt) result(order) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: order + end function + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (LegendreFilter) - order = f % order + order = legendre_filter_get_order(f % ptr) class default err = E_INVALID_TYPE call set_errmsg("Tried to get order on a non-expansion filter.") @@ -106,12 +56,20 @@ contains integer(C_INT), value :: order integer(C_INT) :: err + interface + subroutine legendre_filter_set_order(filt, order) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: order + end subroutine legendre_filter_set_order + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (LegendreFilter) - f % order = order - f % n_bins = order + 1 + call legendre_filter_set_order(f % ptr, order) + f % n_bins = f % n_bins_cpp() class default err = E_INVALID_TYPE call set_errmsg("Tried to set order on a non-expansion filter.") diff --git a/src/tallies/tally_filter_sph_harm.F90 b/src/tallies/tally_filter_sph_harm.F90 index 8fba71564..59120940c 100644 --- a/src/tallies/tally_filter_sph_harm.F90 +++ b/src/tallies/tally_filter_sph_harm.F90 @@ -2,14 +2,9 @@ module tally_filter_sph_harm use, intrinsic :: ISO_C_BINDING - use constants use error - use hdf5_interface - use math, only: calc_pn, calc_rn - use particle_header, only: Particle use string, only: to_str, to_lower, to_f_string use tally_filter_header - use xml_interface implicit none private @@ -26,112 +21,25 @@ module tally_filter_sph_harm ! tally score !=============================================================================== - type, public, extends(TallyFilter) :: SphericalHarmonicsFilter - integer :: order - integer :: cosine + type, public, extends(CppTallyFilter) :: SphericalHarmonicsFilter contains - procedure :: from_xml - procedure :: get_all_bins - procedure :: to_statepoint - procedure :: text_label + procedure :: cosine end type SphericalHarmonicsFilter contains -!=============================================================================== -! SphericalHarmonicsFilter methods -!=============================================================================== - - subroutine from_xml(this, node) - class(SphericalHarmonicsFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - character(MAX_WORD_LEN) :: temp_str - - ! Get specified order - call get_node_value(node, "order", this % order) - this % n_bins = (this % order + 1)**2 - - ! Determine how cosine term is to be treated - if (check_for_node(node, "cosine")) then - call get_node_value(node, "cosine", temp_str) - select case (to_lower(temp_str)) - case ('scatter') - this % cosine = COSINE_SCATTER - case ('particle') - this % cosine = COSINE_PARTICLE - end select - else - this % cosine = COSINE_PARTICLE - end if - end subroutine from_xml - - subroutine get_all_bins(this, p, estimator, match) - class(SphericalHarmonicsFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i, j, n - integer :: num_nm - real(C_DOUBLE) :: wgt(this % order + 1) - real(C_DOUBLE) :: rn(this % n_bins) - - ! Determine cosine term for scatter expansion if necessary - if (this % cosine == COSINE_SCATTER) then - call calc_pn(this % order, p % mu, wgt) - else - wgt = ONE - end if - - ! Find the Rn,m values - call calc_rn(this % order, p % last_uvw, rn) - - j = 0 - do n = 0, this % order - ! Calculate n-th order spherical harmonics for (u,v,w) - num_nm = 2*n + 1 - - ! Append matching (bin,weight) for each moment - do i = 1, num_nm - j = j + 1 - call match % bins_push_back(j) - call match % weights_push_back(wgt(n + 1) * rn(j)) - end do - end do - - end subroutine get_all_bins - - subroutine to_statepoint(this, filter_group) - class(SphericalHarmonicsFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "sphericalharmonics") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "order", this % order) - if (this % cosine == COSINE_SCATTER) then - call write_dataset(filter_group, "cosine", "scatter") - else - call write_dataset(filter_group, "cosine", "particle") - end if - end subroutine to_statepoint - - function text_label(this, bin) result(label) - class(SphericalHarmonicsFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - integer :: n, m - - do n = 0, this % order - if (bin <= (n + 1)**2) then - m = (bin - n**2 - 1) - n - label = "Spherical harmonic expansion, Y" // trim(to_str(n)) // & - "," // trim(to_str(m)) - exit - end if - end do - end function text_label + function cosine(this) result(val) + class(SphericalHarmonicsFilter) :: this + integer :: val + interface + function sphharm_filter_get_cosine(filt) result(val) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: val + end function + end interface + val = sphharm_filter_get_cosine(this % ptr) + end function cosine !=============================================================================== ! C API FUNCTIONS @@ -143,11 +51,19 @@ contains integer(C_INT), intent(out) :: order integer(C_INT) :: err + interface + function sphharm_filter_get_order(filt) result(order) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: order + end function sphharm_filter_get_order + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (SphericalHarmonicsFilter) - order = f % order + order = sphharm_filter_get_order(f % ptr) class default err = E_INVALID_TYPE call set_errmsg("Not a spherical harmonics filter.") @@ -169,7 +85,7 @@ contains if (err == 0) then select type (f => filters(index) % obj) type is (SphericalHarmonicsFilter) - select case (f % cosine) + select case (f % cosine()) case (COSINE_SCATTER) cosine_ = 'scatter' case (COSINE_PARTICLE) @@ -196,12 +112,19 @@ contains integer(C_INT), value :: order integer(C_INT) :: err + interface + subroutine sphharm_filter_set_order(filt, order) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: order + end subroutine + end interface + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (SphericalHarmonicsFilter) - f % order = order - f % n_bins = (order + 1)**2 + call sphharm_filter_set_order(f % ptr, order) class default err = E_INVALID_TYPE call set_errmsg("Not a spherical harmonics filter.") @@ -218,6 +141,14 @@ contains character(:), allocatable :: cosine_ + interface + subroutine sphharm_filter_set_cosine(filt, cosine) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: cosine + end subroutine + end interface + ! Convert C string to Fortran string cosine_ = to_f_string(cosine) @@ -227,9 +158,9 @@ contains type is (SphericalHarmonicsFilter) select case (cosine_) case ('scatter') - f % cosine = COSINE_SCATTER + call sphharm_filter_set_cosine(f % ptr, COSINE_SCATTER) case ('particle') - f % cosine = COSINE_PARTICLE + call sphharm_filter_set_cosine(f % ptr, COSINE_PARTICLE) end select class default diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 75779d1ad..4bb504b8c 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -344,7 +344,7 @@ contains this % estimator = ESTIMATOR_ANALOG type is (SphericalHarmonicsFilter) j = FILTER_SPH_HARMONICS - if (filt % cosine == COSINE_SCATTER) then + if (filt % cosine() == COSINE_SCATTER) then this % estimator = ESTIMATOR_ANALOG end if type is (SpatialLegendreFilter) From 05e51e73f7da2aa9bfa34ed4067ae13b73a1642e Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 16 Oct 2018 17:44:21 -0400 Subject: [PATCH 26/45] Fix legendre_filter_set_order --- src/tallies/tally_filter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index b3b2a7232..c4ce32e7e 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -158,8 +158,12 @@ extern "C" { int legendre_filter_get_order(LegendreFilter* filt) {return filt->order_;} - void legendre_filter_set_order(LegendreFilter* filt, int order) - {filt->order_ = order;} + void + legendre_filter_set_order(LegendreFilter* filt, int order) + { + filt->order_ = order; + filt->n_bins_ = order + 1; + } void material_filter_get_bins(MaterialFilter* filt, int32_t** bins, int32_t* n) From 960c64bc18d00d3dd46e407763938969e34f3303 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 17 Oct 2018 19:59:45 -0400 Subject: [PATCH 27/45] Move the EnergyFunctionFilter to C++ --- .../openmc/tallies/tally_filter_energyfunc.h | 89 ++++++++++++++ src/tallies/tally_filter.cpp | 3 + src/tallies/tally_filter_energyfunc.F90 | 111 +----------------- 3 files changed, 93 insertions(+), 110 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_energyfunc.h diff --git a/include/openmc/tallies/tally_filter_energyfunc.h b/include/openmc/tallies/tally_filter_energyfunc.h new file mode 100644 index 000000000..f180a57a3 --- /dev/null +++ b/include/openmc/tallies/tally_filter_energyfunc.h @@ -0,0 +1,89 @@ +#ifndef OPENMC_TALLY_FILTER_ENERGYFUNC_H +#define OPENMC_TALLY_FILTER_ENERGYFUNC_H + +#include // for setprecision +#include // for scientific +#include +#include + +#include "openmc/error.h" +#include "openmc/search.h" +#include "openmc/settings.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class EnergyFunctionFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "energyfunction";} + + EnergyFunctionFilter() + : TallyFilter {} + { + n_bins_ = 1; + } + + virtual ~EnergyFunctionFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + if (!settings::run_CE) + fatal_error("EnergyFunction filters are only supported for " + "continuous-energy transport calculations"); + + if (!check_for_node(node, "energy")) + fatal_error("Energy grid not specified for EnergyFunction filter."); + + energy_ = get_node_array(node, "energy"); + + if (!check_for_node(node, "y")) + fatal_error("y values not specified for EnergyFunction filter."); + + y_ = get_node_array(node, "y"); + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + if (p->last_E >= energy_.front() && p->last_E <= energy_.back()) { + // Search for the incoming energy bin. + auto i = lower_bound_index(energy_.begin(), energy_.end(), p->last_E); + + // Compute the interpolation factor between the nearest bins. + double f = (p->last_E - energy_[i]) / (energy_[i+1] - energy_[i]); + + // Interpolate on the lin-lin grid. + match.bins.push_back(1); + match.weights.push_back((1-f) * y_[i] + f * y_[i+1]); + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "energy", energy_); + write_dataset(filter_group, "y", y_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + out << std::scientific << std::setprecision(1) + << "Energy Function f" + << "([ " << energy_.front() << ", ..., " << energy_.back() << "]) = " + << "[" << y_.front() << ", ..., " << y_.back() << "]"; + return out.str(); + } + + std::vector energy_; + std::vector y_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_ENERGYFUNC_H diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index c4ce32e7e..cfc54a6a2 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -8,6 +8,7 @@ #include "openmc/tallies/tally_filter_cellborn.h" #include "openmc/tallies/tally_filter_cellfrom.h" #include "openmc/tallies/tally_filter_distribcell.h" +#include "openmc/tallies/tally_filter_energyfunc.h" #include "openmc/tallies/tally_filter_legendre.h" #include "openmc/tallies/tally_filter_material.h" #include "openmc/tallies/tally_filter_mesh.h" @@ -98,6 +99,8 @@ extern "C" { tally_filters.push_back(new CellFromFilter()); } else if (type_ == "distribcell") { tally_filters.push_back(new DistribcellFilter()); + } else if (type_ == "energyfunction") { + tally_filters.push_back(new EnergyFunctionFilter()); } else if (type_ == "legendre") { tally_filters.push_back(new LegendreFilter()); } else if (type_ == "material") { diff --git a/src/tallies/tally_filter_energyfunc.F90 b/src/tallies/tally_filter_energyfunc.F90 index 0581fdacc..de41b0c59 100644 --- a/src/tallies/tally_filter_energyfunc.F90 +++ b/src/tallies/tally_filter_energyfunc.F90 @@ -1,124 +1,15 @@ module tally_filter_energyfunc - use, intrinsic :: ISO_C_BINDING - - use algorithm, only: binary_search - use constants - use error, only: fatal_error - use hdf5_interface - use particle_header, only: Particle - use settings, only: run_CE - use string, only: to_str use tally_filter_header - use xml_interface implicit none - private !=============================================================================== ! EnergyFunctionFilter multiplies tally scores by an arbitrary function of ! incident energy described by a piecewise linear-linear interpolation. !=============================================================================== - type, public, extends(TallyFilter) :: EnergyFunctionFilter - real(8), allocatable :: energy(:) - real(8), allocatable :: y(:) - - contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_energyfunction - procedure :: to_statepoint => to_statepoint_energyfunction - procedure :: text_label => text_label_energyfunction + type, extends(CppTallyFilter) :: EnergyFunctionFilter end type EnergyFunctionFilter -contains - - subroutine from_xml(this, node) - class(EnergyFunctionFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - this % n_bins = 1 - ! Make sure this is continuous-energy mode. - if (.not. run_CE) then - call fatal_error("EnergyFunction filters are only supported for & - &continuous-energy transport calculations") - end if - - ! Allocate and store energy grid. - if (.not. check_for_node(node, "energy")) then - call fatal_error("Energy grid not specified for EnergyFunction & - &filter.") - end if - n = node_word_count(node, "energy") - allocate(this % energy(n)) - call get_node_array(node, "energy", this % energy) - - ! Allocate and store interpolant values. - if (.not. check_for_node(node, "y")) then - call fatal_error("y values not specified for EnergyFunction & - &filter.") - end if - n = node_word_count(node, "y") - allocate(this % y(n)) - call get_node_array(node, "y", this % y) - end subroutine from_xml - - subroutine get_all_bins_energyfunction(this, p, estimator, match) - class(EnergyFunctionFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n, indx - real(8) :: E, f, weight - - select type(this) - type is (EnergyFunctionFilter) - n = size(this % energy) - - ! Get pre-collision energy of particle - E = p % last_E - - ! Search to find incoming energy bin. - indx = binary_search(this % energy, n, E) - - ! Compute an interpolation factor between nearest bins. - f = (E - this % energy(indx)) & - / (this % energy(indx+1) - this % energy(indx)) - - ! Interpolate on the lin-lin grid. - call match % bins_push_back(1) - weight = (ONE - f) * this % y(indx) + f * this % y(indx+1) - call match % weights_push_back(weight) - end select - end subroutine get_all_bins_energyfunction - - subroutine to_statepoint_energyfunction(this, filter_group) - class(EnergyFunctionFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - select type(this) - type is (EnergyFunctionFilter) - call write_dataset(filter_group, "type", "energyfunction") - call write_dataset(filter_group, "energy", this % energy) - call write_dataset(filter_group, "y", this % y) - end select - end subroutine to_statepoint_energyfunction - - function text_label_energyfunction(this, bin) result(label) - class(EnergyFunctionFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - select type(this) - type is (EnergyFunctionFilter) - write(label, FMT="(A, ES8.1, A, ES8.1, A, ES8.1, A, ES8.1, A)") & - "Energy Function f([", this % energy(1), ", ..., ", & - this % energy(size(this % energy)), "]) = [", this % y(1), & - ", ..., ", this % y(size(this % y)), "]" - end select - end function text_label_energyfunction - end module tally_filter_energyfunc From 5a6db8a0de5f1bab399d8cdd071fb664c0d2c3ac Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 17 Oct 2018 23:07:01 -0400 Subject: [PATCH 28/45] Move spatial legendre and zernike filters to C++ --- .../tallies/tally_filter_sptl_legendre.h | 113 +++++++++ include/openmc/tallies/tally_filter_zernike.h | 121 ++++++++++ src/math.F90 | 19 -- src/tallies/tally_filter.cpp | 50 ++++ src/tallies/tally_filter_sptl_legendre.F90 | 162 ++++--------- src/tallies/tally_filter_zernike.F90 | 225 +++--------------- 6 files changed, 365 insertions(+), 325 deletions(-) create mode 100644 include/openmc/tallies/tally_filter_sptl_legendre.h create mode 100644 include/openmc/tallies/tally_filter_zernike.h diff --git a/include/openmc/tallies/tally_filter_sptl_legendre.h b/include/openmc/tallies/tally_filter_sptl_legendre.h new file mode 100644 index 000000000..413a3e3a2 --- /dev/null +++ b/include/openmc/tallies/tally_filter_sptl_legendre.h @@ -0,0 +1,113 @@ +#ifndef OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H +#define OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H + +#include + +#include "openmc/error.h" +#include "openmc/math_functions.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +//TODO: those integer values are not needed when Fortran interop is removed +enum class LegendreAxis { + x = 1, y = 2, z = 3 +}; + +class SpatialLegendreFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "spatiallegendre";} + + virtual ~SpatialLegendreFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + order_ = std::stoi(get_node_value(node, "order")); + + auto axis = get_node_value(node, "axis"); + if (axis == "x") { + axis_ = LegendreAxis::x; + } else if (axis == "y") { + axis_ = LegendreAxis::y; + } else if (axis == "z") { + axis_ = LegendreAxis::z; + } else { + fatal_error("Unrecognized axis on SpatialLegendreFilter"); + } + + min_ = std::stod(get_node_value(node, "min")); + max_ = std::stod(get_node_value(node, "max")); + + n_bins_ = order_ + 1; + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + // Get the coordinate along the axis of interest. + double x; + if (axis_ == LegendreAxis::x) { + x = p->coord[0].xyz[0]; + } else if (axis_ == LegendreAxis::y) { + x = p->coord[0].xyz[1]; + } else { + x = p->coord[0].xyz[2]; + } + + if (x >= min_ && x <= max_) { + // Compute the normalized coordinate value. + double x_norm = 2.0*(x - min_) / (max_ - min_) - 1.0; + + // Compute and return the Legendre weights. + double wgt[order_ + 1]; + calc_pn_c(order_, x_norm, wgt); + for (int i = 0; i < order_ + 1; i++) { + match.bins.push_back(i + 1); + match.weights.push_back(wgt[i]); + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + if (axis_ == LegendreAxis::x) { + write_dataset(filter_group, "axis", "x"); + } else if (axis_ == LegendreAxis::y) { + write_dataset(filter_group, "axis", "y"); + } else { + write_dataset(filter_group, "axis", "z"); + } + write_dataset(filter_group, "min", min_); + write_dataset(filter_group, "max", max_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + out << "Legendre expansion, "; + if (axis_ == LegendreAxis::x) { + out << "x"; + } else if (axis_ == LegendreAxis::y) { + out << "y"; + } else { + out << "z"; + } + out << " axis, P" << std::to_string(bin - 1); + return out.str(); + } + + int order_; + LegendreAxis axis_; + double min_, max_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H diff --git a/include/openmc/tallies/tally_filter_zernike.h b/include/openmc/tallies/tally_filter_zernike.h new file mode 100644 index 000000000..c2052c500 --- /dev/null +++ b/include/openmc/tallies/tally_filter_zernike.h @@ -0,0 +1,121 @@ +#ifndef OPENMC_TALLY_FILTER_ZERNIKE_H +#define OPENMC_TALLY_FILTER_ZERNIKE_H + +#include +#include +#include + +#include "openmc/error.h" +#include "openmc/math_functions.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class ZernikeFilter : public TallyFilter +{ +public: + virtual std::string type() const override {return "zernike";} + + virtual ~ZernikeFilter() override = default; + + virtual void + from_xml(pugi::xml_node node) override + { + order_ = std::stoi(get_node_value(node, "order")); + x_ = std::stod(get_node_value(node, "x")); + y_ = std::stod(get_node_value(node, "y")); + r_ = std::stod(get_node_value(node, "r")); + calc_n_bins(); + } + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + // Determine the normalized (r,theta) coordinates. + double x = p->coord[0].xyz[0] - x_; + double y = p->coord[0].xyz[1] - y_; + double r = std::sqrt(x*x + y*y) / r_; + double theta = std::atan2(y, x); + + if (r <= 1.0) { + // Compute and return the Zernike weights. + double zn[n_bins_]; + calc_zn_c(order_, r, theta, zn); + for (int i = 0; i < n_bins_; i++) { + match.bins.push_back(i+1); + match.weights.push_back(zn[i]); + } + } + } + + virtual void + to_statepoint(hid_t filter_group) const override + { + TallyFilter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + write_dataset(filter_group, "x", x_); + write_dataset(filter_group, "y", y_); + write_dataset(filter_group, "r", r_); + } + + virtual std::string + text_label(int bin) const override + { + std::stringstream out; + for (int n = 0; n < order_+1; n++) { + int last = (n + 1) * (n + 2) / 2; + if (bin <= last) { + int first = last - n; + int m = -n + (bin - first) * 2; + out << "Zernike expansion, Z" << n << "," << m; + return out.str(); + } + } + } + + virtual void calc_n_bins() {n_bins_ = ((order_+1) * (order_+2)) / 2;} + + int order_; + double x_, y_, r_; +}; + +class ZernikeRadialFilter : public ZernikeFilter +{ +public: + virtual std::string type() const override {return "zernikeradial";} + + virtual ~ZernikeRadialFilter() override = default; + + virtual void + get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + const override + { + // Determine the normalized radius coordinate. + double x = p->coord[0].xyz[0] - x_; + double y = p->coord[0].xyz[1] - y_; + double r = std::sqrt(x*x + y*y) / r_; + + if (r <= 1.0) { + // Compute and return the Zernike weights. + double zn[n_bins_]; + calc_zn_rad_c(order_, r, zn); + for (int i = 0; i < n_bins_; i++) { + match.bins.push_back(i+1); + match.weights.push_back(zn[i]); + } + } + } + + virtual std::string + text_label(int bin) const override + { + return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; + } + + virtual void calc_n_bins() override {n_bins_ = order_ / 2 + 1;} +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_ZERNIKE_H diff --git a/src/math.F90 b/src/math.F90 index 143e21e03..fe4156b9d 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -10,8 +10,6 @@ module math public :: t_percentile public :: calc_pn public :: calc_rn - public :: calc_zn - public :: calc_zn_rad public :: rotate_angle public :: faddeeva public :: w_derivative @@ -47,23 +45,6 @@ module math real(C_DOUBLE), intent(out) :: rn(2 * n + 1) end subroutine calc_rn - pure subroutine calc_zn(n, rho, phi, zn) bind(C, name='calc_zn_c') - use ISO_C_BINDING - implicit none - integer(C_INT), value, intent(in) :: n - real(C_DOUBLE), value, intent(in) :: rho - real(C_DOUBLE), value, intent(in) :: phi - real(C_DOUBLE), intent(out) :: zn(((n + 1) * (n + 2)) / 2) - end subroutine calc_zn - - pure subroutine calc_zn_rad(n, rho, zn_rad) bind(C, name='calc_zn_rad_c') - use ISO_C_BINDING - implicit none - integer(C_INT), value, intent(in) :: n - real(C_DOUBLE), value, intent(in) :: rho - real(C_DOUBLE), intent(out) :: zn_rad((n / 2) + 1) - end subroutine calc_zn_rad - subroutine rotate_angle_c_intfc(uvw, mu, phi) bind(C, name='rotate_angle_c') use ISO_C_BINDING implicit none diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index cfc54a6a2..7f615ba54 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -16,8 +16,10 @@ #include "openmc/tallies/tally_filter_mu.h" #include "openmc/tallies/tally_filter_polar.h" #include "openmc/tallies/tally_filter_sph_harm.h" +#include "openmc/tallies/tally_filter_sptl_legendre.h" #include "openmc/tallies/tally_filter_surface.h" #include "openmc/tallies/tally_filter_universe.h" +#include "openmc/tallies/tally_filter_zernike.h" namespace openmc { @@ -115,10 +117,16 @@ extern "C" { tally_filters.push_back(new PolarFilter()); } else if (type_ == "surface") { tally_filters.push_back(new SurfaceFilter()); + } else if (type_ == "spatiallegendre") { + tally_filters.push_back(new SpatialLegendreFilter()); } else if (type_ == "sphericalharmonics") { tally_filters.push_back(new SphericalHarmonicsFilter()); } else if (type_ == "universe") { tally_filters.push_back(new UniverseFilter()); + } else if (type_ == "zernike") { + tally_filters.push_back(new ZernikeFilter()); + } else if (type_ == "zernikeradial") { + tally_filters.push_back(new ZernikeRadialFilter()); } else { return nullptr; } @@ -221,6 +229,48 @@ extern "C" { void sphharm_filter_set_cosine(SphericalHarmonicsFilter* filt, int cosine) {filt->cosine_ = static_cast(cosine);} + + void + sptl_legendre_filter_get_params(SpatialLegendreFilter* filt, int* order, + int* axis, double* min, double* max) + { + *order = filt->order_; + *axis = static_cast(filt->axis_); + *min = filt->min_; + *max = filt->max_; + } + + void + sptl_legendre_filter_set_params(SpatialLegendreFilter* filt, int order, + int axis, double min, double max) + { + filt->order_ = order; + filt->axis_ = static_cast(axis); + filt->min_ = min; + filt->max_ = max; + filt->n_bins_ = order + 1; + } + + void + zernike_filter_get_params(ZernikeFilter* filt, int* order, double* x, + double* y, double* r) + { + *order = filt->order_; + *x = filt->x_; + *y = filt->y_; + *r = filt->r_; + } + + void + zernike_filter_set_params(ZernikeFilter* filt, int order, double x, + double y, double r) + { + filt->order_ = order; + filt->x_ = x; + filt->y_ = y; + filt->r_ = r; + filt->calc_n_bins(); + } } } // namespace openmc diff --git a/src/tallies/tally_filter_sptl_legendre.F90 b/src/tallies/tally_filter_sptl_legendre.F90 index ba2a25b7a..f883e4aec 100644 --- a/src/tallies/tally_filter_sptl_legendre.F90 +++ b/src/tallies/tally_filter_sptl_legendre.F90 @@ -2,14 +2,8 @@ module tally_filter_sptl_legendre use, intrinsic :: ISO_C_BINDING - use constants use error - use hdf5_interface - use math, only: calc_pn - use particle_header, only: Particle - use string, only: to_str, to_lower use tally_filter_header - use xml_interface implicit none private @@ -18,120 +12,38 @@ module tally_filter_sptl_legendre public :: openmc_spatial_legendre_filter_set_order public :: openmc_spatial_legendre_filter_set_params - integer, parameter :: AXIS_X = 1 - integer, parameter :: AXIS_Y = 2 - integer, parameter :: AXIS_Z = 3 + interface + subroutine sptl_legendre_filter_get_params(filt, order, axis, min, max) & + bind(C) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), value :: filt + integer(C_INT) :: order + integer(C_INT) :: axis + real(C_DOUBLE) :: min + real(C_DOUBLE) :: max + end subroutine + + subroutine sptl_legendre_filter_set_params(filt, order, axis, min, max) & + bind(C) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), value :: filt + integer(C_INT), value :: order + integer(C_INT), value :: axis + real(C_DOUBLE), value :: min + real(C_DOUBLE), value :: max + end subroutine + end interface !=============================================================================== ! SPATIALLEGENDREFILTER gives Legendre moments of the particle's normalized ! position along an axis !=============================================================================== - type, public, extends(TallyFilter) :: SpatialLegendreFilter - integer(C_INT) :: order - integer(C_INT) :: axis - real(C_DOUBLE) :: min - real(C_DOUBLE) :: max - contains - procedure :: from_xml - procedure :: get_all_bins - procedure :: to_statepoint - procedure :: text_label + type, public, extends(CppTallyFilter) :: SpatialLegendreFilter end type SpatialLegendreFilter contains -!=============================================================================== -! SpatialLegendreFilter methods -!=============================================================================== - - subroutine from_xml(this, node) - class(SpatialLegendreFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - character(MAX_WORD_LEN) :: axis - - ! Get attributes from XML - call get_node_value(node, "order", this % order) - call get_node_value(node, "axis", axis) - select case (to_lower(axis)) - case ('x') - this % axis = AXIS_X - case ('y') - this % axis = AXIS_Y - case ('z') - this % axis = AXIS_Z - end select - call get_node_value(node, "min", this % min) - call get_node_value(node, "max", this % max) - - this % n_bins = this % order + 1 - end subroutine from_xml - - subroutine get_all_bins(this, p, estimator, match) - class(SpatialLegendreFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - real(C_DOUBLE) :: wgt(this % n_bins) - real(C_DOUBLE) :: x ! Position on specified axis - real(C_DOUBLE) :: x_norm ! Normalized position - - x = p % coord(1) % xyz(this % axis) - if (this % min <= x .and. x <= this % max) then - ! Calculate normalized position between min and max - x_norm = TWO*(x - this % min)/(this % max - this % min) - ONE - - call calc_pn(this % order, x_norm, wgt) - do i = 1, this % n_bins - call match % bins_push_back(i) - call match % weights_push_back(wgt(i)) - end do - end if - end subroutine get_all_bins - - subroutine to_statepoint(this, filter_group) - class(SpatialLegendreFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - character(kind=C_CHAR) :: axis - - call write_dataset(filter_group, "type", "spatiallegendre") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "order", this % order) - select case (this % axis) - case (AXIS_X) - axis = 'x' - case (AXIS_Y) - axis = 'y' - case (AXIS_Z) - axis = 'z' - end select - call write_dataset(filter_group, 'axis', axis) - call write_dataset(filter_group, 'min', this % min) - call write_dataset(filter_group, 'max', this % max) - end subroutine to_statepoint - - function text_label(this, bin) result(label) - class(SpatialLegendreFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - character(1) :: axis - - select case (this % axis) - case (AXIS_X) - axis = 'x' - case (AXIS_Y) - axis = 'y' - case (AXIS_Z) - axis = 'z' - end select - label = "Legendre expansion, " // axis // " axis, P" // & - trim(to_str(bin - 1)) - end function text_label - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -142,11 +54,14 @@ contains integer(C_INT), intent(out) :: order integer(C_INT) :: err + integer(C_INT) :: axis + real(C_DOUBLE) :: min, max + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (SpatialLegendreFilter) - order = f % order + call sptl_legendre_filter_get_params(f % ptr, order, axis, min, max) class default err = E_INVALID_TYPE call set_errmsg("Not a spatial Legendre filter.") @@ -161,12 +76,16 @@ contains integer(C_INT), value :: order integer(C_INT) :: err + integer(C_INT) :: axis, order_ + real(C_DOUBLE) :: min, max + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) type is (SpatialLegendreFilter) - f % order = order - f % n_bins = order + 1 + call sptl_legendre_filter_get_params(f % ptr, order_, axis, min, max) + call sptl_legendre_filter_set_params(f % ptr, order, axis, min, max) + f % n_bins = f % n_bins_cpp() class default err = E_INVALID_TYPE call set_errmsg("Not a spatial Legendre filter.") @@ -184,13 +103,13 @@ contains real(C_DOUBLE), intent(out) :: max integer(C_INT) :: err + integer(C_INT) :: order + err = verify_filter(index) if (err == 0) then select type(f => filters(index) % obj) type is (SpatialLegendreFilter) - axis = f % axis - min = f % min - max = f % max + call sptl_legendre_filter_get_params(f % ptr, order, axis, min, max) class default err = E_INVALID_TYPE call set_errmsg("Not a spatial Legendre filter.") @@ -208,13 +127,18 @@ contains real(C_DOUBLE), intent(in), optional :: max integer(C_INT) :: err + integer(C_INT) :: order, axis_ + real(C_DOUBLE) :: min_, max_ + err = verify_filter(index) if (err == 0) then select type(f => filters(index) % obj) type is (SpatialLegendreFilter) - if (present(axis)) f % axis = axis - if (present(min)) f % min = min - if (present(max)) f % max = max + call sptl_legendre_filter_get_params(f % ptr, order, axis_, min_, max_) + if (present(axis)) axis_ = axis + if (present(min)) min_ = min + if (present(max)) max_ = max + call sptl_legendre_filter_set_params(f % ptr, order, axis_, min_, max_) class default err = E_INVALID_TYPE call set_errmsg("Not a spatial Legendre filter.") diff --git a/src/tallies/tally_filter_zernike.F90 b/src/tallies/tally_filter_zernike.F90 index 1c6955b03..aabb21f3f 100644 --- a/src/tallies/tally_filter_zernike.F90 +++ b/src/tallies/tally_filter_zernike.F90 @@ -2,14 +2,8 @@ module tally_filter_zernike use, intrinsic :: ISO_C_BINDING - use constants use error - use hdf5_interface - use math, only: calc_zn, calc_zn_rad - use particle_header, only: Particle - use string, only: to_str use tally_filter_header - use xml_interface implicit none private @@ -18,21 +12,27 @@ module tally_filter_zernike public :: openmc_zernike_filter_set_order public :: openmc_zernike_filter_set_params + interface + subroutine zernike_filter_get_params(filt, order, x, y, r) bind(C) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), value :: filt + integer(C_INT) :: order + real(C_DOUBLE) :: x, y, r + end subroutine + + subroutine zernike_filter_set_params(filt, order, x, y, r) bind(C) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), value :: filt + integer(C_INT), value :: order + real(C_DOUBLE), value :: x, y, r + end subroutine + end interface + !=============================================================================== ! ZERNIKEFILTER gives Zernike polynomial moments of a particle's position !=============================================================================== - type, public, extends(TallyFilter) :: ZernikeFilter - integer :: order - real(8) :: x - real(8) :: y - real(8) :: r - contains - procedure :: calc_n_bins => calc_n_bins_zn - procedure :: from_xml => from_xml_zn - procedure :: get_all_bins => get_all_bins_zn - procedure :: to_statepoint => to_statepoint_zn - procedure :: text_label => text_label_zn + type, public, extends(CppTallyFilter) :: ZernikeFilter end type ZernikeFilter !=============================================================================== @@ -41,164 +41,10 @@ module tally_filter_zernike !=============================================================================== type, public, extends(ZernikeFilter) :: ZernikeRadialFilter - contains - procedure :: calc_n_bins => calc_n_bins_zn_rad - ! Inherit from_xml from ZernikeFilter - procedure :: get_all_bins => get_all_bins_zn_rad - procedure :: to_statepoint => to_statepoint_zn_rad - procedure :: text_label => text_label_zn_rad end type ZernikeRadialFilter contains -!=============================================================================== -! ZernikeFilter methods -!=============================================================================== - - function calc_n_bins_zn(this) result(n_bins) - class(ZernikeFilter), intent(in) :: this - integer :: n - integer :: n_bins - - n = this % order - n_bins = ((n+1) * (n+2))/2 - end function calc_n_bins_zn - - subroutine from_xml_zn(this, node) - class(ZernikeFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - ! Get center of cylinder and radius - call get_node_value(node, "x", this % x) - call get_node_value(node, "y", this % y) - call get_node_value(node, "r", this % r) - - ! Get specified order - call get_node_value(node, "order", n) - this % order = n - this % n_bins = this % calc_n_bins() - end subroutine from_xml_zn - - subroutine get_all_bins_zn(this, p, estimator, match) - class(ZernikeFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - real(8) :: x, y, r, theta - real(C_DOUBLE) :: zn(this % n_bins) - - ! Determine normalized (r,theta) positions - x = p % coord(1) % xyz(1) - this % x - y = p % coord(1) % xyz(2) - this % y - r = sqrt(x*x + y*y)/this % r - if (r <= ONE) then - theta = atan2(y, x) - - ! Get moments for Zernike polynomial orders 0..n - call calc_zn(this % order, r, theta, zn) - - do i = 1, this % n_bins - call match % bins_push_back(i) - call match % weights_push_back(zn(i)) - end do - endif - end subroutine get_all_bins_zn - - subroutine to_statepoint_zn(this, filter_group) - class(ZernikeFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "zernike") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "order", this % order) - call write_dataset(filter_group, "x", this % x) - call write_dataset(filter_group, "y", this % y) - call write_dataset(filter_group, "r", this % r) - end subroutine to_statepoint_zn - - function text_label_zn(this, bin) result(label) - class(ZernikeFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - integer :: n, m - integer :: first, last - - do n = 0, this % order - last = (n + 1)*(n + 2)/2 - if (bin <= last) then - first = last - n - m = -n + (bin - first)*2 - label = "Zernike expansion, Z" // trim(to_str(n)) // "," & - // trim(to_str(m)) - exit - end if - end do - end function text_label_zn - -!=============================================================================== -! ZernikeRadialFilter methods -!=============================================================================== - - function calc_n_bins_zn_rad(this) result(num_n_bins) - class(ZernikeRadialFilter), intent(in) :: this - integer :: n - integer :: num_n_bins - - n = this % order - num_n_bins = n/2 + 1 - end function calc_n_bins_zn_rad - - subroutine get_all_bins_zn_rad(this, p, estimator, match) - class(ZernikeRadialFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - real(8) :: x, y, r - real(C_DOUBLE) :: zn_rad(this % n_bins) - - ! Determine normalized (r,theta) positions - x = p % coord(1) % xyz(1) - this % x - y = p % coord(1) % xyz(2) - this % y - r = sqrt(x*x + y*y)/this % r - if (r <= ONE) then - - ! Get moments for even order Zernike polynomial orders 0..n - call calc_zn_rad(this % order, r, zn_rad) - - do i = 1, this % n_bins - call match % bins_push_back(i) - call match % weights_push_back(zn_rad(i)) - end do - endif - end subroutine get_all_bins_zn_rad - - subroutine to_statepoint_zn_rad(this, filter_group) - class(ZernikeRadialFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "zernikeradial") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "order", this % order) - call write_dataset(filter_group, "x", this % x) - call write_dataset(filter_group, "y", this % y) - call write_dataset(filter_group, "r", this % r) - end subroutine to_statepoint_zn_rad - - function text_label_zn_rad(this, bin) result(label) - class(ZernikeRadialFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Zernike expansion, Z" // trim(to_str(2*(bin-1))) // ",0" - end function text_label_zn_rad - !=============================================================================== ! C API FUNCTIONS !=============================================================================== @@ -209,13 +55,13 @@ contains integer(C_INT), intent(out) :: order integer(C_INT) :: err + real(C_DOUBLE) :: x, y, r + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) - type is (ZernikeFilter) - order = f % order - type is (ZernikeRadialFilter) - order = f % order + class is (ZernikeFilter) + call zernike_filter_get_params(f % ptr, order, x, y, r) class default err = E_INVALID_TYPE call set_errmsg("Not a Zernike filter.") @@ -232,13 +78,13 @@ contains real(C_DOUBLE), intent(out) :: r integer(C_INT) :: err + integer(C_INT) :: order + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) class is (ZernikeFilter) - x = f % x - y = f % y - r = f % r + call zernike_filter_get_params(f % ptr, order, x, y, r) class default err = E_INVALID_TYPE call set_errmsg("Not a Zernike filter.") @@ -253,15 +99,15 @@ contains integer(C_INT), value :: order integer(C_INT) :: err + integer(C_INT) :: order_ + real(C_DOUBLE) :: x, y, r + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) - type is (ZernikeFilter) - f % order = order - f % n_bins = ((order + 1)*(order + 2))/2 - type is (ZernikeRadialFilter) - f % order = order - f % n_bins = order/2 + 1 + class is (ZernikeFilter) + call zernike_filter_get_params(f % ptr, order_, x, y, r) + call zernike_filter_set_params(f % ptr, order, x, y, r) class default err = E_INVALID_TYPE call set_errmsg("Not a Zernike filter.") @@ -278,13 +124,18 @@ contains real(C_DOUBLE), intent(in), optional :: r integer(C_INT) :: err + integer(C_INT) :: order + real(C_DOUBLE) :: x_, y_, r_ + err = verify_filter(index) if (err == 0) then select type (f => filters(index) % obj) class is (ZernikeFilter) - if (present(x)) f % x = x - if (present(y)) f % y = y - if (present(r)) f % r = r + call zernike_filter_get_params(f % ptr, order, x_, y_, r_) + if (present(x)) x_ = x + if (present(y)) y_ = y + if (present(r)) r_ = r + call zernike_filter_set_params(f % ptr, order, x_, y_, r_) class default err = E_INVALID_TYPE call set_errmsg("Not a Zernike filter.") From 986d388d199e15d9f333ccf388580aa965aeca54 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 19 Oct 2018 09:02:12 -0500 Subject: [PATCH 29/45] Don't import openmc.capi at top-level --- openmc/polynomial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/polynomial.py b/openmc/polynomial.py index 8bcb74f68..ac1ad675d 100644 --- a/openmc/polynomial.py +++ b/openmc/polynomial.py @@ -1,6 +1,5 @@ import numpy as np import openmc -import openmc.capi as capi from collections.abc import Iterable @@ -74,6 +73,7 @@ class ZernikeRadial(Polynomial): return self._order def __call__(self, r): + import openmc.capi as capi if isinstance(r, Iterable): return [np.sum(self._norm_coef * capi.calc_zn_rad(self.order, r_i)) for r_i in r] From 9c35c85712a8b90063d17afaed5fb57eee432a6e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 19 Oct 2018 10:49:01 -0500 Subject: [PATCH 30/45] Fixes in openmc-plot-mesh-tally (thanks to Sharif Abu Darda) --- scripts/openmc-plot-mesh-tally | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/openmc-plot-mesh-tally b/scripts/openmc-plot-mesh-tally index 0dfb29b9b..61ada852c 100755 --- a/scripts/openmc-plot-mesh-tally +++ b/scripts/openmc-plot-mesh-tally @@ -11,8 +11,10 @@ import tkinter.font as font import tkinter.messagebox as messagebox import tkinter.ttk as ttk +import matplotlib +matplotlib.use("TkAgg") from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg +from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk from matplotlib.figure import Figure import matplotlib.pyplot as plt import numpy as np @@ -56,7 +58,7 @@ class MeshPlotter(tk.Frame): self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # Create the navigation toolbar, tied to the canvas - self.mpl_toolbar = NavigationToolbar2TkAgg(self.canvas, figureFrame) + self.mpl_toolbar = NavigationToolbar2Tk(self.canvas, figureFrame) self.mpl_toolbar.update() self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) From 798286337544c8d08e4485b1553e9ae06c922e90 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 19 Oct 2018 13:37:02 -0500 Subject: [PATCH 31/45] Make sure DAGMC test imports openmc.capi, not openmc --- tests/regression_tests/dagmc/test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression_tests/dagmc/test.py b/tests/regression_tests/dagmc/test.py index 943245d27..9817cff95 100644 --- a/tests/regression_tests/dagmc/test.py +++ b/tests/regression_tests/dagmc/test.py @@ -1,7 +1,7 @@ from tests.testing_harness import TestHarness import os import pytest -import openmc +import openmc.capi pytestmark = pytest.mark.skipif( not openmc.capi.dagmc_enabled, @@ -9,4 +9,4 @@ pytestmark = pytest.mark.skipif( def test_dagmc(): harness = TestHarness('statepoint.5.h5') - harness.main() + harness.main() From 2fd6a92074e2bc5600241df31a4f930e9b5e8897 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Oct 2018 15:09:55 -0400 Subject: [PATCH 32/45] Move tally filter C-API functions to C++ --- .../openmc/tallies/tally_filter_sph_harm.h | 2 - src/api.F90 | 5 - src/tallies/tally_filter.cpp | 501 ++++++++++++++---- src/tallies/tally_filter_cell.F90 | 41 +- src/tallies/tally_filter_header.F90 | 31 +- src/tallies/tally_filter_legendre.F90 | 73 +-- src/tallies/tally_filter_material.F90 | 71 --- src/tallies/tally_filter_mesh.F90 | 70 +-- src/tallies/tally_filter_meshsurface.F90 | 80 +-- src/tallies/tally_filter_sph_harm.F90 | 135 ----- src/tallies/tally_filter_sptl_legendre.F90 | 136 +---- src/tallies/tally_filter_zernike.F90 | 128 +---- 12 files changed, 455 insertions(+), 818 deletions(-) diff --git a/include/openmc/tallies/tally_filter_sph_harm.h b/include/openmc/tallies/tally_filter_sph_harm.h index 7c7ef00d8..43c41ea22 100644 --- a/include/openmc/tallies/tally_filter_sph_harm.h +++ b/include/openmc/tallies/tally_filter_sph_harm.h @@ -29,8 +29,6 @@ public: if (check_for_node(node, "cosine")) { auto cos = get_node_value(node, "cosine", true); - std::cout << cos << "\n"; - std::cout << (cos == "scatter") << " " << (cos == "particle") << "\n"; if (cos == "scatter") { cosine_ = SphericalHarmonicsCosine::scatter; } else if (cos == "particle") { diff --git a/src/api.F90 b/src/api.F90 index 18162e600..b9ccdca48 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -37,7 +37,6 @@ module openmc_api private public :: openmc_calculate_volumes - public :: openmc_cell_filter_get_bins public :: openmc_cell_get_id public :: openmc_cell_set_id public :: openmc_energy_filter_get_bins @@ -71,10 +70,6 @@ module openmc_api public :: openmc_material_set_density public :: openmc_material_set_densities public :: openmc_material_set_id - public :: openmc_material_filter_get_bins - public :: openmc_material_filter_set_bins - public :: openmc_mesh_filter_set_mesh - public :: openmc_meshsurface_filter_set_mesh public :: openmc_next_batch public :: openmc_nuclide_name public :: openmc_plot_geometry diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 7f615ba54..bb937806f 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -2,7 +2,9 @@ #include +#include "openmc/capi.h" #include "openmc/constants.h" // for MAX_LINE_LEN; +#include "openmc/error.h" #include "openmc/tallies/tally_filter_azimuthal.h" #include "openmc/tallies/tally_filter_cell.h" #include "openmc/tallies/tally_filter_cellborn.h" @@ -47,6 +49,397 @@ free_memory_tally_c() tally_filters.clear(); } +//============================================================================== +// C-API functions +//============================================================================== + +// Fortran functions that will be called from C++ +extern "C" int verify_filter(int32_t index); +extern "C" TallyFilter* filter_from_f(int32_t index); +extern "C" void filter_update_n_bins(int32_t index); + +extern "C" { + int + openmc_cell_filter_get_bins(int32_t index, int32_t** cells, int32_t* n) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "cell") { + set_errmsg("Tried to get cells from a non-cell filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto cell_filt = static_cast(filt); + *cells = cell_filt->cells_.data(); + *n = cell_filt->cells_.size(); + return 0; + } + + int + openmc_legendre_filter_get_order(int32_t index, int* order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "legendre") { + set_errmsg("Tried to get order on a non-expansion filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *order = l_filt->order_; + return 0; + } + + int + openmc_legendre_filter_set_order(int32_t index, int order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "legendre") { + set_errmsg("Tried to set order on a non-expansion filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + l_filt->order_ = order; + l_filt->n_bins_ = order + 1; + filter_update_n_bins(index); + return 0; + } + + int + openmc_material_filter_get_bins(int32_t index, int32_t** bins, int32_t* n) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "material") { + set_errmsg("Tried to get material filter bins on a non-material filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mat_filt = static_cast(filt); + *bins = mat_filt->materials_.data(); + *n = mat_filt->materials_.size(); + return 0; + } + + int + openmc_material_filter_set_bins(int32_t index, int32_t n, const int32_t* bins) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "material") { + set_errmsg("Tried to set material filter bins on a non-material filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mat_filt = static_cast(filt); + mat_filt->materials_.clear(); + mat_filt->materials_.resize(n); + for (int i = 0; i < n; i++) mat_filt->materials_[i] = bins[i]; + mat_filt->n_bins_ = mat_filt->materials_.size(); + mat_filt->map_.clear(); + for (int i = 0; i < n; i++) mat_filt->map_[mat_filt->materials_[i]] = i; + filter_update_n_bins(index); + return 0; + } + + int + openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "mesh" && filt->type() != "meshsurface") { + set_errmsg("Tried to get mesh on a non-mesh filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mesh_filt = static_cast(filt); + *index_mesh = mesh_filt->mesh_; + return 0; + } + + int + openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "mesh" && filt->type() != "meshsurface") { + set_errmsg("Tried to set mesh on a non-mesh filter."); + return OPENMC_E_INVALID_TYPE; + } + + if (index_mesh < 0 || index_mesh >= meshes.size()) { + set_errmsg("Index in 'meshes' array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } + + auto mesh_filt = static_cast(filt); + mesh_filt->mesh_ = index_mesh; + if (filt->type() == "mesh") { + mesh_filt->n_bins_ = 1; + } else { + filt->n_bins_ = 4 * meshes[index_mesh]->n_dimension_; + } + for (auto dim : meshes[index_mesh]->shape_) mesh_filt->n_bins_ *= dim; + filter_update_n_bins(index); + return 0; + } + + int openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh) + {return openmc_mesh_filter_get_mesh(index, index_mesh);} + + int openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh) + {return openmc_mesh_filter_set_mesh(index, index_mesh);} + + int + openmc_spatial_legendre_filter_get_order(int32_t index, int* order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *order = l_filt->order_; + return 0; + } + + int + openmc_spatial_legendre_filter_get_params(int32_t index, int* axis, + double* min, double* max) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *axis = static_cast(l_filt->axis_); + *min = l_filt->min_; + *max = l_filt->max_; + return 0; + } + + int + openmc_spatial_legendre_filter_set_order(int32_t index, int order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + l_filt->order_ = order; + l_filt->n_bins_ = order + 1; + filter_update_n_bins(index); + return 0; + } + + int + openmc_spatial_legendre_filter_set_params(int32_t index, const int* axis, + const double* min, const double* max) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + if (axis) l_filt->axis_ = static_cast(*axis); + if (min) l_filt->min_ = *min; + if (max) l_filt->max_ = *max; + return 0; + } + + int + openmc_sphharm_filter_get_order(int32_t index, int* order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + *order = sph_filt->order_; + return 0; + } + + int + openmc_sphharm_filter_get_cosine(int32_t index, char cosine[]) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + if (sph_filt->cosine_ == SphericalHarmonicsCosine::scatter) { + strcpy(cosine, "scatter"); + } else { + strcpy(cosine, "particle"); + } + return 0; + } + + int + openmc_sphharm_filter_set_order(int32_t index, int order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + sph_filt->order_ = order; + sph_filt->n_bins_ = (order + 1) * (order + 1); + filter_update_n_bins(index); + return 0; + } + + int + openmc_sphharm_filter_set_cosine(int32_t index, const char cosine[]) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + if (strcmp(cosine, "scatter") == 0) { + sph_filt->cosine_ = SphericalHarmonicsCosine::scatter; + } else if (strcmp(cosine, "particle") == 0) { + sph_filt->cosine_ = SphericalHarmonicsCosine::particle; + } else { + set_errmsg("Invalid spherical harmonics cosine."); + return OPENMC_E_INVALID_ARGUMENT; + } + return 0; + } + + int + openmc_zernike_filter_get_order(int32_t index, int* order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + *order = z_filt->order_; + return 0; + } + + int + openmc_zernike_filter_get_params(int32_t index, double* x, double* y, + double* r) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + *x = z_filt->x_; + *y = z_filt->y_; + *r = z_filt->r_; + return 0; + } + + int + openmc_zernike_filter_set_order(int32_t index, int order) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + z_filt->order_ = order; + z_filt->calc_n_bins(); + filter_update_n_bins(index); + return 0; + } + + int + openmc_zernike_filter_set_params(int32_t index, const double* x, + const double* y, const double* r) + { + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + if (x) z_filt->x_ = *x; + if (y) z_filt->y_ = *y; + if (r) z_filt->r_ = *r; + return 0; + } +} + //============================================================================== // Fortran compatibility functions //============================================================================== @@ -159,118 +552,10 @@ extern "C" { int filter_n_bins(TallyFilter* filt) {return filt->n_bins_;} - void - cell_filter_get_bins(CellFilter* filt, int32_t** cells, int32_t* n) - { - *cells = filt->cells_.data(); - *n = filt->cells_.size(); - } - - int legendre_filter_get_order(LegendreFilter* filt) - {return filt->order_;} - - void - legendre_filter_set_order(LegendreFilter* filt, int order) - { - filt->order_ = order; - filt->n_bins_ = order + 1; - } - - void - material_filter_get_bins(MaterialFilter* filt, int32_t** bins, int32_t* n) - { - *bins = filt->materials_.data(); - *n = filt->materials_.size(); - } - - void - material_filter_set_bins(MaterialFilter* filt, int32_t n, int32_t* bins) - { - filt->materials_.clear(); - filt->materials_.resize(n); - for (int i = 0; i < n; i++) filt->materials_[i] = bins[i]; - filt->n_bins_ = filt->materials_.size(); - filt->map_.clear(); - for (int i = 0; i < n; i++) filt->map_[filt->materials_[i]] = i; - } - int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} - void - mesh_filter_set_mesh(MeshFilter* filt, int mesh) - { - filt->mesh_ = mesh; - filt->n_bins_ = 1; - for (auto dim : meshes[mesh]->shape_) filt->n_bins_ *= dim; - } - - int meshsurface_filter_get_mesh(MeshSurfaceFilter* filt) {return filt->mesh_;} - - void - meshsurface_filter_set_mesh(MeshSurfaceFilter* filt, int mesh) - { - filt->mesh_ = mesh; - filt->n_bins_ = 4 * meshes[mesh]->n_dimension_; - for (auto dim : meshes[mesh]->shape_) filt->n_bins_ *= dim; - } - - int sphharm_filter_get_order(SphericalHarmonicsFilter* filt) - {return filt->order_;} - int sphharm_filter_get_cosine(SphericalHarmonicsFilter* filt) {return static_cast(filt->cosine_);} - - void - sphharm_filter_set_order(SphericalHarmonicsFilter* filt, int order) - { - filt->order_ = order; - filt->n_bins_ = (order + 1) * (order + 1); - } - - void sphharm_filter_set_cosine(SphericalHarmonicsFilter* filt, int cosine) - {filt->cosine_ = static_cast(cosine);} - - void - sptl_legendre_filter_get_params(SpatialLegendreFilter* filt, int* order, - int* axis, double* min, double* max) - { - *order = filt->order_; - *axis = static_cast(filt->axis_); - *min = filt->min_; - *max = filt->max_; - } - - void - sptl_legendre_filter_set_params(SpatialLegendreFilter* filt, int order, - int axis, double min, double max) - { - filt->order_ = order; - filt->axis_ = static_cast(axis); - filt->min_ = min; - filt->max_ = max; - filt->n_bins_ = order + 1; - } - - void - zernike_filter_get_params(ZernikeFilter* filt, int* order, double* x, - double* y, double* r) - { - *order = filt->order_; - *x = filt->x_; - *y = filt->y_; - *r = filt->r_; - } - - void - zernike_filter_set_params(ZernikeFilter* filt, int order, double x, - double y, double r) - { - filt->order_ = order; - filt->x_ = x; - filt->y_ = y; - filt->r_ = r; - filt->calc_n_bins(); - } } } // namespace openmc diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index f4201ffb7..808cbaf57 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -1,53 +1,14 @@ module tally_filter_cell - use, intrinsic :: ISO_C_BINDING - - use error use tally_filter_header implicit none - private - public :: openmc_cell_filter_get_bins !=============================================================================== ! CELLFILTER specifies which geometric cells tally events reside in. !=============================================================================== - type, public, extends(CppTallyFilter) :: CellFilter + type, extends(CppTallyFilter) :: CellFilter end type CellFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_cell_filter_get_bins(index, cells, n) result(err) bind(C) - ! Return the cells associated with a cell filter - integer(C_INT32_T), value :: index - type(C_PTR), intent(out) :: cells - integer(C_INT32_T), intent(out) :: n - integer(C_INT) :: err - - interface - subroutine cell_filter_get_bins(filt, cells, n) bind(C) - import C_PTR, C_INT - type(C_PTR), intent(in), value :: filt - type(C_PTR), intent(out) :: cells - integer(C_INT), intent(out) :: n - end subroutine cell_filter_get_bins - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (CellFilter) - call cell_filter_get_bins(f % ptr, cells, n) - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to get cells from a non-cell filter.") - end select - end if - end function openmc_cell_filter_get_bins - end module tally_filter_cell diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 93e1a82d6..a873310ff 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -424,8 +424,8 @@ contains ! array is sufficient and a filter object has already been allocated. !=============================================================================== - function verify_filter(index) result(err) - integer(C_INT32_T), intent(in) :: index + function verify_filter(index) result(err) bind(C) + integer(C_INT32_T), intent(in), value :: index integer(C_INT) :: err err = 0 @@ -440,6 +440,33 @@ contains end if end function verify_filter +!=============================================================================== +! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter. +!=============================================================================== + + function filter_from_f(index) result(filt) bind(C) + integer(C_INT32_T), intent(in), value :: index + type(C_PTR) :: filt + + filt = C_NULL_PTR + select type(f => filters(index) % obj) + class is (CppTallyFilter) + filt = f % ptr + end select + end function + +!=============================================================================== +! FILTER_UPDATE_N_BINS updates filt % n_bins using C++. +!=============================================================================== + + subroutine filter_update_n_bins(index) bind(C) + integer(C_INT32_T), intent(in), value :: index + select type(f => filters(index) % obj) + class is (CppTallyFilter) + f % n_bins = f % n_bins_cpp() + end select + end subroutine + !=============================================================================== ! C API FUNCTIONS !=============================================================================== diff --git a/src/tallies/tally_filter_legendre.F90 b/src/tallies/tally_filter_legendre.F90 index 60bb59c76..f4d2a3d81 100644 --- a/src/tallies/tally_filter_legendre.F90 +++ b/src/tallies/tally_filter_legendre.F90 @@ -2,13 +2,18 @@ module tally_filter_legendre use, intrinsic :: ISO_C_BINDING - use error use tally_filter_header implicit none - private - public :: openmc_legendre_filter_get_order - public :: openmc_legendre_filter_set_order + + interface + function openmc_legendre_filter_set_order(index, order) result(err) bind(C) + import C_INT32_T, C_INT + integer(C_INT32_T), value :: index + integer(C_INT), value :: order + integer(C_INT) :: err + end function + end interface !=============================================================================== ! LEGENDREFILTER gives Legendre moments of the change in scattering angle @@ -17,64 +22,4 @@ module tally_filter_legendre type, public, extends(CppTallyFilter) :: LegendreFilter end type LegendreFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_legendre_filter_get_order(index, order) result(err) bind(C) - ! Get the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(out) :: order - integer(C_INT) :: err - - interface - function legendre_filter_get_order(filt) result(order) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: order - end function - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (LegendreFilter) - order = legendre_filter_get_order(f % ptr) - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to get order on a non-expansion filter.") - end select - end if - end function openmc_legendre_filter_get_order - - - function openmc_legendre_filter_set_order(index, order) result(err) bind(C) - ! Set the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), value :: order - integer(C_INT) :: err - - interface - subroutine legendre_filter_set_order(filt, order) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT), value :: order - end subroutine legendre_filter_set_order - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (LegendreFilter) - call legendre_filter_set_order(f % ptr, order) - f % n_bins = f % n_bins_cpp() - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set order on a non-expansion filter.") - end select - end if - end function openmc_legendre_filter_set_order - end module tally_filter_legendre diff --git a/src/tallies/tally_filter_material.F90 b/src/tallies/tally_filter_material.F90 index 9b1b83d2d..f2bd7843c 100644 --- a/src/tallies/tally_filter_material.F90 +++ b/src/tallies/tally_filter_material.F90 @@ -1,8 +1,5 @@ module tally_filter_material - use, intrinsic :: ISO_C_BINDING - - use error use tally_filter_header implicit none @@ -14,72 +11,4 @@ module tally_filter_material type, extends(CppTallyFilter) :: MaterialFilter end type MaterialFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_material_filter_get_bins(index, bins, n) result(err) bind(C) - ! Return the bins for a material filter - integer(C_INT32_T), value :: index - type(C_PTR), intent(out) :: bins - integer(C_INT32_T), intent(out) :: n - integer(C_INT) :: err - - interface - subroutine material_filter_get_bins(filt, bins, n) bind(C) - import C_PTR, C_INT32_T - type(C_PTR), value :: filt - type(C_PTR) :: bins - integer(C_INT32_T) :: n - end subroutine material_filter_get_bins - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MaterialFilter) - call material_filter_get_bins(f % ptr, bins, n) - err = 0 - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to get material filter bins on a & - &non-material filter.") - end select - end if - end function openmc_material_filter_get_bins - - - function openmc_material_filter_set_bins(index, n, bins) result(err) bind(C) - ! Set the materials for the filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), value, intent(in) :: n - integer(C_INT32_T), intent(in) :: bins(n) - integer(C_INT) :: err - - interface - subroutine material_filter_set_bins(filt, n, bins) bind(C) - import C_PTR, C_INT32_T - type(C_PTR), value :: filt - integer(C_INT32_T), value :: n - integer(C_INT32_T) :: bins(n) - end subroutine material_filter_set_bins - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MaterialFilter) - call material_filter_set_bins(f % ptr, n, bins) - f % n_bins = f % n_bins_cpp() - - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set material filter bins on a & - &non-material filter.") - end select - end if - end function openmc_material_filter_set_bins - end module tally_filter_material diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index 5d2307aef..c26376601 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -2,15 +2,18 @@ module tally_filter_mesh use, intrinsic :: ISO_C_BINDING - use constants - use error - use mesh_header use tally_filter_header implicit none - private - public :: openmc_mesh_filter_get_mesh - public :: openmc_mesh_filter_set_mesh + + interface + function openmc_mesh_filter_set_mesh(index, index_mesh) result(err) bind(C) + import C_INT32_T, C_INT + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: index_mesh + integer(C_INT) :: err + end function + end interface !=============================================================================== ! MESHFILTER indexes the location of particle events to a regular mesh. For @@ -38,59 +41,4 @@ contains mesh = mesh_filter_get_mesh(this % ptr) end function get_mesh -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_mesh_filter_get_mesh(index, index_mesh) result(err) bind(C) - ! Get the mesh for a mesh filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), intent(out) :: index_mesh - integer(C_INT) :: err - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MeshFilter) - index_mesh = f % mesh() - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set mesh on a non-mesh filter.") - end select - end if - end function openmc_mesh_filter_get_mesh - - - function openmc_mesh_filter_set_mesh(index, index_mesh) result(err) bind(C) - ! Set the mesh for a mesh filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), value, intent(in) :: index_mesh - integer(C_INT) :: err - - interface - subroutine mesh_filter_set_mesh(filt, mesh) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT), value :: mesh - end subroutine mesh_filter_set_mesh - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MeshFilter) - if (index_mesh >= 0 .and. index_mesh < n_meshes()) then - call mesh_filter_set_mesh(f % ptr, index_mesh) - f % n_bins = f % n_bins_cpp() - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in 'meshes' array is out of bounds.") - end if - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set mesh on a non-mesh filter.") - end select - end if - end function openmc_mesh_filter_set_mesh - end module tally_filter_mesh diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index 22453a40f..0b10c9cce 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -8,9 +8,16 @@ module tally_filter_meshsurface use tally_filter_header implicit none - private - public :: openmc_meshsurface_filter_get_mesh - public :: openmc_meshsurface_filter_set_mesh + + interface + function openmc_meshsurface_filter_set_mesh(index, index_mesh) result(err) & + bind(C) + import C_INT32_T, C_INT + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: index_mesh + integer(C_INT) :: err + end function + end interface !=============================================================================== ! MESHFILTER indexes the location of particle events to a regular mesh. For @@ -18,72 +25,7 @@ module tally_filter_meshsurface ! will correspond to the fraction of the track length that lies in that bin. !=============================================================================== - type, public, extends(CppTallyFilter) :: MeshSurfaceFilter + type, extends(CppTallyFilter) :: MeshSurfaceFilter end type MeshSurfaceFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_meshsurface_filter_get_mesh(index, index_mesh) result(err) bind(C) - ! Get the mesh for a mesh surface filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), intent(out) :: index_mesh - integer(C_INT) :: err - - interface - function meshsurface_filter_get_mesh(filt) result(index_mesh) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: index_mesh - end function meshsurface_filter_get_mesh - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MeshSurfaceFilter) - index_mesh = meshsurface_filter_get_mesh(f % ptr) - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set mesh on a non-mesh filter.") - end select - end if - end function openmc_meshsurface_filter_get_mesh - - - function openmc_meshsurface_filter_set_mesh(index, index_mesh) result(err) bind(C) - ! Set the mesh for a mesh surface filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), value, intent(in) :: index_mesh - integer(C_INT) :: err - - interface - subroutine meshsurface_filter_set_mesh(filt, mesh) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT), value :: mesh - end subroutine meshsurface_filter_set_mesh - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (MeshSurfaceFilter) - if (index_mesh >= 0 .and. index_mesh < n_meshes()) then - call meshsurface_filter_set_mesh(f % ptr, index_mesh) - f % n_bins = f % n_bins_cpp() - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in 'meshes' array is out of bounds.") - end if - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to set mesh on a non-mesh filter.") - end select - end if - end function openmc_meshsurface_filter_set_mesh - end module tally_filter_meshsurface diff --git a/src/tallies/tally_filter_sph_harm.F90 b/src/tallies/tally_filter_sph_harm.F90 index 59120940c..a2854841c 100644 --- a/src/tallies/tally_filter_sph_harm.F90 +++ b/src/tallies/tally_filter_sph_harm.F90 @@ -2,16 +2,10 @@ module tally_filter_sph_harm use, intrinsic :: ISO_C_BINDING - use error - use string, only: to_str, to_lower, to_f_string use tally_filter_header implicit none private - public :: openmc_sphharm_filter_get_order - public :: openmc_sphharm_filter_get_cosine - public :: openmc_sphharm_filter_set_order - public :: openmc_sphharm_filter_set_cosine integer, public, parameter :: COSINE_SCATTER = 1 integer, public, parameter :: COSINE_PARTICLE = 2 @@ -41,133 +35,4 @@ contains val = sphharm_filter_get_cosine(this % ptr) end function cosine -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_sphharm_filter_get_order(index, order) result(err) bind(C) - ! Get the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(out) :: order - integer(C_INT) :: err - - interface - function sphharm_filter_get_order(filt) result(order) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: order - end function sphharm_filter_get_order - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SphericalHarmonicsFilter) - order = sphharm_filter_get_order(f % ptr) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spherical harmonics filter.") - end select - end if - end function openmc_sphharm_filter_get_order - - - function openmc_sphharm_filter_get_cosine(index, cosine) result(err) bind(C) - ! Get the order of an expansion filter - integer(C_INT32_T), value :: index - character(kind=C_CHAR), intent(out) :: cosine(*) - integer(C_INT) :: err - - integer :: i - character(10) :: cosine_ - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SphericalHarmonicsFilter) - select case (f % cosine()) - case (COSINE_SCATTER) - cosine_ = 'scatter' - case (COSINE_PARTICLE) - cosine_ = 'particle' - end select - - ! Convert to C string - do i = 1, len_trim(cosine_) - cosine(i) = cosine_(i:i) - end do - cosine(len_trim(cosine_) + 1) = C_NULL_CHAR - - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spherical harmonics filter.") - end select - end if - end function openmc_sphharm_filter_get_cosine - - - function openmc_sphharm_filter_set_order(index, order) result(err) bind(C) - ! Set the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), value :: order - integer(C_INT) :: err - - interface - subroutine sphharm_filter_set_order(filt, order) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT), value :: order - end subroutine - end interface - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SphericalHarmonicsFilter) - call sphharm_filter_set_order(f % ptr, order) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spherical harmonics filter.") - end select - end if - end function openmc_sphharm_filter_set_order - - - function openmc_sphharm_filter_set_cosine(index, cosine) result(err) bind(C) - ! Set the cosine parameter - integer(C_INT32_T), value :: index - character(kind=C_CHAR), intent(in) :: cosine(*) - integer(C_INT) :: err - - character(:), allocatable :: cosine_ - - interface - subroutine sphharm_filter_set_cosine(filt, cosine) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT), value :: cosine - end subroutine - end interface - - ! Convert C string to Fortran string - cosine_ = to_f_string(cosine) - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SphericalHarmonicsFilter) - select case (cosine_) - case ('scatter') - call sphharm_filter_set_cosine(f % ptr, COSINE_SCATTER) - case ('particle') - call sphharm_filter_set_cosine(f % ptr, COSINE_PARTICLE) - end select - - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spherical harmonics filter.") - end select - end if - end function openmc_sphharm_filter_set_cosine - end module tally_filter_sph_harm diff --git a/src/tallies/tally_filter_sptl_legendre.F90 b/src/tallies/tally_filter_sptl_legendre.F90 index f883e4aec..f73e2322a 100644 --- a/src/tallies/tally_filter_sptl_legendre.F90 +++ b/src/tallies/tally_filter_sptl_legendre.F90 @@ -1,149 +1,15 @@ module tally_filter_sptl_legendre - use, intrinsic :: ISO_C_BINDING - - use error use tally_filter_header implicit none - private - public :: openmc_spatial_legendre_filter_get_order - public :: openmc_spatial_legendre_filter_get_params - public :: openmc_spatial_legendre_filter_set_order - public :: openmc_spatial_legendre_filter_set_params - - interface - subroutine sptl_legendre_filter_get_params(filt, order, axis, min, max) & - bind(C) - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), value :: filt - integer(C_INT) :: order - integer(C_INT) :: axis - real(C_DOUBLE) :: min - real(C_DOUBLE) :: max - end subroutine - - subroutine sptl_legendre_filter_set_params(filt, order, axis, min, max) & - bind(C) - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), value :: filt - integer(C_INT), value :: order - integer(C_INT), value :: axis - real(C_DOUBLE), value :: min - real(C_DOUBLE), value :: max - end subroutine - end interface !=============================================================================== ! SPATIALLEGENDREFILTER gives Legendre moments of the particle's normalized ! position along an axis !=============================================================================== - type, public, extends(CppTallyFilter) :: SpatialLegendreFilter + type, extends(CppTallyFilter) :: SpatialLegendreFilter end type SpatialLegendreFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_spatial_legendre_filter_get_order(index, order) result(err) bind(C) - ! Get the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(out) :: order - integer(C_INT) :: err - - integer(C_INT) :: axis - real(C_DOUBLE) :: min, max - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SpatialLegendreFilter) - call sptl_legendre_filter_get_params(f % ptr, order, axis, min, max) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spatial Legendre filter.") - end select - end if - end function openmc_spatial_legendre_filter_get_order - - - function openmc_spatial_legendre_filter_set_order(index, order) result(err) bind(C) - ! Set the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), value :: order - integer(C_INT) :: err - - integer(C_INT) :: axis, order_ - real(C_DOUBLE) :: min, max - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (SpatialLegendreFilter) - call sptl_legendre_filter_get_params(f % ptr, order_, axis, min, max) - call sptl_legendre_filter_set_params(f % ptr, order, axis, min, max) - f % n_bins = f % n_bins_cpp() - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spatial Legendre filter.") - end select - end if - end function openmc_spatial_legendre_filter_set_order - - - function openmc_spatial_legendre_filter_get_params(index, axis, min, max) & - result(err) bind(C) - ! Get the parameters for a spatial Legendre filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(out) :: axis - real(C_DOUBLE), intent(out) :: min - real(C_DOUBLE), intent(out) :: max - integer(C_INT) :: err - - integer(C_INT) :: order - - err = verify_filter(index) - if (err == 0) then - select type(f => filters(index) % obj) - type is (SpatialLegendreFilter) - call sptl_legendre_filter_get_params(f % ptr, order, axis, min, max) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spatial Legendre filter.") - end select - end if - end function openmc_spatial_legendre_filter_get_params - - - function openmc_spatial_legendre_filter_set_params(index, axis, min, max) & - result(err) bind(C) - ! Set the parameters for a spatial Legendre filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(in), optional :: axis - real(C_DOUBLE), intent(in), optional :: min - real(C_DOUBLE), intent(in), optional :: max - integer(C_INT) :: err - - integer(C_INT) :: order, axis_ - real(C_DOUBLE) :: min_, max_ - - err = verify_filter(index) - if (err == 0) then - select type(f => filters(index) % obj) - type is (SpatialLegendreFilter) - call sptl_legendre_filter_get_params(f % ptr, order, axis_, min_, max_) - if (present(axis)) axis_ = axis - if (present(min)) min_ = min - if (present(max)) max_ = max - call sptl_legendre_filter_set_params(f % ptr, order, axis_, min_, max_) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a spatial Legendre filter.") - end select - end if - end function openmc_spatial_legendre_filter_set_params - end module tally_filter_sptl_legendre diff --git a/src/tallies/tally_filter_zernike.F90 b/src/tallies/tally_filter_zernike.F90 index aabb21f3f..c4330120d 100644 --- a/src/tallies/tally_filter_zernike.F90 +++ b/src/tallies/tally_filter_zernike.F90 @@ -1,38 +1,14 @@ module tally_filter_zernike - use, intrinsic :: ISO_C_BINDING - - use error use tally_filter_header implicit none - private - public :: openmc_zernike_filter_get_order - public :: openmc_zernike_filter_get_params - public :: openmc_zernike_filter_set_order - public :: openmc_zernike_filter_set_params - - interface - subroutine zernike_filter_get_params(filt, order, x, y, r) bind(C) - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), value :: filt - integer(C_INT) :: order - real(C_DOUBLE) :: x, y, r - end subroutine - - subroutine zernike_filter_set_params(filt, order, x, y, r) bind(C) - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), value :: filt - integer(C_INT), value :: order - real(C_DOUBLE), value :: x, y, r - end subroutine - end interface !=============================================================================== ! ZERNIKEFILTER gives Zernike polynomial moments of a particle's position !=============================================================================== - type, public, extends(CppTallyFilter) :: ZernikeFilter + type, extends(CppTallyFilter) :: ZernikeFilter end type ZernikeFilter !=============================================================================== @@ -40,107 +16,7 @@ module tally_filter_zernike ! particle's position !=============================================================================== - type, public, extends(ZernikeFilter) :: ZernikeRadialFilter + type, extends(ZernikeFilter) :: ZernikeRadialFilter end type ZernikeRadialFilter -contains - -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_zernike_filter_get_order(index, order) result(err) bind(C) - ! Get the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), intent(out) :: order - integer(C_INT) :: err - - real(C_DOUBLE) :: x, y, r - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - class is (ZernikeFilter) - call zernike_filter_get_params(f % ptr, order, x, y, r) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a Zernike filter.") - end select - end if - end function openmc_zernike_filter_get_order - - - function openmc_zernike_filter_get_params(index, x, y, r) result(err) bind(C) - ! Get the Zernike filter parameters - integer(C_INT32_T), value :: index - real(C_DOUBLE), intent(out) :: x - real(C_DOUBLE), intent(out) :: y - real(C_DOUBLE), intent(out) :: r - integer(C_INT) :: err - - integer(C_INT) :: order - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - class is (ZernikeFilter) - call zernike_filter_get_params(f % ptr, order, x, y, r) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a Zernike filter.") - end select - end if - end function openmc_zernike_filter_get_params - - - function openmc_zernike_filter_set_order(index, order) result(err) bind(C) - ! Set the order of an expansion filter - integer(C_INT32_T), value :: index - integer(C_INT), value :: order - integer(C_INT) :: err - - integer(C_INT) :: order_ - real(C_DOUBLE) :: x, y, r - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - class is (ZernikeFilter) - call zernike_filter_get_params(f % ptr, order_, x, y, r) - call zernike_filter_set_params(f % ptr, order, x, y, r) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a Zernike filter.") - end select - end if - end function openmc_zernike_filter_set_order - - - function openmc_zernike_filter_set_params(index, x, y, r) result(err) bind(C) - ! Set the Zernike filter parameters - integer(C_INT32_T), value :: index - real(C_DOUBLE), intent(in), optional :: x - real(C_DOUBLE), intent(in), optional :: y - real(C_DOUBLE), intent(in), optional :: r - integer(C_INT) :: err - - integer(C_INT) :: order - real(C_DOUBLE) :: x_, y_, r_ - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - class is (ZernikeFilter) - call zernike_filter_get_params(f % ptr, order, x_, y_, r_) - if (present(x)) x_ = x - if (present(y)) y_ = y - if (present(r)) r_ = r - call zernike_filter_set_params(f % ptr, order, x_, y_, r_) - class default - err = E_INVALID_TYPE - call set_errmsg("Not a Zernike filter.") - end select - end if - end function openmc_zernike_filter_set_params - end module tally_filter_zernike From 3beaf4f36473b65f95ead46f0963979d272069a5 Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 19 Oct 2018 16:43:01 -0400 Subject: [PATCH 33/45] update WMP file format to v1.1 --- docs/source/io_formats/data_wmp.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/source/io_formats/data_wmp.rst b/docs/source/io_formats/data_wmp.rst index 25916c522..8d7cf6ba0 100644 --- a/docs/source/io_formats/data_wmp.rst +++ b/docs/source/io_formats/data_wmp.rst @@ -4,10 +4,15 @@ Windowed Multipole Library Format ================================= -**/version** (*char[]*) - The format version of the file. The current version is "v1.0" +**/** + +:Attributes: - **filetype** (*char[]*) -- String indicating the type of file + - **version** (*int[2]*) -- Major and minor version of the data + +**//** + +:Datasets: -**/nuclide/** - **broaden_poly** (*int[]*) If 1, Doppler broaden curve fit for window with corresponding index. If 0, do not. From 1343ce472d1c93790a2ce9fa0ed30725c1ccff3c Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 19 Oct 2018 16:44:17 -0400 Subject: [PATCH 34/45] download WMP library v1.1 --- scripts/openmc-get-multipole-data | 6 +++--- tools/ci/download-xs.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/openmc-get-multipole-data b/scripts/openmc-get-multipole-data index c8a2d1e9b..554a18428 100755 --- a/scripts/openmc-get-multipole-data +++ b/scripts/openmc-get-multipole-data @@ -29,9 +29,9 @@ parser.add_argument('-b', '--batch', action='store_true', args = parser.parse_args() -baseUrl = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/' -files = ['WMP_Library_v1.0.tar.gz'] -checksums = ['22cb675734cfccb278dffd40dcfbf26a'] +baseUrl = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/' +files = ['WMP_Library_v1.1.tar.gz'] +checksums = ['8523895928dd6ba63fba803e3a45d4f3'] block_size = 16384 # ============================================================================== diff --git a/tools/ci/download-xs.sh b/tools/ci/download-xs.sh index ff430ab2c..eed9e23c4 100755 --- a/tools/ci/download-xs.sh +++ b/tools/ci/download-xs.sh @@ -14,6 +14,6 @@ fi # Download multipole library if [[ ! -e $HOME/WMP_Library/092235.h5 ]]; then - wget -q https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/WMP_Library_v1.0.tar.gz - tar -C $HOME -xzf WMP_Library_v1.0.tar.gz + wget -q https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/WMP_Library_v1.1.tar.gz + tar -C $HOME -xzf WMP_Library_v1.1.tar.gz fi From 5351f723611be28a574d5cb399daa68027538c0c Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 19 Oct 2018 16:47:42 -0400 Subject: [PATCH 35/45] openmc reads v1.1 library now --- src/constants.F90 | 3 ++ src/input_xml.F90 | 21 ++++++++--- src/multipole_header.F90 | 77 +++++++++++++++++++++++----------------- src/nuclide_header.F90 | 2 +- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/constants.F90 b/src/constants.F90 index a3118f84d..3e8cbb2dd 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -17,6 +17,9 @@ module constants ! HDF5 data format integer, parameter :: HDF5_VERSION(2) = [1, 0] + ! WMP data format + integer, parameter :: WMP_VERSION(2) = [1, 1] + ! Version numbers for binary files integer, parameter :: VERSION_STATEPOINT(2) = [17, 0] integer, parameter :: VERSION_PARTICLE_RESTART(2) = [2, 0] diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 81f323351..f0e8a5fdd 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -22,6 +22,7 @@ module input_xml use mgxs_data, only: create_macro_xs, read_mgxs use mgxs_interface use nuclide_header + use multipole_header use output, only: title, header, print_plot use photon_header use plot_header @@ -3110,7 +3111,9 @@ contains logical :: file_exists ! Does multipole library exist? character(7) :: readable ! Is multipole library readable? - character(MAX_FILE_LEN) :: filename ! Path to multipole xs library + character(MAX_FILE_LEN) :: filename ! Path to multipole xs library + integer(HID_T) :: file_id + integer(HID_T) :: group_id ! For the time being, and I know this is a bit hacky, we just assume ! that the file will be ZZZAAAmM.h5. @@ -3136,14 +3139,22 @@ contains end if ! Display message - call write_message("Loading Multipole XS table: " // filename, 6) + call write_message("Loading Windowed Multipole XS from " // filename, 6) + ! Open file and make sure version is sufficient + file_id = file_open(filename, 'r') + call check_wmp_version(file_id) + + ! Read nuclide data from HDF5 + group_id = open_group(file_id, nuc % name) allocate(nuc % multipole) - - ! Call the read routine - call nuc % multipole % from_hdf5(filename) + call nuc % multipole % from_hdf5(group_id) nuc % mp_present = .true. + ! Close the group and file. + call close_group(group_id) + call file_close(file_id) + end associate end subroutine read_multipole_data diff --git a/src/multipole_header.F90 b/src/multipole_header.F90 index 64610e471..359bb3ac1 100644 --- a/src/multipole_header.F90 +++ b/src/multipole_header.F90 @@ -1,8 +1,9 @@ module multipole_header use constants - use error, only: fatal_error use hdf5_interface + use error, only: fatal_error + use string, only: to_str implicit none @@ -30,17 +31,15 @@ module multipole_header type MultipoleArray - !========================================================================= + character(20) :: name ! name of nuclide, e.g. U235 + ! Isotope Properties + logical :: fissionable ! Is this isotope fissionable? + complex(8), allocatable :: data(:,:) ! Poles and residues + real(8) :: sqrtAWR ! Square root of the atomic + ! weight ratio - logical :: fissionable ! Is this isotope fissionable? - complex(8), allocatable :: data(:,:) ! Poles and residues - real(8) :: sqrtAWR ! Square root of the atomic - ! weight ratio - - !========================================================================= ! Windows - integer :: fit_order ! Order of the fit. 1 linear, ! 2 quadratic, etc. real(8) :: E_min ! Start energy for the windows @@ -53,11 +52,9 @@ module multipole_header real(8), allocatable :: curvefit(:,:,:) ! Contains the fitting function. ! (reaction type, coeff index, ! window index) - integer, allocatable :: broaden_poly(:) ! if 1, broaden, if 0, don't. contains - procedure :: from_hdf5 => multipole_from_hdf5 end type MultipoleArray @@ -65,29 +62,22 @@ module multipole_header contains !=============================================================================== -! FROM_HDF5 loads multipole data from an HDF5 file. +! FROM_HDF5 loads multipole data from a HDF5 file. !=============================================================================== - subroutine multipole_from_hdf5(this, filename) + subroutine multipole_from_hdf5(this, group_id) class(MultipoleArray), intent(inout) :: this - character(len=*), intent(in) :: filename + integer(HID_T), intent(in) :: group_id - character(len=10) :: version integer :: n_poles, n_residues, n_windows integer(HSIZE_T) :: dims_1d(1), dims_2d(2), dims_3d(3) - integer(HID_T) :: file_id - integer(HID_T) :: group_id integer(HID_T) :: dset - ! Open file for reading and move into the /isotope group - file_id = file_open(filename, 'r', parallel=.true.) - group_id = open_group(file_id, "/nuclide") + ! Get name of nuclide from group + this % name = get_name(group_id) - ! Check the file version number. - call read_dataset(version, file_id, "version") - if (version /= VERSION_MULTIPOLE) call fatal_error("The current multipole& - & format version is " // trim(VERSION_MULTIPOLE) // " but the file "& - // trim(filename) // " uses version " // trim(version) // ".") + ! Get rid of leading '/' + this % name = trim(this % name(2:)) ! Read scalar values. call read_dataset(this % spacing, group_id, "spacing") @@ -121,8 +111,8 @@ contains dset = open_dataset(group_id, "broaden_poly") call get_shape(dset, dims_1d) if (dims_1d(1) /= n_windows) call fatal_error("broaden_poly array shape is& - ¬ consistent with the windows array shape in multipole library"& - // trim(filename) // ".") + ¬ consistent with the windows array shape in WMP library for"& + // trim(this % name) // ".") allocate(this % broaden_poly(n_windows)) call read_dataset(this % broaden_poly, dset) call close_dataset(dset) @@ -131,15 +121,38 @@ contains dset = open_dataset(group_id, "curvefit") call get_shape(dset, dims_3d) if (dims_3d(3) /= n_windows) call fatal_error("curvefit array shape is not& - &consistent with the windows array shape in multipole library"& - // trim(filename) // ".") + &consistent with the windows array shape in WMP library for"& + // trim(this % name) // ".") allocate(this % curvefit(dims_3d(1), dims_3d(2), dims_3d(3))) call read_dataset(this % curvefit, dset) call close_dataset(dset) this % fit_order = int(dims_3d(2), 4) - 1 - ! Close the group and file. - call close_group(group_id) - call file_close(file_id) end subroutine multipole_from_hdf5 + +!=============================================================================== +! CHECK_WMP_VERSION checks for the right version of WMP data within HDF5 +! files +!=============================================================================== + + subroutine check_wmp_version(file_id) + integer(HID_T), intent(in) :: file_id + + integer, allocatable :: version(:) + + if (attribute_exists(file_id, 'version')) then + call read_attribute(version, file_id, 'version') + if (version(1) /= WMP_VERSION(1)) then + call fatal_error("WMP data format uses version " // trim(to_str(& + version(1))) // "." // trim(to_str(version(2))) // " whereas & + &your installation of OpenMC expects version " // trim(to_str(& + WMP_VERSION(1))) // ".x data.") + end if + else + call fatal_error("WMP data does not indicate a version. Your & + &installation of OpenMC expects version " // trim(to_str(& + WMP_VERSION(1))) // ".x data.") + end if + end subroutine check_wmp_version + end module multipole_header diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 341ff6511..da66aea4a 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -53,7 +53,7 @@ module nuclide_header type :: Nuclide ! Nuclide meta-data - character(20) :: name ! name of nuclide, e.g. U235.71c + character(20) :: name ! name of nuclide, e.g. U235 integer :: Z ! atomic number integer :: A ! mass number integer :: metastable ! metastable state From 31b92723c6a7231830672b45f8ed7cc984301ba3 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Oct 2018 16:52:02 -0400 Subject: [PATCH 36/45] Clean up tally filter code --- CMakeLists.txt | 13 +- include/openmc/tallies/tally_filter.h | 18 +- .../openmc/tallies/tally_filter_azimuthal.h | 8 +- include/openmc/tallies/tally_filter_cell.h | 8 +- .../openmc/tallies/tally_filter_cellborn.h | 8 +- .../openmc/tallies/tally_filter_cellfrom.h | 8 +- .../openmc/tallies/tally_filter_distribcell.h | 8 +- .../openmc/tallies/tally_filter_energyfunc.h | 9 +- .../openmc/tallies/tally_filter_legendre.h | 8 +- .../openmc/tallies/tally_filter_material.h | 8 +- include/openmc/tallies/tally_filter_mesh.h | 12 +- .../openmc/tallies/tally_filter_meshsurface.h | 4 +- include/openmc/tallies/tally_filter_mu.h | 9 +- include/openmc/tallies/tally_filter_polar.h | 8 +- .../openmc/tallies/tally_filter_sph_harm.h | 8 +- .../tallies/tally_filter_sptl_legendre.h | 8 +- include/openmc/tallies/tally_filter_surface.h | 10 +- .../openmc/tallies/tally_filter_universe.h | 9 +- include/openmc/tallies/tally_filter_zernike.h | 16 +- src/tallies/tally_filter.F90 | 13 +- src/tallies/tally_filter.cpp | 16 +- src/tallies/tally_filter_azimuthal.F90 | 15 -- src/tallies/tally_filter_cell.F90 | 14 -- src/tallies/tally_filter_cellborn.F90 | 14 -- src/tallies/tally_filter_cellfrom.F90 | 18 -- src/tallies/tally_filter_cpp.F90 | 235 ++++++++++++++++++ src/tallies/tally_filter_distribcell.F90 | 7 +- src/tallies/tally_filter_energyfunc.F90 | 15 -- src/tallies/tally_filter_header.F90 | 172 +------------ src/tallies/tally_filter_legendre.F90 | 8 +- src/tallies/tally_filter_material.F90 | 14 -- src/tallies/tally_filter_mesh.F90 | 8 +- src/tallies/tally_filter_meshsurface.F90 | 11 +- src/tallies/tally_filter_mu.F90 | 15 -- src/tallies/tally_filter_polar.F90 | 15 -- src/tallies/tally_filter_sph_harm.F90 | 7 +- src/tallies/tally_filter_sptl_legendre.F90 | 15 -- src/tallies/tally_filter_surface.F90 | 16 -- src/tallies/tally_filter_universe.F90 | 14 -- src/tallies/tally_filter_zernike.F90 | 22 -- 40 files changed, 376 insertions(+), 468 deletions(-) delete mode 100644 src/tallies/tally_filter_azimuthal.F90 delete mode 100644 src/tallies/tally_filter_cell.F90 delete mode 100644 src/tallies/tally_filter_cellborn.F90 delete mode 100644 src/tallies/tally_filter_cellfrom.F90 create mode 100644 src/tallies/tally_filter_cpp.F90 delete mode 100644 src/tallies/tally_filter_energyfunc.F90 delete mode 100644 src/tallies/tally_filter_material.F90 delete mode 100644 src/tallies/tally_filter_mu.F90 delete mode 100644 src/tallies/tally_filter_polar.F90 delete mode 100644 src/tallies/tally_filter_sptl_legendre.F90 delete mode 100644 src/tallies/tally_filter_surface.F90 delete mode 100644 src/tallies/tally_filter_universe.F90 delete mode 100644 src/tallies/tally_filter_zernike.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c8b5e17e..feb3776ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,26 +373,15 @@ add_library(libopenmc SHARED src/tallies/tally_derivative_header.F90 src/tallies/tally_filter.F90 src/tallies/tally_filter_header.F90 - src/tallies/tally_filter_azimuthal.F90 - src/tallies/tally_filter_cell.F90 - src/tallies/tally_filter_cellborn.F90 - src/tallies/tally_filter_cellfrom.F90 + src/tallies/tally_filter_cpp.F90 src/tallies/tally_filter_delayedgroup.F90 src/tallies/tally_filter_distribcell.F90 src/tallies/tally_filter_energy.F90 - src/tallies/tally_filter_energyfunc.F90 src/tallies/tally_filter_legendre.F90 - src/tallies/tally_filter_material.F90 src/tallies/tally_filter_mesh.F90 src/tallies/tally_filter_meshsurface.F90 - src/tallies/tally_filter_mu.F90 src/tallies/tally_filter_particle.F90 - src/tallies/tally_filter_polar.F90 src/tallies/tally_filter_sph_harm.F90 - src/tallies/tally_filter_sptl_legendre.F90 - src/tallies/tally_filter_surface.F90 - src/tallies/tally_filter_universe.F90 - src/tallies/tally_filter_zernike.F90 src/tallies/tally_header.F90 src/tallies/trigger.F90 src/tallies/trigger_header.F90 diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 73b8eda64..08d92f404 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -32,10 +32,10 @@ extern std::vector tally_filters; class TallyFilterMatch { public: - //int i_bin; - std::vector bins; - std::vector weights; - //bool bins_present; + //int i_bin_; + std::vector bins_; + std::vector weights_; + //bool bins_present_; }; //============================================================================== @@ -49,11 +49,17 @@ public: virtual ~TallyFilter() = 0; + //! Uses an XML input to fill the filter's data fields. virtual void from_xml(pugi::xml_node node) = 0; + //! Matches a tally event to a set of filter bins and weights. + //! + //! \param[out] match will contain the matching bins and corresponding + //! weights; note that there may be zero matching bins virtual void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; + //! Writes data describing this filter to an HDF5 statepoint group. virtual void to_statepoint(hid_t filter_group) const { @@ -61,6 +67,10 @@ public: write_dataset(filter_group, "n_bins", n_bins_); } + //! Return a string describing a filter bin for the tallies.out file. + // + //! For example, an `EnergyFilter` might return the string + //! "Incoming Energy [0.625E-6, 20.0)". virtual std::string text_label(int bin) const = 0; virtual void initialize() {} diff --git a/include/openmc/tallies/tally_filter_azimuthal.h b/include/openmc/tallies/tally_filter_azimuthal.h index 182e32bc0..556cfff92 100644 --- a/include/openmc/tallies/tally_filter_azimuthal.h +++ b/include/openmc/tallies/tally_filter_azimuthal.h @@ -12,6 +12,10 @@ namespace openmc { +//============================================================================== +//! Bins the incident neutron azimuthal angle (relative to the global xy-plane). +//============================================================================== + class AzimuthalFilter : public TallyFilter { public: @@ -58,8 +62,8 @@ public: if (phi >= bins_[0] && phi <= bins_.back()) { auto bin = lower_bound_index(bins_.begin(), bins_.end(), phi) + 1; - match.bins.push_back(bin); - match.weights.push_back(1); + match.bins_.push_back(bin); + match.weights_.push_back(1); } } diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index cdf9a00cf..c3b39eeb8 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -13,6 +13,10 @@ namespace openmc { +//============================================================================== +//! Specifies which geometric cells tally events reside in. +//============================================================================== + class CellFilter : public TallyFilter { public: @@ -54,8 +58,8 @@ public: auto search = map_.find(p->coord[i].cell); if (search != map_.end()) { // TODO: off-by-one - match.bins.push_back(search->second + 1); - match.weights.push_back(1); + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); } } } diff --git a/include/openmc/tallies/tally_filter_cellborn.h b/include/openmc/tallies/tally_filter_cellborn.h index 92e8721e7..df77fe2b8 100644 --- a/include/openmc/tallies/tally_filter_cellborn.h +++ b/include/openmc/tallies/tally_filter_cellborn.h @@ -5,6 +5,10 @@ namespace openmc { +//============================================================================== +//! Specifies which cell the particle was born in. +//============================================================================== + class CellbornFilter : public CellFilter { public: @@ -17,8 +21,8 @@ public: auto search = map_.find(p->cell_born); if (search != map_.end()) { // TODO: off-by-one - match.bins.push_back(search->second + 1); - match.weights.push_back(1); + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); } } diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index 1b7e8f6db..a45b97719 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -6,6 +6,10 @@ namespace openmc { +//============================================================================== +//! Specifies which geometric cells particles exit when crossing a surface. +//============================================================================== + class CellFromFilter : public CellFilter { public: @@ -19,8 +23,8 @@ public: auto search = map_.find(p->last_cell[i]); if (search != map_.end()) { // TODO: off-by-one - match.bins.push_back(search->second + 1); - match.weights.push_back(1); + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); } } } diff --git a/include/openmc/tallies/tally_filter_distribcell.h b/include/openmc/tallies/tally_filter_distribcell.h index 97a016bc4..45894c8a5 100644 --- a/include/openmc/tallies/tally_filter_distribcell.h +++ b/include/openmc/tallies/tally_filter_distribcell.h @@ -12,6 +12,10 @@ namespace openmc { +//============================================================================== +//! Specifies which distributed geometric cells tally events reside in. +//============================================================================== + class DistribcellFilter : public TallyFilter { public: @@ -64,8 +68,8 @@ public: } } if (cell_ == p->coord[i].cell) { - match.bins.push_back(offset + 1); - match.weights.push_back(1); + match.bins_.push_back(offset + 1); + match.weights_.push_back(1); return; } } diff --git a/include/openmc/tallies/tally_filter_energyfunc.h b/include/openmc/tallies/tally_filter_energyfunc.h index f180a57a3..87b40dc46 100644 --- a/include/openmc/tallies/tally_filter_energyfunc.h +++ b/include/openmc/tallies/tally_filter_energyfunc.h @@ -14,6 +14,11 @@ namespace openmc { +//============================================================================== +//! Multiplies tally scores by an arbitrary function of incident energy +//! described by a piecewise linear-linear interpolation. +//============================================================================== + class EnergyFunctionFilter : public TallyFilter { public: @@ -57,8 +62,8 @@ public: double f = (p->last_E - energy_[i]) / (energy_[i+1] - energy_[i]); // Interpolate on the lin-lin grid. - match.bins.push_back(1); - match.weights.push_back((1-f) * y_[i] + f * y_[i+1]); + match.bins_.push_back(1); + match.weights_.push_back((1-f) * y_[i] + f * y_[i+1]); } } diff --git a/include/openmc/tallies/tally_filter_legendre.h b/include/openmc/tallies/tally_filter_legendre.h index f70cdf663..42ee1a0f6 100644 --- a/include/openmc/tallies/tally_filter_legendre.h +++ b/include/openmc/tallies/tally_filter_legendre.h @@ -11,6 +11,10 @@ namespace openmc { +//============================================================================== +//! Gives Legendre moments of the change in scattering angle +//============================================================================== + class LegendreFilter : public TallyFilter { public: @@ -32,8 +36,8 @@ public: double wgt[n_bins_]; calc_pn_c(order_, p->mu, wgt); for (int i = 0; i < n_bins_; i++) { - match.bins.push_back(i + 1); - match.weights.push_back(wgt[i]); + match.bins_.push_back(i + 1); + match.weights_.push_back(wgt[i]); } } diff --git a/include/openmc/tallies/tally_filter_material.h b/include/openmc/tallies/tally_filter_material.h index 92f2df640..41e551ef0 100644 --- a/include/openmc/tallies/tally_filter_material.h +++ b/include/openmc/tallies/tally_filter_material.h @@ -13,6 +13,10 @@ namespace openmc { +//============================================================================== +//! Specifies which material tally events reside in. +//============================================================================== + class MaterialFilter : public TallyFilter { public: @@ -54,8 +58,8 @@ public: auto search = map_.find(p->material - 1); if (search != map_.end()) { // TODO: off-by-one - match.bins.push_back(search->second + 1); - match.weights.push_back(1); + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); } } diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index 0fba1ca0c..ca97a9b68 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -12,6 +12,12 @@ namespace openmc { +//============================================================================== +//! Indexes the location of particle events to a regular mesh. For tracklength +//! tallies, it will produce multiple valid bins and the bin weight will +//! correspond to the fraction of the track length that lies in that bin. +//============================================================================== + class MeshFilter : public TallyFilter { public: @@ -49,11 +55,11 @@ public: if (estimator != ESTIMATOR_TRACKLENGTH) { auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); if (bin >= 0) { - match.bins.push_back(bin); - match.weights.push_back(1.0); + match.bins_.push_back(bin); + match.weights_.push_back(1.0); } } else { - meshes[mesh_]->bins_crossed(p, match.bins, match.weights); + meshes[mesh_]->bins_crossed(p, match.bins_, match.weights_); } } diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 99a748481..6588f646a 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -29,8 +29,8 @@ public: get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { - meshes[mesh_]->surface_bins_crossed(p, match.bins); - for (auto b : match.bins) match.weights.push_back(1.0); + meshes[mesh_]->surface_bins_crossed(p, match.bins_); + for (auto b : match.bins_) match.weights_.push_back(1.0); } virtual std::string diff --git a/include/openmc/tallies/tally_filter_mu.h b/include/openmc/tallies/tally_filter_mu.h index e76d56e43..be11e2936 100644 --- a/include/openmc/tallies/tally_filter_mu.h +++ b/include/openmc/tallies/tally_filter_mu.h @@ -12,6 +12,11 @@ namespace openmc { +//============================================================================== +//! Bins the incoming-outgoing direction cosine. This is only used for scatter +//! reactions. +//============================================================================== + class MuFilter : public TallyFilter { public: @@ -51,8 +56,8 @@ public: { if (p->mu >= bins_[0] && p->mu <= bins_.back()) { auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->mu) + 1; - match.bins.push_back(bin); - match.weights.push_back(1); + match.bins_.push_back(bin); + match.weights_.push_back(1); } } diff --git a/include/openmc/tallies/tally_filter_polar.h b/include/openmc/tallies/tally_filter_polar.h index d9f003330..4916c3088 100644 --- a/include/openmc/tallies/tally_filter_polar.h +++ b/include/openmc/tallies/tally_filter_polar.h @@ -12,6 +12,10 @@ namespace openmc { +//============================================================================== +//! Bins the incident neutron polar angle (relative to the global z-axis). +//============================================================================== + class PolarFilter : public TallyFilter { public: @@ -58,8 +62,8 @@ public: if (theta >= bins_[0] && theta <= bins_.back()) { auto bin = lower_bound_index(bins_.begin(), bins_.end(), theta) + 1; - match.bins.push_back(bin); - match.weights.push_back(1); + match.bins_.push_back(bin); + match.weights_.push_back(1); } } diff --git a/include/openmc/tallies/tally_filter_sph_harm.h b/include/openmc/tallies/tally_filter_sph_harm.h index 43c41ea22..e31c2ed65 100644 --- a/include/openmc/tallies/tally_filter_sph_harm.h +++ b/include/openmc/tallies/tally_filter_sph_harm.h @@ -14,6 +14,10 @@ enum class SphericalHarmonicsCosine { scatter = 1, particle = 2 }; +//============================================================================== +//! Gives spherical harmonics expansion moments of a tally score +//============================================================================== + class SphericalHarmonicsFilter : public TallyFilter { public: @@ -65,8 +69,8 @@ public: // Append the matching (bin,weight) for each moment for (int i = 0; i < num_nm; i++) { - match.weights.push_back(wgt[n] * rn[j]); - match.bins.push_back(++j); + match.weights_.push_back(wgt[n] * rn[j]); + match.bins_.push_back(++j); } } } diff --git a/include/openmc/tallies/tally_filter_sptl_legendre.h b/include/openmc/tallies/tally_filter_sptl_legendre.h index 413a3e3a2..49415a585 100644 --- a/include/openmc/tallies/tally_filter_sptl_legendre.h +++ b/include/openmc/tallies/tally_filter_sptl_legendre.h @@ -15,6 +15,10 @@ enum class LegendreAxis { x = 1, y = 2, z = 3 }; +//============================================================================== +//! Gives Legendre moments of the particle's normalized position along an axis +//============================================================================== + class SpatialLegendreFilter : public TallyFilter { public: @@ -66,8 +70,8 @@ public: double wgt[order_ + 1]; calc_pn_c(order_, x_norm, wgt); for (int i = 0; i < order_ + 1; i++) { - match.bins.push_back(i + 1); - match.weights.push_back(wgt[i]); + match.bins_.push_back(i + 1); + match.weights_.push_back(wgt[i]); } } } diff --git a/include/openmc/tallies/tally_filter_surface.h b/include/openmc/tallies/tally_filter_surface.h index a80fcaf12..d8e4075f9 100644 --- a/include/openmc/tallies/tally_filter_surface.h +++ b/include/openmc/tallies/tally_filter_surface.h @@ -13,6 +13,10 @@ namespace openmc { +//============================================================================== +//! Specifies which surface particles are crossing +//============================================================================== + class SurfaceFilter : public TallyFilter { public: @@ -53,11 +57,11 @@ public: { auto search = map_.find(std::abs(p->surface)-1); if (search != map_.end()) { - match.bins.push_back(search->second + 1); + match.bins_.push_back(search->second + 1); if (p->surface < 0) { - match.weights.push_back(-1); + match.weights_.push_back(-1); } else { - match.weights.push_back(1); + match.weights_.push_back(1); } } } diff --git a/include/openmc/tallies/tally_filter_universe.h b/include/openmc/tallies/tally_filter_universe.h index c61301c36..930856c6a 100644 --- a/include/openmc/tallies/tally_filter_universe.h +++ b/include/openmc/tallies/tally_filter_universe.h @@ -13,6 +13,10 @@ namespace openmc { +//============================================================================== +//! Specifies which geometric universes tally events reside in. +//============================================================================== + class UniverseFilter : public TallyFilter { public: @@ -54,9 +58,8 @@ public: for (int i = 0; i < p->n_coord; i++) { auto search = map_.find(p->coord[i].universe); if (search != map_.end()) { - // TODO: off-by-one - match.bins.push_back(search->second + 1); - match.weights.push_back(1); + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); } } } diff --git a/include/openmc/tallies/tally_filter_zernike.h b/include/openmc/tallies/tally_filter_zernike.h index c2052c500..c074d171f 100644 --- a/include/openmc/tallies/tally_filter_zernike.h +++ b/include/openmc/tallies/tally_filter_zernike.h @@ -12,6 +12,10 @@ namespace openmc { +//============================================================================== +//! Gives Zernike polynomial moments of a particle's position +//============================================================================== + class ZernikeFilter : public TallyFilter { public: @@ -44,8 +48,8 @@ public: double zn[n_bins_]; calc_zn_c(order_, r, theta, zn); for (int i = 0; i < n_bins_; i++) { - match.bins.push_back(i+1); - match.weights.push_back(zn[i]); + match.bins_.push_back(i+1); + match.weights_.push_back(zn[i]); } } } @@ -81,6 +85,10 @@ public: double x_, y_, r_; }; +//============================================================================== +//! Gives even order radial Zernike polynomial moments of a particle's position +//============================================================================== + class ZernikeRadialFilter : public ZernikeFilter { public: @@ -102,8 +110,8 @@ public: double zn[n_bins_]; calc_zn_rad_c(order_, r, zn); for (int i = 0; i < n_bins_; i++) { - match.bins.push_back(i+1); - match.weights.push_back(zn[i]); + match.bins_.push_back(i+1); + match.weights_.push_back(zn[i]); } } } diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index 6a699e2e6..98b7bf9a3 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -7,26 +7,15 @@ module tally_filter use tally_filter_header ! Inherit other filters - use tally_filter_azimuthal - use tally_filter_cell - use tally_filter_cellborn - use tally_filter_cellfrom + use tally_filter_cpp use tally_filter_delayedgroup use tally_filter_distribcell use tally_filter_energy - use tally_filter_energyfunc use tally_filter_legendre - use tally_filter_material use tally_filter_mesh use tally_filter_meshsurface - use tally_filter_mu use tally_filter_particle - use tally_filter_polar use tally_filter_sph_harm - use tally_filter_sptl_legendre - use tally_filter_surface - use tally_filter_universe - use tally_filter_zernike implicit none diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index bb937806f..d32440146 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -450,35 +450,35 @@ extern "C" { void filter_match_bins_push_back(TallyFilterMatch* match, int val) - {match->bins.push_back(val);} + {match->bins_.push_back(val);} void filter_match_weights_push_back(TallyFilterMatch* match, double val) - {match->weights.push_back(val);} + {match->weights_.push_back(val);} void filter_match_bins_clear(TallyFilterMatch* match) - {match->bins.clear();} + {match->bins_.clear();} void filter_match_weights_clear(TallyFilterMatch* match) - {match->weights.clear();} + {match->weights_.clear();} int filter_match_bins_size(TallyFilterMatch* match) - {return match->bins.size();} + {return match->bins_.size();} int filter_match_bins_data(TallyFilterMatch* match, int indx) - {return match->bins.at(indx-1);} + {return match->bins_[indx-1];} double filter_match_weights_data(TallyFilterMatch* match, int indx) - {return match->weights.at(indx-1);} + {return match->weights_[indx-1];} void filter_match_bins_set_data(TallyFilterMatch* match, int indx, int val) - {match->bins.at(indx-1) = val;} + {match->bins_[indx-1] = val;} TallyFilter* allocate_filter(const char* type) diff --git a/src/tallies/tally_filter_azimuthal.F90 b/src/tallies/tally_filter_azimuthal.F90 deleted file mode 100644 index 69513c26d..000000000 --- a/src/tallies/tally_filter_azimuthal.F90 +++ /dev/null @@ -1,15 +0,0 @@ -module tally_filter_azimuthal - - use tally_filter_header - - implicit none - -!=============================================================================== -! AZIMUTHALFILTER bins the incident neutron azimuthal angle (relative to the -! global xy-plane). -!=============================================================================== - - type, extends(CppTallyFilter) :: AzimuthalFilter - end type AzimuthalFilter - -end module tally_filter_azimuthal diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 deleted file mode 100644 index 808cbaf57..000000000 --- a/src/tallies/tally_filter_cell.F90 +++ /dev/null @@ -1,14 +0,0 @@ -module tally_filter_cell - - use tally_filter_header - - implicit none - -!=============================================================================== -! CELLFILTER specifies which geometric cells tally events reside in. -!=============================================================================== - - type, extends(CppTallyFilter) :: CellFilter - end type CellFilter - -end module tally_filter_cell diff --git a/src/tallies/tally_filter_cellborn.F90 b/src/tallies/tally_filter_cellborn.F90 deleted file mode 100644 index dd7e65bf3..000000000 --- a/src/tallies/tally_filter_cellborn.F90 +++ /dev/null @@ -1,14 +0,0 @@ -module tally_filter_cellborn - - use tally_filter_header - - implicit none - -!=============================================================================== -! CELLBORNFILTER specifies which cell the particle was born in. -!=============================================================================== - - type, public, extends(CppTallyFilter) :: CellbornFilter - end type CellbornFilter - -end module tally_filter_cellborn diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 deleted file mode 100644 index 201f94688..000000000 --- a/src/tallies/tally_filter_cellfrom.F90 +++ /dev/null @@ -1,18 +0,0 @@ -module tally_filter_cellfrom - - use, intrinsic :: ISO_C_BINDING - - use tally_filter_cell - - implicit none - private - -!=============================================================================== -! CELLFROMFILTER specifies which geometric cells particles exit when crossing a -! surface. -!=============================================================================== - - type, public, extends(CellFilter) :: CellFromFilter - end type CellFromFilter - -end module tally_filter_cellfrom diff --git a/src/tallies/tally_filter_cpp.F90 b/src/tallies/tally_filter_cpp.F90 new file mode 100644 index 000000000..d0e8abfb4 --- /dev/null +++ b/src/tallies/tally_filter_cpp.F90 @@ -0,0 +1,235 @@ +module tally_filter_cpp + use, intrinsic :: ISO_C_BINDING + + use constants, only: MAX_LINE_LEN + use hdf5_interface, only: HID_T + use particle_header, only: Particle + use tally_filter_header + use xml_interface, only: XMLNode + + implicit none + +!=============================================================================== +! CPPTALLYFILTER is a TallyFilter that is at least partially implemented in C++. +! +! Moving a tally to C++ is easier if done piece-by-piece, so this filter has +! *_cpp_inner procedures that allows the Fortran code to override e.g. +! get_all_bins and still call the C++ implementation for side-by-side comparison +!=============================================================================== + + type, abstract, extends(TallyFilter) :: CppTallyFilter + type(C_PTR) :: ptr + contains + procedure :: n_bins_cpp + procedure :: from_xml_cpp_inner + procedure :: get_all_bins_cpp_inner + procedure :: to_statepoint_cpp_inner + procedure :: text_label_cpp_inner + procedure :: initialize_cpp_inner + procedure :: from_xml => from_xml_cpp_default + procedure :: get_all_bins => get_all_bins_cpp_default + procedure :: to_statepoint => to_statepoint_cpp_default + procedure :: text_label => text_label_cpp_default + procedure :: initialize => initialize_cpp_default + end type CppTallyFilter + +!=============================================================================== +! Pure C++ filters +!=============================================================================== + + type, extends(CppTallyFilter) :: AzimuthalFilter + end type + + type, extends(CppTallyFilter) :: CellFilter + end type + + type, extends(CppTallyFilter) :: CellbornFilter + end type + + type, extends(CellFilter) :: CellFromFilter + end type + + type, extends(CppTallyFilter) :: EnergyFunctionFilter + end type + + type, extends(CppTallyFilter) :: MaterialFilter + end type + + type, extends(CppTallyFilter) :: MuFilter + end type + + type, extends(CppTallyFilter) :: PolarFilter + end type + + type, extends(CppTallyFilter) :: SpatialLegendreFilter + end type + + type, extends(CppTallyFilter) :: SurfaceFilter + ! True if this filter is used for surface currents + logical :: current = .false. + end type + + type, extends(CppTallyFilter) :: UniverseFilter + end type + + type, extends(CppTallyFilter) :: ZernikeFilter + end type + + type, extends(ZernikeFilter) :: ZernikeRadialFilter + end type + +contains + +!=============================================================================== +! CppTallyFilter implementation +!=============================================================================== + + function n_bins_cpp(this) result(n_bins) + class(CppTallyFilter), intent(inout) :: this + integer :: n_bins + interface + function filter_n_bins(filt) result(n_bins) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: n_bins + end function filter_n_bins + end interface + n_bins = filter_n_bins(this % ptr) + end function n_bins_cpp + + subroutine from_xml_cpp_inner(this, node) + class(CppTallyFilter), intent(inout) :: this + class(XMLNode), intent(in) :: node + interface + subroutine filter_from_xml(filt, node) bind(C) + import C_PTR + type(C_PTR), value :: filt + type(C_PTR) :: node + end subroutine filter_from_xml + end interface + call filter_from_xml(this % ptr, node % ptr) + end subroutine from_xml_cpp_inner + + subroutine get_all_bins_cpp_inner(this, p, estimator, match) + class(CppTallyFilter), intent(in) :: this + type(Particle), intent(in) :: p + integer, intent(in) :: estimator + type(TallyFilterMatch), intent(inout) :: match + interface + subroutine filter_get_all_bins(filt, p, estimator, match) bind(C) + import C_PTR, Particle, C_INT + type(C_PTR), value :: filt + type(Particle), intent(in) :: p + integer(C_INT), intent(in), value :: estimator + type(C_PTR), value :: match + end subroutine filter_get_all_bins + end interface + call filter_get_all_bins(this % ptr, p, estimator, match % ptr) + end subroutine get_all_bins_cpp_inner + + subroutine to_statepoint_cpp_inner(this, filter_group) + class(CppTallyFilter), intent(in) :: this + integer(HID_T), intent(in) :: filter_group + interface + subroutine filter_to_statepoint(filt, filter_group) bind(C) + import C_PTR, HID_T + type(C_PTR), value :: filt + integer(HID_T), intent(in), value :: filter_group + end subroutine filter_to_statepoint + end interface + call filter_to_statepoint(this % ptr, filter_group) + end subroutine to_statepoint_cpp_inner + + function text_label_cpp_inner(this, bin) result(label) + class(CppTallyFilter), intent(in) :: this + integer, intent(in) :: bin + character(MAX_LINE_LEN) :: label + character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1) + integer :: i + interface + subroutine filter_text_label(filt, bin, label) bind(C) + import C_PTR, C_INT, C_CHAR + type(C_PTR), value :: filt + integer(C_INT), value :: bin + character(kind=C_CHAR) :: label(*) + end subroutine filter_text_label + end interface + call filter_text_label(this % ptr, bin, label_) + label = " " + do i = 1, MAX_LINE_LEN + if (label_(i) == C_NULL_CHAR) exit + label(i:i) = label_(i) + end do + end function text_label_cpp_inner + + subroutine initialize_cpp_inner(this) + class(CppTallyFilter), intent(inout) :: this + interface + subroutine filter_initialize(filt) bind(C) + import C_PTR + type(C_PTR), value :: filt + end subroutine filter_initialize + end interface + call filter_initialize(this % ptr) + end subroutine initialize_cpp_inner + + subroutine from_xml_cpp_default(this, node) + class(CppTallyFilter), intent(inout) :: this + type(XMLNode), intent(in) :: node + call this % from_xml_cpp_inner(node) + this % n_bins = this % n_bins_cpp() + end subroutine from_xml_cpp_default + + subroutine get_all_bins_cpp_default(this, p, estimator, match) + class(CppTallyFilter), intent(in) :: this + type(Particle), intent(in) :: p + integer, intent(in) :: estimator + type(TallyFilterMatch), intent(inout) :: match + call this % get_all_bins_cpp_inner(p, estimator, match) + end subroutine get_all_bins_cpp_default + + subroutine to_statepoint_cpp_default(this, filter_group) + class(CppTallyFilter), intent(in) :: this + integer(HID_T), intent(in) :: filter_group + call this % to_statepoint_cpp_inner(filter_group) + end subroutine to_statepoint_cpp_default + + function text_label_cpp_default(this, bin) result(label) + class(CppTallyFilter), intent(in) :: this + integer, intent(in) :: bin + character(MAX_LINE_LEN) :: label + label = this % text_label_cpp_inner(bin) + end function text_label_cpp_default + + subroutine initialize_cpp_default(this) + class(CppTallyFilter), intent(inout) :: this + call this % initialize_cpp_inner() + end subroutine initialize_cpp_default + +!=============================================================================== +! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter. +!=============================================================================== + + function filter_from_f(index) result(filt) bind(C) + integer(C_INT32_T), intent(in), value :: index + type(C_PTR) :: filt + + filt = C_NULL_PTR + select type(f => filters(index) % obj) + class is (CppTallyFilter) + filt = f % ptr + end select + end function + +!=============================================================================== +! FILTER_UPDATE_N_BINS given a Fortran index, updates filt % n_bins using C++. +!=============================================================================== + + subroutine filter_update_n_bins(index) bind(C) + integer(C_INT32_T), intent(in), value :: index + select type(f => filters(index) % obj) + class is (CppTallyFilter) + f % n_bins = f % n_bins_cpp() + end select + end subroutine +end module tally_filter_cpp diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index 8b25e2747..9033ae6a0 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -1,15 +1,10 @@ module tally_filter_distribcell - use tally_filter_header + use tally_filter_cpp implicit none private -!=============================================================================== -! DISTRIBCELLFILTER specifies which distributed geometric cells tally events -! reside in. -!=============================================================================== - type, public, extends(CppTallyFilter) :: DistribcellFilter contains procedure :: initialize => initialize_distribcell diff --git a/src/tallies/tally_filter_energyfunc.F90 b/src/tallies/tally_filter_energyfunc.F90 deleted file mode 100644 index de41b0c59..000000000 --- a/src/tallies/tally_filter_energyfunc.F90 +++ /dev/null @@ -1,15 +0,0 @@ -module tally_filter_energyfunc - - use tally_filter_header - - implicit none - -!=============================================================================== -! EnergyFunctionFilter multiplies tally scores by an arbitrary function of -! incident energy described by a piecewise linear-linear interpolation. -!=============================================================================== - - type, extends(CppTallyFilter) :: EnergyFunctionFilter - end type EnergyFunctionFilter - -end module tally_filter_energyfunc diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index a873310ff..4116934b3 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -7,7 +7,6 @@ module tally_filter_header use error use hdf5_interface, only: HID_T use particle_header, only: Particle - use stl_vector, only: VectorInt, VectorReal use string, only: to_str use xml_interface, only: XMLNode @@ -124,25 +123,6 @@ module tally_filter_header end interface -!=============================================================================== -!=============================================================================== - - type, public, abstract, extends(TallyFilter) :: CppTallyFilter - type(C_PTR) :: ptr - contains - procedure :: n_bins_cpp - procedure :: from_xml_cpp_inner - procedure :: get_all_bins_cpp_inner - procedure :: to_statepoint_cpp_inner - procedure :: text_label_cpp_inner - procedure :: initialize_cpp_inner - procedure :: from_xml => from_xml_cpp_default - procedure :: get_all_bins => get_all_bins_cpp_default - procedure :: to_statepoint => to_statepoint_cpp_default - procedure :: text_label => text_label_cpp_default - procedure :: initialize => initialize_cpp_default - end type CppTallyFilter - !=============================================================================== ! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of ! TallyFilters @@ -168,6 +148,7 @@ module tally_filter_header contains !=============================================================================== +! TallyFilterMatch implementation !=============================================================================== subroutine bins_push_back(this, val) @@ -284,130 +265,6 @@ contains class(TallyFilter), intent(inout) :: this end subroutine filter_initialize -!=============================================================================== - - function n_bins_cpp(this) result(n_bins) - class(CppTallyFilter), intent(inout) :: this - integer :: n_bins - interface - function filter_n_bins(filt) result(n_bins) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: n_bins - end function filter_n_bins - end interface - n_bins = filter_n_bins(this % ptr) - end function n_bins_cpp - - subroutine from_xml_cpp_inner(this, node) - class(CppTallyFilter), intent(inout) :: this - class(XMLNode), intent(in) :: node - interface - subroutine filter_from_xml(filt, node) bind(C) - import C_PTR - type(C_PTR), value :: filt - type(C_PTR) :: node - end subroutine filter_from_xml - end interface - call filter_from_xml(this % ptr, node % ptr) - end subroutine from_xml_cpp_inner - - subroutine get_all_bins_cpp_inner(this, p, estimator, match) - class(CppTallyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - interface - subroutine filter_get_all_bins(filt, p, estimator, match) bind(C) - import C_PTR, Particle, C_INT - type(C_PTR), value :: filt - type(Particle), intent(in) :: p - integer(C_INT), intent(in), value :: estimator - type(C_PTR), value :: match - end subroutine filter_get_all_bins - end interface - call filter_get_all_bins(this % ptr, p, estimator, match % ptr) - end subroutine get_all_bins_cpp_inner - - subroutine to_statepoint_cpp_inner(this, filter_group) - class(CppTallyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - interface - subroutine filter_to_statepoint(filt, filter_group) bind(C) - import C_PTR, HID_T - type(C_PTR), value :: filt - integer(HID_T), intent(in), value :: filter_group - end subroutine filter_to_statepoint - end interface - call filter_to_statepoint(this % ptr, filter_group) - end subroutine to_statepoint_cpp_inner - - function text_label_cpp_inner(this, bin) result(label) - class(CppTallyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1) - integer :: i - interface - subroutine filter_text_label(filt, bin, label) bind(C) - import C_PTR, C_INT, C_CHAR - type(C_PTR), value :: filt - integer(C_INT), value :: bin - character(kind=C_CHAR) :: label(*) - end subroutine filter_text_label - end interface - call filter_text_label(this % ptr, bin, label_) - label = " " - do i = 1, MAX_LINE_LEN - if (label_(i) == C_NULL_CHAR) exit - label(i:i) = label_(i) - end do - end function text_label_cpp_inner - - subroutine initialize_cpp_inner(this) - class(CppTallyFilter), intent(inout) :: this - interface - subroutine filter_initialize(filt) bind(C) - import C_PTR - type(C_PTR), value :: filt - end subroutine filter_initialize - end interface - call filter_initialize(this % ptr) - end subroutine initialize_cpp_inner - - subroutine from_xml_cpp_default(this, node) - class(CppTallyFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - call this % from_xml_cpp_inner(node) - this % n_bins = this % n_bins_cpp() - end subroutine from_xml_cpp_default - - subroutine get_all_bins_cpp_default(this, p, estimator, match) - class(CppTallyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - call this % get_all_bins_cpp_inner(p, estimator, match) - end subroutine get_all_bins_cpp_default - - subroutine to_statepoint_cpp_default(this, filter_group) - class(CppTallyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - call this % to_statepoint_cpp_inner(filter_group) - end subroutine to_statepoint_cpp_default - - function text_label_cpp_default(this, bin) result(label) - class(CppTallyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - label = this % text_label_cpp_inner(bin) - end function text_label_cpp_default - - subroutine initialize_cpp_default(this) - class(CppTallyFilter), intent(inout) :: this - call this % initialize_cpp_inner() - end subroutine initialize_cpp_default - !=============================================================================== ! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module !=============================================================================== @@ -440,33 +297,6 @@ contains end if end function verify_filter -!=============================================================================== -! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter. -!=============================================================================== - - function filter_from_f(index) result(filt) bind(C) - integer(C_INT32_T), intent(in), value :: index - type(C_PTR) :: filt - - filt = C_NULL_PTR - select type(f => filters(index) % obj) - class is (CppTallyFilter) - filt = f % ptr - end select - end function - -!=============================================================================== -! FILTER_UPDATE_N_BINS updates filt % n_bins using C++. -!=============================================================================== - - subroutine filter_update_n_bins(index) bind(C) - integer(C_INT32_T), intent(in), value :: index - select type(f => filters(index) % obj) - class is (CppTallyFilter) - f % n_bins = f % n_bins_cpp() - end select - end subroutine - !=============================================================================== ! C API FUNCTIONS !=============================================================================== diff --git a/src/tallies/tally_filter_legendre.F90 b/src/tallies/tally_filter_legendre.F90 index f4d2a3d81..9c0f9e41a 100644 --- a/src/tallies/tally_filter_legendre.F90 +++ b/src/tallies/tally_filter_legendre.F90 @@ -2,7 +2,7 @@ module tally_filter_legendre use, intrinsic :: ISO_C_BINDING - use tally_filter_header + use tally_filter_cpp implicit none @@ -15,11 +15,7 @@ module tally_filter_legendre end function end interface -!=============================================================================== -! LEGENDREFILTER gives Legendre moments of the change in scattering angle -!=============================================================================== - - type, public, extends(CppTallyFilter) :: LegendreFilter + type, extends(CppTallyFilter) :: LegendreFilter end type LegendreFilter end module tally_filter_legendre diff --git a/src/tallies/tally_filter_material.F90 b/src/tallies/tally_filter_material.F90 deleted file mode 100644 index f2bd7843c..000000000 --- a/src/tallies/tally_filter_material.F90 +++ /dev/null @@ -1,14 +0,0 @@ -module tally_filter_material - - use tally_filter_header - - implicit none - -!=============================================================================== -! MATERIAL specifies which material tally events reside in. -!=============================================================================== - - type, extends(CppTallyFilter) :: MaterialFilter - end type MaterialFilter - -end module tally_filter_material diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index c26376601..8f6dd185e 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -2,7 +2,7 @@ module tally_filter_mesh use, intrinsic :: ISO_C_BINDING - use tally_filter_header + use tally_filter_cpp implicit none @@ -15,12 +15,6 @@ module tally_filter_mesh end function end interface -!=============================================================================== -! MESHFILTER indexes the location of particle events to a regular mesh. For -! tracklength tallies, it will produce multiple valid bins and the bin weight -! will correspond to the fraction of the track length that lies in that bin. -!=============================================================================== - type, public, extends(CppTallyFilter) :: MeshFilter contains procedure :: mesh => get_mesh diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index 0b10c9cce..f70f5425f 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -2,10 +2,7 @@ module tally_filter_meshsurface use, intrinsic :: ISO_C_BINDING - use constants - use error - use mesh_header - use tally_filter_header + use tally_filter_cpp implicit none @@ -19,12 +16,6 @@ module tally_filter_meshsurface end function end interface -!=============================================================================== -! MESHFILTER indexes the location of particle events to a regular mesh. For -! tracklength tallies, it will produce multiple valid bins and the bin weight -! will correspond to the fraction of the track length that lies in that bin. -!=============================================================================== - type, extends(CppTallyFilter) :: MeshSurfaceFilter end type MeshSurfaceFilter diff --git a/src/tallies/tally_filter_mu.F90 b/src/tallies/tally_filter_mu.F90 deleted file mode 100644 index 8f8d14a7d..000000000 --- a/src/tallies/tally_filter_mu.F90 +++ /dev/null @@ -1,15 +0,0 @@ -module tally_filter_mu - - use tally_filter_header - - implicit none - -!=============================================================================== -! MUFILTER bins the incoming-outgoing direction cosine. This is only used for -! scatter reactions. -!=============================================================================== - - type, extends(CppTallyFilter) :: MuFilter - end type MuFilter - -end module tally_filter_mu diff --git a/src/tallies/tally_filter_polar.F90 b/src/tallies/tally_filter_polar.F90 deleted file mode 100644 index 957f0f51c..000000000 --- a/src/tallies/tally_filter_polar.F90 +++ /dev/null @@ -1,15 +0,0 @@ -module tally_filter_polar - - use tally_filter_header - - implicit none - -!=============================================================================== -! POLARFILTER bins the incident neutron polar angle (relative to the global -! z-axis). -!=============================================================================== - - type, extends(CppTallyFilter) :: PolarFilter - end type PolarFilter - -end module tally_filter_polar diff --git a/src/tallies/tally_filter_sph_harm.F90 b/src/tallies/tally_filter_sph_harm.F90 index a2854841c..455da042c 100644 --- a/src/tallies/tally_filter_sph_harm.F90 +++ b/src/tallies/tally_filter_sph_harm.F90 @@ -2,7 +2,7 @@ module tally_filter_sph_harm use, intrinsic :: ISO_C_BINDING - use tally_filter_header + use tally_filter_cpp implicit none private @@ -10,11 +10,6 @@ module tally_filter_sph_harm integer, public, parameter :: COSINE_SCATTER = 1 integer, public, parameter :: COSINE_PARTICLE = 2 -!=============================================================================== -! SPHERICALHARMONICSFILTER gives spherical harmonics expansion moments of a -! tally score -!=============================================================================== - type, public, extends(CppTallyFilter) :: SphericalHarmonicsFilter contains procedure :: cosine diff --git a/src/tallies/tally_filter_sptl_legendre.F90 b/src/tallies/tally_filter_sptl_legendre.F90 deleted file mode 100644 index f73e2322a..000000000 --- a/src/tallies/tally_filter_sptl_legendre.F90 +++ /dev/null @@ -1,15 +0,0 @@ -module tally_filter_sptl_legendre - - use tally_filter_header - - implicit none - -!=============================================================================== -! SPATIALLEGENDREFILTER gives Legendre moments of the particle's normalized -! position along an axis -!=============================================================================== - - type, extends(CppTallyFilter) :: SpatialLegendreFilter - end type SpatialLegendreFilter - -end module tally_filter_sptl_legendre diff --git a/src/tallies/tally_filter_surface.F90 b/src/tallies/tally_filter_surface.F90 deleted file mode 100644 index 1dcb56022..000000000 --- a/src/tallies/tally_filter_surface.F90 +++ /dev/null @@ -1,16 +0,0 @@ -module tally_filter_surface - - use tally_filter_header - - implicit none - -!=============================================================================== -! SURFACEFILTER specifies which surface particles are crossing -!=============================================================================== - - type, extends(CppTallyFilter) :: SurfaceFilter - ! True if this filter is used for surface currents - logical :: current = .false. - end type SurfaceFilter - -end module tally_filter_surface diff --git a/src/tallies/tally_filter_universe.F90 b/src/tallies/tally_filter_universe.F90 deleted file mode 100644 index 2f3d5011c..000000000 --- a/src/tallies/tally_filter_universe.F90 +++ /dev/null @@ -1,14 +0,0 @@ -module tally_filter_universe - - use tally_filter_header - - implicit none - -!=============================================================================== -! UNIVERSEFILTER specifies which geometric universes tally events reside in. -!=============================================================================== - - type, extends(CppTallyFilter) :: UniverseFilter - end type UniverseFilter - -end module tally_filter_universe diff --git a/src/tallies/tally_filter_zernike.F90 b/src/tallies/tally_filter_zernike.F90 deleted file mode 100644 index c4330120d..000000000 --- a/src/tallies/tally_filter_zernike.F90 +++ /dev/null @@ -1,22 +0,0 @@ -module tally_filter_zernike - - use tally_filter_header - - implicit none - -!=============================================================================== -! ZERNIKEFILTER gives Zernike polynomial moments of a particle's position -!=============================================================================== - - type, extends(CppTallyFilter) :: ZernikeFilter - end type ZernikeFilter - -!=============================================================================== -! ZERNIKERADIALFILTER gives even order radial Zernike polynomial moments of a -! particle's position -!=============================================================================== - - type, extends(ZernikeFilter) :: ZernikeRadialFilter - end type ZernikeRadialFilter - -end module tally_filter_zernike From e2dc2cee43224c3a5a9fc19641c3b724509e72be Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 19 Oct 2018 16:48:12 -0400 Subject: [PATCH 37/45] update python api for wmp v1.1 --- examples/jupyter/nuclear-data.ipynb | 2 +- openmc/data/__init__.py | 4 +- openmc/data/multipole.py | 58 ++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/examples/jupyter/nuclear-data.ipynb b/examples/jupyter/nuclear-data.ipynb index 91923faa1..f1c4c2b2a 100644 --- a/examples/jupyter/nuclear-data.ipynb +++ b/examples/jupyter/nuclear-data.ipynb @@ -1466,7 +1466,7 @@ }, "outputs": [], "source": [ - "url = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/092238.h5'\n", + "url = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/092238.h5'\n", "filename, headers = urllib.request.urlretrieve(url, '092238.h5')" ] }, diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index dec11cd3a..9aff59444 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -4,7 +4,9 @@ HDF5_VERSION_MINOR = 0 HDF5_VERSION = (HDF5_VERSION_MAJOR, HDF5_VERSION_MINOR) # Version of WMP nuclear data format -WMP_VERSION = 'v1.0' +WMP_VERSION_MAJOR = 1 +WMP_VERSION_MINOR = 1 +WMP_VERSION = (WMP_VERSION_MAJOR, WMP_VERSION_MINOR) from .data import * diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index a0d90ac01..5d34c9ff6 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -4,7 +4,7 @@ from math import exp, erf, pi, sqrt import h5py import numpy as np -from . import WMP_VERSION +from . import WMP_VERSION, WMP_VERSION_MAJOR from .data import K_BOLTZMANN import openmc.checkvalue as cv from openmc.mixin import EqualityMixin @@ -133,6 +133,8 @@ class WindowedMultipole(EqualityMixin): Parameters ---------- + name : str + Name of the nuclide using the GND naming convention Attributes ---------- @@ -171,7 +173,8 @@ class WindowedMultipole(EqualityMixin): a/E + b/sqrt(E) + c + d sqrt(E) + ... """ - def __init__(self): + def __init__(self, name): + self.name = name self.spacing = None self.sqrtAWR = None self.E_min = None @@ -181,6 +184,10 @@ class WindowedMultipole(EqualityMixin): self.broaden_poly = None self.curvefit = None + @property + def name(self): + return self._name + @property def fit_order(self): return self.curvefit.shape[1] - 1 @@ -221,6 +228,11 @@ class WindowedMultipole(EqualityMixin): def curvefit(self): return self._curvefit + @name.setter + def name(self, name): + cv.check_type('name', name, str) + self._name = name + @spacing.setter def spacing(self, spacing): if spacing is not None: @@ -322,17 +334,25 @@ class WindowedMultipole(EqualityMixin): group = group_or_filename else: h5file = h5py.File(group_or_filename, 'r') - try: - version = h5file['version'].value.decode() - except AttributeError: - version = h5file['version'].value[0].decode() - if version != WMP_VERSION: - raise ValueError('The given WMP data uses version ' - + version + ' whereas your installation of the OpenMC ' - 'Python API expects version ' + WMP_VERSION) - group = h5file['nuclide'] - out = cls() + # Make sure version matches + if 'version' in h5file.attrs: + major, minor = h5file.attrs['version'] + if major != WMP_VERSION_MAJOR: + raise IOError( + 'WMP data format uses version {}. {} whereas your ' + 'installation of the OpenMC Python API expects version ' + '{}.x.'.format(major, minor, WMP_VERSION_MAJOR)) + else: + raise IOError( + 'WMP data does not indicate a version. Your installation of ' + 'the OpenMC Python API expects version {}.x data.' + .format(WMP_VERSION_MAJOR)) + + group = list(h5file.values())[0] + + name = group.name[1:] + out = cls(name) # Read scalars. @@ -478,13 +498,16 @@ class WindowedMultipole(EqualityMixin): fun = np.vectorize(lambda x: self._evaluate(x, T)) return fun(E) - def export_to_hdf5(self, path, libver='earliest'): + def export_to_hdf5(self, path, mode='a', libver='earliest'): """Export windowed multipole data to an HDF5 file. Parameters ---------- path : str Path to write HDF5 file to + mode : {'r', r+', 'w', 'x', 'a'} + Mode that is used to open the HDF5 file. This is the second argument + to the :class:`h5py.File` constructor. libver : {'earliest', 'latest'} Compatibility mode for the HDF5 file. 'latest' will produce files that are less backwards compatible but have performance benefits. @@ -492,12 +515,11 @@ class WindowedMultipole(EqualityMixin): """ # Open file and write version. - with h5py.File(path, 'w', libver=libver) as f: - f.create_dataset('version', (1, ), dtype='S10') - f['version'][:] = WMP_VERSION.encode('ASCII') + with h5py.File(path, mode, libver=libver) as f: + f.attrs['filetype'] = np.string_('data_wmp') + f.attrs['version'] = np.array(WMP_VERSION) - # Make a nuclide group. - g = f.create_group('nuclide') + g = f.create_group(self.name) # Write scalars. g.create_dataset('spacing', data=np.array(self.spacing)) From 4e1ed5799d48852d6a90fa7ba97bc00dbfae5431 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Oct 2018 17:17:59 -0400 Subject: [PATCH 38/45] Update the cell map in openmc_cell_set_id --- src/cell.cpp | 15 +++++++++++++-- src/cmfd_data.F90 | 8 -------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index 8896cde98..65582d780 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -650,7 +650,6 @@ read_cells(pugi::xml_node* node) } // Fill the cell map. - // TODO: update this map when openmc_extend_cells is called for (int i = 0; i < cells.size(); i++) { int32_t id = cells[i]->id_; auto search = cell_map.find(id); @@ -780,7 +779,19 @@ extern "C" { int32_t cell_id(Cell* c) {return c->id_;} - void cell_set_id(Cell* c, int32_t id) {c->id_ = id;} + void + cell_set_id(Cell* c, int32_t id) + { + c->id_ = id; + + // Find the index of this cell and update the cell map. + for (int i = 0; i < cells.size(); i++) { + if (cells[i] == c) { + cell_map[id] = i; + break; + } + } + } int cell_type(Cell* c) {return c->type_;} diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index b090c6394..f2fb4dc26 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -82,14 +82,6 @@ contains real(8) :: flux ! temp variable for flux type(RegularMesh) :: m ! pointer for mesh object - interface - function mesh_filter_get_mesh(filt) result(index_mesh) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: index_mesh - end function mesh_filter_get_mesh - end interface - ! Extract spatial and energy indices from object nx = cmfd % indices(1) ny = cmfd % indices(2) From c5146cdedbad4d8d85ac7c013dfc41c438428dde Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 19 Oct 2018 19:32:23 -0400 Subject: [PATCH 39/45] remove unused variable --- src/constants.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/constants.F90 b/src/constants.F90 index 3e8cbb2dd..250b1ef37 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -28,7 +28,6 @@ module constants integer, parameter :: VERSION_VOLUME(2) = [1, 0] integer, parameter :: VERSION_VOXEL(2) = [1, 0] integer, parameter :: VERSION_MGXS_LIBRARY(2) = [1, 0] - character(10), parameter :: VERSION_MULTIPOLE = "v1.0" ! ============================================================================ ! ADJUSTABLE PARAMETERS From 4d84d483efcb86b5bc594bd94d627f4002fde31f Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 21 Oct 2018 18:53:15 -0400 Subject: [PATCH 40/45] Meet Core Guidelines for virtual & override --- .../openmc/tallies/tally_filter_azimuthal.h | 12 +++++----- include/openmc/tallies/tally_filter_cell.h | 14 ++++++------ .../openmc/tallies/tally_filter_cellborn.h | 6 ++--- .../openmc/tallies/tally_filter_cellfrom.h | 6 ++--- .../openmc/tallies/tally_filter_distribcell.h | 14 ++++++------ .../openmc/tallies/tally_filter_energyfunc.h | 12 +++++----- .../openmc/tallies/tally_filter_legendre.h | 12 +++++----- .../openmc/tallies/tally_filter_material.h | 14 ++++++------ include/openmc/tallies/tally_filter_mesh.h | 12 +++++----- .../openmc/tallies/tally_filter_meshsurface.h | 8 +++---- include/openmc/tallies/tally_filter_mu.h | 12 +++++----- include/openmc/tallies/tally_filter_polar.h | 12 +++++----- .../openmc/tallies/tally_filter_sph_harm.h | 12 +++++----- .../tallies/tally_filter_sptl_legendre.h | 12 +++++----- include/openmc/tallies/tally_filter_surface.h | 14 ++++++------ .../openmc/tallies/tally_filter_universe.h | 14 ++++++------ include/openmc/tallies/tally_filter_zernike.h | 22 +++++++++---------- 17 files changed, 103 insertions(+), 105 deletions(-) diff --git a/include/openmc/tallies/tally_filter_azimuthal.h b/include/openmc/tallies/tally_filter_azimuthal.h index 556cfff92..091fde7c9 100644 --- a/include/openmc/tallies/tally_filter_azimuthal.h +++ b/include/openmc/tallies/tally_filter_azimuthal.h @@ -19,11 +19,11 @@ namespace openmc { class AzimuthalFilter : public TallyFilter { public: - virtual std::string type() const override {return "azimuthal";} + std::string type() const override {return "azimuthal";} - virtual ~AzimuthalFilter() override = default; + ~AzimuthalFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { auto bins = get_node_array(node, "bins"); @@ -49,7 +49,7 @@ public: n_bins_ = bins_.size() - 1; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -67,14 +67,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h index c3b39eeb8..ecef014a0 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/tally_filter_cell.h @@ -20,18 +20,18 @@ namespace openmc { class CellFilter : public TallyFilter { public: - virtual std::string type() const override {return "cell";} + std::string type() const override {return "cell";} - virtual ~CellFilter() override = default; + ~CellFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { cells_ = get_node_array(node, "bins"); n_bins_ = cells_.size(); } - virtual void + void initialize() override { for (auto& c : cells_) { @@ -50,7 +50,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -64,7 +64,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -73,7 +73,7 @@ public: write_dataset(filter_group, "bins", cell_ids); } - virtual std::string + std::string text_label(int bin) const override { return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_cellborn.h b/include/openmc/tallies/tally_filter_cellborn.h index df77fe2b8..a7e5634dd 100644 --- a/include/openmc/tallies/tally_filter_cellborn.h +++ b/include/openmc/tallies/tally_filter_cellborn.h @@ -12,9 +12,9 @@ namespace openmc { class CellbornFilter : public CellFilter { public: - virtual std::string type() const override {return "cellborn";} + std::string type() const override {return "cellborn";} - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -26,7 +26,7 @@ public: } } - virtual std::string + std::string text_label(int bin) const override { return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/tally_filter_cellfrom.h index a45b97719..40bc38227 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/tally_filter_cellfrom.h @@ -13,9 +13,9 @@ namespace openmc { class CellFromFilter : public CellFilter { public: - virtual std::string type() const override {return "cellfrom";} + std::string type() const override {return "cellfrom";} - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -29,7 +29,7 @@ public: } } - virtual std::string + std::string text_label(int bin) const override { return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_distribcell.h b/include/openmc/tallies/tally_filter_distribcell.h index 45894c8a5..ab36d0b87 100644 --- a/include/openmc/tallies/tally_filter_distribcell.h +++ b/include/openmc/tallies/tally_filter_distribcell.h @@ -19,11 +19,11 @@ namespace openmc { class DistribcellFilter : public TallyFilter { public: - virtual std::string type() const override {return "distribcell";} + std::string type() const override {return "distribcell";} - virtual ~DistribcellFilter() override = default; + ~DistribcellFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { auto cells = get_node_array(node, "bins"); @@ -33,7 +33,7 @@ public: cell_ = cells[0]; } - virtual void + void initialize() override { auto search = cell_map.find(cell_); @@ -48,7 +48,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -75,14 +75,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", cells[cell_]->id_); } - virtual std::string + std::string text_label(int bin) const override { auto map = cells[cell_]->distribcell_index_; diff --git a/include/openmc/tallies/tally_filter_energyfunc.h b/include/openmc/tallies/tally_filter_energyfunc.h index 87b40dc46..73f31008a 100644 --- a/include/openmc/tallies/tally_filter_energyfunc.h +++ b/include/openmc/tallies/tally_filter_energyfunc.h @@ -22,7 +22,7 @@ namespace openmc { class EnergyFunctionFilter : public TallyFilter { public: - virtual std::string type() const override {return "energyfunction";} + std::string type() const override {return "energyfunction";} EnergyFunctionFilter() : TallyFilter {} @@ -30,9 +30,9 @@ public: n_bins_ = 1; } - virtual ~EnergyFunctionFilter() override = default; + ~EnergyFunctionFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { if (!settings::run_CE) @@ -50,7 +50,7 @@ public: y_ = get_node_array(node, "y"); } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -67,7 +67,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -75,7 +75,7 @@ public: write_dataset(filter_group, "y", y_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_legendre.h b/include/openmc/tallies/tally_filter_legendre.h index 42ee1a0f6..c72cd6a19 100644 --- a/include/openmc/tallies/tally_filter_legendre.h +++ b/include/openmc/tallies/tally_filter_legendre.h @@ -18,18 +18,18 @@ namespace openmc { class LegendreFilter : public TallyFilter { public: - virtual std::string type() const override {return "legendre";} + std::string type() const override {return "legendre";} - virtual ~LegendreFilter() override = default; + ~LegendreFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { order_ = std::stoi(get_node_value(node, "order")); n_bins_ = order_ + 1; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -41,14 +41,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "order", order_); } - virtual std::string + std::string text_label(int bin) const override { return "Legendre expansion, P" + std::to_string(bin - 1); diff --git a/include/openmc/tallies/tally_filter_material.h b/include/openmc/tallies/tally_filter_material.h index 41e551ef0..971788331 100644 --- a/include/openmc/tallies/tally_filter_material.h +++ b/include/openmc/tallies/tally_filter_material.h @@ -20,18 +20,18 @@ namespace openmc { class MaterialFilter : public TallyFilter { public: - virtual std::string type() const override {return "material";} + std::string type() const override {return "material";} - virtual ~MaterialFilter() override = default; + ~MaterialFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { materials_ = get_node_array(node, "bins"); n_bins_ = materials_.size(); } - virtual void + void initialize() override { for (auto& m : materials_) { @@ -51,7 +51,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -63,7 +63,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -72,7 +72,7 @@ public: write_dataset(filter_group, "bins", material_ids); } - virtual std::string + std::string text_label(int bin) const override { return "Material " + std::to_string(materials[materials_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/tally_filter_mesh.h index ca97a9b68..c0c13c655 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/tally_filter_mesh.h @@ -21,11 +21,11 @@ namespace openmc { class MeshFilter : public TallyFilter { public: - virtual std::string type() const override {return "mesh";} + std::string type() const override {return "mesh";} - virtual ~MeshFilter() override = default; + ~MeshFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { auto bins_ = get_node_array(node, "bins"); @@ -48,7 +48,7 @@ public: for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -63,14 +63,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", meshes[mesh_]->id_); } - virtual std::string + std::string text_label(int bin) const override { auto& mesh = *meshes[mesh_]; diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/tally_filter_meshsurface.h index 6588f646a..abc5ef80d 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/tally_filter_meshsurface.h @@ -15,9 +15,9 @@ namespace openmc { class MeshSurfaceFilter : public MeshFilter { public: - virtual std::string type() const override {return "meshsurface";} + std::string type() const override {return "meshsurface";} - virtual void + void from_xml(pugi::xml_node node) override { MeshFilter::from_xml(node); @@ -25,7 +25,7 @@ public: for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -33,7 +33,7 @@ public: for (auto b : match.bins_) match.weights_.push_back(1.0); } - virtual std::string + std::string text_label(int bin) const override { auto& mesh = *meshes[mesh_]; diff --git a/include/openmc/tallies/tally_filter_mu.h b/include/openmc/tallies/tally_filter_mu.h index be11e2936..93fc7020a 100644 --- a/include/openmc/tallies/tally_filter_mu.h +++ b/include/openmc/tallies/tally_filter_mu.h @@ -20,11 +20,11 @@ namespace openmc { class MuFilter : public TallyFilter { public: - virtual std::string type() const override {return "mu";} + std::string type() const override {return "mu";} - virtual ~MuFilter() override = default; + ~MuFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { auto bins = get_node_array(node, "bins"); @@ -50,7 +50,7 @@ public: n_bins_ = bins_.size() - 1; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -61,14 +61,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_polar.h b/include/openmc/tallies/tally_filter_polar.h index 4916c3088..5dcd28340 100644 --- a/include/openmc/tallies/tally_filter_polar.h +++ b/include/openmc/tallies/tally_filter_polar.h @@ -19,11 +19,11 @@ namespace openmc { class PolarFilter : public TallyFilter { public: - virtual std::string type() const override {return "polar";} + std::string type() const override {return "polar";} - virtual ~PolarFilter() override = default; + ~PolarFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { auto bins = get_node_array(node, "bins"); @@ -49,7 +49,7 @@ public: n_bins_ = bins_.size() - 1; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -67,14 +67,14 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_sph_harm.h b/include/openmc/tallies/tally_filter_sph_harm.h index e31c2ed65..79577f67c 100644 --- a/include/openmc/tallies/tally_filter_sph_harm.h +++ b/include/openmc/tallies/tally_filter_sph_harm.h @@ -21,11 +21,11 @@ enum class SphericalHarmonicsCosine { class SphericalHarmonicsFilter : public TallyFilter { public: - virtual std::string type() const override {return "sphericalharmonics";} + std::string type() const override {return "sphericalharmonics";} - virtual ~SphericalHarmonicsFilter() override = default; + ~SphericalHarmonicsFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { order_ = std::stoi(get_node_value(node, "order")); @@ -46,7 +46,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -75,7 +75,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -87,7 +87,7 @@ public: } } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_sptl_legendre.h b/include/openmc/tallies/tally_filter_sptl_legendre.h index 49415a585..19176b42b 100644 --- a/include/openmc/tallies/tally_filter_sptl_legendre.h +++ b/include/openmc/tallies/tally_filter_sptl_legendre.h @@ -22,11 +22,11 @@ enum class LegendreAxis { class SpatialLegendreFilter : public TallyFilter { public: - virtual std::string type() const override {return "spatiallegendre";} + std::string type() const override {return "spatiallegendre";} - virtual ~SpatialLegendreFilter() override = default; + ~SpatialLegendreFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { order_ = std::stoi(get_node_value(node, "order")); @@ -48,7 +48,7 @@ public: n_bins_ = order_ + 1; } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -76,7 +76,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -92,7 +92,7 @@ public: write_dataset(filter_group, "max", max_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; diff --git a/include/openmc/tallies/tally_filter_surface.h b/include/openmc/tallies/tally_filter_surface.h index d8e4075f9..fa98be8be 100644 --- a/include/openmc/tallies/tally_filter_surface.h +++ b/include/openmc/tallies/tally_filter_surface.h @@ -20,18 +20,18 @@ namespace openmc { class SurfaceFilter : public TallyFilter { public: - virtual std::string type() const override {return "surface";} + std::string type() const override {return "surface";} - virtual ~SurfaceFilter() override = default; + ~SurfaceFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { surfaces_ = get_node_array(node, "bins"); n_bins_ = surfaces_.size(); } - virtual void + void initialize() override { for (auto& s : surfaces_) { @@ -51,7 +51,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -66,7 +66,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -75,7 +75,7 @@ public: write_dataset(filter_group, "bins", surface_ids); } - virtual std::string + std::string text_label(int bin) const override { return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_universe.h b/include/openmc/tallies/tally_filter_universe.h index 930856c6a..9654f7625 100644 --- a/include/openmc/tallies/tally_filter_universe.h +++ b/include/openmc/tallies/tally_filter_universe.h @@ -20,18 +20,18 @@ namespace openmc { class UniverseFilter : public TallyFilter { public: - virtual std::string type() const override {return "universe";} + std::string type() const override {return "universe";} - virtual ~UniverseFilter() override = default; + ~UniverseFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { universes_ = get_node_array(node, "bins"); n_bins_ = universes_.size(); } - virtual void + void initialize() override { for (auto& u : universes_) { @@ -51,7 +51,7 @@ public: } } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -64,7 +64,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -73,7 +73,7 @@ public: write_dataset(filter_group, "bins", universe_ids); } - virtual std::string + std::string text_label(int bin) const override { return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); diff --git a/include/openmc/tallies/tally_filter_zernike.h b/include/openmc/tallies/tally_filter_zernike.h index c074d171f..397750ebd 100644 --- a/include/openmc/tallies/tally_filter_zernike.h +++ b/include/openmc/tallies/tally_filter_zernike.h @@ -19,11 +19,11 @@ namespace openmc { class ZernikeFilter : public TallyFilter { public: - virtual std::string type() const override {return "zernike";} + std::string type() const override {return "zernike";} - virtual ~ZernikeFilter() override = default; + ~ZernikeFilter() = default; - virtual void + void from_xml(pugi::xml_node node) override { order_ = std::stoi(get_node_value(node, "order")); @@ -33,7 +33,7 @@ public: calc_n_bins(); } - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -54,7 +54,7 @@ public: } } - virtual void + void to_statepoint(hid_t filter_group) const override { TallyFilter::to_statepoint(filter_group); @@ -64,7 +64,7 @@ public: write_dataset(filter_group, "r", r_); } - virtual std::string + std::string text_label(int bin) const override { std::stringstream out; @@ -92,11 +92,9 @@ public: class ZernikeRadialFilter : public ZernikeFilter { public: - virtual std::string type() const override {return "zernikeradial";} + std::string type() const override {return "zernikeradial";} - virtual ~ZernikeRadialFilter() override = default; - - virtual void + void get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const override { @@ -116,13 +114,13 @@ public: } } - virtual std::string + std::string text_label(int bin) const override { return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; } - virtual void calc_n_bins() override {n_bins_ = order_ / 2 + 1;} + void calc_n_bins() override {n_bins_ = order_ / 2 + 1;} }; } // namespace openmc From 15caa0c1ca60ab00a97aeb813e79eab99a408635 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 21 Oct 2018 18:59:03 -0400 Subject: [PATCH 41/45] Address #1101 comments --- include/openmc/math_functions.h | 4 ++-- include/openmc/tallies/tally_filter_mu.h | 2 +- include/openmc/tallies/tally_filter_zernike.h | 4 ++-- openmc/capi/math.py | 12 ++++++------ src/math_functions.cpp | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/openmc/math_functions.h b/include/openmc/math_functions.h index 8bfa11899..ca0646961 100644 --- a/include/openmc/math_functions.h +++ b/include/openmc/math_functions.h @@ -90,7 +90,7 @@ extern "C" void calc_rn_c(int n, const double uvw[3], double rn[]); //! evaluated at rho and phi. //============================================================================== -extern "C" void calc_zn_c(int n, double rho, double phi, double zn[]); +extern "C" void calc_zn(int n, double rho, double phi, double zn[]); //============================================================================== //! Calculate only the even radial components of n-th order modified Zernike @@ -113,7 +113,7 @@ extern "C" void calc_zn_c(int n, double rho, double phi, double zn[]); //! evaluated at rho and phi when m = 0. //============================================================================== -extern "C" void calc_zn_rad_c(int n, double rho, double zn_rad[]); +extern "C" void calc_zn_rad(int n, double rho, double zn_rad[]); //============================================================================== //! Rotate the direction cosines through a polar angle whose cosine is mu and diff --git a/include/openmc/tallies/tally_filter_mu.h b/include/openmc/tallies/tally_filter_mu.h index 93fc7020a..ee3435036 100644 --- a/include/openmc/tallies/tally_filter_mu.h +++ b/include/openmc/tallies/tally_filter_mu.h @@ -44,7 +44,7 @@ public: double d_angle = 2.0 / n_angle; bins_.resize(n_angle + 1); for (int i = 0; i < n_angle; i++) bins_[i] = -1 + i * d_angle; - bins_[n_angle] = PI; + bins_[n_angle] = 1; } n_bins_ = bins_.size() - 1; diff --git a/include/openmc/tallies/tally_filter_zernike.h b/include/openmc/tallies/tally_filter_zernike.h index 397750ebd..12f7f0ff6 100644 --- a/include/openmc/tallies/tally_filter_zernike.h +++ b/include/openmc/tallies/tally_filter_zernike.h @@ -46,7 +46,7 @@ public: if (r <= 1.0) { // Compute and return the Zernike weights. double zn[n_bins_]; - calc_zn_c(order_, r, theta, zn); + calc_zn(order_, r, theta, zn); for (int i = 0; i < n_bins_; i++) { match.bins_.push_back(i+1); match.weights_.push_back(zn[i]); @@ -106,7 +106,7 @@ public: if (r <= 1.0) { // Compute and return the Zernike weights. double zn[n_bins_]; - calc_zn_rad_c(order_, r, zn); + calc_zn_rad(order_, r, zn); for (int i = 0; i < n_bins_; i++) { match.bins_.push_back(i+1); match.weights_.push_back(zn[i]); diff --git a/openmc/capi/math.py b/openmc/capi/math.py index a8ea849b3..34beb585f 100644 --- a/openmc/capi/math.py +++ b/openmc/capi/math.py @@ -18,11 +18,11 @@ _dll.evaluate_legendre.argtypes = [c_int, POINTER(c_double), c_double] _dll.calc_rn_c.restype = None _dll.calc_rn_c.argtypes = [c_int, ndpointer(c_double), ndpointer(c_double)] -_dll.calc_zn_c.restype = None -_dll.calc_zn_c.argtypes = [c_int, c_double, c_double, ndpointer(c_double)] +_dll.calc_zn.restype = None +_dll.calc_zn.argtypes = [c_int, c_double, c_double, ndpointer(c_double)] -_dll.calc_zn_rad_c.restype = None -_dll.calc_zn_rad_c.argtypes = [c_int, c_double, ndpointer(c_double)] +_dll.calc_zn_rad.restype = None +_dll.calc_zn_rad.argtypes = [c_int, c_double, ndpointer(c_double)] _dll.rotate_angle_c.restype = None _dll.rotate_angle_c.argtypes = [ndpointer(c_double), c_double, @@ -153,7 +153,7 @@ def calc_zn(n, rho, phi): num_bins = ((n + 1) * (n + 2)) // 2 zn = np.zeros(num_bins, dtype=np.float64) - _dll.calc_zn_c(n, rho, phi, zn) + _dll.calc_zn(n, rho, phi, zn) return zn @@ -179,7 +179,7 @@ def calc_zn_rad(n, rho): num_bins = n // 2 + 1 zn_rad = np.zeros(num_bins, dtype=np.float64) - _dll.calc_zn_rad_c(n, rho, zn_rad) + _dll.calc_zn_rad(n, rho, zn_rad) return zn_rad diff --git a/src/math_functions.cpp b/src/math_functions.cpp index 8d30ea84d..a8646f09d 100644 --- a/src/math_functions.cpp +++ b/src/math_functions.cpp @@ -510,7 +510,7 @@ void calc_rn_c(int n, const double uvw[3], double rn[]){ } -void calc_zn_c(int n, double rho, double phi, double zn[]) { +void calc_zn(int n, double rho, double phi, double zn[]) { // =========================================================================== // Determine vector of sin(n*phi) and cos(n*phi). This takes advantage of the // following recurrence relations so that only a single sin/cos have to be @@ -587,7 +587,7 @@ void calc_zn_c(int n, double rho, double phi, double zn[]) { } -void calc_zn_rad_c(int n, double rho, double zn_rad[]) { +void calc_zn_rad(int n, double rho, double zn_rad[]) { // Calculate R_p0(rho) as Zn_p0(rho) // Set up the array of the coefficients From e2e813adb84ced43b0a009d1b1c0e6cd2e0e79b1 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 22 Oct 2018 10:22:55 -0400 Subject: [PATCH 42/45] Remove "tally_" prefix from tally filter files --- include/openmc/geometry_aux.h | 24 +++--- .../tallies/{tally_filter.h => filter.h} | 26 +++---- ..._filter_azimuthal.h => filter_azimuthal.h} | 14 ++-- .../{tally_filter_cell.h => filter_cell.h} | 14 ++-- ...ly_filter_cellborn.h => filter_cellborn.h} | 10 +-- ...ly_filter_cellfrom.h => filter_cellfrom.h} | 10 +-- ...ter_distribcell.h => filter_distribcell.h} | 14 ++-- ...ilter_energyfunc.h => filter_energyfunc.h} | 16 ++-- ...ly_filter_legendre.h => filter_legendre.h} | 14 ++-- ...ly_filter_material.h => filter_material.h} | 14 ++-- .../{tally_filter_mesh.h => filter_mesh.h} | 14 ++-- ...ter_meshsurface.h => filter_meshsurface.h} | 10 +-- .../{tally_filter_mu.h => filter_mu.h} | 14 ++-- .../{tally_filter_polar.h => filter_polar.h} | 14 ++-- ...ly_filter_sph_harm.h => filter_sph_harm.h} | 14 ++-- ...sptl_legendre.h => filter_sptl_legendre.h} | 14 ++-- ...ally_filter_surface.h => filter_surface.h} | 14 ++-- ...ly_filter_universe.h => filter_universe.h} | 14 ++-- ...ally_filter_zernike.h => filter_zernike.h} | 16 ++-- src/geometry_aux.cpp | 4 +- src/mesh.cpp | 2 +- src/simulation.cpp | 2 +- src/tallies/tally_filter.cpp | 78 +++++++++---------- 23 files changed, 181 insertions(+), 185 deletions(-) rename include/openmc/tallies/{tally_filter.h => filter.h} (80%) rename include/openmc/tallies/{tally_filter_azimuthal.h => filter_azimuthal.h} (86%) rename include/openmc/tallies/{tally_filter_cell.h => filter_cell.h} (85%) rename include/openmc/tallies/{tally_filter_cellborn.h => filter_cellborn.h} (75%) rename include/openmc/tallies/{tally_filter_cellfrom.h => filter_cellfrom.h} (77%) rename include/openmc/tallies/{tally_filter_distribcell.h => filter_distribcell.h} (87%) rename include/openmc/tallies/{tally_filter_energyfunc.h => filter_energyfunc.h} (86%) rename include/openmc/tallies/{tally_filter_legendre.h => filter_legendre.h} (77%) rename include/openmc/tallies/{tally_filter_material.h => filter_material.h} (84%) rename include/openmc/tallies/{tally_filter_mesh.h => filter_mesh.h} (87%) rename include/openmc/tallies/{tally_filter_meshsurface.h => filter_meshsurface.h} (88%) rename include/openmc/tallies/{tally_filter_mu.h => filter_mu.h} (85%) rename include/openmc/tallies/{tally_filter_polar.h => filter_polar.h} (86%) rename include/openmc/tallies/{tally_filter_sph_harm.h => filter_sph_harm.h} (88%) rename include/openmc/tallies/{tally_filter_sptl_legendre.h => filter_sptl_legendre.h} (88%) rename include/openmc/tallies/{tally_filter_surface.h => filter_surface.h} (85%) rename include/openmc/tallies/{tally_filter_universe.h => filter_universe.h} (85%) rename include/openmc/tallies/{tally_filter_zernike.h => filter_zernike.h} (88%) diff --git a/include/openmc/geometry_aux.h b/include/openmc/geometry_aux.h index 34ed206da..da55c3d9b 100644 --- a/include/openmc/geometry_aux.h +++ b/include/openmc/geometry_aux.h @@ -27,7 +27,7 @@ extern "C" void assign_temperatures(); //! //! This function looks for a universe that is not listed in a Cell::fill or in //! a Lattice. -//! @return The index of the root universe. +//! \return The index of the root universe. //============================================================================== extern "C" int32_t find_root_universe(); @@ -49,7 +49,7 @@ extern "C" void prepare_distribcell(); //! //! This function will update the Cell::n_instances value for each cell in the //! geometry. -//! @param univ_indx The index of the universe to begin searching from (probably +//! \param univ_indx The index of the universe to begin searching from (probably //! the root universe). //============================================================================== @@ -57,9 +57,9 @@ extern "C" void count_cell_instances(int32_t univ_indx); //============================================================================== //! Recursively search through universes and count universe instances. -//! @param search_univ The index of the universe to begin searching from. -//! @param target_univ_id The ID of the universe to be counted. -//! @return The number of instances of target_univ_id in the geometry tree under +//! \param search_univ The index of the universe to begin searching from. +//! \param target_univ_id The ID of the universe to be counted. +//! \return The number of instances of target_univ_id in the geometry tree under //! search_univ. //============================================================================== @@ -68,13 +68,11 @@ count_universe_instances(int32_t search_univ, int32_t target_univ_id); //============================================================================== //! Build a character array representing the path to a distribcell instance. -//! @param target_cell The index of the Cell in the global Cell array. -//! @param map The index of the distribcell mapping corresponding to the target +//! \param target_cell The index of the Cell in the global Cell array. +//! \param map The index of the distribcell mapping corresponding to the target //! cell. -//! @param target_offset An instance number for a distributed cell. -//! @param root_univ The index of the root Universe in the global Universe -//! array. -//! @return The unique traversal through the geometry tree that leads to the +//! \param target_offset An instance number for a distributed cell. +//! \return The unique traversal through the geometry tree that leads to the //! desired instance of the target cell. //============================================================================== @@ -83,9 +81,9 @@ distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset); //============================================================================== //! Determine the maximum number of nested coordinate levels in the geometry. -//! @param univ The index of the universe to begin seraching from (probably the +//! \param univ The index of the universe to begin seraching from (probably the //! root universe). -//! @return The number of coordinate levels. +//! \return The number of coordinate levels. //============================================================================== extern "C" int maximum_levels(int32_t univ); diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/filter.h similarity index 80% rename from include/openmc/tallies/tally_filter.h rename to include/openmc/tallies/filter.h index 08d92f404..e87e35b78 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/filter.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_H -#define OPENMC_TALLY_FILTER_H +#ifndef OPENMC_TALLIES_FILTER_H +#define OPENMC_TALLIES_FILTER_H #include #include @@ -18,36 +18,34 @@ namespace openmc { extern "C" int32_t n_filters; -class TallyFilterMatch; -extern std::vector filter_matches; +class FilterMatch; +extern std::vector filter_matches; #pragma omp threadprivate(filter_matches) -class TallyFilter; -extern std::vector tally_filters; +class Filter; +extern std::vector tally_filters; //============================================================================== //! Stores bins and weights for filtered tally events. //============================================================================== -class TallyFilterMatch +class FilterMatch { public: - //int i_bin_; std::vector bins_; std::vector weights_; - //bool bins_present_; }; //============================================================================== //! Modifies tally score events. //============================================================================== -class TallyFilter +class Filter { public: virtual std::string type() const = 0; - virtual ~TallyFilter() = 0; + virtual ~Filter() = 0; //! Uses an XML input to fill the filter's data fields. virtual void from_xml(pugi::xml_node node) = 0; @@ -57,7 +55,7 @@ public: //! \param[out] match will contain the matching bins and corresponding //! weights; note that there may be zero matching bins virtual void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) const = 0; + get_all_bins(Particle* p, int estimator, FilterMatch& match) const = 0; //! Writes data describing this filter to an HDF5 statepoint group. virtual void @@ -78,11 +76,11 @@ public: int n_bins_; }; -inline TallyFilter::~TallyFilter() {} +inline Filter::~Filter() {} //============================================================================== extern "C" void free_memory_tally_c(); } // namespace openmc -#endif // OPENMC_TALLY_FILTER_H +#endif // OPENMC_TALLIES_FILTER_H diff --git a/include/openmc/tallies/tally_filter_azimuthal.h b/include/openmc/tallies/filter_azimuthal.h similarity index 86% rename from include/openmc/tallies/tally_filter_azimuthal.h rename to include/openmc/tallies/filter_azimuthal.h index 091fde7c9..a7fc8ff3e 100644 --- a/include/openmc/tallies/tally_filter_azimuthal.h +++ b/include/openmc/tallies/filter_azimuthal.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_AZIMUTHAL_H -#define OPENMC_TALLY_FILTER_AZIMUTHAL_H +#ifndef OPENMC_TALLIES_FILTER_AZIMUTHAL_H +#define OPENMC_TALLIES_FILTER_AZIMUTHAL_H #include #include @@ -7,7 +7,7 @@ #include "openmc/error.h" #include "openmc/search.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -16,7 +16,7 @@ namespace openmc { //! Bins the incident neutron azimuthal angle (relative to the global xy-plane). //============================================================================== -class AzimuthalFilter : public TallyFilter +class AzimuthalFilter : public Filter { public: std::string type() const override {return "azimuthal";} @@ -50,7 +50,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { double phi; @@ -70,7 +70,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } @@ -87,4 +87,4 @@ protected: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_AZIMUTHAL_H +#endif // OPENMC_TALLIES_FILTER_AZIMUTHAL_H diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/filter_cell.h similarity index 85% rename from include/openmc/tallies/tally_filter_cell.h rename to include/openmc/tallies/filter_cell.h index ecef014a0..689cc11d6 100644 --- a/include/openmc/tallies/tally_filter_cell.h +++ b/include/openmc/tallies/filter_cell.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_CELL_H -#define OPENMC_TALLY_FILTER_CELL_H +#ifndef OPENMC_TALLIES_FILTER_CELL_H +#define OPENMC_TALLIES_FILTER_CELL_H #include #include @@ -8,7 +8,7 @@ #include "openmc/cell.h" #include "openmc/error.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -17,7 +17,7 @@ namespace openmc { //! Specifies which geometric cells tally events reside in. //============================================================================== -class CellFilter : public TallyFilter +class CellFilter : public Filter { public: std::string type() const override {return "cell";} @@ -51,7 +51,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { for (int i = 0; i < p->n_coord; i++) { @@ -67,7 +67,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); std::vector cell_ids; for (auto c : cells_) cell_ids.push_back(cells[c]->id_); write_dataset(filter_group, "bins", cell_ids); @@ -84,4 +84,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_CELL_H +#endif // OPENMC_TALLIES_FILTER_CELL_H diff --git a/include/openmc/tallies/tally_filter_cellborn.h b/include/openmc/tallies/filter_cellborn.h similarity index 75% rename from include/openmc/tallies/tally_filter_cellborn.h rename to include/openmc/tallies/filter_cellborn.h index a7e5634dd..acc9e0290 100644 --- a/include/openmc/tallies/tally_filter_cellborn.h +++ b/include/openmc/tallies/filter_cellborn.h @@ -1,7 +1,7 @@ -#ifndef OPENMC_TALLY_FILTER_CELLBORN_H -#define OPENMC_TALLY_FILTER_CELLBORN_H +#ifndef OPENMC_TALLIES_FILTER_CELLBORN_H +#define OPENMC_TALLIES_FILTER_CELLBORN_H -#include "openmc/tallies/tally_filter_cell.h" +#include "openmc/tallies/filter_cell.h" namespace openmc { @@ -15,7 +15,7 @@ public: std::string type() const override {return "cellborn";} void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { auto search = map_.find(p->cell_born); @@ -34,4 +34,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_CELLBORN_H +#endif // OPENMC_TALLIES_FILTER_CELLBORN_H diff --git a/include/openmc/tallies/tally_filter_cellfrom.h b/include/openmc/tallies/filter_cellfrom.h similarity index 77% rename from include/openmc/tallies/tally_filter_cellfrom.h rename to include/openmc/tallies/filter_cellfrom.h index 40bc38227..6490992d7 100644 --- a/include/openmc/tallies/tally_filter_cellfrom.h +++ b/include/openmc/tallies/filter_cellfrom.h @@ -1,7 +1,7 @@ -#ifndef OPENMC_TALLY_FILTER_CELLFROM_H -#define OPENMC_TALLY_FILTER_CELLFROM_H +#ifndef OPENMC_TALLIES_FILTER_CELLFROM_H +#define OPENMC_TALLIES_FILTER_CELLFROM_H -#include "openmc/tallies/tally_filter_cell.h" +#include "openmc/tallies/filter_cell.h" namespace openmc { @@ -16,7 +16,7 @@ public: std::string type() const override {return "cellfrom";} void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { for (int i = 0; i < p->last_n_coord; i++) { @@ -37,4 +37,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_CELLFROM_H +#endif // OPENMC_TALLIES_FILTER_CELLFROM_H diff --git a/include/openmc/tallies/tally_filter_distribcell.h b/include/openmc/tallies/filter_distribcell.h similarity index 87% rename from include/openmc/tallies/tally_filter_distribcell.h rename to include/openmc/tallies/filter_distribcell.h index ab36d0b87..de98b4a73 100644 --- a/include/openmc/tallies/tally_filter_distribcell.h +++ b/include/openmc/tallies/filter_distribcell.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_DISTRIBCELL_H -#define OPENMC_TALLY_FILTER_DISTRIBCELL_H +#ifndef OPENMC_TALLIES_FILTER_DISTRIBCELL_H +#define OPENMC_TALLIES_FILTER_DISTRIBCELL_H #include @@ -7,7 +7,7 @@ #include "openmc/error.h" #include "openmc/geometry_aux.h" // For distribcell_path #include "openmc/lattice.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -16,7 +16,7 @@ namespace openmc { //! Specifies which distributed geometric cells tally events reside in. //============================================================================== -class DistribcellFilter : public TallyFilter +class DistribcellFilter : public Filter { public: std::string type() const override {return "distribcell";} @@ -49,7 +49,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { int offset = 0; @@ -78,7 +78,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "bins", cells[cell_]->id_); } @@ -95,4 +95,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_DISTRIBCELL_H +#endif // OPENMC_TALLIES_FILTER_DISTRIBCELL_H diff --git a/include/openmc/tallies/tally_filter_energyfunc.h b/include/openmc/tallies/filter_energyfunc.h similarity index 86% rename from include/openmc/tallies/tally_filter_energyfunc.h rename to include/openmc/tallies/filter_energyfunc.h index 73f31008a..40cc1d16e 100644 --- a/include/openmc/tallies/tally_filter_energyfunc.h +++ b/include/openmc/tallies/filter_energyfunc.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_ENERGYFUNC_H -#define OPENMC_TALLY_FILTER_ENERGYFUNC_H +#ifndef OPENMC_TALLIES_FILTER_ENERGYFUNC_H +#define OPENMC_TALLIES_FILTER_ENERGYFUNC_H #include // for setprecision #include // for scientific @@ -9,7 +9,7 @@ #include "openmc/error.h" #include "openmc/search.h" #include "openmc/settings.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -19,13 +19,13 @@ namespace openmc { //! described by a piecewise linear-linear interpolation. //============================================================================== -class EnergyFunctionFilter : public TallyFilter +class EnergyFunctionFilter : public Filter { public: std::string type() const override {return "energyfunction";} EnergyFunctionFilter() - : TallyFilter {} + : Filter {} { n_bins_ = 1; } @@ -51,7 +51,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { if (p->last_E >= energy_.front() && p->last_E <= energy_.back()) { @@ -70,7 +70,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "energy", energy_); write_dataset(filter_group, "y", y_); } @@ -91,4 +91,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_ENERGYFUNC_H +#endif // OPENMC_TALLIES_FILTER_ENERGYFUNC_H diff --git a/include/openmc/tallies/tally_filter_legendre.h b/include/openmc/tallies/filter_legendre.h similarity index 77% rename from include/openmc/tallies/tally_filter_legendre.h rename to include/openmc/tallies/filter_legendre.h index c72cd6a19..d423d70a3 100644 --- a/include/openmc/tallies/tally_filter_legendre.h +++ b/include/openmc/tallies/filter_legendre.h @@ -1,12 +1,12 @@ -#ifndef OPENMC_TALLY_FILTER_LEGENDRE_H -#define OPENMC_TALLY_FILTER_LEGENDRE_H +#ifndef OPENMC_TALLIES_FILTER_LEGENDRE_H +#define OPENMC_TALLIES_FILTER_LEGENDRE_H #include #include "openmc/cell.h" #include "openmc/error.h" #include "openmc/math_functions.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -15,7 +15,7 @@ namespace openmc { //! Gives Legendre moments of the change in scattering angle //============================================================================== -class LegendreFilter : public TallyFilter +class LegendreFilter : public Filter { public: std::string type() const override {return "legendre";} @@ -30,7 +30,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { double wgt[n_bins_]; @@ -44,7 +44,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "order", order_); } @@ -58,4 +58,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_LEGENDRE_H +#endif // OPENMC_TALLIES_FILTER_LEGENDRE_H diff --git a/include/openmc/tallies/tally_filter_material.h b/include/openmc/tallies/filter_material.h similarity index 84% rename from include/openmc/tallies/tally_filter_material.h rename to include/openmc/tallies/filter_material.h index 971788331..fed29a173 100644 --- a/include/openmc/tallies/tally_filter_material.h +++ b/include/openmc/tallies/filter_material.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_MATERIAL_H -#define OPENMC_TALLY_FILTER_MATERIAL_H +#ifndef OPENMC_TALLIES_FILTER_MATERIAL_H +#define OPENMC_TALLIES_FILTER_MATERIAL_H #include #include @@ -8,7 +8,7 @@ #include "openmc/error.h" #include "openmc/material.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -17,7 +17,7 @@ namespace openmc { //! Specifies which material tally events reside in. //============================================================================== -class MaterialFilter : public TallyFilter +class MaterialFilter : public Filter { public: std::string type() const override {return "material";} @@ -52,7 +52,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { auto search = map_.find(p->material - 1); @@ -66,7 +66,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); std::vector material_ids; for (auto c : materials_) material_ids.push_back(materials[c]->id_); write_dataset(filter_group, "bins", material_ids); @@ -83,4 +83,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_MATERIAL_H +#endif // OPENMC_TALLIES_FILTER_MATERIAL_H diff --git a/include/openmc/tallies/tally_filter_mesh.h b/include/openmc/tallies/filter_mesh.h similarity index 87% rename from include/openmc/tallies/tally_filter_mesh.h rename to include/openmc/tallies/filter_mesh.h index c0c13c655..d3e046812 100644 --- a/include/openmc/tallies/tally_filter_mesh.h +++ b/include/openmc/tallies/filter_mesh.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_MESH_H -#define OPENMC_TALLY_FILTER_MESH_H +#ifndef OPENMC_TALLIES_FILTER_MESH_H +#define OPENMC_TALLIES_FILTER_MESH_H #include #include @@ -7,7 +7,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/mesh.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -18,7 +18,7 @@ namespace openmc { //! correspond to the fraction of the track length that lies in that bin. //============================================================================== -class MeshFilter : public TallyFilter +class MeshFilter : public Filter { public: std::string type() const override {return "mesh";} @@ -49,7 +49,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { if (estimator != ESTIMATOR_TRACKLENGTH) { @@ -66,7 +66,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "bins", meshes[mesh_]->id_); } @@ -92,4 +92,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_MESH_H +#endif // OPENMC_TALLIES_FILTER_MESH_H diff --git a/include/openmc/tallies/tally_filter_meshsurface.h b/include/openmc/tallies/filter_meshsurface.h similarity index 88% rename from include/openmc/tallies/tally_filter_meshsurface.h rename to include/openmc/tallies/filter_meshsurface.h index abc5ef80d..3184e2584 100644 --- a/include/openmc/tallies/tally_filter_meshsurface.h +++ b/include/openmc/tallies/filter_meshsurface.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_MESHSURFACE_H -#define OPENMC_TALLY_FILTER_MESHSURFACE_H +#ifndef OPENMC_TALLIES_FILTER_MESHSURFACE_H +#define OPENMC_TALLIES_FILTER_MESHSURFACE_H #include #include @@ -7,7 +7,7 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/mesh.h" -#include "openmc/tallies/tally_filter_mesh.h" +#include "openmc/tallies/filter_mesh.h" namespace openmc { @@ -26,7 +26,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { meshes[mesh_]->surface_bins_crossed(p, match.bins_); @@ -78,4 +78,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_MESHSURFACE_H +#endif // OPENMC_TALLIES_FILTER_MESHSURFACE_H diff --git a/include/openmc/tallies/tally_filter_mu.h b/include/openmc/tallies/filter_mu.h similarity index 85% rename from include/openmc/tallies/tally_filter_mu.h rename to include/openmc/tallies/filter_mu.h index ee3435036..4bb2db5ed 100644 --- a/include/openmc/tallies/tally_filter_mu.h +++ b/include/openmc/tallies/filter_mu.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_MU_H -#define OPENMC_TALLY_FILTER_MU_H +#ifndef OPENMC_TALLIES_FILTER_MU_H +#define OPENMC_TALLIES_FILTER_MU_H #include #include @@ -7,7 +7,7 @@ #include "openmc/error.h" #include "openmc/search.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -17,7 +17,7 @@ namespace openmc { //! reactions. //============================================================================== -class MuFilter : public TallyFilter +class MuFilter : public Filter { public: std::string type() const override {return "mu";} @@ -51,7 +51,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { if (p->mu >= bins_[0] && p->mu <= bins_.back()) { @@ -64,7 +64,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } @@ -81,4 +81,4 @@ protected: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_MU_H +#endif // OPENMC_TALLIES_FILTER_MU_H diff --git a/include/openmc/tallies/tally_filter_polar.h b/include/openmc/tallies/filter_polar.h similarity index 86% rename from include/openmc/tallies/tally_filter_polar.h rename to include/openmc/tallies/filter_polar.h index 5dcd28340..f73b52f60 100644 --- a/include/openmc/tallies/tally_filter_polar.h +++ b/include/openmc/tallies/filter_polar.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_POLAR_H -#define OPENMC_TALLY_FILTER_POLAR_H +#ifndef OPENMC_TALLIES_FILTER_POLAR_H +#define OPENMC_TALLIES_FILTER_POLAR_H #include #include @@ -7,7 +7,7 @@ #include "openmc/error.h" #include "openmc/search.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -16,7 +16,7 @@ namespace openmc { //! Bins the incident neutron polar angle (relative to the global z-axis). //============================================================================== -class PolarFilter : public TallyFilter +class PolarFilter : public Filter { public: std::string type() const override {return "polar";} @@ -50,7 +50,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { double theta; @@ -70,7 +70,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "bins", bins_); } @@ -87,4 +87,4 @@ protected: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_POLAR_H +#endif // OPENMC_TALLIES_FILTER_POLAR_H diff --git a/include/openmc/tallies/tally_filter_sph_harm.h b/include/openmc/tallies/filter_sph_harm.h similarity index 88% rename from include/openmc/tallies/tally_filter_sph_harm.h rename to include/openmc/tallies/filter_sph_harm.h index 79577f67c..5a7492114 100644 --- a/include/openmc/tallies/tally_filter_sph_harm.h +++ b/include/openmc/tallies/filter_sph_harm.h @@ -1,10 +1,10 @@ -#ifndef OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H -#define OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H +#ifndef OPENMC_TALLIES_FILTER_SPH_HAR_H +#define OPENMC_TALLIES_FILTER_SPH_HAR_H #include #include "openmc/error.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -18,7 +18,7 @@ enum class SphericalHarmonicsCosine { //! Gives spherical harmonics expansion moments of a tally score //============================================================================== -class SphericalHarmonicsFilter : public TallyFilter +class SphericalHarmonicsFilter : public Filter { public: std::string type() const override {return "sphericalharmonics";} @@ -47,7 +47,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { // Determine cosine term for scatter expansion if necessary @@ -78,7 +78,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "order", order_); if (cosine_ == SphericalHarmonicsCosine::scatter) { write_dataset(filter_group, "cosine", "scatter"); @@ -105,4 +105,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_SPHERICAL_HARMONICS_H +#endif // OPENMC_TALLIES_FILTER_SPH_HAR_H diff --git a/include/openmc/tallies/tally_filter_sptl_legendre.h b/include/openmc/tallies/filter_sptl_legendre.h similarity index 88% rename from include/openmc/tallies/tally_filter_sptl_legendre.h rename to include/openmc/tallies/filter_sptl_legendre.h index 19176b42b..d3f507941 100644 --- a/include/openmc/tallies/tally_filter_sptl_legendre.h +++ b/include/openmc/tallies/filter_sptl_legendre.h @@ -1,11 +1,11 @@ -#ifndef OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H -#define OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H +#ifndef OPENMC_TALLIES_FILTER_SPTL_LEGENDRE_H +#define OPENMC_TALLIES_FILTER_SPTL_LEGENDRE_H #include #include "openmc/error.h" #include "openmc/math_functions.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -19,7 +19,7 @@ enum class LegendreAxis { //! Gives Legendre moments of the particle's normalized position along an axis //============================================================================== -class SpatialLegendreFilter : public TallyFilter +class SpatialLegendreFilter : public Filter { public: std::string type() const override {return "spatiallegendre";} @@ -49,7 +49,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { // Get the coordinate along the axis of interest. @@ -79,7 +79,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "order", order_); if (axis_ == LegendreAxis::x) { write_dataset(filter_group, "axis", "x"); @@ -114,4 +114,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_SPTL_LEGENDRE_H +#endif // OPENMC_TALLIES_FILTER_SPTL_LEGENDRE_H diff --git a/include/openmc/tallies/tally_filter_surface.h b/include/openmc/tallies/filter_surface.h similarity index 85% rename from include/openmc/tallies/tally_filter_surface.h rename to include/openmc/tallies/filter_surface.h index fa98be8be..7e32572c8 100644 --- a/include/openmc/tallies/tally_filter_surface.h +++ b/include/openmc/tallies/filter_surface.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_SURFACE_H -#define OPENMC_TALLY_FILTER_SURFACE_H +#ifndef OPENMC_TALLIES_FILTER_SURFACE_H +#define OPENMC_TALLIES_FILTER_SURFACE_H #include #include @@ -8,7 +8,7 @@ #include "openmc/error.h" #include "openmc/surface.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -17,7 +17,7 @@ namespace openmc { //! Specifies which surface particles are crossing //============================================================================== -class SurfaceFilter : public TallyFilter +class SurfaceFilter : public Filter { public: std::string type() const override {return "surface";} @@ -52,7 +52,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { auto search = map_.find(std::abs(p->surface)-1); @@ -69,7 +69,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); std::vector surface_ids; for (auto c : surfaces_) surface_ids.push_back(surfaces[c]->id_); write_dataset(filter_group, "bins", surface_ids); @@ -86,4 +86,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_SURFACE_H +#endif // OPENMC_TALLIES_FILTER_SURFACE_H diff --git a/include/openmc/tallies/tally_filter_universe.h b/include/openmc/tallies/filter_universe.h similarity index 85% rename from include/openmc/tallies/tally_filter_universe.h rename to include/openmc/tallies/filter_universe.h index 9654f7625..75feccdd4 100644 --- a/include/openmc/tallies/tally_filter_universe.h +++ b/include/openmc/tallies/filter_universe.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_UNIVERSE_H -#define OPENMC_TALLY_FILTER_UNIVERSE_H +#ifndef OPENMC_TALLIES_FILTER_UNIVERSE_H +#define OPENMC_TALLIES_FILTER_UNIVERSE_H #include #include @@ -8,7 +8,7 @@ #include "openmc/cell.h" #include "openmc/error.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -17,7 +17,7 @@ namespace openmc { //! Specifies which geometric universes tally events reside in. //============================================================================== -class UniverseFilter : public TallyFilter +class UniverseFilter : public Filter { public: std::string type() const override {return "universe";} @@ -52,7 +52,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { for (int i = 0; i < p->n_coord; i++) { @@ -67,7 +67,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); std::vector universe_ids; for (auto u : universes_) universe_ids.push_back(universes[u]->id_); write_dataset(filter_group, "bins", universe_ids); @@ -84,4 +84,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_UNIVERSE_H +#endif // OPENMC_TALLIES_FILTER_UNIVERSE_H diff --git a/include/openmc/tallies/tally_filter_zernike.h b/include/openmc/tallies/filter_zernike.h similarity index 88% rename from include/openmc/tallies/tally_filter_zernike.h rename to include/openmc/tallies/filter_zernike.h index 12f7f0ff6..6f3d96077 100644 --- a/include/openmc/tallies/tally_filter_zernike.h +++ b/include/openmc/tallies/filter_zernike.h @@ -1,5 +1,5 @@ -#ifndef OPENMC_TALLY_FILTER_ZERNIKE_H -#define OPENMC_TALLY_FILTER_ZERNIKE_H +#ifndef OPENMC_TALLIES_FILTER_ZERNIKE_H +#define OPENMC_TALLIES_FILTER_ZERNIKE_H #include #include @@ -7,7 +7,7 @@ #include "openmc/error.h" #include "openmc/math_functions.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" namespace openmc { @@ -16,7 +16,7 @@ namespace openmc { //! Gives Zernike polynomial moments of a particle's position //============================================================================== -class ZernikeFilter : public TallyFilter +class ZernikeFilter : public Filter { public: std::string type() const override {return "zernike";} @@ -34,7 +34,7 @@ public: } void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { // Determine the normalized (r,theta) coordinates. @@ -57,7 +57,7 @@ public: void to_statepoint(hid_t filter_group) const override { - TallyFilter::to_statepoint(filter_group); + Filter::to_statepoint(filter_group); write_dataset(filter_group, "order", order_); write_dataset(filter_group, "x", x_); write_dataset(filter_group, "y", y_); @@ -95,7 +95,7 @@ public: std::string type() const override {return "zernikeradial";} void - get_all_bins(Particle* p, int estimator, TallyFilterMatch& match) + get_all_bins(Particle* p, int estimator, FilterMatch& match) const override { // Determine the normalized radius coordinate. @@ -124,4 +124,4 @@ public: }; } // namespace openmc -#endif // OPENMC_TALLY_FILTER_ZERNIKE_H +#endif // OPENMC_TALLIES_FILTER_ZERNIKE_H diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index ee1949788..c0d9066a0 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -12,8 +12,8 @@ #include "openmc/material.h" #include "openmc/settings.h" #include "openmc/surface.h" -#include "openmc/tallies/tally_filter.h" -#include "openmc/tallies/tally_filter_distribcell.h" +#include "openmc/tallies/filter.h" +#include "openmc/tallies/filter_distribcell.h" namespace openmc { diff --git a/src/mesh.cpp b/src/mesh.cpp index e878467fc..a9b716ecd 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -20,7 +20,7 @@ #include "openmc/hdf5_interface.h" #include "openmc/message_passing.h" #include "openmc/search.h" -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" #include "openmc/xml_interface.h" namespace openmc { diff --git a/src/simulation.cpp b/src/simulation.cpp index 01fd2ebf7..36f981109 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -4,8 +4,8 @@ #include "openmc/eigenvalue.h" #include "openmc/message_passing.h" #include "openmc/settings.h" +#include "openmc/tallies/filter.h" #include "openmc/tallies/tally.h" -#include "openmc/tallies/tally_filter.h" #include diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index d32440146..5ad918110 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -1,27 +1,27 @@ -#include "openmc/tallies/tally_filter.h" +#include "openmc/tallies/filter.h" #include #include "openmc/capi.h" #include "openmc/constants.h" // for MAX_LINE_LEN; #include "openmc/error.h" -#include "openmc/tallies/tally_filter_azimuthal.h" -#include "openmc/tallies/tally_filter_cell.h" -#include "openmc/tallies/tally_filter_cellborn.h" -#include "openmc/tallies/tally_filter_cellfrom.h" -#include "openmc/tallies/tally_filter_distribcell.h" -#include "openmc/tallies/tally_filter_energyfunc.h" -#include "openmc/tallies/tally_filter_legendre.h" -#include "openmc/tallies/tally_filter_material.h" -#include "openmc/tallies/tally_filter_mesh.h" -#include "openmc/tallies/tally_filter_meshsurface.h" -#include "openmc/tallies/tally_filter_mu.h" -#include "openmc/tallies/tally_filter_polar.h" -#include "openmc/tallies/tally_filter_sph_harm.h" -#include "openmc/tallies/tally_filter_sptl_legendre.h" -#include "openmc/tallies/tally_filter_surface.h" -#include "openmc/tallies/tally_filter_universe.h" -#include "openmc/tallies/tally_filter_zernike.h" +#include "openmc/tallies/filter_azimuthal.h" +#include "openmc/tallies/filter_cell.h" +#include "openmc/tallies/filter_cellborn.h" +#include "openmc/tallies/filter_cellfrom.h" +#include "openmc/tallies/filter_distribcell.h" +#include "openmc/tallies/filter_energyfunc.h" +#include "openmc/tallies/filter_legendre.h" +#include "openmc/tallies/filter_material.h" +#include "openmc/tallies/filter_mesh.h" +#include "openmc/tallies/filter_meshsurface.h" +#include "openmc/tallies/filter_mu.h" +#include "openmc/tallies/filter_polar.h" +#include "openmc/tallies/filter_sph_harm.h" +#include "openmc/tallies/filter_sptl_legendre.h" +#include "openmc/tallies/filter_surface.h" +#include "openmc/tallies/filter_universe.h" +#include "openmc/tallies/filter_zernike.h" namespace openmc { @@ -30,8 +30,8 @@ namespace openmc { // Global variables //============================================================================== -std::vector filter_matches; -std::vector tally_filters; +std::vector filter_matches; +std::vector tally_filters; //============================================================================== // Non-member functions @@ -45,7 +45,7 @@ free_memory_tally_c() filter_matches.clear(); } - for (TallyFilter* filt : tally_filters) {delete filt;} + for (Filter* filt : tally_filters) {delete filt;} tally_filters.clear(); } @@ -55,7 +55,7 @@ free_memory_tally_c() // Fortran functions that will be called from C++ extern "C" int verify_filter(int32_t index); -extern "C" TallyFilter* filter_from_f(int32_t index); +extern "C" Filter* filter_from_f(int32_t index); extern "C" void filter_update_n_bins(int32_t index); extern "C" { @@ -445,42 +445,42 @@ extern "C" { //============================================================================== extern "C" { - TallyFilterMatch* filter_match_pointer(int indx) + FilterMatch* filter_match_pointer(int indx) {return &filter_matches[indx];} void - filter_match_bins_push_back(TallyFilterMatch* match, int val) + filter_match_bins_push_back(FilterMatch* match, int val) {match->bins_.push_back(val);} void - filter_match_weights_push_back(TallyFilterMatch* match, double val) + filter_match_weights_push_back(FilterMatch* match, double val) {match->weights_.push_back(val);} void - filter_match_bins_clear(TallyFilterMatch* match) + filter_match_bins_clear(FilterMatch* match) {match->bins_.clear();} void - filter_match_weights_clear(TallyFilterMatch* match) + filter_match_weights_clear(FilterMatch* match) {match->weights_.clear();} int - filter_match_bins_size(TallyFilterMatch* match) + filter_match_bins_size(FilterMatch* match) {return match->bins_.size();} int - filter_match_bins_data(TallyFilterMatch* match, int indx) + filter_match_bins_data(FilterMatch* match, int indx) {return match->bins_[indx-1];} double - filter_match_weights_data(TallyFilterMatch* match, int indx) + filter_match_weights_data(FilterMatch* match, int indx) {return match->weights_[indx-1];} void - filter_match_bins_set_data(TallyFilterMatch* match, int indx, int val) + filter_match_bins_set_data(FilterMatch* match, int indx, int val) {match->bins_[indx-1] = val;} - TallyFilter* + Filter* allocate_filter(const char* type) { std::string type_ {type}; @@ -526,20 +526,20 @@ extern "C" { return tally_filters.back(); } - void filter_from_xml(TallyFilter* filt, pugi::xml_node* node) + void filter_from_xml(Filter* filt, pugi::xml_node* node) {filt->from_xml(*node);} void - filter_get_all_bins(TallyFilter* filt, Particle* p, int estimator, - TallyFilterMatch* match) + filter_get_all_bins(Filter* filt, Particle* p, int estimator, + FilterMatch* match) { filt->get_all_bins(p, estimator, *match); } - void filter_to_statepoint(TallyFilter* filt, hid_t group) + void filter_to_statepoint(Filter* filt, hid_t group) {filt->to_statepoint(group);} - void filter_text_label(TallyFilter* filt, int bin, char* label) + void filter_text_label(Filter* filt, int bin, char* label) { std::string label_str = filt->text_label(bin); int i = 0; @@ -548,9 +548,9 @@ extern "C" { label[i] = '\0'; } - void filter_initialize(TallyFilter* filt) {filt->initialize();} + void filter_initialize(Filter* filt) {filt->initialize();} - int filter_n_bins(TallyFilter* filt) {return filt->n_bins_;} + int filter_n_bins(Filter* filt) {return filt->n_bins_;} int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} From fa419332c91393b08c89194fc9c618e85ba0e285 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 22 Oct 2018 20:06:54 -0400 Subject: [PATCH 43/45] Move tally filter implementation from .h to .cpp --- CMakeLists.txt | 19 +- include/openmc/tallies/filter.h | 7 + include/openmc/tallies/filter_azimuthal.h | 69 +-- include/openmc/tallies/filter_cell.h | 62 +- include/openmc/tallies/filter_cellborn.h | 21 +- include/openmc/tallies/filter_cellfrom.h | 24 +- include/openmc/tallies/filter_distribcell.h | 76 +-- include/openmc/tallies/filter_energyfunc.h | 64 +- include/openmc/tallies/filter_legendre.h | 41 +- include/openmc/tallies/filter_material.h | 61 +- include/openmc/tallies/filter_mesh.h | 71 +-- include/openmc/tallies/filter_meshsurface.h | 67 +-- include/openmc/tallies/filter_mu.h | 61 +- include/openmc/tallies/filter_polar.h | 67 +-- include/openmc/tallies/filter_sph_harm.h | 86 +-- include/openmc/tallies/filter_sptl_legendre.h | 88 +-- include/openmc/tallies/filter_surface.h | 64 +- include/openmc/tallies/filter_universe.h | 62 +- include/openmc/tallies/filter_zernike.h | 89 +-- src/tallies/filter.cpp | 170 ++++++ src/tallies/filter_azimuthal.cpp | 71 +++ src/tallies/filter_cell.cpp | 86 +++ src/tallies/filter_cellborn.cpp | 24 + src/tallies/filter_cellfrom.cpp | 26 + src/tallies/filter_distribcell.cpp | 77 +++ src/tallies/filter_energyfunc.cpp | 67 +++ src/tallies/filter_legendre.cpp | 81 +++ src/tallies/filter_material.cpp | 109 ++++ src/tallies/filter_mesh.cpp | 125 ++++ src/tallies/filter_meshsurface.cpp | 81 +++ src/tallies/filter_mu.cpp | 61 ++ src/tallies/filter_polar.cpp | 70 +++ src/tallies/filter_sph_harm.cpp | 169 ++++++ src/tallies/filter_sptl_legendre.cpp | 171 ++++++ src/tallies/filter_surface.cpp | 67 +++ src/tallies/filter_universe.cpp | 65 ++ src/tallies/filter_zernike.cpp | 182 ++++++ src/tallies/tally_filter.cpp | 561 ------------------ 38 files changed, 1837 insertions(+), 1525 deletions(-) create mode 100644 src/tallies/filter.cpp create mode 100644 src/tallies/filter_azimuthal.cpp create mode 100644 src/tallies/filter_cell.cpp create mode 100644 src/tallies/filter_cellborn.cpp create mode 100644 src/tallies/filter_cellfrom.cpp create mode 100644 src/tallies/filter_distribcell.cpp create mode 100644 src/tallies/filter_energyfunc.cpp create mode 100644 src/tallies/filter_legendre.cpp create mode 100644 src/tallies/filter_material.cpp create mode 100644 src/tallies/filter_mesh.cpp create mode 100644 src/tallies/filter_meshsurface.cpp create mode 100644 src/tallies/filter_mu.cpp create mode 100644 src/tallies/filter_polar.cpp create mode 100644 src/tallies/filter_sph_harm.cpp create mode 100644 src/tallies/filter_sptl_legendre.cpp create mode 100644 src/tallies/filter_surface.cpp create mode 100644 src/tallies/filter_universe.cpp create mode 100644 src/tallies/filter_zernike.cpp delete mode 100644 src/tallies/tally_filter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index feb3776ff..4ac9d9c5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,8 +431,25 @@ add_library(libopenmc SHARED src/string_functions.cpp src/summary.cpp src/surface.cpp + src/tallies/filter.cpp + src/tallies/filter_azimuthal.cpp + src/tallies/filter_cellborn.cpp + src/tallies/filter_cellfrom.cpp + src/tallies/filter_cell.cpp + src/tallies/filter_distribcell.cpp + src/tallies/filter_energyfunc.cpp + src/tallies/filter_legendre.cpp + src/tallies/filter_material.cpp + src/tallies/filter_mesh.cpp + src/tallies/filter_meshsurface.cpp + src/tallies/filter_mu.cpp + src/tallies/filter_polar.cpp + src/tallies/filter_sph_harm.cpp + src/tallies/filter_sptl_legendre.cpp + src/tallies/filter_surface.cpp + src/tallies/filter_universe.cpp + src/tallies/filter_zernike.cpp src/tallies/tally.cpp - src/tallies/tally_filter.cpp src/timer.cpp src/thermal.cpp src/xml_interface.cpp diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index e87e35b78..9398d3ab8 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -82,5 +82,12 @@ inline Filter::~Filter() {} extern "C" void free_memory_tally_c(); +//============================================================================== + +// Filter-related Fortran functions that will be called from C++ +extern "C" int verify_filter(int32_t index); +extern "C" Filter* filter_from_f(int32_t index); +extern "C" void filter_update_n_bins(int32_t index); + } // namespace openmc #endif // OPENMC_TALLIES_FILTER_H diff --git a/include/openmc/tallies/filter_azimuthal.h b/include/openmc/tallies/filter_azimuthal.h index a7fc8ff3e..fdbe20ca5 100644 --- a/include/openmc/tallies/filter_azimuthal.h +++ b/include/openmc/tallies/filter_azimuthal.h @@ -1,15 +1,11 @@ #ifndef OPENMC_TALLIES_FILTER_AZIMUTHAL_H #define OPENMC_TALLIES_FILTER_AZIMUTHAL_H -#include -#include +#include #include -#include "openmc/error.h" -#include "openmc/search.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -19,70 +15,19 @@ namespace openmc { class AzimuthalFilter : public Filter { public: - std::string type() const override {return "azimuthal";} - ~AzimuthalFilter() = default; - void - from_xml(pugi::xml_node node) override - { - auto bins = get_node_array(node, "bins"); + std::string type() const override {return "azimuthal";} - if (bins.size() > 1) { - bins_ = bins; + void from_xml(pugi::xml_node node) override; - } else { - // Allow a user to input a lone number which will mean that you subdivide - // [-pi,pi) evenly with the input being the number of bins + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - int n_angle = bins[0]; + void to_statepoint(hid_t filter_group) const override; - if (n_angle <= 1) fatal_error("Number of bins for azimuthal filter must " - "be greater than 1."); + std::string text_label(int bin) const override; - double d_angle = 2.0 * PI / n_angle; - bins_.resize(n_angle + 1); - for (int i = 0; i < n_angle; i++) bins_[i] = -PI + i * d_angle; - bins_[n_angle] = PI; - } - - n_bins_ = bins_.size() - 1; - } - - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - double phi; - if (estimator == ESTIMATOR_TRACKLENGTH) { - phi = std::atan2(p->coord[0].uvw[1], p->coord[0].uvw[0]); - } else { - phi = std::atan2(p->last_uvw[1], p->last_uvw[0]); - } - - if (phi >= bins_[0] && phi <= bins_.back()) { - auto bin = lower_bound_index(bins_.begin(), bins_.end(), phi) + 1; - match.bins_.push_back(bin); - match.weights_.push_back(1); - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", bins_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - out << "Azimuthal Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; - return out.str(); - } - -protected: std::vector bins_; }; diff --git a/include/openmc/tallies/filter_cell.h b/include/openmc/tallies/filter_cell.h index 689cc11d6..38cb1e57e 100644 --- a/include/openmc/tallies/filter_cell.h +++ b/include/openmc/tallies/filter_cell.h @@ -2,15 +2,11 @@ #define OPENMC_TALLIES_FILTER_CELL_H #include -#include #include #include -#include "openmc/cell.h" -#include "openmc/error.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -20,64 +16,20 @@ namespace openmc { class CellFilter : public Filter { public: - std::string type() const override {return "cell";} - ~CellFilter() = default; - void - from_xml(pugi::xml_node node) override - { - cells_ = get_node_array(node, "bins"); - n_bins_ = cells_.size(); - } + std::string type() const override {return "cell";} - void - initialize() override - { - for (auto& c : cells_) { - auto search = cell_map.find(c); - if (search != cell_map.end()) { - c = search->second; - } else { - std::stringstream err_msg; - err_msg << "Could not find cell " << c << " specified on tally filter."; - fatal_error(err_msg); - } - } + void from_xml(pugi::xml_node node) override; - for (int i = 0; i < cells_.size(); i++) { - map_[cells_[i]] = i; - } - } + void initialize() override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - for (int i = 0; i < p->n_coord; i++) { - auto search = map_.find(p->coord[i].cell); - if (search != map_.end()) { - // TODO: off-by-one - match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); - } - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - std::vector cell_ids; - for (auto c : cells_) cell_ids.push_back(cells[c]->id_); - write_dataset(filter_group, "bins", cell_ids); - } + void to_statepoint(hid_t filter_group) const override; - std::string - text_label(int bin) const override - { - return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); - } + std::string text_label(int bin) const override; std::vector cells_; std::unordered_map map_; diff --git a/include/openmc/tallies/filter_cellborn.h b/include/openmc/tallies/filter_cellborn.h index acc9e0290..414a96ec7 100644 --- a/include/openmc/tallies/filter_cellborn.h +++ b/include/openmc/tallies/filter_cellborn.h @@ -1,6 +1,8 @@ #ifndef OPENMC_TALLIES_FILTER_CELLBORN_H #define OPENMC_TALLIES_FILTER_CELLBORN_H +#include + #include "openmc/tallies/filter_cell.h" namespace openmc { @@ -14,23 +16,10 @@ class CellbornFilter : public CellFilter public: std::string type() const override {return "cellborn";} - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - auto search = map_.find(p->cell_born); - if (search != map_.end()) { - // TODO: off-by-one - match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - std::string - text_label(int bin) const override - { - return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); - } + std::string text_label(int bin) const override; }; } // namespace openmc diff --git a/include/openmc/tallies/filter_cellfrom.h b/include/openmc/tallies/filter_cellfrom.h index 6490992d7..0826c669b 100644 --- a/include/openmc/tallies/filter_cellfrom.h +++ b/include/openmc/tallies/filter_cellfrom.h @@ -1,8 +1,9 @@ #ifndef OPENMC_TALLIES_FILTER_CELLFROM_H #define OPENMC_TALLIES_FILTER_CELLFROM_H -#include "openmc/tallies/filter_cell.h" +#include +#include "openmc/tallies/filter_cell.h" namespace openmc { @@ -15,25 +16,10 @@ class CellFromFilter : public CellFilter public: std::string type() const override {return "cellfrom";} - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - for (int i = 0; i < p->last_n_coord; i++) { - auto search = map_.find(p->last_cell[i]); - if (search != map_.end()) { - // TODO: off-by-one - match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); - } - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - std::string - text_label(int bin) const override - { - return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); - } + std::string text_label(int bin) const override; }; } // namespace openmc diff --git a/include/openmc/tallies/filter_distribcell.h b/include/openmc/tallies/filter_distribcell.h index de98b4a73..e66ee6213 100644 --- a/include/openmc/tallies/filter_distribcell.h +++ b/include/openmc/tallies/filter_distribcell.h @@ -3,13 +3,8 @@ #include -#include "openmc/cell.h" -#include "openmc/error.h" -#include "openmc/geometry_aux.h" // For distribcell_path -#include "openmc/lattice.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -19,77 +14,20 @@ namespace openmc { class DistribcellFilter : public Filter { public: - std::string type() const override {return "distribcell";} - ~DistribcellFilter() = default; - void - from_xml(pugi::xml_node node) override - { - auto cells = get_node_array(node, "bins"); - if (cells.size() != 1) { - fatal_error("Only one cell can be specified per distribcell filter."); - } - cell_ = cells[0]; - } + std::string type() const override {return "distribcell";} - void - initialize() override - { - auto search = cell_map.find(cell_); - if (search != cell_map.end()) { - cell_ = search->second; - n_bins_ = cells[cell_]->n_instances_; - } else { - std::stringstream err_msg; - err_msg << "Could not find cell " << cell_ - << " specified on tally filter."; - fatal_error(err_msg); - } - } + void from_xml(pugi::xml_node node) override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - int offset = 0; - auto distribcell_index = cells[cell_]->distribcell_index_; - for (int i = 0; i < p->n_coord; i++) { - auto& c {*cells[p->coord[i].cell]}; - if (c.type_ == FILL_UNIVERSE) { - offset += c.offset_[distribcell_index]; - } else if (c.type_ == FILL_LATTICE) { - auto& lat {*lattices[p->coord[i+1].lattice-1]}; - int i_xyz[3] {p->coord[i+1].lattice_x, - p->coord[i+1].lattice_y, - p->coord[i+1].lattice_z}; - if (lat.are_valid_indices(i_xyz)) { - offset += lat.offset(distribcell_index, i_xyz); - } - } - if (cell_ == p->coord[i].cell) { - match.bins_.push_back(offset + 1); - match.weights_.push_back(1); - return; - } - } - } + void initialize() override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", cells[cell_]->id_); - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - std::string - text_label(int bin) const override - { - auto map = cells[cell_]->distribcell_index_; - auto path = distribcell_path(cell_, map, bin-1); + void to_statepoint(hid_t filter_group) const override; - return "Distributed Cell " + path; - } + std::string text_label(int bin) const override; int32_t cell_; }; diff --git a/include/openmc/tallies/filter_energyfunc.h b/include/openmc/tallies/filter_energyfunc.h index 40cc1d16e..8fb1b9ede 100644 --- a/include/openmc/tallies/filter_energyfunc.h +++ b/include/openmc/tallies/filter_energyfunc.h @@ -1,17 +1,10 @@ #ifndef OPENMC_TALLIES_FILTER_ENERGYFUNC_H #define OPENMC_TALLIES_FILTER_ENERGYFUNC_H -#include // for setprecision -#include // for scientific -#include #include -#include "openmc/error.h" -#include "openmc/search.h" -#include "openmc/settings.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -22,8 +15,6 @@ namespace openmc { class EnergyFunctionFilter : public Filter { public: - std::string type() const override {return "energyfunction";} - EnergyFunctionFilter() : Filter {} { @@ -32,59 +23,16 @@ public: ~EnergyFunctionFilter() = default; - void - from_xml(pugi::xml_node node) override - { - if (!settings::run_CE) - fatal_error("EnergyFunction filters are only supported for " - "continuous-energy transport calculations"); + std::string type() const override {return "energyfunction";} - if (!check_for_node(node, "energy")) - fatal_error("Energy grid not specified for EnergyFunction filter."); + void from_xml(pugi::xml_node node) override; - energy_ = get_node_array(node, "energy"); + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - if (!check_for_node(node, "y")) - fatal_error("y values not specified for EnergyFunction filter."); + void to_statepoint(hid_t filter_group) const override; - y_ = get_node_array(node, "y"); - } - - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - if (p->last_E >= energy_.front() && p->last_E <= energy_.back()) { - // Search for the incoming energy bin. - auto i = lower_bound_index(energy_.begin(), energy_.end(), p->last_E); - - // Compute the interpolation factor between the nearest bins. - double f = (p->last_E - energy_[i]) / (energy_[i+1] - energy_[i]); - - // Interpolate on the lin-lin grid. - match.bins_.push_back(1); - match.weights_.push_back((1-f) * y_[i] + f * y_[i+1]); - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "energy", energy_); - write_dataset(filter_group, "y", y_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - out << std::scientific << std::setprecision(1) - << "Energy Function f" - << "([ " << energy_.front() << ", ..., " << energy_.back() << "]) = " - << "[" << y_.front() << ", ..., " << y_.back() << "]"; - return out.str(); - } + std::string text_label(int bin) const override; std::vector energy_; std::vector y_; diff --git a/include/openmc/tallies/filter_legendre.h b/include/openmc/tallies/filter_legendre.h index d423d70a3..fabb8140b 100644 --- a/include/openmc/tallies/filter_legendre.h +++ b/include/openmc/tallies/filter_legendre.h @@ -3,12 +3,8 @@ #include -#include "openmc/cell.h" -#include "openmc/error.h" -#include "openmc/math_functions.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -18,41 +14,18 @@ namespace openmc { class LegendreFilter : public Filter { public: - std::string type() const override {return "legendre";} - ~LegendreFilter() = default; - void - from_xml(pugi::xml_node node) override - { - order_ = std::stoi(get_node_value(node, "order")); - n_bins_ = order_ + 1; - } + std::string type() const override {return "legendre";} - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - double wgt[n_bins_]; - calc_pn_c(order_, p->mu, wgt); - for (int i = 0; i < n_bins_; i++) { - match.bins_.push_back(i + 1); - match.weights_.push_back(wgt[i]); - } - } + void from_xml(pugi::xml_node node) override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "order", order_); - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - std::string - text_label(int bin) const override - { - return "Legendre expansion, P" + std::to_string(bin - 1); - } + void to_statepoint(hid_t filter_group) const override; + + std::string text_label(int bin) const override; int order_; }; diff --git a/include/openmc/tallies/filter_material.h b/include/openmc/tallies/filter_material.h index fed29a173..e78b056a4 100644 --- a/include/openmc/tallies/filter_material.h +++ b/include/openmc/tallies/filter_material.h @@ -2,15 +2,11 @@ #define OPENMC_TALLIES_FILTER_MATERIAL_H #include -#include #include #include -#include "openmc/error.h" -#include "openmc/material.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -20,63 +16,20 @@ namespace openmc { class MaterialFilter : public Filter { public: - std::string type() const override {return "material";} - ~MaterialFilter() = default; - void - from_xml(pugi::xml_node node) override - { - materials_ = get_node_array(node, "bins"); - n_bins_ = materials_.size(); - } + std::string type() const override {return "material";} - void - initialize() override - { - for (auto& m : materials_) { - auto search = material_map.find(m); - if (search != material_map.end()) { - m = search->second; - } else { - std::stringstream err_msg; - err_msg << "Could not find material " << m - << " specified on tally filter."; - fatal_error(err_msg); - } - } + void from_xml(pugi::xml_node node) override; - for (int i = 0; i < materials_.size(); i++) { - map_[materials_[i]] = i; - } - } + void initialize() override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - auto search = map_.find(p->material - 1); - if (search != map_.end()) { - // TODO: off-by-one - match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - std::vector material_ids; - for (auto c : materials_) material_ids.push_back(materials[c]->id_); - write_dataset(filter_group, "bins", material_ids); - } + void to_statepoint(hid_t filter_group) const override; - std::string - text_label(int bin) const override - { - return "Material " + std::to_string(materials[materials_[bin-1]]->id_); - } + std::string text_label(int bin) const override; std::vector materials_; std::unordered_map map_; diff --git a/include/openmc/tallies/filter_mesh.h b/include/openmc/tallies/filter_mesh.h index d3e046812..98853e653 100644 --- a/include/openmc/tallies/filter_mesh.h +++ b/include/openmc/tallies/filter_mesh.h @@ -2,14 +2,9 @@ #define OPENMC_TALLIES_FILTER_MESH_H #include -#include -#include "openmc/capi.h" -#include "openmc/error.h" -#include "openmc/mesh.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -21,72 +16,18 @@ namespace openmc { class MeshFilter : public Filter { public: - std::string type() const override {return "mesh";} - ~MeshFilter() = default; - void - from_xml(pugi::xml_node node) override - { - auto bins_ = get_node_array(node, "bins"); - if (bins_.size() != 1) { - fatal_error("Only one mesh can be specified per " + type() - + " mesh filter."); - } + std::string type() const override {return "mesh";} - auto id = bins_[0]; - auto search = mesh_map.find(id); - if (search != mesh_map.end()) { - mesh_ = search->second; - } else{ - std::stringstream err_msg; - err_msg << "Could not find cell " << id << " specified on tally filter."; - fatal_error(err_msg); - } + void from_xml(pugi::xml_node node) override; - n_bins_ = 1; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - if (estimator != ESTIMATOR_TRACKLENGTH) { - auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); - if (bin >= 0) { - match.bins_.push_back(bin); - match.weights_.push_back(1.0); - } - } else { - meshes[mesh_]->bins_crossed(p, match.bins_, match.weights_); - } - } + void to_statepoint(hid_t filter_group) const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", meshes[mesh_]->id_); - } - - std::string - text_label(int bin) const override - { - auto& mesh = *meshes[mesh_]; - int n_dim = mesh.n_dimension_; - - int ijk[n_dim]; - mesh.get_indices_from_bin(bin, ijk); - - std::stringstream out; - out << "Mesh Index (" << ijk[0]; - if (n_dim > 1) out << ", " << ijk[1]; - if (n_dim > 2) out << ", " << ijk[2]; - out << ")"; - - return out.str(); - } + std::string text_label(int bin) const override; int32_t mesh_; }; diff --git a/include/openmc/tallies/filter_meshsurface.h b/include/openmc/tallies/filter_meshsurface.h index 3184e2584..2d5aefef6 100644 --- a/include/openmc/tallies/filter_meshsurface.h +++ b/include/openmc/tallies/filter_meshsurface.h @@ -1,15 +1,8 @@ #ifndef OPENMC_TALLIES_FILTER_MESHSURFACE_H #define OPENMC_TALLIES_FILTER_MESHSURFACE_H -#include -#include - -#include "openmc/constants.h" -#include "openmc/error.h" -#include "openmc/mesh.h" #include "openmc/tallies/filter_mesh.h" - namespace openmc { class MeshSurfaceFilter : public MeshFilter @@ -17,64 +10,12 @@ class MeshSurfaceFilter : public MeshFilter public: std::string type() const override {return "meshsurface";} - void - from_xml(pugi::xml_node node) override - { - MeshFilter::from_xml(node); - n_bins_ = 4 * meshes[mesh_]->n_dimension_;; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; - } + void from_xml(pugi::xml_node node) override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - meshes[mesh_]->surface_bins_crossed(p, match.bins_); - for (auto b : match.bins_) match.weights_.push_back(1.0); - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - std::string - text_label(int bin) const override - { - auto& mesh = *meshes[mesh_]; - int n_dim = mesh.n_dimension_; - - // Get flattend mesh index and surface index. - int i_mesh = (bin - 1) / (4 * n_dim) + 1; - int i_surf = ((bin - 1) % (4 * n_dim)) + 1; - - // Get mesh index part of label. - std::string out = MeshFilter::text_label(i_mesh); - - // Get surface part of label. - if (i_surf == OUT_LEFT) { - out += " Outgoing, x-min"; - } else if (i_surf == IN_LEFT) { - out += " Incoming, x-min"; - } else if (i_surf == OUT_RIGHT) { - out += " Outgoing, x-max"; - } else if (i_surf == IN_RIGHT) { - out += " Incoming, x-max"; - } else if (i_surf == OUT_BACK) { - out += " Outgoing, y-min"; - } else if (i_surf == IN_BACK) { - out += " Incoming, y-min"; - } else if (i_surf == OUT_FRONT) { - out += " Outgoing, y-max"; - } else if (i_surf == IN_FRONT) { - out += " Incoming, y-max"; - } else if (i_surf == OUT_BOTTOM) { - out += " Outgoing, z-min"; - } else if (i_surf == IN_BOTTOM) { - out += " Incoming, z-min"; - } else if (i_surf == OUT_TOP) { - out += " Outgoing, z-max"; - } else if (i_surf == IN_TOP) { - out += " Incoming, z-max"; - } - - return out; - } + std::string text_label(int bin) const override; }; } // namespace openmc diff --git a/include/openmc/tallies/filter_mu.h b/include/openmc/tallies/filter_mu.h index 4bb2db5ed..fdc311b27 100644 --- a/include/openmc/tallies/filter_mu.h +++ b/include/openmc/tallies/filter_mu.h @@ -1,15 +1,10 @@ #ifndef OPENMC_TALLIES_FILTER_MU_H #define OPENMC_TALLIES_FILTER_MU_H -#include -#include #include -#include "openmc/error.h" -#include "openmc/search.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -20,63 +15,19 @@ namespace openmc { class MuFilter : public Filter { public: - std::string type() const override {return "mu";} - ~MuFilter() = default; - void - from_xml(pugi::xml_node node) override - { - auto bins = get_node_array(node, "bins"); + std::string type() const override {return "mu";} - if (bins.size() > 1) { - bins_ = bins; + void from_xml(pugi::xml_node node) override; - } else { - // Allow a user to input a lone number which will mean that you subdivide - // [-1,1) evenly with the input being the number of bins + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - int n_angle = bins[0]; + void to_statepoint(hid_t filter_group) const override; - if (n_angle <= 1) fatal_error("Number of bins for mu filter must " - "be greater than 1."); + std::string text_label(int bin) const override; - double d_angle = 2.0 / n_angle; - bins_.resize(n_angle + 1); - for (int i = 0; i < n_angle; i++) bins_[i] = -1 + i * d_angle; - bins_[n_angle] = 1; - } - - n_bins_ = bins_.size() - 1; - } - - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - if (p->mu >= bins_[0] && p->mu <= bins_.back()) { - auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->mu) + 1; - match.bins_.push_back(bin); - match.weights_.push_back(1); - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", bins_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - out << "Change-in-Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; - return out.str(); - } - -protected: std::vector bins_; }; diff --git a/include/openmc/tallies/filter_polar.h b/include/openmc/tallies/filter_polar.h index f73b52f60..3cc113a4f 100644 --- a/include/openmc/tallies/filter_polar.h +++ b/include/openmc/tallies/filter_polar.h @@ -1,15 +1,11 @@ #ifndef OPENMC_TALLIES_FILTER_POLAR_H #define OPENMC_TALLIES_FILTER_POLAR_H -#include #include #include -#include "openmc/error.h" -#include "openmc/search.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -19,70 +15,19 @@ namespace openmc { class PolarFilter : public Filter { public: - std::string type() const override {return "polar";} - ~PolarFilter() = default; - void - from_xml(pugi::xml_node node) override - { - auto bins = get_node_array(node, "bins"); + std::string type() const override {return "polar";} - if (bins.size() > 1) { - bins_ = bins; + void from_xml(pugi::xml_node node) override; - } else { - // Allow a user to input a lone number which will mean that you subdivide - // [0,pi] evenly with the input being the number of bins + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - int n_angle = bins[0]; + void to_statepoint(hid_t filter_group) const override; - if (n_angle <= 1) fatal_error("Number of bins for polar filter must " - "be greater than 1."); + std::string text_label(int bin) const override; - double d_angle = PI / n_angle; - bins_.resize(n_angle + 1); - for (int i = 0; i < n_angle; i++) bins_[i] = i * d_angle; - bins_[n_angle] = PI; - } - - n_bins_ = bins_.size() - 1; - } - - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - double theta; - if (estimator == ESTIMATOR_TRACKLENGTH) { - theta = std::acos(p->coord[0].uvw[2]); - } else { - theta = std::acos(p->last_uvw[2]); - } - - if (theta >= bins_[0] && theta <= bins_.back()) { - auto bin = lower_bound_index(bins_.begin(), bins_.end(), theta) + 1; - match.bins_.push_back(bin); - match.weights_.push_back(1); - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", bins_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - out << "Polar Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; - return out.str(); - } - -protected: std::vector bins_; }; diff --git a/include/openmc/tallies/filter_sph_harm.h b/include/openmc/tallies/filter_sph_harm.h index 5a7492114..8e429b953 100644 --- a/include/openmc/tallies/filter_sph_harm.h +++ b/include/openmc/tallies/filter_sph_harm.h @@ -1,12 +1,10 @@ -#ifndef OPENMC_TALLIES_FILTER_SPH_HAR_H -#define OPENMC_TALLIES_FILTER_SPH_HAR_H +#ifndef OPENMC_TALLIES_FILTER_SPH_HARM_H +#define OPENMC_TALLIES_FILTER_SPH_HARM_H #include -#include "openmc/error.h" #include "openmc/tallies/filter.h" - namespace openmc { //TODO: those integer values are not needed when Fortran interop is removed @@ -21,88 +19,22 @@ enum class SphericalHarmonicsCosine { class SphericalHarmonicsFilter : public Filter { public: - std::string type() const override {return "sphericalharmonics";} - ~SphericalHarmonicsFilter() = default; - void - from_xml(pugi::xml_node node) override - { - order_ = std::stoi(get_node_value(node, "order")); - n_bins_ = (order_ + 1) * (order_ + 1); + std::string type() const override {return "sphericalharmonics";} - if (check_for_node(node, "cosine")) { - auto cos = get_node_value(node, "cosine", true); - if (cos == "scatter") { - cosine_ = SphericalHarmonicsCosine::scatter; - } else if (cos == "particle") { - cosine_ = SphericalHarmonicsCosine::particle; - } else { - std::stringstream err_msg; - err_msg << "Unrecognized cosine type, \"" << cos - << "\" in spherical harmonics filter"; - fatal_error(err_msg); - } - } - } + void from_xml(pugi::xml_node node) override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - // Determine cosine term for scatter expansion if necessary - double wgt[order_ + 1]; - if (cosine_ == SphericalHarmonicsCosine::scatter) { - calc_pn_c(order_, p->mu, wgt); - } else { - for (int i = 0; i < order_ + 1; i++) wgt[i] = 1; - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - // Find the Rn,m values - double rn[n_bins_]; - calc_rn_c(order_, p->last_uvw, rn); + void to_statepoint(hid_t filter_group) const override; - int j = 0; - for (int n = 0; n < order_ + 1; n++) { - // Calculate n-th order spherical harmonics for (u,v,w) - int num_nm = 2*n + 1; - - // Append the matching (bin,weight) for each moment - for (int i = 0; i < num_nm; i++) { - match.weights_.push_back(wgt[n] * rn[j]); - match.bins_.push_back(++j); - } - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "order", order_); - if (cosine_ == SphericalHarmonicsCosine::scatter) { - write_dataset(filter_group, "cosine", "scatter"); - } else { - write_dataset(filter_group, "cosine", "particle"); - } - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - for (int n = 0; n < order_ + 1; n++) { - if (bin <= (n + 1) * (n + 1)) { - int m = (bin - n*n - 1) - n; - out << "Spherical harmonic expansion, Y" << n << "," << m; - return out.str(); - } - } - } + std::string text_label(int bin) const override; int order_; SphericalHarmonicsCosine cosine_ {SphericalHarmonicsCosine::particle}; }; } // namespace openmc -#endif // OPENMC_TALLIES_FILTER_SPH_HAR_H +#endif // OPENMC_TALLIES_FILTER_SPH_HARM_H diff --git a/include/openmc/tallies/filter_sptl_legendre.h b/include/openmc/tallies/filter_sptl_legendre.h index d3f507941..560239569 100644 --- a/include/openmc/tallies/filter_sptl_legendre.h +++ b/include/openmc/tallies/filter_sptl_legendre.h @@ -3,11 +3,8 @@ #include -#include "openmc/error.h" -#include "openmc/math_functions.h" #include "openmc/tallies/filter.h" - namespace openmc { //TODO: those integer values are not needed when Fortran interop is removed @@ -22,91 +19,18 @@ enum class LegendreAxis { class SpatialLegendreFilter : public Filter { public: - std::string type() const override {return "spatiallegendre";} - ~SpatialLegendreFilter() = default; - void - from_xml(pugi::xml_node node) override - { - order_ = std::stoi(get_node_value(node, "order")); + std::string type() const override {return "spatiallegendre";} - auto axis = get_node_value(node, "axis"); - if (axis == "x") { - axis_ = LegendreAxis::x; - } else if (axis == "y") { - axis_ = LegendreAxis::y; - } else if (axis == "z") { - axis_ = LegendreAxis::z; - } else { - fatal_error("Unrecognized axis on SpatialLegendreFilter"); - } + void from_xml(pugi::xml_node node) override; - min_ = std::stod(get_node_value(node, "min")); - max_ = std::stod(get_node_value(node, "max")); + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - n_bins_ = order_ + 1; - } + void to_statepoint(hid_t filter_group) const override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - // Get the coordinate along the axis of interest. - double x; - if (axis_ == LegendreAxis::x) { - x = p->coord[0].xyz[0]; - } else if (axis_ == LegendreAxis::y) { - x = p->coord[0].xyz[1]; - } else { - x = p->coord[0].xyz[2]; - } - - if (x >= min_ && x <= max_) { - // Compute the normalized coordinate value. - double x_norm = 2.0*(x - min_) / (max_ - min_) - 1.0; - - // Compute and return the Legendre weights. - double wgt[order_ + 1]; - calc_pn_c(order_, x_norm, wgt); - for (int i = 0; i < order_ + 1; i++) { - match.bins_.push_back(i + 1); - match.weights_.push_back(wgt[i]); - } - } - } - - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "order", order_); - if (axis_ == LegendreAxis::x) { - write_dataset(filter_group, "axis", "x"); - } else if (axis_ == LegendreAxis::y) { - write_dataset(filter_group, "axis", "y"); - } else { - write_dataset(filter_group, "axis", "z"); - } - write_dataset(filter_group, "min", min_); - write_dataset(filter_group, "max", max_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - out << "Legendre expansion, "; - if (axis_ == LegendreAxis::x) { - out << "x"; - } else if (axis_ == LegendreAxis::y) { - out << "y"; - } else { - out << "z"; - } - out << " axis, P" << std::to_string(bin - 1); - return out.str(); - } + std::string text_label(int bin) const override; int order_; LegendreAxis axis_; diff --git a/include/openmc/tallies/filter_surface.h b/include/openmc/tallies/filter_surface.h index 7e32572c8..85af6d004 100644 --- a/include/openmc/tallies/filter_surface.h +++ b/include/openmc/tallies/filter_surface.h @@ -2,15 +2,11 @@ #define OPENMC_TALLIES_FILTER_SURFACE_H #include -#include #include #include -#include "openmc/error.h" -#include "openmc/surface.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -20,66 +16,20 @@ namespace openmc { class SurfaceFilter : public Filter { public: - std::string type() const override {return "surface";} - ~SurfaceFilter() = default; - void - from_xml(pugi::xml_node node) override - { - surfaces_ = get_node_array(node, "bins"); - n_bins_ = surfaces_.size(); - } + std::string type() const override {return "surface";} - void - initialize() override - { - for (auto& s : surfaces_) { - auto search = surface_map.find(s); - if (search != surface_map.end()) { - s = search->second; - } else { - std::stringstream err_msg; - err_msg << "Could not find surface " << s - << " specified on tally filter."; - fatal_error(err_msg); - } - } + void from_xml(pugi::xml_node node) override; - for (int i = 0; i < surfaces_.size(); i++) { - map_[surfaces_[i]] = i; - } - } + void initialize() override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - auto search = map_.find(std::abs(p->surface)-1); - if (search != map_.end()) { - match.bins_.push_back(search->second + 1); - if (p->surface < 0) { - match.weights_.push_back(-1); - } else { - match.weights_.push_back(1); - } - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - std::vector surface_ids; - for (auto c : surfaces_) surface_ids.push_back(surfaces[c]->id_); - write_dataset(filter_group, "bins", surface_ids); - } + void to_statepoint(hid_t filter_group) const override; - std::string - text_label(int bin) const override - { - return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); - } + std::string text_label(int bin) const override; std::vector surfaces_; std::unordered_map map_; diff --git a/include/openmc/tallies/filter_universe.h b/include/openmc/tallies/filter_universe.h index 75feccdd4..5e7c85d1f 100644 --- a/include/openmc/tallies/filter_universe.h +++ b/include/openmc/tallies/filter_universe.h @@ -2,15 +2,11 @@ #define OPENMC_TALLIES_FILTER_UNIVERSE_H #include -#include #include #include -#include "openmc/cell.h" -#include "openmc/error.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -20,64 +16,20 @@ namespace openmc { class UniverseFilter : public Filter { public: - std::string type() const override {return "universe";} - ~UniverseFilter() = default; - void - from_xml(pugi::xml_node node) override - { - universes_ = get_node_array(node, "bins"); - n_bins_ = universes_.size(); - } + std::string type() const override {return "universe";} - void - initialize() override - { - for (auto& u : universes_) { - auto search = universe_map.find(u); - if (search != universe_map.end()) { - u = search->second; - } else { - std::stringstream err_msg; - err_msg << "Could not find universe " << u - << " specified on tally filter."; - fatal_error(err_msg); - } - } + void from_xml(pugi::xml_node node) override; - for (int i = 0; i < universes_.size(); i++) { - map_[universes_[i]] = i; - } - } + void initialize() override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - for (int i = 0; i < p->n_coord; i++) { - auto search = map_.find(p->coord[i].universe); - if (search != map_.end()) { - match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); - } - } - } + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - std::vector universe_ids; - for (auto u : universes_) universe_ids.push_back(universes[u]->id_); - write_dataset(filter_group, "bins", universe_ids); - } + void to_statepoint(hid_t filter_group) const override; - std::string - text_label(int bin) const override - { - return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); - } + std::string text_label(int bin) const override; std::vector universes_; std::unordered_map map_; diff --git a/include/openmc/tallies/filter_zernike.h b/include/openmc/tallies/filter_zernike.h index 6f3d96077..6450c6c17 100644 --- a/include/openmc/tallies/filter_zernike.h +++ b/include/openmc/tallies/filter_zernike.h @@ -1,15 +1,10 @@ #ifndef OPENMC_TALLIES_FILTER_ZERNIKE_H #define OPENMC_TALLIES_FILTER_ZERNIKE_H -#include -#include #include -#include "openmc/error.h" -#include "openmc/math_functions.h" #include "openmc/tallies/filter.h" - namespace openmc { //============================================================================== @@ -23,61 +18,14 @@ public: ~ZernikeFilter() = default; - void - from_xml(pugi::xml_node node) override - { - order_ = std::stoi(get_node_value(node, "order")); - x_ = std::stod(get_node_value(node, "x")); - y_ = std::stod(get_node_value(node, "y")); - r_ = std::stod(get_node_value(node, "r")); - calc_n_bins(); - } + void from_xml(pugi::xml_node node) override; - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - // Determine the normalized (r,theta) coordinates. - double x = p->coord[0].xyz[0] - x_; - double y = p->coord[0].xyz[1] - y_; - double r = std::sqrt(x*x + y*y) / r_; - double theta = std::atan2(y, x); + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - if (r <= 1.0) { - // Compute and return the Zernike weights. - double zn[n_bins_]; - calc_zn(order_, r, theta, zn); - for (int i = 0; i < n_bins_; i++) { - match.bins_.push_back(i+1); - match.weights_.push_back(zn[i]); - } - } - } + void to_statepoint(hid_t filter_group) const override; - void - to_statepoint(hid_t filter_group) const override - { - Filter::to_statepoint(filter_group); - write_dataset(filter_group, "order", order_); - write_dataset(filter_group, "x", x_); - write_dataset(filter_group, "y", y_); - write_dataset(filter_group, "r", r_); - } - - std::string - text_label(int bin) const override - { - std::stringstream out; - for (int n = 0; n < order_+1; n++) { - int last = (n + 1) * (n + 2) / 2; - if (bin <= last) { - int first = last - n; - int m = -n + (bin - first) * 2; - out << "Zernike expansion, Z" << n << "," << m; - return out.str(); - } - } - } + std::string text_label(int bin) const override; virtual void calc_n_bins() {n_bins_ = ((order_+1) * (order_+2)) / 2;} @@ -94,31 +42,10 @@ class ZernikeRadialFilter : public ZernikeFilter public: std::string type() const override {return "zernikeradial";} - void - get_all_bins(Particle* p, int estimator, FilterMatch& match) - const override - { - // Determine the normalized radius coordinate. - double x = p->coord[0].xyz[0] - x_; - double y = p->coord[0].xyz[1] - y_; - double r = std::sqrt(x*x + y*y) / r_; + void get_all_bins(Particle* p, int estimator, FilterMatch& match) + const override; - if (r <= 1.0) { - // Compute and return the Zernike weights. - double zn[n_bins_]; - calc_zn_rad(order_, r, zn); - for (int i = 0; i < n_bins_; i++) { - match.bins_.push_back(i+1); - match.weights_.push_back(zn[i]); - } - } - } - - std::string - text_label(int bin) const override - { - return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; - } + std::string text_label(int bin) const override; void calc_n_bins() override {n_bins_ = order_ / 2 + 1;} }; diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp new file mode 100644 index 000000000..3d7b35726 --- /dev/null +++ b/src/tallies/filter.cpp @@ -0,0 +1,170 @@ +#include "openmc/tallies/filter.h" + +#include + +#include "openmc/capi.h" +#include "openmc/constants.h" // for MAX_LINE_LEN; +#include "openmc/error.h" +#include "openmc/tallies/filter_azimuthal.h" +#include "openmc/tallies/filter_cell.h" +#include "openmc/tallies/filter_cellborn.h" +#include "openmc/tallies/filter_cellfrom.h" +#include "openmc/tallies/filter_distribcell.h" +#include "openmc/tallies/filter_energyfunc.h" +#include "openmc/tallies/filter_legendre.h" +#include "openmc/tallies/filter_material.h" +#include "openmc/tallies/filter_mesh.h" +#include "openmc/tallies/filter_meshsurface.h" +#include "openmc/tallies/filter_mu.h" +#include "openmc/tallies/filter_polar.h" +#include "openmc/tallies/filter_sph_harm.h" +#include "openmc/tallies/filter_sptl_legendre.h" +#include "openmc/tallies/filter_surface.h" +#include "openmc/tallies/filter_universe.h" +#include "openmc/tallies/filter_zernike.h" + + +namespace openmc { + +//============================================================================== +// Global variables +//============================================================================== + +std::vector filter_matches; +std::vector tally_filters; + +//============================================================================== +// Non-member functions +//============================================================================== + +void +free_memory_tally_c() +{ + #pragma omp parallel + { + filter_matches.clear(); + } + + for (Filter* filt : tally_filters) {delete filt;} + tally_filters.clear(); +} + +//============================================================================== +// Fortran compatibility functions +//============================================================================== + +extern "C" { + FilterMatch* filter_match_pointer(int indx) + {return &filter_matches[indx];} + + void + filter_match_bins_push_back(FilterMatch* match, int val) + {match->bins_.push_back(val);} + + void + filter_match_weights_push_back(FilterMatch* match, double val) + {match->weights_.push_back(val);} + + void + filter_match_bins_clear(FilterMatch* match) + {match->bins_.clear();} + + void + filter_match_weights_clear(FilterMatch* match) + {match->weights_.clear();} + + int + filter_match_bins_size(FilterMatch* match) + {return match->bins_.size();} + + int + filter_match_bins_data(FilterMatch* match, int indx) + {return match->bins_[indx-1];} + + double + filter_match_weights_data(FilterMatch* match, int indx) + {return match->weights_[indx-1];} + + void + filter_match_bins_set_data(FilterMatch* match, int indx, int val) + {match->bins_[indx-1] = val;} + + Filter* + allocate_filter(const char* type) + { + std::string type_ {type}; + if (type_ == "azimuthal") { + tally_filters.push_back(new AzimuthalFilter()); + } else if (type_ == "cell") { + tally_filters.push_back(new CellFilter()); + } else if (type_ == "cellborn") { + tally_filters.push_back(new CellbornFilter()); + } else if (type_ == "cellfrom") { + tally_filters.push_back(new CellFromFilter()); + } else if (type_ == "distribcell") { + tally_filters.push_back(new DistribcellFilter()); + } else if (type_ == "energyfunction") { + tally_filters.push_back(new EnergyFunctionFilter()); + } else if (type_ == "legendre") { + tally_filters.push_back(new LegendreFilter()); + } else if (type_ == "material") { + tally_filters.push_back(new MaterialFilter()); + } else if (type_ == "mesh") { + tally_filters.push_back(new MeshFilter()); + } else if (type_ == "meshsurface") { + tally_filters.push_back(new MeshSurfaceFilter()); + } else if (type_ == "mu") { + tally_filters.push_back(new MuFilter()); + } else if (type_ == "polar") { + tally_filters.push_back(new PolarFilter()); + } else if (type_ == "surface") { + tally_filters.push_back(new SurfaceFilter()); + } else if (type_ == "spatiallegendre") { + tally_filters.push_back(new SpatialLegendreFilter()); + } else if (type_ == "sphericalharmonics") { + tally_filters.push_back(new SphericalHarmonicsFilter()); + } else if (type_ == "universe") { + tally_filters.push_back(new UniverseFilter()); + } else if (type_ == "zernike") { + tally_filters.push_back(new ZernikeFilter()); + } else if (type_ == "zernikeradial") { + tally_filters.push_back(new ZernikeRadialFilter()); + } else { + return nullptr; + } + return tally_filters.back(); + } + + void filter_from_xml(Filter* filt, pugi::xml_node* node) + {filt->from_xml(*node);} + + void + filter_get_all_bins(Filter* filt, Particle* p, int estimator, + FilterMatch* match) + { + filt->get_all_bins(p, estimator, *match); + } + + void filter_to_statepoint(Filter* filt, hid_t group) + {filt->to_statepoint(group);} + + void filter_text_label(Filter* filt, int bin, char* label) + { + std::string label_str = filt->text_label(bin); + int i = 0; + for (; i < label_str.size() && i < MAX_LINE_LEN; i++) + label[i] = label_str[i]; + label[i] = '\0'; + } + + void filter_initialize(Filter* filt) {filt->initialize();} + + int filter_n_bins(Filter* filt) {return filt->n_bins_;} + + int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} + + int sphharm_filter_get_cosine(SphericalHarmonicsFilter* filt) + {return static_cast(filt->cosine_);} +} + +} // namespace openmc diff --git a/src/tallies/filter_azimuthal.cpp b/src/tallies/filter_azimuthal.cpp new file mode 100644 index 000000000..7611cb1f1 --- /dev/null +++ b/src/tallies/filter_azimuthal.cpp @@ -0,0 +1,71 @@ +#include "openmc/tallies/filter_azimuthal.h" + +#include +#include + +#include "openmc/constants.h" +#include "openmc/error.h" +#include "openmc/search.h" + +namespace openmc { + +void +AzimuthalFilter::from_xml(pugi::xml_node node) +{ + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [-pi,pi) evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for azimuthal filter must " + "be greater than 1."); + + double d_angle = 2.0 * PI / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = -PI + i * d_angle; + bins_[n_angle] = PI; + } + + n_bins_ = bins_.size() - 1; +} + +void +AzimuthalFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + double phi; + if (estimator == ESTIMATOR_TRACKLENGTH) { + phi = std::atan2(p->coord[0].uvw[1], p->coord[0].uvw[0]); + } else { + phi = std::atan2(p->last_uvw[1], p->last_uvw[0]); + } + + if (phi >= bins_[0] && phi <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), phi) + 1; + match.bins_.push_back(bin); + match.weights_.push_back(1); + } +} + +void +AzimuthalFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); +} + +std::string +AzimuthalFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Azimuthal Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); +} + +} // namespace openmc diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp new file mode 100644 index 000000000..d52c6bb5f --- /dev/null +++ b/src/tallies/filter_cell.cpp @@ -0,0 +1,86 @@ +#include "openmc/tallies/filter_cell.h" + +#include + +#include "openmc/capi.h" +#include "openmc/cell.h" +#include "openmc/error.h" + +namespace openmc { + +void +CellFilter::from_xml(pugi::xml_node node) +{ + cells_ = get_node_array(node, "bins"); + n_bins_ = cells_.size(); +} + +void +CellFilter::initialize() +{ + for (auto& c : cells_) { + auto search = cell_map.find(c); + if (search != cell_map.end()) { + c = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find cell " << c << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < cells_.size(); i++) { + map_[cells_[i]] = i; + } +} + +void +CellFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) const +{ + for (int i = 0; i < p->n_coord; i++) { + auto search = map_.find(p->coord[i].cell); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); + } + } +} + +void +CellFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + std::vector cell_ids; + for (auto c : cells_) cell_ids.push_back(cells[c]->id_); + write_dataset(filter_group, "bins", cell_ids); +} + +std::string +CellFilter::text_label(int bin) const +{ + return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_cell_filter_get_bins(int32_t index, int32_t** cells, int32_t* n) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "cell") { + set_errmsg("Tried to get cells from a non-cell filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto cell_filt = static_cast(filt); + *cells = cell_filt->cells_.data(); + *n = cell_filt->cells_.size(); + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_cellborn.cpp b/src/tallies/filter_cellborn.cpp new file mode 100644 index 000000000..c42740119 --- /dev/null +++ b/src/tallies/filter_cellborn.cpp @@ -0,0 +1,24 @@ +#include "openmc/tallies/filter_cellborn.h" + +#include "openmc/cell.h" + +namespace openmc { + +void +CellbornFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + auto search = map_.find(p->cell_born); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); + } +} + +std::string +CellbornFilter::text_label(int bin) const +{ + return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); +} + +} // namespace openmc diff --git a/src/tallies/filter_cellfrom.cpp b/src/tallies/filter_cellfrom.cpp new file mode 100644 index 000000000..5771f0b13 --- /dev/null +++ b/src/tallies/filter_cellfrom.cpp @@ -0,0 +1,26 @@ +#include "openmc/tallies/filter_cellfrom.h" + +#include "openmc/cell.h" + +namespace openmc { + +void +CellFromFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + for (int i = 0; i < p->last_n_coord; i++) { + auto search = map_.find(p->last_cell[i]); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); + } + } +} + +std::string +CellFromFilter::text_label(int bin) const +{ + return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); +} + +} // namespace openmc diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp new file mode 100644 index 000000000..db1cd59c9 --- /dev/null +++ b/src/tallies/filter_distribcell.cpp @@ -0,0 +1,77 @@ +#include "openmc/tallies/filter_distribcell.h" + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/geometry_aux.h" // For distribcell_path +#include "openmc/lattice.h" + +namespace openmc { + +void +DistribcellFilter::from_xml(pugi::xml_node node) +{ + auto cells = get_node_array(node, "bins"); + if (cells.size() != 1) { + fatal_error("Only one cell can be specified per distribcell filter."); + } + cell_ = cells[0]; +} + +void +DistribcellFilter::initialize() +{ + auto search = cell_map.find(cell_); + if (search != cell_map.end()) { + cell_ = search->second; + n_bins_ = cells[cell_]->n_instances_; + } else { + std::stringstream err_msg; + err_msg << "Could not find cell " << cell_ + << " specified on tally filter."; + fatal_error(err_msg); + } +} + +void +DistribcellFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + int offset = 0; + auto distribcell_index = cells[cell_]->distribcell_index_; + for (int i = 0; i < p->n_coord; i++) { + auto& c {*cells[p->coord[i].cell]}; + if (c.type_ == FILL_UNIVERSE) { + offset += c.offset_[distribcell_index]; + } else if (c.type_ == FILL_LATTICE) { + auto& lat {*lattices[p->coord[i+1].lattice-1]}; + int i_xyz[3] {p->coord[i+1].lattice_x, + p->coord[i+1].lattice_y, + p->coord[i+1].lattice_z}; + if (lat.are_valid_indices(i_xyz)) { + offset += lat.offset(distribcell_index, i_xyz); + } + } + if (cell_ == p->coord[i].cell) { + match.bins_.push_back(offset + 1); + match.weights_.push_back(1); + return; + } + } +} + +void +DistribcellFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", cells[cell_]->id_); +} + +std::string +DistribcellFilter::text_label(int bin) const +{ + auto map = cells[cell_]->distribcell_index_; + auto path = distribcell_path(cell_, map, bin-1); + return "Distributed Cell " + path; +} + +} // namespace openmc diff --git a/src/tallies/filter_energyfunc.cpp b/src/tallies/filter_energyfunc.cpp new file mode 100644 index 000000000..92c9592a0 --- /dev/null +++ b/src/tallies/filter_energyfunc.cpp @@ -0,0 +1,67 @@ +#include "openmc/tallies/filter_energyfunc.h" + +#include // for setprecision +#include // for scientific +#include + +#include "openmc/error.h" +#include "openmc/search.h" +#include "openmc/settings.h" + +namespace openmc { + +void +EnergyFunctionFilter::from_xml(pugi::xml_node node) +{ + if (!settings::run_CE) + fatal_error("EnergyFunction filters are only supported for " + "continuous-energy transport calculations"); + + if (!check_for_node(node, "energy")) + fatal_error("Energy grid not specified for EnergyFunction filter."); + + energy_ = get_node_array(node, "energy"); + + if (!check_for_node(node, "y")) + fatal_error("y values not specified for EnergyFunction filter."); + + y_ = get_node_array(node, "y"); +} + +void +EnergyFunctionFilter::get_all_bins(Particle* p, int estimator, + FilterMatch& match) const +{ + if (p->last_E >= energy_.front() && p->last_E <= energy_.back()) { + // Search for the incoming energy bin. + auto i = lower_bound_index(energy_.begin(), energy_.end(), p->last_E); + + // Compute the interpolation factor between the nearest bins. + double f = (p->last_E - energy_[i]) / (energy_[i+1] - energy_[i]); + + // Interpolate on the lin-lin grid. + match.bins_.push_back(1); + match.weights_.push_back((1-f) * y_[i] + f * y_[i+1]); + } +} + +void +EnergyFunctionFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "energy", energy_); + write_dataset(filter_group, "y", y_); +} + +std::string +EnergyFunctionFilter::text_label(int bin) const +{ + std::stringstream out; + out << std::scientific << std::setprecision(1) + << "Energy Function f" + << "([ " << energy_.front() << ", ..., " << energy_.back() << "]) = " + << "[" << y_.front() << ", ..., " << y_.back() << "]"; + return out.str(); +} + +} // namespace openmc diff --git a/src/tallies/filter_legendre.cpp b/src/tallies/filter_legendre.cpp new file mode 100644 index 000000000..c8666f6b9 --- /dev/null +++ b/src/tallies/filter_legendre.cpp @@ -0,0 +1,81 @@ +#include "openmc/tallies/filter_legendre.h" + +#include "openmc/capi.h" +#include "openmc/error.h" +#include "openmc/math_functions.h" + +namespace openmc { + +void +LegendreFilter::from_xml(pugi::xml_node node) +{ + order_ = std::stoi(get_node_value(node, "order")); + n_bins_ = order_ + 1; +} + +void +LegendreFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + double wgt[n_bins_]; + calc_pn_c(order_, p->mu, wgt); + for (int i = 0; i < n_bins_; i++) { + match.bins_.push_back(i + 1); + match.weights_.push_back(wgt[i]); + } +} + +void +LegendreFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); +} + +std::string +LegendreFilter::text_label(int bin) const +{ + return "Legendre expansion, P" + std::to_string(bin - 1); +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_legendre_filter_get_order(int32_t index, int* order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "legendre") { + set_errmsg("Tried to get order on a non-expansion filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *order = l_filt->order_; + return 0; +} + +extern "C" int +openmc_legendre_filter_set_order(int32_t index, int order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "legendre") { + set_errmsg("Tried to set order on a non-expansion filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + l_filt->order_ = order; + l_filt->n_bins_ = order + 1; + filter_update_n_bins(index); + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp new file mode 100644 index 000000000..66d948088 --- /dev/null +++ b/src/tallies/filter_material.cpp @@ -0,0 +1,109 @@ +#include "openmc/tallies/filter_material.h" + +#include + +#include "openmc/capi.h" +#include "openmc/error.h" +#include "openmc/material.h" + +namespace openmc { + +void +MaterialFilter::from_xml(pugi::xml_node node) +{ + materials_ = get_node_array(node, "bins"); + n_bins_ = materials_.size(); +} + +void +MaterialFilter::initialize() +{ + for (auto& m : materials_) { + auto search = material_map.find(m); + if (search != material_map.end()) { + m = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find material " << m + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < materials_.size(); i++) { + map_[materials_[i]] = i; + } +} + +void +MaterialFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + auto search = map_.find(p->material - 1); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); + } +} + +void +MaterialFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + std::vector material_ids; + for (auto c : materials_) material_ids.push_back(materials[c]->id_); + write_dataset(filter_group, "bins", material_ids); +} + +std::string +MaterialFilter::text_label(int bin) const +{ + return "Material " + std::to_string(materials[materials_[bin-1]]->id_); +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_material_filter_get_bins(int32_t index, int32_t** bins, int32_t* n) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "material") { + set_errmsg("Tried to get material filter bins on a non-material filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mat_filt = static_cast(filt); + *bins = mat_filt->materials_.data(); + *n = mat_filt->materials_.size(); + return 0; +} + +extern "C" int +openmc_material_filter_set_bins(int32_t index, int32_t n, const int32_t* bins) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "material") { + set_errmsg("Tried to set material filter bins on a non-material filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mat_filt = static_cast(filt); + mat_filt->materials_.clear(); + mat_filt->materials_.resize(n); + for (int i = 0; i < n; i++) mat_filt->materials_[i] = bins[i]; + mat_filt->n_bins_ = mat_filt->materials_.size(); + mat_filt->map_.clear(); + for (int i = 0; i < n; i++) mat_filt->map_[mat_filt->materials_[i]] = i; + filter_update_n_bins(index); + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp new file mode 100644 index 000000000..ad17543c6 --- /dev/null +++ b/src/tallies/filter_mesh.cpp @@ -0,0 +1,125 @@ +#include "openmc/tallies/filter_mesh.h" + +#include + +#include "openmc/capi.h" +#include "openmc/constants.h" +#include "openmc/error.h" +#include "openmc/mesh.h" + +namespace openmc { + +void +MeshFilter::from_xml(pugi::xml_node node) +{ + auto bins_ = get_node_array(node, "bins"); + if (bins_.size() != 1) { + fatal_error("Only one mesh can be specified per " + type() + + " mesh filter."); + } + + auto id = bins_[0]; + auto search = mesh_map.find(id); + if (search != mesh_map.end()) { + mesh_ = search->second; + } else{ + std::stringstream err_msg; + err_msg << "Could not find cell " << id << " specified on tally filter."; + fatal_error(err_msg); + } + + n_bins_ = 1; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; +} + +void +MeshFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + if (estimator != ESTIMATOR_TRACKLENGTH) { + auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); + if (bin >= 0) { + match.bins_.push_back(bin); + match.weights_.push_back(1.0); + } + } else { + meshes[mesh_]->bins_crossed(p, match.bins_, match.weights_); + } +} + +void +MeshFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", meshes[mesh_]->id_); +} + +std::string +MeshFilter::text_label(int bin) const +{ + auto& mesh = *meshes[mesh_]; + int n_dim = mesh.n_dimension_; + + int ijk[n_dim]; + mesh.get_indices_from_bin(bin, ijk); + + std::stringstream out; + out << "Mesh Index (" << ijk[0]; + if (n_dim > 1) out << ", " << ijk[1]; + if (n_dim > 2) out << ", " << ijk[2]; + out << ")"; + + return out.str(); +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "mesh" && filt->type() != "meshsurface") { + set_errmsg("Tried to get mesh on a non-mesh filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto mesh_filt = static_cast(filt); + *index_mesh = mesh_filt->mesh_; + return 0; +} + +extern "C" int +openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "mesh" && filt->type() != "meshsurface") { + set_errmsg("Tried to set mesh on a non-mesh filter."); + return OPENMC_E_INVALID_TYPE; + } + + if (index_mesh < 0 || index_mesh >= meshes.size()) { + set_errmsg("Index in 'meshes' array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } + + auto mesh_filt = static_cast(filt); + mesh_filt->mesh_ = index_mesh; + if (filt->type() == "mesh") { + mesh_filt->n_bins_ = 1; + } else { + filt->n_bins_ = 4 * meshes[index_mesh]->n_dimension_; + } + for (auto dim : meshes[index_mesh]->shape_) mesh_filt->n_bins_ *= dim; + filter_update_n_bins(index); + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp new file mode 100644 index 000000000..124d3df33 --- /dev/null +++ b/src/tallies/filter_meshsurface.cpp @@ -0,0 +1,81 @@ +#include "openmc/tallies/filter_meshsurface.h" + +#include "openmc/capi.h" +#include "openmc/constants.h" +#include "openmc/error.h" +#include "openmc/mesh.h" + +namespace openmc { + +void +MeshSurfaceFilter::from_xml(pugi::xml_node node) +{ + MeshFilter::from_xml(node); + n_bins_ = 4 * meshes[mesh_]->n_dimension_;; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; +} + +void +MeshSurfaceFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + meshes[mesh_]->surface_bins_crossed(p, match.bins_); + for (auto b : match.bins_) match.weights_.push_back(1.0); +} + +std::string +MeshSurfaceFilter::text_label(int bin) const +{ + auto& mesh = *meshes[mesh_]; + int n_dim = mesh.n_dimension_; + + // Get flattend mesh index and surface index. + int i_mesh = (bin - 1) / (4 * n_dim) + 1; + int i_surf = ((bin - 1) % (4 * n_dim)) + 1; + + // Get mesh index part of label. + std::string out = MeshFilter::text_label(i_mesh); + + // Get surface part of label. + if (i_surf == OUT_LEFT) { + out += " Outgoing, x-min"; + } else if (i_surf == IN_LEFT) { + out += " Incoming, x-min"; + } else if (i_surf == OUT_RIGHT) { + out += " Outgoing, x-max"; + } else if (i_surf == IN_RIGHT) { + out += " Incoming, x-max"; + } else if (i_surf == OUT_BACK) { + out += " Outgoing, y-min"; + } else if (i_surf == IN_BACK) { + out += " Incoming, y-min"; + } else if (i_surf == OUT_FRONT) { + out += " Outgoing, y-max"; + } else if (i_surf == IN_FRONT) { + out += " Incoming, y-max"; + } else if (i_surf == OUT_BOTTOM) { + out += " Outgoing, z-min"; + } else if (i_surf == IN_BOTTOM) { + out += " Incoming, z-min"; + } else if (i_surf == OUT_TOP) { + out += " Outgoing, z-max"; + } else if (i_surf == IN_TOP) { + out += " Incoming, z-max"; + } + + return out; +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern"C" int +openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh) +{return openmc_mesh_filter_get_mesh(index, index_mesh);} + +extern"C" int +openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh) +{return openmc_mesh_filter_set_mesh(index, index_mesh);} + +} // namespace openmc diff --git a/src/tallies/filter_mu.cpp b/src/tallies/filter_mu.cpp new file mode 100644 index 000000000..cd428a4e4 --- /dev/null +++ b/src/tallies/filter_mu.cpp @@ -0,0 +1,61 @@ +#include "openmc/tallies/filter_mu.h" + +#include + +#include "openmc/error.h" +#include "openmc/search.h" + +namespace openmc { + +void +MuFilter::from_xml(pugi::xml_node node) +{ + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [-1,1) evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for mu filter must " + "be greater than 1."); + + double d_angle = 2.0 / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = -1 + i * d_angle; + bins_[n_angle] = 1; + } + + n_bins_ = bins_.size() - 1; +} + +void +MuFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) const +{ + if (p->mu >= bins_[0] && p->mu <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->mu) + 1; + match.bins_.push_back(bin); + match.weights_.push_back(1); + } +} + +void +MuFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); +} + +std::string +MuFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Change-in-Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); +} + +} // namespace openmc diff --git a/src/tallies/filter_polar.cpp b/src/tallies/filter_polar.cpp new file mode 100644 index 000000000..81839cecb --- /dev/null +++ b/src/tallies/filter_polar.cpp @@ -0,0 +1,70 @@ +#include "openmc/tallies/filter_polar.h" + +#include + +#include "openmc/constants.h" +#include "openmc/error.h" +#include "openmc/search.h" + +namespace openmc { + +void +PolarFilter::from_xml(pugi::xml_node node) +{ + auto bins = get_node_array(node, "bins"); + + if (bins.size() > 1) { + bins_ = bins; + + } else { + // Allow a user to input a lone number which will mean that you subdivide + // [0,pi] evenly with the input being the number of bins + + int n_angle = bins[0]; + + if (n_angle <= 1) fatal_error("Number of bins for polar filter must " + "be greater than 1."); + + double d_angle = PI / n_angle; + bins_.resize(n_angle + 1); + for (int i = 0; i < n_angle; i++) bins_[i] = i * d_angle; + bins_[n_angle] = PI; + } + + n_bins_ = bins_.size() - 1; +} + +void +PolarFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + double theta; + if (estimator == ESTIMATOR_TRACKLENGTH) { + theta = std::acos(p->coord[0].uvw[2]); + } else { + theta = std::acos(p->last_uvw[2]); + } + + if (theta >= bins_[0] && theta <= bins_.back()) { + auto bin = lower_bound_index(bins_.begin(), bins_.end(), theta) + 1; + match.bins_.push_back(bin); + match.weights_.push_back(1); + } +} + +void +PolarFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); +} + +std::string +PolarFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Polar Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); +} + +} // namespace openmc diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp new file mode 100644 index 000000000..f6d165621 --- /dev/null +++ b/src/tallies/filter_sph_harm.cpp @@ -0,0 +1,169 @@ +#include "openmc/tallies/filter_sph_harm.h" + +#include "openmc/capi.h" +#include "openmc/error.h" +#include "openmc/math_functions.h" + +namespace openmc { + +void +SphericalHarmonicsFilter::from_xml(pugi::xml_node node) +{ + order_ = std::stoi(get_node_value(node, "order")); + n_bins_ = (order_ + 1) * (order_ + 1); + + if (check_for_node(node, "cosine")) { + auto cos = get_node_value(node, "cosine", true); + if (cos == "scatter") { + cosine_ = SphericalHarmonicsCosine::scatter; + } else if (cos == "particle") { + cosine_ = SphericalHarmonicsCosine::particle; + } else { + std::stringstream err_msg; + err_msg << "Unrecognized cosine type, \"" << cos + << "\" in spherical harmonics filter"; + fatal_error(err_msg); + } + } +} + +void +SphericalHarmonicsFilter::get_all_bins(Particle* p, int estimator, + FilterMatch& match) const +{ + // Determine cosine term for scatter expansion if necessary + double wgt[order_ + 1]; + if (cosine_ == SphericalHarmonicsCosine::scatter) { + calc_pn_c(order_, p->mu, wgt); + } else { + for (int i = 0; i < order_ + 1; i++) wgt[i] = 1; + } + + // Find the Rn,m values + double rn[n_bins_]; + calc_rn_c(order_, p->last_uvw, rn); + + int j = 0; + for (int n = 0; n < order_ + 1; n++) { + // Calculate n-th order spherical harmonics for (u,v,w) + int num_nm = 2*n + 1; + + // Append the matching (bin,weight) for each moment + for (int i = 0; i < num_nm; i++) { + match.weights_.push_back(wgt[n] * rn[j]); + match.bins_.push_back(++j); + } + } +} + +void +SphericalHarmonicsFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + if (cosine_ == SphericalHarmonicsCosine::scatter) { + write_dataset(filter_group, "cosine", "scatter"); + } else { + write_dataset(filter_group, "cosine", "particle"); + } +} + +std::string +SphericalHarmonicsFilter::text_label(int bin) const +{ + std::stringstream out; + for (int n = 0; n < order_ + 1; n++) { + if (bin <= (n + 1) * (n + 1)) { + int m = (bin - n*n - 1) - n; + out << "Spherical harmonic expansion, Y" << n << "," << m; + return out.str(); + } + } +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_sphharm_filter_get_order(int32_t index, int* order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + *order = sph_filt->order_; + return 0; +} + +extern "C" int +openmc_sphharm_filter_get_cosine(int32_t index, char cosine[]) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + if (sph_filt->cosine_ == SphericalHarmonicsCosine::scatter) { + strcpy(cosine, "scatter"); + } else { + strcpy(cosine, "particle"); + } + return 0; +} + +extern "C" int +openmc_sphharm_filter_set_order(int32_t index, int order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + sph_filt->order_ = order; + sph_filt->n_bins_ = (order + 1) * (order + 1); + filter_update_n_bins(index); + return 0; +} + +extern "C" int +openmc_sphharm_filter_set_cosine(int32_t index, const char cosine[]) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "sphericalharmonics") { + set_errmsg("Not a spherical harmonics filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto sph_filt = static_cast(filt); + if (strcmp(cosine, "scatter") == 0) { + sph_filt->cosine_ = SphericalHarmonicsCosine::scatter; + } else if (strcmp(cosine, "particle") == 0) { + sph_filt->cosine_ = SphericalHarmonicsCosine::particle; + } else { + set_errmsg("Invalid spherical harmonics cosine."); + return OPENMC_E_INVALID_ARGUMENT; + } + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp new file mode 100644 index 000000000..a5507b614 --- /dev/null +++ b/src/tallies/filter_sptl_legendre.cpp @@ -0,0 +1,171 @@ +#include "openmc/tallies/filter_sptl_legendre.h" + +#include "openmc/capi.h" +#include "openmc/error.h" +#include "openmc/math_functions.h" + +namespace openmc { + +void +SpatialLegendreFilter::from_xml(pugi::xml_node node) +{ + order_ = std::stoi(get_node_value(node, "order")); + + auto axis = get_node_value(node, "axis"); + if (axis == "x") { + axis_ = LegendreAxis::x; + } else if (axis == "y") { + axis_ = LegendreAxis::y; + } else if (axis == "z") { + axis_ = LegendreAxis::z; + } else { + fatal_error("Unrecognized axis on SpatialLegendreFilter"); + } + + min_ = std::stod(get_node_value(node, "min")); + max_ = std::stod(get_node_value(node, "max")); + + n_bins_ = order_ + 1; +} + +void +SpatialLegendreFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + // Get the coordinate along the axis of interest. + double x; + if (axis_ == LegendreAxis::x) { + x = p->coord[0].xyz[0]; + } else if (axis_ == LegendreAxis::y) { + x = p->coord[0].xyz[1]; + } else { + x = p->coord[0].xyz[2]; + } + + if (x >= min_ && x <= max_) { + // Compute the normalized coordinate value. + double x_norm = 2.0*(x - min_) / (max_ - min_) - 1.0; + + // Compute and return the Legendre weights. + double wgt[order_ + 1]; + calc_pn_c(order_, x_norm, wgt); + for (int i = 0; i < order_ + 1; i++) { + match.bins_.push_back(i + 1); + match.weights_.push_back(wgt[i]); + } + } +} + +void +SpatialLegendreFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + if (axis_ == LegendreAxis::x) { + write_dataset(filter_group, "axis", "x"); + } else if (axis_ == LegendreAxis::y) { + write_dataset(filter_group, "axis", "y"); + } else { + write_dataset(filter_group, "axis", "z"); + } + write_dataset(filter_group, "min", min_); + write_dataset(filter_group, "max", max_); +} + +std::string +SpatialLegendreFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Legendre expansion, "; + if (axis_ == LegendreAxis::x) { + out << "x"; + } else if (axis_ == LegendreAxis::y) { + out << "y"; + } else { + out << "z"; + } + out << " axis, P" << std::to_string(bin - 1); + return out.str(); +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_spatial_legendre_filter_get_order(int32_t index, int* order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *order = l_filt->order_; + return 0; +} + +extern "C" int +openmc_spatial_legendre_filter_get_params(int32_t index, int* axis, + double* min, double* max) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + *axis = static_cast(l_filt->axis_); + *min = l_filt->min_; + *max = l_filt->max_; + return 0; +} + +extern "C" int +openmc_spatial_legendre_filter_set_order(int32_t index, int order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + l_filt->order_ = order; + l_filt->n_bins_ = order + 1; + filter_update_n_bins(index); + return 0; +} + +extern "C" int +openmc_spatial_legendre_filter_set_params(int32_t index, const int* axis, + const double* min, const double* max) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "spatiallegendre") { + set_errmsg("Not a spatial Legendre filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto l_filt = static_cast(filt); + if (axis) l_filt->axis_ = static_cast(*axis); + if (min) l_filt->min_ = *min; + if (max) l_filt->max_ = *max; + return 0; +} + +} // namespace openmc diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp new file mode 100644 index 000000000..9ce61e84d --- /dev/null +++ b/src/tallies/filter_surface.cpp @@ -0,0 +1,67 @@ +#include "openmc/tallies/filter_surface.h" + +#include + +#include "openmc/error.h" +#include "openmc/surface.h" + +namespace openmc { + +void +SurfaceFilter::from_xml(pugi::xml_node node) +{ + surfaces_ = get_node_array(node, "bins"); + n_bins_ = surfaces_.size(); +} + +void +SurfaceFilter::initialize() +{ + for (auto& s : surfaces_) { + auto search = surface_map.find(s); + if (search != surface_map.end()) { + s = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find surface " << s + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < surfaces_.size(); i++) { + map_[surfaces_[i]] = i; + } +} + +void +SurfaceFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + auto search = map_.find(std::abs(p->surface)-1); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + if (p->surface < 0) { + match.weights_.push_back(-1); + } else { + match.weights_.push_back(1); + } + } +} + +void +SurfaceFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + std::vector surface_ids; + for (auto c : surfaces_) surface_ids.push_back(surfaces[c]->id_); + write_dataset(filter_group, "bins", surface_ids); +} + +std::string +SurfaceFilter::text_label(int bin) const +{ + return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); +} + +} // namespace openmc diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp new file mode 100644 index 000000000..bd90ed091 --- /dev/null +++ b/src/tallies/filter_universe.cpp @@ -0,0 +1,65 @@ +#include "openmc/tallies/filter_universe.h" + +#include + +#include "openmc/cell.h" +#include "openmc/error.h" + +namespace openmc { + +void +UniverseFilter::from_xml(pugi::xml_node node) +{ + universes_ = get_node_array(node, "bins"); + n_bins_ = universes_.size(); +} + +void +UniverseFilter::initialize() +{ + for (auto& u : universes_) { + auto search = universe_map.find(u); + if (search != universe_map.end()) { + u = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find universe " << u + << " specified on tally filter."; + fatal_error(err_msg); + } + } + + for (int i = 0; i < universes_.size(); i++) { + map_[universes_[i]] = i; + } +} + +void +UniverseFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + for (int i = 0; i < p->n_coord; i++) { + auto search = map_.find(p->coord[i].universe); + if (search != map_.end()) { + match.bins_.push_back(search->second + 1); + match.weights_.push_back(1); + } + } +} + +void +UniverseFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + std::vector universe_ids; + for (auto u : universes_) universe_ids.push_back(universes[u]->id_); + write_dataset(filter_group, "bins", universe_ids); +} + +std::string +UniverseFilter::text_label(int bin) const +{ + return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); +} + +} // namespace openmc diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp new file mode 100644 index 000000000..c7413f341 --- /dev/null +++ b/src/tallies/filter_zernike.cpp @@ -0,0 +1,182 @@ +#include "openmc/tallies/filter_zernike.h" + +#include +#include + +#include "openmc/capi.h" +#include "openmc/error.h" +#include "openmc/math_functions.h" + +namespace openmc { + +//============================================================================== +// ZernikeFilter implementation +//============================================================================== + +void +ZernikeFilter::from_xml(pugi::xml_node node) +{ + order_ = std::stoi(get_node_value(node, "order")); + x_ = std::stod(get_node_value(node, "x")); + y_ = std::stod(get_node_value(node, "y")); + r_ = std::stod(get_node_value(node, "r")); + calc_n_bins(); +} + +void +ZernikeFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +const +{ + // Determine the normalized (r,theta) coordinates. + double x = p->coord[0].xyz[0] - x_; + double y = p->coord[0].xyz[1] - y_; + double r = std::sqrt(x*x + y*y) / r_; + double theta = std::atan2(y, x); + + if (r <= 1.0) { + // Compute and return the Zernike weights. + double zn[n_bins_]; + calc_zn(order_, r, theta, zn); + for (int i = 0; i < n_bins_; i++) { + match.bins_.push_back(i+1); + match.weights_.push_back(zn[i]); + } + } +} + +void +ZernikeFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "order", order_); + write_dataset(filter_group, "x", x_); + write_dataset(filter_group, "y", y_); + write_dataset(filter_group, "r", r_); +} + +std::string +ZernikeFilter::text_label(int bin) const +{ + std::stringstream out; + for (int n = 0; n < order_+1; n++) { + int last = (n + 1) * (n + 2) / 2; + if (bin <= last) { + int first = last - n; + int m = -n + (bin - first) * 2; + out << "Zernike expansion, Z" << n << "," << m; + return out.str(); + } + } +} + +//============================================================================== +// ZernikeRadialFilter implementation +//============================================================================== + +void +ZernikeRadialFilter::get_all_bins(Particle* p, int estimator, + FilterMatch& match) const +{ + // Determine the normalized radius coordinate. + double x = p->coord[0].xyz[0] - x_; + double y = p->coord[0].xyz[1] - y_; + double r = std::sqrt(x*x + y*y) / r_; + + if (r <= 1.0) { + // Compute and return the Zernike weights. + double zn[n_bins_]; + calc_zn_rad(order_, r, zn); + for (int i = 0; i < n_bins_; i++) { + match.bins_.push_back(i+1); + match.weights_.push_back(zn[i]); + } + } +} + +std::string +ZernikeRadialFilter::text_label(int bin) const +{ + return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int +openmc_zernike_filter_get_order(int32_t index, int* order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + *order = z_filt->order_; + return 0; +} + +extern "C" int +openmc_zernike_filter_get_params(int32_t index, double* x, double* y, + double* r) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + *x = z_filt->x_; + *y = z_filt->y_; + *r = z_filt->r_; + return 0; +} + +extern "C" int +openmc_zernike_filter_set_order(int32_t index, int order) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + z_filt->order_ = order; + z_filt->calc_n_bins(); + filter_update_n_bins(index); + return 0; +} + +extern "C" int +openmc_zernike_filter_set_params(int32_t index, const double* x, + const double* y, const double* r) +{ + int err = verify_filter(index); + if (err) return err; + + auto filt = filter_from_f(index); + if (filt->type() != "zernike" && filt->type() != "zernikeradial") { + set_errmsg("Not a Zernike filter."); + return OPENMC_E_INVALID_TYPE; + } + + auto z_filt = static_cast(filt); + if (x) z_filt->x_ = *x; + if (y) z_filt->y_ = *y; + if (r) z_filt->r_ = *r; + return 0; +} + +} // namespace openmc diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp deleted file mode 100644 index 5ad918110..000000000 --- a/src/tallies/tally_filter.cpp +++ /dev/null @@ -1,561 +0,0 @@ -#include "openmc/tallies/filter.h" - -#include - -#include "openmc/capi.h" -#include "openmc/constants.h" // for MAX_LINE_LEN; -#include "openmc/error.h" -#include "openmc/tallies/filter_azimuthal.h" -#include "openmc/tallies/filter_cell.h" -#include "openmc/tallies/filter_cellborn.h" -#include "openmc/tallies/filter_cellfrom.h" -#include "openmc/tallies/filter_distribcell.h" -#include "openmc/tallies/filter_energyfunc.h" -#include "openmc/tallies/filter_legendre.h" -#include "openmc/tallies/filter_material.h" -#include "openmc/tallies/filter_mesh.h" -#include "openmc/tallies/filter_meshsurface.h" -#include "openmc/tallies/filter_mu.h" -#include "openmc/tallies/filter_polar.h" -#include "openmc/tallies/filter_sph_harm.h" -#include "openmc/tallies/filter_sptl_legendre.h" -#include "openmc/tallies/filter_surface.h" -#include "openmc/tallies/filter_universe.h" -#include "openmc/tallies/filter_zernike.h" - - -namespace openmc { - -//============================================================================== -// Global variables -//============================================================================== - -std::vector filter_matches; -std::vector tally_filters; - -//============================================================================== -// Non-member functions -//============================================================================== - -void -free_memory_tally_c() -{ - #pragma omp parallel - { - filter_matches.clear(); - } - - for (Filter* filt : tally_filters) {delete filt;} - tally_filters.clear(); -} - -//============================================================================== -// C-API functions -//============================================================================== - -// Fortran functions that will be called from C++ -extern "C" int verify_filter(int32_t index); -extern "C" Filter* filter_from_f(int32_t index); -extern "C" void filter_update_n_bins(int32_t index); - -extern "C" { - int - openmc_cell_filter_get_bins(int32_t index, int32_t** cells, int32_t* n) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "cell") { - set_errmsg("Tried to get cells from a non-cell filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto cell_filt = static_cast(filt); - *cells = cell_filt->cells_.data(); - *n = cell_filt->cells_.size(); - return 0; - } - - int - openmc_legendre_filter_get_order(int32_t index, int* order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "legendre") { - set_errmsg("Tried to get order on a non-expansion filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - *order = l_filt->order_; - return 0; - } - - int - openmc_legendre_filter_set_order(int32_t index, int order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "legendre") { - set_errmsg("Tried to set order on a non-expansion filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - l_filt->order_ = order; - l_filt->n_bins_ = order + 1; - filter_update_n_bins(index); - return 0; - } - - int - openmc_material_filter_get_bins(int32_t index, int32_t** bins, int32_t* n) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "material") { - set_errmsg("Tried to get material filter bins on a non-material filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto mat_filt = static_cast(filt); - *bins = mat_filt->materials_.data(); - *n = mat_filt->materials_.size(); - return 0; - } - - int - openmc_material_filter_set_bins(int32_t index, int32_t n, const int32_t* bins) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "material") { - set_errmsg("Tried to set material filter bins on a non-material filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto mat_filt = static_cast(filt); - mat_filt->materials_.clear(); - mat_filt->materials_.resize(n); - for (int i = 0; i < n; i++) mat_filt->materials_[i] = bins[i]; - mat_filt->n_bins_ = mat_filt->materials_.size(); - mat_filt->map_.clear(); - for (int i = 0; i < n; i++) mat_filt->map_[mat_filt->materials_[i]] = i; - filter_update_n_bins(index); - return 0; - } - - int - openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "mesh" && filt->type() != "meshsurface") { - set_errmsg("Tried to get mesh on a non-mesh filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto mesh_filt = static_cast(filt); - *index_mesh = mesh_filt->mesh_; - return 0; - } - - int - openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "mesh" && filt->type() != "meshsurface") { - set_errmsg("Tried to set mesh on a non-mesh filter."); - return OPENMC_E_INVALID_TYPE; - } - - if (index_mesh < 0 || index_mesh >= meshes.size()) { - set_errmsg("Index in 'meshes' array is out of bounds."); - return OPENMC_E_OUT_OF_BOUNDS; - } - - auto mesh_filt = static_cast(filt); - mesh_filt->mesh_ = index_mesh; - if (filt->type() == "mesh") { - mesh_filt->n_bins_ = 1; - } else { - filt->n_bins_ = 4 * meshes[index_mesh]->n_dimension_; - } - for (auto dim : meshes[index_mesh]->shape_) mesh_filt->n_bins_ *= dim; - filter_update_n_bins(index); - return 0; - } - - int openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh) - {return openmc_mesh_filter_get_mesh(index, index_mesh);} - - int openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh) - {return openmc_mesh_filter_set_mesh(index, index_mesh);} - - int - openmc_spatial_legendre_filter_get_order(int32_t index, int* order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - *order = l_filt->order_; - return 0; - } - - int - openmc_spatial_legendre_filter_get_params(int32_t index, int* axis, - double* min, double* max) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - *axis = static_cast(l_filt->axis_); - *min = l_filt->min_; - *max = l_filt->max_; - return 0; - } - - int - openmc_spatial_legendre_filter_set_order(int32_t index, int order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - l_filt->order_ = order; - l_filt->n_bins_ = order + 1; - filter_update_n_bins(index); - return 0; - } - - int - openmc_spatial_legendre_filter_set_params(int32_t index, const int* axis, - const double* min, const double* max) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - if (axis) l_filt->axis_ = static_cast(*axis); - if (min) l_filt->min_ = *min; - if (max) l_filt->max_ = *max; - return 0; - } - - int - openmc_sphharm_filter_get_order(int32_t index, int* order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - *order = sph_filt->order_; - return 0; - } - - int - openmc_sphharm_filter_get_cosine(int32_t index, char cosine[]) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - if (sph_filt->cosine_ == SphericalHarmonicsCosine::scatter) { - strcpy(cosine, "scatter"); - } else { - strcpy(cosine, "particle"); - } - return 0; - } - - int - openmc_sphharm_filter_set_order(int32_t index, int order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - sph_filt->order_ = order; - sph_filt->n_bins_ = (order + 1) * (order + 1); - filter_update_n_bins(index); - return 0; - } - - int - openmc_sphharm_filter_set_cosine(int32_t index, const char cosine[]) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - if (strcmp(cosine, "scatter") == 0) { - sph_filt->cosine_ = SphericalHarmonicsCosine::scatter; - } else if (strcmp(cosine, "particle") == 0) { - sph_filt->cosine_ = SphericalHarmonicsCosine::particle; - } else { - set_errmsg("Invalid spherical harmonics cosine."); - return OPENMC_E_INVALID_ARGUMENT; - } - return 0; - } - - int - openmc_zernike_filter_get_order(int32_t index, int* order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - *order = z_filt->order_; - return 0; - } - - int - openmc_zernike_filter_get_params(int32_t index, double* x, double* y, - double* r) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - *x = z_filt->x_; - *y = z_filt->y_; - *r = z_filt->r_; - return 0; - } - - int - openmc_zernike_filter_set_order(int32_t index, int order) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - z_filt->order_ = order; - z_filt->calc_n_bins(); - filter_update_n_bins(index); - return 0; - } - - int - openmc_zernike_filter_set_params(int32_t index, const double* x, - const double* y, const double* r) - { - int err = verify_filter(index); - if (err) return err; - - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - if (x) z_filt->x_ = *x; - if (y) z_filt->y_ = *y; - if (r) z_filt->r_ = *r; - return 0; - } -} - -//============================================================================== -// Fortran compatibility functions -//============================================================================== - -extern "C" { - FilterMatch* filter_match_pointer(int indx) - {return &filter_matches[indx];} - - void - filter_match_bins_push_back(FilterMatch* match, int val) - {match->bins_.push_back(val);} - - void - filter_match_weights_push_back(FilterMatch* match, double val) - {match->weights_.push_back(val);} - - void - filter_match_bins_clear(FilterMatch* match) - {match->bins_.clear();} - - void - filter_match_weights_clear(FilterMatch* match) - {match->weights_.clear();} - - int - filter_match_bins_size(FilterMatch* match) - {return match->bins_.size();} - - int - filter_match_bins_data(FilterMatch* match, int indx) - {return match->bins_[indx-1];} - - double - filter_match_weights_data(FilterMatch* match, int indx) - {return match->weights_[indx-1];} - - void - filter_match_bins_set_data(FilterMatch* match, int indx, int val) - {match->bins_[indx-1] = val;} - - Filter* - allocate_filter(const char* type) - { - std::string type_ {type}; - if (type_ == "azimuthal") { - tally_filters.push_back(new AzimuthalFilter()); - } else if (type_ == "cell") { - tally_filters.push_back(new CellFilter()); - } else if (type_ == "cellborn") { - tally_filters.push_back(new CellbornFilter()); - } else if (type_ == "cellfrom") { - tally_filters.push_back(new CellFromFilter()); - } else if (type_ == "distribcell") { - tally_filters.push_back(new DistribcellFilter()); - } else if (type_ == "energyfunction") { - tally_filters.push_back(new EnergyFunctionFilter()); - } else if (type_ == "legendre") { - tally_filters.push_back(new LegendreFilter()); - } else if (type_ == "material") { - tally_filters.push_back(new MaterialFilter()); - } else if (type_ == "mesh") { - tally_filters.push_back(new MeshFilter()); - } else if (type_ == "meshsurface") { - tally_filters.push_back(new MeshSurfaceFilter()); - } else if (type_ == "mu") { - tally_filters.push_back(new MuFilter()); - } else if (type_ == "polar") { - tally_filters.push_back(new PolarFilter()); - } else if (type_ == "surface") { - tally_filters.push_back(new SurfaceFilter()); - } else if (type_ == "spatiallegendre") { - tally_filters.push_back(new SpatialLegendreFilter()); - } else if (type_ == "sphericalharmonics") { - tally_filters.push_back(new SphericalHarmonicsFilter()); - } else if (type_ == "universe") { - tally_filters.push_back(new UniverseFilter()); - } else if (type_ == "zernike") { - tally_filters.push_back(new ZernikeFilter()); - } else if (type_ == "zernikeradial") { - tally_filters.push_back(new ZernikeRadialFilter()); - } else { - return nullptr; - } - return tally_filters.back(); - } - - void filter_from_xml(Filter* filt, pugi::xml_node* node) - {filt->from_xml(*node);} - - void - filter_get_all_bins(Filter* filt, Particle* p, int estimator, - FilterMatch* match) - { - filt->get_all_bins(p, estimator, *match); - } - - void filter_to_statepoint(Filter* filt, hid_t group) - {filt->to_statepoint(group);} - - void filter_text_label(Filter* filt, int bin, char* label) - { - std::string label_str = filt->text_label(bin); - int i = 0; - for (; i < label_str.size() && i < MAX_LINE_LEN; i++) - label[i] = label_str[i]; - label[i] = '\0'; - } - - void filter_initialize(Filter* filt) {filt->initialize();} - - int filter_n_bins(Filter* filt) {return filt->n_bins_;} - - int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} - - int sphharm_filter_get_cosine(SphericalHarmonicsFilter* filt) - {return static_cast(filt->cosine_);} -} - -} // namespace openmc From 321b255aea2f43e9bb5710a473314b7ae5eca75b Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 22 Oct 2018 21:55:06 -0400 Subject: [PATCH 44/45] Address #1101 comments --- include/openmc/tallies/filter.h | 8 +-- include/openmc/tallies/filter_azimuthal.h | 2 +- include/openmc/tallies/filter_cell.h | 5 +- include/openmc/tallies/filter_cellborn.h | 2 +- include/openmc/tallies/filter_cellfrom.h | 2 +- include/openmc/tallies/filter_distribcell.h | 2 +- include/openmc/tallies/filter_energyfunc.h | 5 +- include/openmc/tallies/filter_legendre.h | 2 +- include/openmc/tallies/filter_material.h | 5 +- include/openmc/tallies/filter_mesh.h | 2 +- include/openmc/tallies/filter_meshsurface.h | 2 +- include/openmc/tallies/filter_mu.h | 2 +- include/openmc/tallies/filter_polar.h | 2 +- include/openmc/tallies/filter_sph_harm.h | 4 +- include/openmc/tallies/filter_sptl_legendre.h | 11 +++- include/openmc/tallies/filter_surface.h | 5 +- include/openmc/tallies/filter_universe.h | 5 +- include/openmc/tallies/filter_zernike.h | 21 ++++-- src/tallies/filter_azimuthal.cpp | 10 +-- src/tallies/filter_cell.cpp | 9 ++- src/tallies/filter_cellborn.cpp | 7 +- src/tallies/filter_cellfrom.cpp | 7 +- src/tallies/filter_distribcell.cpp | 9 ++- src/tallies/filter_energyfunc.cpp | 4 +- src/tallies/filter_legendre.cpp | 6 +- src/tallies/filter_material.cpp | 10 ++- src/tallies/filter_mesh.cpp | 4 +- src/tallies/filter_meshsurface.cpp | 65 +++++++++++-------- src/tallies/filter_mu.cpp | 9 ++- src/tallies/filter_polar.cpp | 8 ++- src/tallies/filter_sph_harm.cpp | 4 +- src/tallies/filter_sptl_legendre.cpp | 6 +- src/tallies/filter_surface.cpp | 12 ++-- src/tallies/filter_universe.cpp | 10 ++- src/tallies/filter_zernike.cpp | 31 ++++++--- 35 files changed, 200 insertions(+), 98 deletions(-) diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index 9398d3ab8..286497d37 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -7,7 +7,7 @@ #include "openmc/hdf5_interface.h" #include "openmc/particle.h" -#include "openmc/xml_interface.h" +#include "pugixml.hpp" namespace openmc { @@ -43,10 +43,10 @@ public: class Filter { public: - virtual std::string type() const = 0; - virtual ~Filter() = 0; + virtual std::string type() const = 0; + //! Uses an XML input to fill the filter's data fields. virtual void from_xml(pugi::xml_node node) = 0; @@ -55,7 +55,7 @@ public: //! \param[out] match will contain the matching bins and corresponding //! weights; note that there may be zero matching bins virtual void - get_all_bins(Particle* p, int estimator, FilterMatch& match) const = 0; + get_all_bins(const Particle* p, int estimator, FilterMatch& match) const = 0; //! Writes data describing this filter to an HDF5 statepoint group. virtual void diff --git a/include/openmc/tallies/filter_azimuthal.h b/include/openmc/tallies/filter_azimuthal.h index fdbe20ca5..b89640031 100644 --- a/include/openmc/tallies/filter_azimuthal.h +++ b/include/openmc/tallies/filter_azimuthal.h @@ -21,7 +21,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_cell.h b/include/openmc/tallies/filter_cell.h index 38cb1e57e..9c654e82e 100644 --- a/include/openmc/tallies/filter_cell.h +++ b/include/openmc/tallies/filter_cell.h @@ -24,14 +24,17 @@ public: void initialize() override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; + //! The indices of the cells binned by this filter. std::vector cells_; + + //! A map from cell indices to filter bin indices. std::unordered_map map_; }; diff --git a/include/openmc/tallies/filter_cellborn.h b/include/openmc/tallies/filter_cellborn.h index 414a96ec7..400e82c28 100644 --- a/include/openmc/tallies/filter_cellborn.h +++ b/include/openmc/tallies/filter_cellborn.h @@ -16,7 +16,7 @@ class CellbornFilter : public CellFilter public: std::string type() const override {return "cellborn";} - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; std::string text_label(int bin) const override; diff --git a/include/openmc/tallies/filter_cellfrom.h b/include/openmc/tallies/filter_cellfrom.h index 0826c669b..bd3e08dcb 100644 --- a/include/openmc/tallies/filter_cellfrom.h +++ b/include/openmc/tallies/filter_cellfrom.h @@ -16,7 +16,7 @@ class CellFromFilter : public CellFilter public: std::string type() const override {return "cellfrom";} - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; std::string text_label(int bin) const override; diff --git a/include/openmc/tallies/filter_distribcell.h b/include/openmc/tallies/filter_distribcell.h index e66ee6213..73857e7cb 100644 --- a/include/openmc/tallies/filter_distribcell.h +++ b/include/openmc/tallies/filter_distribcell.h @@ -22,7 +22,7 @@ public: void initialize() override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_energyfunc.h b/include/openmc/tallies/filter_energyfunc.h index 8fb1b9ede..6f5182626 100644 --- a/include/openmc/tallies/filter_energyfunc.h +++ b/include/openmc/tallies/filter_energyfunc.h @@ -27,14 +27,17 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; + //! Incident neutron energy interpolation grid. std::vector energy_; + + //! Interpolant values. std::vector y_; }; diff --git a/include/openmc/tallies/filter_legendre.h b/include/openmc/tallies/filter_legendre.h index fabb8140b..054ba14e7 100644 --- a/include/openmc/tallies/filter_legendre.h +++ b/include/openmc/tallies/filter_legendre.h @@ -20,7 +20,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_material.h b/include/openmc/tallies/filter_material.h index e78b056a4..d272451db 100644 --- a/include/openmc/tallies/filter_material.h +++ b/include/openmc/tallies/filter_material.h @@ -24,14 +24,17 @@ public: void initialize() override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; + //! The indices of the materials binned by this filter. std::vector materials_; + + //! A map from material indices to filter bin indices. std::unordered_map map_; }; diff --git a/include/openmc/tallies/filter_mesh.h b/include/openmc/tallies/filter_mesh.h index 98853e653..250eb00e0 100644 --- a/include/openmc/tallies/filter_mesh.h +++ b/include/openmc/tallies/filter_mesh.h @@ -22,7 +22,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_meshsurface.h b/include/openmc/tallies/filter_meshsurface.h index 2d5aefef6..08218ac3d 100644 --- a/include/openmc/tallies/filter_meshsurface.h +++ b/include/openmc/tallies/filter_meshsurface.h @@ -12,7 +12,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; std::string text_label(int bin) const override; diff --git a/include/openmc/tallies/filter_mu.h b/include/openmc/tallies/filter_mu.h index fdc311b27..68b2f7b02 100644 --- a/include/openmc/tallies/filter_mu.h +++ b/include/openmc/tallies/filter_mu.h @@ -21,7 +21,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_polar.h b/include/openmc/tallies/filter_polar.h index 3cc113a4f..2bcdcd07f 100644 --- a/include/openmc/tallies/filter_polar.h +++ b/include/openmc/tallies/filter_polar.h @@ -21,7 +21,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; diff --git a/include/openmc/tallies/filter_sph_harm.h b/include/openmc/tallies/filter_sph_harm.h index 8e429b953..786ef1a58 100644 --- a/include/openmc/tallies/filter_sph_harm.h +++ b/include/openmc/tallies/filter_sph_harm.h @@ -25,7 +25,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; @@ -33,6 +33,8 @@ public: std::string text_label(int bin) const override; int order_; + + //! The type of angle that this filter measures when binning events. SphericalHarmonicsCosine cosine_ {SphericalHarmonicsCosine::particle}; }; diff --git a/include/openmc/tallies/filter_sptl_legendre.h b/include/openmc/tallies/filter_sptl_legendre.h index 560239569..1b94ecf3d 100644 --- a/include/openmc/tallies/filter_sptl_legendre.h +++ b/include/openmc/tallies/filter_sptl_legendre.h @@ -25,7 +25,7 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; @@ -33,8 +33,15 @@ public: std::string text_label(int bin) const override; int order_; + + //! The Cartesian coordinate axis that the Legendre expansion is applied to. LegendreAxis axis_; - double min_, max_; + + //! The minimum coordinate along the reference axis that the expansion covers. + double min_; + + //! The maximum coordinate along the reference axis that the expansion covers. + double max_; }; } // namespace openmc diff --git a/include/openmc/tallies/filter_surface.h b/include/openmc/tallies/filter_surface.h index 85af6d004..ea4dc5b99 100644 --- a/include/openmc/tallies/filter_surface.h +++ b/include/openmc/tallies/filter_surface.h @@ -24,14 +24,17 @@ public: void initialize() override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; + //! The indices of the surfaces binned by this filter. std::vector surfaces_; + + //! A map from surface indices to filter bin indices. std::unordered_map map_; }; diff --git a/include/openmc/tallies/filter_universe.h b/include/openmc/tallies/filter_universe.h index 5e7c85d1f..3ae0093cb 100644 --- a/include/openmc/tallies/filter_universe.h +++ b/include/openmc/tallies/filter_universe.h @@ -24,14 +24,17 @@ public: void initialize() override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; + //! The indices of the universes binned by this filter. std::vector universes_; + + //! A map from universe indices to filter bin indices. std::unordered_map map_; }; diff --git a/include/openmc/tallies/filter_zernike.h b/include/openmc/tallies/filter_zernike.h index 6450c6c17..19fff1336 100644 --- a/include/openmc/tallies/filter_zernike.h +++ b/include/openmc/tallies/filter_zernike.h @@ -20,17 +20,28 @@ public: void from_xml(pugi::xml_node node) override; - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; void to_statepoint(hid_t filter_group) const override; std::string text_label(int bin) const override; - virtual void calc_n_bins() {n_bins_ = ((order_+1) * (order_+2)) / 2;} + int order() const {return order_;} + virtual void set_order(int order); + + //! Cartesian x coordinate for the origin of this expansion. + double x_; + + //! Cartesian y coordinate for the origin of this expansion. + double y_; + + //! Maximum radius from the origin covered by this expansion. + double r_; + +protected: int order_; - double x_, y_, r_; }; //============================================================================== @@ -42,12 +53,12 @@ class ZernikeRadialFilter : public ZernikeFilter public: std::string type() const override {return "zernikeradial";} - void get_all_bins(Particle* p, int estimator, FilterMatch& match) + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; std::string text_label(int bin) const override; - void calc_n_bins() override {n_bins_ = order_ / 2 + 1;} + void set_order(int order) override; }; } // namespace openmc diff --git a/src/tallies/filter_azimuthal.cpp b/src/tallies/filter_azimuthal.cpp index 7611cb1f1..99a649cd9 100644 --- a/src/tallies/filter_azimuthal.cpp +++ b/src/tallies/filter_azimuthal.cpp @@ -6,6 +6,7 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/search.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -36,8 +37,8 @@ AzimuthalFilter::from_xml(pugi::xml_node node) } void -AzimuthalFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +AzimuthalFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { double phi; if (estimator == ESTIMATOR_TRACKLENGTH) { @@ -46,10 +47,11 @@ const phi = std::atan2(p->last_uvw[1], p->last_uvw[0]); } - if (phi >= bins_[0] && phi <= bins_.back()) { + if (phi >= bins_.front() && phi <= bins_.back()) { + //TODO: off-by-one auto bin = lower_bound_index(bins_.begin(), bins_.end(), phi) + 1; match.bins_.push_back(bin); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp index d52c6bb5f..a09c331bf 100644 --- a/src/tallies/filter_cell.cpp +++ b/src/tallies/filter_cell.cpp @@ -5,6 +5,7 @@ #include "openmc/capi.h" #include "openmc/cell.h" #include "openmc/error.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -18,6 +19,7 @@ CellFilter::from_xml(pugi::xml_node node) void CellFilter::initialize() { + // Convert cell IDs to indices of the global array. for (auto& c : cells_) { auto search = cell_map.find(c); if (search != cell_map.end()) { @@ -29,19 +31,22 @@ CellFilter::initialize() } } + // Populate the index->bin map. for (int i = 0; i < cells_.size(); i++) { map_[cells_[i]] = i; } } void -CellFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) const +CellFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { for (int i = 0; i < p->n_coord; i++) { auto search = map_.find(p->coord[i].cell); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } } diff --git a/src/tallies/filter_cellborn.cpp b/src/tallies/filter_cellborn.cpp index c42740119..e77c2e42f 100644 --- a/src/tallies/filter_cellborn.cpp +++ b/src/tallies/filter_cellborn.cpp @@ -5,13 +5,14 @@ namespace openmc { void -CellbornFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +CellbornFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { auto search = map_.find(p->cell_born); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } diff --git a/src/tallies/filter_cellfrom.cpp b/src/tallies/filter_cellfrom.cpp index 5771f0b13..4ce24e890 100644 --- a/src/tallies/filter_cellfrom.cpp +++ b/src/tallies/filter_cellfrom.cpp @@ -5,14 +5,15 @@ namespace openmc { void -CellFromFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +CellFromFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { for (int i = 0; i < p->last_n_coord; i++) { auto search = map_.find(p->last_cell[i]); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } } diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index db1cd59c9..f1e69b62a 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -4,6 +4,7 @@ #include "openmc/error.h" #include "openmc/geometry_aux.h" // For distribcell_path #include "openmc/lattice.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -20,6 +21,7 @@ DistribcellFilter::from_xml(pugi::xml_node node) void DistribcellFilter::initialize() { + // Convert the cell ID to an index of the global array. auto search = cell_map.find(cell_); if (search != cell_map.end()) { cell_ = search->second; @@ -33,8 +35,8 @@ DistribcellFilter::initialize() } void -DistribcellFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +DistribcellFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { int offset = 0; auto distribcell_index = cells[cell_]->distribcell_index_; @@ -52,8 +54,9 @@ const } } if (cell_ == p->coord[i].cell) { + //TODO: off-by-one match.bins_.push_back(offset + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); return; } } diff --git a/src/tallies/filter_energyfunc.cpp b/src/tallies/filter_energyfunc.cpp index 92c9592a0..b47e7b7b6 100644 --- a/src/tallies/filter_energyfunc.cpp +++ b/src/tallies/filter_energyfunc.cpp @@ -7,6 +7,7 @@ #include "openmc/error.h" #include "openmc/search.h" #include "openmc/settings.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -29,7 +30,7 @@ EnergyFunctionFilter::from_xml(pugi::xml_node node) } void -EnergyFunctionFilter::get_all_bins(Particle* p, int estimator, +EnergyFunctionFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { if (p->last_E >= energy_.front() && p->last_E <= energy_.back()) { @@ -40,6 +41,7 @@ EnergyFunctionFilter::get_all_bins(Particle* p, int estimator, double f = (p->last_E - energy_[i]) / (energy_[i+1] - energy_[i]); // Interpolate on the lin-lin grid. + //TODO: off-by-one match.bins_.push_back(1); match.weights_.push_back((1-f) * y_[i] + f * y_[i+1]); } diff --git a/src/tallies/filter_legendre.cpp b/src/tallies/filter_legendre.cpp index c8666f6b9..32cedcfa0 100644 --- a/src/tallies/filter_legendre.cpp +++ b/src/tallies/filter_legendre.cpp @@ -3,6 +3,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -14,12 +15,13 @@ LegendreFilter::from_xml(pugi::xml_node node) } void -LegendreFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +LegendreFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { double wgt[n_bins_]; calc_pn_c(order_, p->mu, wgt); for (int i = 0; i < n_bins_; i++) { + //TODO: off-by-one match.bins_.push_back(i + 1); match.weights_.push_back(wgt[i]); } diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index 66d948088..2b6542d78 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -5,6 +5,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/material.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -18,6 +19,7 @@ MaterialFilter::from_xml(pugi::xml_node node) void MaterialFilter::initialize() { + // Convert material IDs to indices of the global array. for (auto& m : materials_) { auto search = material_map.find(m); if (search != material_map.end()) { @@ -30,19 +32,21 @@ MaterialFilter::initialize() } } + // Populate the index->bin map. for (int i = 0; i < materials_.size(); i++) { map_[materials_[i]] = i; } } void -MaterialFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +MaterialFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { auto search = map_.find(p->material - 1); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index ad17543c6..41b8e642b 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -6,6 +6,7 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/mesh.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -33,12 +34,13 @@ MeshFilter::from_xml(pugi::xml_node node) } void -MeshFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +MeshFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { if (estimator != ESTIMATOR_TRACKLENGTH) { auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); if (bin >= 0) { + //TODO: off-by-one match.bins_.push_back(bin); match.weights_.push_back(1.0); } diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp index 124d3df33..aafa91e6e 100644 --- a/src/tallies/filter_meshsurface.cpp +++ b/src/tallies/filter_meshsurface.cpp @@ -16,8 +16,8 @@ MeshSurfaceFilter::from_xml(pugi::xml_node node) } void -MeshSurfaceFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +MeshSurfaceFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { meshes[mesh_]->surface_bins_crossed(p, match.bins_); for (auto b : match.bins_) match.weights_.push_back(1.0); @@ -37,30 +37,43 @@ MeshSurfaceFilter::text_label(int bin) const std::string out = MeshFilter::text_label(i_mesh); // Get surface part of label. - if (i_surf == OUT_LEFT) { - out += " Outgoing, x-min"; - } else if (i_surf == IN_LEFT) { - out += " Incoming, x-min"; - } else if (i_surf == OUT_RIGHT) { - out += " Outgoing, x-max"; - } else if (i_surf == IN_RIGHT) { - out += " Incoming, x-max"; - } else if (i_surf == OUT_BACK) { - out += " Outgoing, y-min"; - } else if (i_surf == IN_BACK) { - out += " Incoming, y-min"; - } else if (i_surf == OUT_FRONT) { - out += " Outgoing, y-max"; - } else if (i_surf == IN_FRONT) { - out += " Incoming, y-max"; - } else if (i_surf == OUT_BOTTOM) { - out += " Outgoing, z-min"; - } else if (i_surf == IN_BOTTOM) { - out += " Incoming, z-min"; - } else if (i_surf == OUT_TOP) { - out += " Outgoing, z-max"; - } else if (i_surf == IN_TOP) { - out += " Incoming, z-max"; + switch (i_surf) { + case OUT_LEFT: + out += " Outgoing, x-min"; + break; + case IN_LEFT: + out += " Incoming, x-min"; + break; + case OUT_RIGHT: + out += " Outgoing, x-max"; + break; + case IN_RIGHT: + out += " Incoming, x-max"; + break; + case OUT_BACK: + out += " Outgoing, y-min"; + break; + case IN_BACK: + out += " Incoming, y-min"; + break; + case OUT_FRONT: + out += " Outgoing, y-max"; + break; + case IN_FRONT: + out += " Incoming, y-max"; + break; + case OUT_BOTTOM: + out += " Outgoing, z-min"; + break; + case IN_BOTTOM: + out += " Incoming, z-min"; + break; + case OUT_TOP: + out += " Outgoing, z-max"; + break; + case IN_TOP: + out += " Incoming, z-max"; + break; } return out; diff --git a/src/tallies/filter_mu.cpp b/src/tallies/filter_mu.cpp index cd428a4e4..e57a8aa2e 100644 --- a/src/tallies/filter_mu.cpp +++ b/src/tallies/filter_mu.cpp @@ -4,6 +4,7 @@ #include "openmc/error.h" #include "openmc/search.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -34,12 +35,14 @@ MuFilter::from_xml(pugi::xml_node node) } void -MuFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) const +MuFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) +const { - if (p->mu >= bins_[0] && p->mu <= bins_.back()) { + if (p->mu >= bins_.front() && p->mu <= bins_.back()) { + //TODO: off-by-one auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->mu) + 1; match.bins_.push_back(bin); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } diff --git a/src/tallies/filter_polar.cpp b/src/tallies/filter_polar.cpp index 81839cecb..bfa87a341 100644 --- a/src/tallies/filter_polar.cpp +++ b/src/tallies/filter_polar.cpp @@ -5,6 +5,7 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/search.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -35,7 +36,7 @@ PolarFilter::from_xml(pugi::xml_node node) } void -PolarFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) +PolarFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { double theta; @@ -45,10 +46,11 @@ const theta = std::acos(p->last_uvw[2]); } - if (theta >= bins_[0] && theta <= bins_.back()) { + if (theta >= bins_.front() && theta <= bins_.back()) { + //TODO: off-by-one auto bin = lower_bound_index(bins_.begin(), bins_.end(), theta) + 1; match.bins_.push_back(bin); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp index f6d165621..1c085bcce 100644 --- a/src/tallies/filter_sph_harm.cpp +++ b/src/tallies/filter_sph_harm.cpp @@ -3,6 +3,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -28,7 +29,7 @@ SphericalHarmonicsFilter::from_xml(pugi::xml_node node) } void -SphericalHarmonicsFilter::get_all_bins(Particle* p, int estimator, +SphericalHarmonicsFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { // Determine cosine term for scatter expansion if necessary @@ -51,6 +52,7 @@ SphericalHarmonicsFilter::get_all_bins(Particle* p, int estimator, // Append the matching (bin,weight) for each moment for (int i = 0; i < num_nm; i++) { match.weights_.push_back(wgt[n] * rn[j]); + //TODO: off-by-one match.bins_.push_back(++j); } } diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp index a5507b614..4043a4389 100644 --- a/src/tallies/filter_sptl_legendre.cpp +++ b/src/tallies/filter_sptl_legendre.cpp @@ -3,6 +3,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -29,8 +30,8 @@ SpatialLegendreFilter::from_xml(pugi::xml_node node) } void -SpatialLegendreFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +SpatialLegendreFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { // Get the coordinate along the axis of interest. double x; @@ -50,6 +51,7 @@ const double wgt[order_ + 1]; calc_pn_c(order_, x_norm, wgt); for (int i = 0; i < order_ + 1; i++) { + //TODO: off-by-one match.bins_.push_back(i + 1); match.weights_.push_back(wgt[i]); } diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp index 9ce61e84d..7fd2c6e24 100644 --- a/src/tallies/filter_surface.cpp +++ b/src/tallies/filter_surface.cpp @@ -4,6 +4,7 @@ #include "openmc/error.h" #include "openmc/surface.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -17,6 +18,7 @@ SurfaceFilter::from_xml(pugi::xml_node node) void SurfaceFilter::initialize() { + // Convert surface IDs to indices of the global array. for (auto& s : surfaces_) { auto search = surface_map.find(s); if (search != surface_map.end()) { @@ -29,22 +31,24 @@ SurfaceFilter::initialize() } } + // Populate the index->bin map. for (int i = 0; i < surfaces_.size(); i++) { map_[surfaces_[i]] = i; } } void -SurfaceFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +SurfaceFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { auto search = map_.find(std::abs(p->surface)-1); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); if (p->surface < 0) { - match.weights_.push_back(-1); + match.weights_.push_back(-1.0); } else { - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } } diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp index bd90ed091..de0d33d29 100644 --- a/src/tallies/filter_universe.cpp +++ b/src/tallies/filter_universe.cpp @@ -4,6 +4,7 @@ #include "openmc/cell.h" #include "openmc/error.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -17,6 +18,7 @@ UniverseFilter::from_xml(pugi::xml_node node) void UniverseFilter::initialize() { + // Convert universe IDs to indices of the global array. for (auto& u : universes_) { auto search = universe_map.find(u); if (search != universe_map.end()) { @@ -29,20 +31,22 @@ UniverseFilter::initialize() } } + // Populate the index->bin map. for (int i = 0; i < universes_.size(); i++) { map_[universes_[i]] = i; } } void -UniverseFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +UniverseFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { for (int i = 0; i < p->n_coord; i++) { auto search = map_.find(p->coord[i].universe); if (search != map_.end()) { + //TODO: off-by-one match.bins_.push_back(search->second + 1); - match.weights_.push_back(1); + match.weights_.push_back(1.0); } } } diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp index c7413f341..ed658e2d2 100644 --- a/src/tallies/filter_zernike.cpp +++ b/src/tallies/filter_zernike.cpp @@ -6,6 +6,7 @@ #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" +#include "openmc/xml_interface.h" namespace openmc { @@ -16,16 +17,15 @@ namespace openmc { void ZernikeFilter::from_xml(pugi::xml_node node) { - order_ = std::stoi(get_node_value(node, "order")); + set_order(std::stoi(get_node_value(node, "order"))); x_ = std::stod(get_node_value(node, "x")); y_ = std::stod(get_node_value(node, "y")); r_ = std::stod(get_node_value(node, "r")); - calc_n_bins(); } void -ZernikeFilter::get_all_bins(Particle* p, int estimator, FilterMatch& match) -const +ZernikeFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const { // Determine the normalized (r,theta) coordinates. double x = p->coord[0].xyz[0] - x_; @@ -38,6 +38,7 @@ const double zn[n_bins_]; calc_zn(order_, r, theta, zn); for (int i = 0; i < n_bins_; i++) { + //TODO: off-by-one match.bins_.push_back(i+1); match.weights_.push_back(zn[i]); } @@ -69,12 +70,19 @@ ZernikeFilter::text_label(int bin) const } } +void +ZernikeFilter::set_order(int order) +{ + order_ = order; + n_bins_ = ((order+1) * (order+2)) / 2; +} + //============================================================================== // ZernikeRadialFilter implementation //============================================================================== void -ZernikeRadialFilter::get_all_bins(Particle* p, int estimator, +ZernikeRadialFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { // Determine the normalized radius coordinate. @@ -87,6 +95,7 @@ ZernikeRadialFilter::get_all_bins(Particle* p, int estimator, double zn[n_bins_]; calc_zn_rad(order_, r, zn); for (int i = 0; i < n_bins_; i++) { + //TODO: off-by-one match.bins_.push_back(i+1); match.weights_.push_back(zn[i]); } @@ -99,6 +108,13 @@ ZernikeRadialFilter::text_label(int bin) const return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; } +void +ZernikeRadialFilter::set_order(int order) +{ + order_ = order; + n_bins_ = order / 2 + 1; +} + //============================================================================== // C-API functions //============================================================================== @@ -116,7 +132,7 @@ openmc_zernike_filter_get_order(int32_t index, int* order) } auto z_filt = static_cast(filt); - *order = z_filt->order_; + *order = z_filt->order(); return 0; } @@ -153,8 +169,7 @@ openmc_zernike_filter_set_order(int32_t index, int order) } auto z_filt = static_cast(filt); - z_filt->order_ = order; - z_filt->calc_n_bins(); + z_filt->set_order(order); filter_update_n_bins(index); return 0; } From 91f4196f0f444f4a68106948bd54f33729f8b71c Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 25 Oct 2018 12:58:09 -0400 Subject: [PATCH 45/45] Use dynamic_cast for filter type-checking --- include/openmc/tallies/filter.h | 4 +- include/openmc/tallies/filter_mesh.h | 5 ++ include/openmc/tallies/filter_meshsurface.h | 4 +- src/tallies/filter.cpp | 2 +- src/tallies/filter_legendre.cpp | 32 ++++--- src/tallies/filter_material.cpp | 38 +++++---- src/tallies/filter_mesh.cpp | 46 ++++++---- src/tallies/filter_meshsurface.cpp | 16 ++-- src/tallies/filter_sph_harm.cpp | 87 ++++++++++--------- src/tallies/filter_sptl_legendre.cpp | 93 ++++++++++++--------- src/tallies/filter_zernike.cpp | 90 +++++++++++--------- 11 files changed, 241 insertions(+), 176 deletions(-) diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index 286497d37..7920191aa 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -43,7 +43,7 @@ public: class Filter { public: - virtual ~Filter() = 0; + virtual ~Filter() = default; virtual std::string type() const = 0; @@ -76,8 +76,6 @@ public: int n_bins_; }; -inline Filter::~Filter() {} - //============================================================================== extern "C" void free_memory_tally_c(); diff --git a/include/openmc/tallies/filter_mesh.h b/include/openmc/tallies/filter_mesh.h index 250eb00e0..a6caa8f56 100644 --- a/include/openmc/tallies/filter_mesh.h +++ b/include/openmc/tallies/filter_mesh.h @@ -29,6 +29,11 @@ public: std::string text_label(int bin) const override; + virtual int32_t mesh() const {return mesh_;} + + virtual void set_mesh(int32_t mesh); + +protected: int32_t mesh_; }; diff --git a/include/openmc/tallies/filter_meshsurface.h b/include/openmc/tallies/filter_meshsurface.h index 08218ac3d..32393cfac 100644 --- a/include/openmc/tallies/filter_meshsurface.h +++ b/include/openmc/tallies/filter_meshsurface.h @@ -10,12 +10,12 @@ class MeshSurfaceFilter : public MeshFilter public: std::string type() const override {return "meshsurface";} - void from_xml(pugi::xml_node node) override; - void get_all_bins(const Particle* p, int estimator, FilterMatch& match) const override; std::string text_label(int bin) const override; + + void set_mesh(int32_t mesh) override; }; } // namespace openmc diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 3d7b35726..44758f379 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -161,7 +161,7 @@ extern "C" { int filter_n_bins(Filter* filt) {return filt->n_bins_;} - int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh_;} + int mesh_filter_get_mesh(MeshFilter* filt) {return filt->mesh();} int sphharm_filter_get_cosine(SphericalHarmonicsFilter* filt) {return static_cast(filt->cosine_);} diff --git a/src/tallies/filter_legendre.cpp b/src/tallies/filter_legendre.cpp index 32cedcfa0..3b59fa763 100644 --- a/src/tallies/filter_legendre.cpp +++ b/src/tallies/filter_legendre.cpp @@ -47,35 +47,45 @@ LegendreFilter::text_label(int bin) const extern "C" int openmc_legendre_filter_get_order(int32_t index, int* order) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "legendre") { - set_errmsg("Tried to get order on a non-expansion filter."); + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Not a legendre filter."); return OPENMC_E_INVALID_TYPE; } - auto l_filt = static_cast(filt); - *order = l_filt->order_; + // Output the order. + *order = filt->order_; return 0; } extern "C" int openmc_legendre_filter_set_order(int32_t index, int order) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "legendre") { - set_errmsg("Tried to set order on a non-expansion filter."); + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Not a legendre filter."); return OPENMC_E_INVALID_TYPE; } - auto l_filt = static_cast(filt); - l_filt->order_ = order; - l_filt->n_bins_ = order + 1; + // Update the filter. + filt->order_ = order; + filt->n_bins_ = order + 1; filter_update_n_bins(index); return 0; } diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index 2b6542d78..0334efae9 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -72,40 +72,50 @@ MaterialFilter::text_label(int bin) const extern "C" int openmc_material_filter_get_bins(int32_t index, int32_t** bins, int32_t* n) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "material") { + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { set_errmsg("Tried to get material filter bins on a non-material filter."); return OPENMC_E_INVALID_TYPE; } - auto mat_filt = static_cast(filt); - *bins = mat_filt->materials_.data(); - *n = mat_filt->materials_.size(); + // Output the bins. + *bins = filt->materials_.data(); + *n = filt->materials_.size(); return 0; } extern "C" int openmc_material_filter_set_bins(int32_t index, int32_t n, const int32_t* bins) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "material") { + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { set_errmsg("Tried to set material filter bins on a non-material filter."); return OPENMC_E_INVALID_TYPE; } - auto mat_filt = static_cast(filt); - mat_filt->materials_.clear(); - mat_filt->materials_.resize(n); - for (int i = 0; i < n; i++) mat_filt->materials_[i] = bins[i]; - mat_filt->n_bins_ = mat_filt->materials_.size(); - mat_filt->map_.clear(); - for (int i = 0; i < n; i++) mat_filt->map_[mat_filt->materials_[i]] = i; + // Update the filter. + filt->materials_.clear(); + filt->materials_.resize(n); + for (int i = 0; i < n; i++) filt->materials_[i] = bins[i]; + filt->n_bins_ = filt->materials_.size(); + filt->map_.clear(); + for (int i = 0; i < n; i++) filt->map_[filt->materials_[i]] = i; filter_update_n_bins(index); return 0; } diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index 41b8e642b..5ff54bcf5 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -22,15 +22,12 @@ MeshFilter::from_xml(pugi::xml_node node) auto id = bins_[0]; auto search = mesh_map.find(id); if (search != mesh_map.end()) { - mesh_ = search->second; + set_mesh(search->second); } else{ std::stringstream err_msg; err_msg << "Could not find cell " << id << " specified on tally filter."; fatal_error(err_msg); } - - n_bins_ = 1; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; } void @@ -74,6 +71,14 @@ MeshFilter::text_label(int bin) const return out.str(); } +void +MeshFilter::set_mesh(int32_t mesh) +{ + mesh_ = mesh; + n_bins_ = 1; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; +} + //============================================================================== // C-API functions //============================================================================== @@ -81,45 +86,50 @@ MeshFilter::text_label(int bin) const extern "C" int openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "mesh" && filt->type() != "meshsurface") { + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { set_errmsg("Tried to get mesh on a non-mesh filter."); return OPENMC_E_INVALID_TYPE; } - auto mesh_filt = static_cast(filt); - *index_mesh = mesh_filt->mesh_; + // Output the mesh. + *index_mesh = filt->mesh(); return 0; } extern "C" int openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) { + // Make sure this is a valid index to an allocated filter. int err = verify_filter(index); if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "mesh" && filt->type() != "meshsurface") { + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { set_errmsg("Tried to set mesh on a non-mesh filter."); return OPENMC_E_INVALID_TYPE; } + // Check the mesh index. if (index_mesh < 0 || index_mesh >= meshes.size()) { set_errmsg("Index in 'meshes' array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - auto mesh_filt = static_cast(filt); - mesh_filt->mesh_ = index_mesh; - if (filt->type() == "mesh") { - mesh_filt->n_bins_ = 1; - } else { - filt->n_bins_ = 4 * meshes[index_mesh]->n_dimension_; - } - for (auto dim : meshes[index_mesh]->shape_) mesh_filt->n_bins_ *= dim; + // Update the filter. + filt->set_mesh(index_mesh); filter_update_n_bins(index); return 0; } diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp index aafa91e6e..8074b4a4c 100644 --- a/src/tallies/filter_meshsurface.cpp +++ b/src/tallies/filter_meshsurface.cpp @@ -7,14 +7,6 @@ namespace openmc { -void -MeshSurfaceFilter::from_xml(pugi::xml_node node) -{ - MeshFilter::from_xml(node); - n_bins_ = 4 * meshes[mesh_]->n_dimension_;; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; -} - void MeshSurfaceFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const @@ -79,6 +71,14 @@ MeshSurfaceFilter::text_label(int bin) const return out; } +void +MeshSurfaceFilter::set_mesh(int32_t mesh) +{ + mesh_ = mesh; + n_bins_ = 4 * meshes[mesh_]->n_dimension_; + for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; +} + //============================================================================== // C-API functions //============================================================================== diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp index 1c085bcce..764c56223 100644 --- a/src/tallies/filter_sph_harm.cpp +++ b/src/tallies/filter_sph_harm.cpp @@ -1,5 +1,7 @@ #include "openmc/tallies/filter_sph_harm.h" +#include // For pair + #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -87,37 +89,52 @@ SphericalHarmonicsFilter::text_label(int bin) const // C-API functions //============================================================================== +std::pair +check_sphharm_filter(int32_t index) +{ + // Make sure this is a valid index to an allocated filter. + int err = verify_filter(index); + if (err) { + return {err, nullptr}; + } + + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Not a spherical harmonics filter."); + err = OPENMC_E_INVALID_TYPE; + } + return {err, filt}; +} + extern "C" int openmc_sphharm_filter_get_order(int32_t index, int* order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sphharm_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - *order = sph_filt->order_; + // Output the order. + *order = filt->order_; return 0; } extern "C" int openmc_sphharm_filter_get_cosine(int32_t index, char cosine[]) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sphharm_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - if (sph_filt->cosine_ == SphericalHarmonicsCosine::scatter) { + // Output the cosine. + if (filt->cosine_ == SphericalHarmonicsCosine::scatter) { strcpy(cosine, "scatter"); } else { strcpy(cosine, "particle"); @@ -128,18 +145,15 @@ openmc_sphharm_filter_get_cosine(int32_t index, char cosine[]) extern "C" int openmc_sphharm_filter_set_order(int32_t index, int order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sphharm_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); - sph_filt->order_ = order; - sph_filt->n_bins_ = (order + 1) * (order + 1); + // Update the filter. + filt->order_ = order; + filt->n_bins_ = (order + 1) * (order + 1); filter_update_n_bins(index); return 0; } @@ -147,20 +161,17 @@ openmc_sphharm_filter_set_order(int32_t index, int order) extern "C" int openmc_sphharm_filter_set_cosine(int32_t index, const char cosine[]) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sphharm_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "sphericalharmonics") { - set_errmsg("Not a spherical harmonics filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto sph_filt = static_cast(filt); + // Update the filter. if (strcmp(cosine, "scatter") == 0) { - sph_filt->cosine_ = SphericalHarmonicsCosine::scatter; + filt->cosine_ = SphericalHarmonicsCosine::scatter; } else if (strcmp(cosine, "particle") == 0) { - sph_filt->cosine_ = SphericalHarmonicsCosine::particle; + filt->cosine_ = SphericalHarmonicsCosine::particle; } else { set_errmsg("Invalid spherical harmonics cosine."); return OPENMC_E_INVALID_ARGUMENT; diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp index 4043a4389..3f93be1cb 100644 --- a/src/tallies/filter_sptl_legendre.cpp +++ b/src/tallies/filter_sptl_legendre.cpp @@ -1,5 +1,7 @@ #include "openmc/tallies/filter_sptl_legendre.h" +#include // For pair + #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -94,20 +96,38 @@ SpatialLegendreFilter::text_label(int bin) const // C-API functions //============================================================================== +std::pair +check_sptl_legendre_filter(int32_t index) +{ + // Make sure this is a valid index to an allocated filter. + int err = verify_filter(index); + if (err) { + return {err, nullptr}; + } + + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Not a spatial Legendre filter."); + err = OPENMC_E_INVALID_TYPE; + } + return {err, filt}; +} + extern "C" int openmc_spatial_legendre_filter_get_order(int32_t index, int* order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sptl_legendre_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - *order = l_filt->order_; + // Output the order. + *order = filt->order_; return 0; } @@ -115,37 +135,31 @@ extern "C" int openmc_spatial_legendre_filter_get_params(int32_t index, int* axis, double* min, double* max) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sptl_legendre_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - *axis = static_cast(l_filt->axis_); - *min = l_filt->min_; - *max = l_filt->max_; + // Output the params. + *axis = static_cast(filt->axis_); + *min = filt->min_; + *max = filt->max_; return 0; } extern "C" int openmc_spatial_legendre_filter_set_order(int32_t index, int order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sptl_legendre_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - l_filt->order_ = order; - l_filt->n_bins_ = order + 1; + // Update the filter. + filt->order_ = order; + filt->n_bins_ = order + 1; filter_update_n_bins(index); return 0; } @@ -154,19 +168,16 @@ extern "C" int openmc_spatial_legendre_filter_set_params(int32_t index, const int* axis, const double* min, const double* max) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_sptl_legendre_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "spatiallegendre") { - set_errmsg("Not a spatial Legendre filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto l_filt = static_cast(filt); - if (axis) l_filt->axis_ = static_cast(*axis); - if (min) l_filt->min_ = *min; - if (max) l_filt->max_ = *max; + // Update the filter. + if (axis) filt->axis_ = static_cast(*axis); + if (min) filt->min_ = *min; + if (max) filt->max_ = *max; return 0; } diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp index ed658e2d2..198bd8cb7 100644 --- a/src/tallies/filter_zernike.cpp +++ b/src/tallies/filter_zernike.cpp @@ -2,6 +2,7 @@ #include #include +#include // For pair #include "openmc/capi.h" #include "openmc/error.h" @@ -119,20 +120,38 @@ ZernikeRadialFilter::set_order(int order) // C-API functions //============================================================================== +std::pair +check_zernike_filter(int32_t index) +{ + // Make sure this is a valid index to an allocated filter. + int err = verify_filter(index); + if (err) { + return {err, nullptr}; + } + + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Not a Zernike filter."); + err = OPENMC_E_INVALID_TYPE; + } + return {err, filt}; +} + extern "C" int openmc_zernike_filter_get_order(int32_t index, int* order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_zernike_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - *order = z_filt->order(); + // Output the order. + *order = filt->order(); return 0; } @@ -140,36 +159,30 @@ extern "C" int openmc_zernike_filter_get_params(int32_t index, double* x, double* y, double* r) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_zernike_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - *x = z_filt->x_; - *y = z_filt->y_; - *r = z_filt->r_; + // Output the params. + *x = filt->x_; + *y = filt->y_; + *r = filt->r_; return 0; } extern "C" int openmc_zernike_filter_set_order(int32_t index, int order) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_zernike_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - z_filt->set_order(order); + // Update the filter. + filt->set_order(order); filter_update_n_bins(index); return 0; } @@ -178,19 +191,16 @@ extern "C" int openmc_zernike_filter_set_params(int32_t index, const double* x, const double* y, const double* r) { - int err = verify_filter(index); + // Check the filter. + auto check_result = check_zernike_filter(index); + auto err = check_result.first; + auto filt = check_result.second; if (err) return err; - auto filt = filter_from_f(index); - if (filt->type() != "zernike" && filt->type() != "zernikeradial") { - set_errmsg("Not a Zernike filter."); - return OPENMC_E_INVALID_TYPE; - } - - auto z_filt = static_cast(filt); - if (x) z_filt->x_ = *x; - if (y) z_filt->y_ = *y; - if (r) z_filt->r_ = *r; + // Update the filter. + if (x) filt->x_ = *x; + if (y) filt->y_ = *y; + if (r) filt->r_ = *r; return 0; }