Skip to content

Commit d25bb8c

Browse files
committed
Merge branch 'feature/fluorescence' into 'develop'
Feature/fluorescence See merge request njoy/dryad!116
2 parents 6b3f572 + 1f260e5 commit d25bb8c

34 files changed

+66257
-49
lines changed

cmake/unit_testing.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ add_cpp_test( dryad.format.ace.electroatomic.createAceBremsstrahlungBlock
154154

155155
add_cpp_test( dryad.format.ace.photoatomic.createAcePrincipalCrossSectionBlock dryad/format/ace/photoatomic/createAcePrincipalCrossSectionBlock.test.cpp )
156156
add_cpp_test( dryad.format.ace.photoatomic.createAcePhotoelectricCrossSectionBlock dryad/format/ace/photoatomic/createAcePhotoelectricCrossSectionBlock.test.cpp )
157+
add_cpp_test( dryad.format.ace.photoatomic.createAceFluorescenceDataBlock dryad/format/ace/photoatomic/createAceFluorescenceDataBlock.test.cpp )
157158
add_cpp_test( dryad.format.ace.photoatomic.createAceIncoherentScatteringFunctionBlock dryad/format/ace/photoatomic/createAceIncoherentScatteringFunctionBlock.test.cpp )
158159
add_cpp_test( dryad.format.ace.photoatomic.createAceComptonProfileBlock dryad/format/ace/photoatomic/createAceComptonProfileBlock.test.cpp )
159160
add_cpp_test( dryad.format.ace.photoatomic.createAceCoherentFormFactorBlock dryad/format/ace/photoatomic/createAceCoherentFormFactorBlock.test.cpp )

docs/src/dryad/atomic/ElectronSubshellConfiguration.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. currentmodule:: njoy.dryad.atomic
22

33

4-
ElectronSubshellConfiguration
4+
ElectronSubshellConfiguration
55
=============================
66

77
General information about the concept
@@ -32,16 +32,22 @@ Read-only Attributes
3232

3333
~ElectronSubshellConfiguration.number_radiative_transitions
3434
~ElectronSubshellConfiguration.number_non_radiative_transitions
35-
~ElectronSubshellConfiguration.number_transitions
35+
~ElectronSubshellConfiguration.number_transitions
3636
~ElectronSubshellConfiguration.has_radiative_transitions
3737
~ElectronSubshellConfiguration.has_non_radiative_transitions
3838
~ElectronSubshellConfiguration.has_transitions
3939
~ElectronSubshellConfiguration.total_radiative_probability
4040
~ElectronSubshellConfiguration.total_non_radiative_probability
41+
~ElectronSubshellConfiguration.average_radiative_energy
42+
~ElectronSubshellConfiguration.average_non_radiative_energy
4143

4244
Methods
4345
~~~~~~~
4446
.. autosummary::
4547
:toctree: generated/
4648

49+
~ElectronSubshellConfiguration.has_radiative_transition
50+
~ElectronSubshellConfiguration.has_non_radiative_transition
51+
~ElectronSubshellConfiguration.radiative_transition
52+
~ElectronSubshellConfiguration.non_radiative_transition
4753
~ElectronSubshellConfiguration.normalise

python/src/dryad/atomic/ElectronSubshellConfiguration.python.cpp

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ void wrapElectronSubshellConfiguration( python::module& module ) {
3434
" - the electron population, i.e. the number of electrons in the subshell\n"
3535
" when the atom is neutral (given as a floating point number)\n"
3636
" - the decay modes or transitions that can fill a hole in this shell\n\n"
37-
"If there are transitions defined, the transition probabilities\n"
38-
"can be normalised to 1 upon construction.\n\n"
37+
"If there are transitions defined, the transition probabilities can be\n"
38+
"normalised to 1 upon construction. Transitions are always sorted at\n"
39+
"construction time (by originating shell for radiative transitions and\n"
40+
"by originating and emitting shell for non-radiative transitions).\n\n"
3941
"Parameters\n"
4042
"----------\n"
4143
" id : njoy.dryad.id.ElectronSubshellID \n"
@@ -123,6 +125,60 @@ void wrapElectronSubshellConfiguration( python::module& module ) {
123125
&Component::hasTransitions,
124126
"Flag to indicate whether or not transitions are available"
125127
)
128+
.def(
129+
130+
"has_radiative_transition",
131+
&Component::hasRadiativeTransition,
132+
python::arg( "originating_shell" ),
133+
"Return whether or not a given radiative transition is present\n\n"
134+
"Parameters\n"
135+
"----------\n"
136+
" originating_shell : njoy.dryad.id.ElectronSubshellID\n"
137+
" the identifier of the subshell from which the\n"
138+
" vacancy filling electron originated\n"
139+
)
140+
.def(
141+
142+
"has_non_radiative_transition",
143+
&Component::hasNonRadiativeTransition,
144+
python::arg( "originating_shell" ),
145+
python::arg( "emitting_shell" ),
146+
"Return whether or not a given non-radiative transition is present\n\n"
147+
"Parameters\n"
148+
"----------\n"
149+
" originating_shell : njoy.dryad.id.ElectronSubshellID\n"
150+
" the identifier of the subshell from which the\n"
151+
" vacancy filling electron originated\n"
152+
" emitting_shell : njoy.dryad.id.ElectronSubshellID\n"
153+
" the identifier of the subshell from which the emitted electron originated\n"
154+
)
155+
.def(
156+
157+
"radiative_transition",
158+
&Component::radiativeTransition,
159+
python::arg( "originating_shell" ),
160+
"Return the requested radiative transition\n\n"
161+
"Parameters\n"
162+
"----------\n"
163+
" originating_shell : njoy.dryad.id.ElectronSubshellID\n"
164+
" the identifier of the subshell from which the\n"
165+
" vacancy filling electron originated\n"
166+
)
167+
.def(
168+
169+
"non_radiative_transition",
170+
&Component::nonRadiativeTransition,
171+
python::arg( "originating_shell" ),
172+
python::arg( "emitting_shell" ),
173+
"Return the requested non-radiative transition\n\n"
174+
"Parameters\n"
175+
"----------\n"
176+
" originating_shell : njoy.dryad.id.ElectronSubshellID\n"
177+
" the identifier of the subshell from which the\n"
178+
" vacancy filling electron originated\n"
179+
" emitting_shell : njoy.dryad.id.ElectronSubshellID\n"
180+
" the identifier of the subshell from which the emitted electron originated\n"
181+
)
126182
.def_property(
127183

128184
"radiative_transitions",
@@ -149,6 +205,18 @@ void wrapElectronSubshellConfiguration( python::module& module ) {
149205
&Component::totalNonRadiativeProbability,
150206
"The total non-radiative probability"
151207
)
208+
.def_property_readonly(
209+
210+
"average_radiative_energy",
211+
python::overload_cast<>( &Component::averageRadiativeEnergy, python::const_ ),
212+
"The average radiative energy"
213+
)
214+
.def_property_readonly(
215+
216+
"average_non_radiative_energy",
217+
python::overload_cast<>( &Component::averageNonRadiativeEnergy, python::const_ ),
218+
"The average non-radiative energy"
219+
)
152220
.def(
153221

154222
"normalise",

python/src/dryad/atomic/NonRadiativeTransitionData.python.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ void wrapNonRadiativeTransitionData( python::module& module ) {
3535
"Parameters\n"
3636
"----------\n"
3737
" originating_shell : njoy.dryad.id.ElectronSubshellID\n"
38-
" The identifier of the subshell from which the vacancy filling electron originated\n"
38+
" the identifier of the subshell from which the vacancy filling electron originated\n"
3939
" emitting_shell : njoy.dryad.id.ElectronSubshellID\n"
40-
" The identifier of the subshell from which the emitted electron originated\n"
40+
" the identifier of the subshell from which the emitted electron originated\n"
4141
" probability : float\n"
42-
" The probability of the transition\n"
42+
" the probability of the transition\n"
4343
" energy : float, default none\n"
44-
" The energy of the emitted electron\n\n"
44+
" the energy of the emitted electron\n\n"
4545
);
4646

4747
// wrap the component

python/test/dryad/atomic/Test_ElectronSubshellConfiguration.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ def verify_chunk_without_transitions( self, chunk ) :
2121
self.assertEqual( False, chunk.has_non_radiative_transitions )
2222
self.assertEqual( False, chunk.has_transitions )
2323

24+
self.assertEqual( False, chunk.has_radiative_transition( ElectronSubshellID( 'L1' ) ) )
25+
self.assertEqual( False, chunk.has_radiative_transition( ElectronSubshellID( 'L2' ) ) )
26+
self.assertEqual( False, chunk.has_radiative_transition( ElectronSubshellID( 'L3' ) ) )
27+
28+
self.assertEqual( False, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L1' ) ) )
29+
self.assertEqual( False, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L2' ) ) )
30+
self.assertEqual( False, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L3' ) ) )
31+
self.assertEqual( False, chunk.has_non_radiative_transition( ElectronSubshellID( 'M1' ), ElectronSubshellID( 'L1' ) ) )
32+
2433
self.assertEqual( 0, chunk.number_radiative_transitions )
2534
self.assertEqual( 0, chunk.number_non_radiative_transitions )
2635
self.assertEqual( 0, chunk.number_transitions )
@@ -29,6 +38,8 @@ def verify_chunk_without_transitions( self, chunk ) :
2938

3039
self.assertAlmostEqual( 0, chunk.total_radiative_probability )
3140
self.assertAlmostEqual( 0, chunk.total_non_radiative_probability )
41+
self.assertAlmostEqual( 0, chunk.average_radiative_energy )
42+
self.assertAlmostEqual( 0, chunk.average_non_radiative_energy )
3243

3344
def verify_chunk( self, chunk, normalise ) :
3445

@@ -40,6 +51,15 @@ def verify_chunk( self, chunk, normalise ) :
4051
self.assertEqual( True, chunk.has_non_radiative_transitions )
4152
self.assertEqual( True, chunk.has_transitions )
4253

54+
self.assertEqual( False, chunk.has_radiative_transition( ElectronSubshellID( 'L1' ) ) )
55+
self.assertEqual( True, chunk.has_radiative_transition( ElectronSubshellID( 'L2' ) ) )
56+
self.assertEqual( True, chunk.has_radiative_transition( ElectronSubshellID( 'L3' ) ) )
57+
58+
self.assertEqual( True, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L1' ) ) )
59+
self.assertEqual( True, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L2' ) ) )
60+
self.assertEqual( True, chunk.has_non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L3' ) ) )
61+
self.assertEqual( False, chunk.has_non_radiative_transition( ElectronSubshellID( 'M1' ), ElectronSubshellID( 'L1' ) ) )
62+
4363
self.assertEqual( 2, chunk.number_radiative_transitions )
4464
self.assertEqual( 6, chunk.number_non_radiative_transitions )
4565
self.assertEqual( 8, chunk.number_transitions )
@@ -48,6 +68,54 @@ def verify_chunk( self, chunk, normalise ) :
4868

4969
normalisation = 1.00000015 if normalise else 1.0
5070

71+
radiative0 = chunk.radiative_transition( ElectronSubshellID( 'L2' ) )
72+
radiative1 = chunk.radiative_transition( ElectronSubshellID( 'L3' ) )
73+
self.assertEqual( TransitionType.Radiative, radiative0.type )
74+
self.assertEqual( TransitionType.Radiative, radiative1.type )
75+
self.assertEqual( ElectronSubshellID( 'L2' ), radiative0.originating_shell )
76+
self.assertEqual( ElectronSubshellID( 'L3' ), radiative1.originating_shell )
77+
self.assertAlmostEqual( 0.00190768 / normalisation, radiative0.probability )
78+
self.assertAlmostEqual( 0.00380027 / normalisation, radiative1.probability )
79+
self.assertAlmostEqual( 523.09, radiative0.energy )
80+
self.assertAlmostEqual( 523.13, radiative1.energy )
81+
82+
nonradiative0 = chunk.non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L1' ) )
83+
nonradiative1 = chunk.non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L2' ) )
84+
nonradiative2 = chunk.non_radiative_transition( ElectronSubshellID( 'L1' ), ElectronSubshellID( 'L3' ) )
85+
nonradiative3 = chunk.non_radiative_transition( ElectronSubshellID( 'L2' ), ElectronSubshellID( 'L2' ) )
86+
nonradiative4 = chunk.non_radiative_transition( ElectronSubshellID( 'L2' ), ElectronSubshellID( 'L3' ) )
87+
nonradiative5 = chunk.non_radiative_transition( ElectronSubshellID( 'L3' ), ElectronSubshellID( 'L3' ) )
88+
self.assertEqual( TransitionType.NonRadiative, nonradiative0.type )
89+
self.assertEqual( TransitionType.NonRadiative, nonradiative1.type )
90+
self.assertEqual( TransitionType.NonRadiative, nonradiative2.type )
91+
self.assertEqual( TransitionType.NonRadiative, nonradiative3.type )
92+
self.assertEqual( TransitionType.NonRadiative, nonradiative4.type )
93+
self.assertEqual( TransitionType.NonRadiative, nonradiative5.type )
94+
self.assertEqual( ElectronSubshellID( 'L1' ), nonradiative0.originating_shell )
95+
self.assertEqual( ElectronSubshellID( 'L1' ), nonradiative1.originating_shell )
96+
self.assertEqual( ElectronSubshellID( 'L1' ), nonradiative2.originating_shell )
97+
self.assertEqual( ElectronSubshellID( 'L2' ), nonradiative3.originating_shell )
98+
self.assertEqual( ElectronSubshellID( 'L2' ), nonradiative4.originating_shell )
99+
self.assertEqual( ElectronSubshellID( 'L3' ), nonradiative5.originating_shell )
100+
self.assertEqual( ElectronSubshellID( 'L1' ), nonradiative0.emitting_shell )
101+
self.assertEqual( ElectronSubshellID( 'L2' ), nonradiative1.emitting_shell )
102+
self.assertEqual( ElectronSubshellID( 'L3' ), nonradiative2.emitting_shell )
103+
self.assertEqual( ElectronSubshellID( 'L2' ), nonradiative3.emitting_shell )
104+
self.assertEqual( ElectronSubshellID( 'L3' ), nonradiative4.emitting_shell )
105+
self.assertEqual( ElectronSubshellID( 'L3' ), nonradiative5.emitting_shell )
106+
self.assertAlmostEqual( 0.178644 / normalisation, nonradiative0.probability )
107+
self.assertAlmostEqual( 0.116224 / normalisation, nonradiative1.probability )
108+
self.assertAlmostEqual( 0.230418 / normalisation, nonradiative2.probability )
109+
self.assertAlmostEqual( 0.0110822 / normalisation, nonradiative3.probability )
110+
self.assertAlmostEqual( 0.291115 / normalisation, nonradiative4.probability )
111+
self.assertAlmostEqual( 0.166809 / normalisation, nonradiative5.probability )
112+
self.assertAlmostEqual( 478.82, nonradiative0.energy )
113+
self.assertAlmostEqual( 493.86, nonradiative1.energy )
114+
self.assertAlmostEqual( 493.9 , nonradiative2.energy )
115+
self.assertAlmostEqual( 508.9 , nonradiative3.energy )
116+
self.assertAlmostEqual( 508.94, nonradiative4.energy )
117+
self.assertAlmostEqual( 508.98, nonradiative5.energy )
118+
51119
self.assertEqual( TransitionType.Radiative, chunk.radiative_transitions[0].type )
52120
self.assertEqual( TransitionType.Radiative, chunk.radiative_transitions[1].type )
53121
self.assertEqual( ElectronSubshellID( 'L2' ), chunk.radiative_transitions[0].originating_shell )
@@ -90,6 +158,8 @@ def verify_chunk( self, chunk, normalise ) :
90158

91159
self.assertAlmostEqual( 0.00570795 / normalisation, chunk.total_radiative_probability )
92160
self.assertAlmostEqual( 0.9942922 / normalisation, chunk.total_non_radiative_probability )
161+
self.assertAlmostEqual( 523.116631417584, chunk.average_radiative_energy )
162+
self.assertAlmostEqual( 498.286519214372, chunk.average_non_radiative_energy )
93163

94164
class Test_ElectronSubshellConfiguration( unittest.TestCase ) :
95165
"""Unit test for the ElectronSubshellConfiguration class."""

src/njoy/acer/processElectronPhotonRelaxation.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace acer {
2626
const std::string& filename ) {
2727

2828
if ( photoatomic.interactionType() != dryad::InteractionType::Atomic ||
29-
photoatomic.projectileIdentifier() != dryad::id::ParticleID::neutron() ) {
29+
photoatomic.projectileIdentifier() != dryad::id::ParticleID::photon() ) {
3030

3131
throw std::runtime_error( "The projectile-target is not photoatomic" );
3232
}
@@ -42,6 +42,7 @@ namespace acer {
4242
}
4343

4444
//! @todo verify unionisation of the photoatomic and electroatomic data
45+
//! @todo verify if binding energies of shells appear in total ionisation as jumps
4546
//! @todo verify normalisation?
4647

4748
bool relativistic = true;
@@ -55,7 +56,7 @@ namespace acer {
5556
auto jinc = dryad::format::ace::photoatomic::createAceIncoherentScatteringFunctionBlock( photoatomic );
5657
auto jcoh = dryad::format::ace::photoatomic::createAceCoherentFormFactorBlock( photoatomic );
5758
// auto lhnm = ;
58-
// auto jflo = ;
59+
auto jflo = dryad::format::ace::photoatomic::createAceFluorescenceDataBlock( photoatomic, relaxation );
5960
auto eps = dryad::format::ace::atomic::createAceElectronShellBlock( relativistic, relaxation );
6061
auto swd = dryad::format::ace::photoatomic::createAceComptonProfileBlock( photoatomic );
6162
auto subsh = dryad::format::ace::atomic::createAceElectronSubshellBlock( relaxation );

src/njoy/dryad/AtomicRelaxation.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ namespace dryad {
127127
bool hasSubshell( const id::ElectronSubshellID& id ) const {
128128

129129
auto iter = this->iterator( id );
130-
return iter != this->subshells().end();
130+
return iter != this->subshells().end() && iter->identifier() == id;
131131
}
132132

133133
/**
@@ -139,7 +139,7 @@ namespace dryad {
139139
subshell( const id::ElectronSubshellID& id ) const {
140140

141141
auto iter = this->iterator( id );
142-
if ( ( iter != this->subshells().end() ) && ( iter->identifier() == id ) ) {
142+
if ( iter != this->subshells().end() && iter->identifier() == id ) {
143143

144144
return *iter;
145145
}

0 commit comments

Comments
 (0)