mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
added collision filter
This commit is contained in:
parent
342101e88e
commit
7569139d51
5 changed files with 183 additions and 0 deletions
|
|
@ -320,6 +320,7 @@ list(APPEND libopenmc_SOURCES
|
|||
src/tallies/filter_distribcell.cpp
|
||||
src/tallies/filter_energyfunc.cpp
|
||||
src/tallies/filter_energy.cpp
|
||||
src/tallies/filter_collision.cpp
|
||||
src/tallies/filter_legendre.cpp
|
||||
src/tallies/filter_material.cpp
|
||||
src/tallies/filter_mesh.cpp
|
||||
|
|
|
|||
54
include/openmc/tallies/filter_collision.h
Normal file
54
include/openmc/tallies/filter_collision.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef OPENMC_TALLIES_FILTER_COLLISIONS_H
|
||||
#define OPENMC_TALLIES_FILTER_COLLISIONS_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gsl/gsl>
|
||||
|
||||
#include "openmc/tallies/filter.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
//==============================================================================
|
||||
//! Bins the incident neutron energy.
|
||||
//==============================================================================
|
||||
|
||||
class CollisionFilter : public Filter
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
// Constructors, destructors
|
||||
|
||||
~CollisionFilter() = default;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Methods
|
||||
|
||||
std::string type() const override {return "numCollisions";}
|
||||
|
||||
void from_xml(pugi::xml_node node) override;
|
||||
|
||||
void get_all_bins(const Particle& p, TallyEstimator estimator, FilterMatch& match)
|
||||
const override;
|
||||
|
||||
void to_statepoint(hid_t filter_group) const override;
|
||||
|
||||
std::string text_label(int bin) const override;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Accessors
|
||||
|
||||
const std::vector<int>& bins() const { return bins_; }
|
||||
void set_bins(gsl::span<const int> bins);
|
||||
|
||||
protected:
|
||||
//----------------------------------------------------------------------------
|
||||
// Data members
|
||||
|
||||
std::vector<int> bins_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace openmc
|
||||
#endif // OPENMC_TALLIES_FILTER_COLLISIONS_H
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#include "openmc/tallies/filter_distribcell.h"
|
||||
#include "openmc/tallies/filter_energyfunc.h"
|
||||
#include "openmc/tallies/filter_energy.h"
|
||||
#include "openmc/tallies/filter_collision.h"
|
||||
#include "openmc/tallies/filter_legendre.h"
|
||||
#include "openmc/tallies/filter_material.h"
|
||||
#include "openmc/tallies/filter_mesh.h"
|
||||
|
|
@ -125,6 +126,8 @@ Filter* Filter::create(const std::string& type, int32_t id)
|
|||
return Filter::create<EnergyFunctionFilter>(id);
|
||||
} else if (type == "energy") {
|
||||
return Filter::create<EnergyFilter>(id);
|
||||
} else if (type == "collision") {
|
||||
return Filter::create<CollisionFilter>(id);
|
||||
} else if (type == "energyout") {
|
||||
return Filter::create<EnergyoutFilter>(id);
|
||||
} else if (type == "legendre") {
|
||||
|
|
|
|||
124
src/tallies/filter_collision.cpp
Normal file
124
src/tallies/filter_collision.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include "openmc/tallies/filter_collision.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "openmc/capi.h"
|
||||
#include "openmc/constants.h" // For F90_NONE
|
||||
#include "openmc/mgxs_interface.h"
|
||||
#include "openmc/search.h"
|
||||
#include "openmc/settings.h"
|
||||
#include "openmc/xml_interface.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
//==============================================================================
|
||||
// CollisionFilter implementation
|
||||
//==============================================================================
|
||||
|
||||
void
|
||||
CollisionFilter::from_xml(pugi::xml_node node)
|
||||
{
|
||||
auto bins = get_node_array<int>(node, "bins");
|
||||
this->set_bins(bins);
|
||||
}
|
||||
|
||||
void
|
||||
CollisionFilter::set_bins(gsl::span<const int> bins)
|
||||
{
|
||||
// Clear existing bins
|
||||
bins_.clear();
|
||||
bins_.reserve(bins.size());
|
||||
|
||||
// Copy bins, ensuring they are valid
|
||||
for (gsl::index i = 0; i < bins.size(); ++i) {
|
||||
if (i > 0 && bins[i] <= bins[i-1]) {
|
||||
throw std::runtime_error{"Number of Collisions bins must be monotonically increasing."};
|
||||
}
|
||||
bins_.push_back(bins[i]);
|
||||
}
|
||||
|
||||
n_bins_ = bins_.size();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CollisionFilter::get_all_bins(const Particle& p, TallyEstimator estimator, FilterMatch& match)
|
||||
const
|
||||
{
|
||||
// Get the number of collisions for the particle
|
||||
auto n = p.n_collision_;
|
||||
|
||||
// Bin the collision number. Must fit exactly the desired collision number .
|
||||
if (n >= bins_.front() && n <= bins_.back()) {
|
||||
auto it = find(bins_.begin(), bins_.end(), n);
|
||||
if (it != bins_.end()){
|
||||
size_t bin = it - bins_.begin();
|
||||
if (int(bins_[bin]) == n){
|
||||
match.bins_.push_back(bin);
|
||||
match.weights_.push_back(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CollisionFilter::to_statepoint(hid_t filter_group) const
|
||||
{
|
||||
Filter::to_statepoint(filter_group);
|
||||
write_dataset(filter_group, "bins", bins_);
|
||||
}
|
||||
|
||||
std::string
|
||||
CollisionFilter::text_label(int bin) const
|
||||
{
|
||||
return fmt::format("Collision Number {}", int(bins_[bin]));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// C-API functions
|
||||
//==============================================================================
|
||||
|
||||
extern"C" int
|
||||
openmc_collision_filter_get_bins(int32_t index, const int** energies, size_t* n)
|
||||
{
|
||||
// Make sure this is a valid index to an allocated filter.
|
||||
if (int err = verify_filter(index)) return err;
|
||||
|
||||
// Get a pointer to the filter and downcast.
|
||||
const auto& filt_base = model::tally_filters[index].get();
|
||||
auto* filt = dynamic_cast<CollisionFilter*>(filt_base);
|
||||
|
||||
// Check the filter type.
|
||||
if (!filt) {
|
||||
set_errmsg("Tried to get collision bins on a non-collision filter.");
|
||||
return OPENMC_E_INVALID_TYPE;
|
||||
}
|
||||
|
||||
// Output the bins.
|
||||
*energies = filt->bins().data();
|
||||
*n = filt->bins().size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
openmc_collision_filter_set_bins(int32_t index, size_t n, const int* energies)
|
||||
{
|
||||
// Make sure this is a valid index to an allocated filter.
|
||||
if (int err = verify_filter(index)) return err;
|
||||
|
||||
// Get a pointer to the filter and downcast.
|
||||
const auto& filt_base = model::tally_filters[index].get();
|
||||
auto* filt = dynamic_cast<CollisionFilter*>(filt_base);
|
||||
|
||||
// Check the filter type.
|
||||
if (!filt) {
|
||||
set_errmsg("Tried to set collision bins on a non-collision filter.");
|
||||
return OPENMC_E_INVALID_TYPE;
|
||||
}
|
||||
|
||||
// Update the filter.
|
||||
filt->set_bins({energies, n});
|
||||
return 0;
|
||||
}
|
||||
|
||||
}// namespace openmc
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#include "openmc/tallies/filter_cellfrom.h"
|
||||
#include "openmc/tallies/filter_delayedgroup.h"
|
||||
#include "openmc/tallies/filter_energy.h"
|
||||
#include "openmc/tallies/filter_collision.h"
|
||||
#include "openmc/tallies/filter_legendre.h"
|
||||
#include "openmc/tallies/filter_mesh.h"
|
||||
#include "openmc/tallies/filter_meshsurface.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue