cp-f
January 3, 2022, 2:45pm
1
Hey,
I want to use the customized source to model more complicated source geometries in combination with giving a list of energies and their intensities, as I describe here:
opened 04:35PM - 30 Dec 21 UTC
Maybe somebody is already working on that:
Defining a gamma source from radio… active isotopes directly is currently not possible (to the best of my knowledge). To do so, you need to figure out the gammas created in the decay chain (for example, with PyNE `material.gammas()`) and then use the
`source.energy = openmc.stats.Discrete(energy_list, intensity_list)` functionality. The entries of the first list indicate the respective energies of the photons, and the entries of the second list indicate which relative intensity these particles have.
When I am doing this, I am working with PyNE or using the LANA data from
http://www.lnhb.fr/donnees-nucleaires/donnees-nucleaires-tableau/.
I think it could be a helpful feature to extend the Python API to have the option to specify gamma sources as radioactive isotopes. We could define the source material as the other materials are defined in OpenMC. Probably at one point we need to state which total amount of material we have.
There are some things I am not sure about:
- Perhaps it is enough to do this entirely in the Python API part of the simulation? This will then create again the `<energy type="discrete">` distribution in the xml file.
- We would probably need to provide the gamma emission data, similar to cross-sections and decay chains. (I extracted the data to python dictionaries, I am happy to share the .pickle files.), but probably for OpenMC hdf5 is the standard?
Best
Christopher
Is there a way to define this in the customized source, or is the customized source so far only capable of modeling particles with one specific energy, as in the example:
Or would I have to implement it somehow so that I also select a random value from an energy list and weight that somehow with the intensity?
Thanks a lot!
Best
Christopher
Hi @cp-f ! Yes, you would have to implement the sampling of the energy/intensity within the custom source itself. However, note that there is a class in OpenMC that handles this, so it should be as simple as feeding the energies/intensities to that class and then calling sample(seed)
on it:
class Discrete : public Distribution {
public:
explicit Discrete(pugi::xml_node node);
Discrete(const double* x, const double* p, int n);
//! Sample a value from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
// Properties
const vector<double>& x() const { return x_; }
const vector<double>& p() const { return p_; }
private:
vector<double> x_; //!< Possible outcomes
vector<double> p_; //!< Probability of each outcome
//! Normalize distribution so that probabilities sum to unity
void normalize();
};
ZENGJIE
December 25, 2023, 7:41am
5
paulromano:
Yes, you would have to implement the sampling of the energy/intensity within the custom source itself. However, note that there is a class in OpenMC that handles this, so it should be as simple as feeding the energies/intensities to that class and then calling sample(seed)
on it:
@ paulromano,hello!
I refer to this function, However, when the energy spectrum of the surface is counted, the count of each group of the energy spectrum is 0.
The input file for CustomSource is as follows:
#include <memory> // for unique_ptr
#include <cmath> // for M_PI
#include "openmc/source.h"
#include "openmc/particle.h"
#include "openmc/random_lcg.h"
#include "openmc/distribution_multi.h"
class CustomSource : public openmc::Source
{
public:
CustomSource(double energy) : energy_{energy}
{
explicit Discrete(pugi::xml_node node);
Discrete(const double* x=[0, 1.000E-03,1.307E-02,2.115E-01,3.423E+00,2.914E+01,3.807E+02,2.112E+03,2.760E+04,1.896E+05,1.303E+06],
const double* p=[0.1,0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0 ],
int 10);
double sample(uint64_t* seed) const;
// Properties
const vector<double>& x() const { return x_; }
const vector<double>& p() const { return p_; }
private:
vector<double> x_; //!< Possible outcomes
vector<double> p_; //!< Probability of each outcome
//! Normalize distribution so that probabilities sum to unity
void normalize();
}
// Samples from an instance of this class.
openmc::SourceSite sample(uint64_t* seed) const
{
openmc::SourceSite particle;
// weight
particle.particle = openmc::ParticleType::neutron;
particle.wgt = 1.0;
// position
double r_min =1.0;
double r_max =7.5;
double radius_sq = r_min*r_min + openmc::prn(seed)*(r_max*r_max - r_min*r_min);
double radius = std::sqrt(radius_sq);
//角度为0~360之间的任何值
double angle = 2* M_PI * openmc::prn(seed);
//初始源空间位置抽样
particle.r.x = radius * std::cos(angle);
particle.r.y = radius * std::sin(angle);
particle.r.z = 0.0;
// angle
particle.u = {0, 0, 1};
particle.E = this->energy_;
//particle.E = 14.08;
particle.delayed_group = 0;
return particle;
}
};
extern "C" std::unique_ptr<CustomSource> openmc_create_source(std::string parameter)
{
double energy = std::stod(parameter);
return std::make_unique<CustomSource>();
}
Excuse me, how can I modify it?
Thanks a lot!
ZENGJIE
December 25, 2023, 7:43am
6
@ paulromano,hello!
In addition, there are multiple concentric sources of this sample (custom sources) merged into a source, and what method to write?
Thanks a lot!
ZENGJIE
December 26, 2023, 1:18am
7
@ cp-f hello!
May I ask, have you solved this problem? If so, how did you solve it?