12
12
import openmc .checkvalue as cv
13
13
from .._xml import get_elem_list , get_text
14
14
from ..mesh import MeshBase
15
- from .univariate import PowerLaw , Uniform , Univariate
15
+ from .univariate import PowerLaw , Uniform , Univariate , delta_function
16
16
17
17
18
18
class UnitSphere (ABC ):
@@ -532,6 +532,10 @@ class CylindricalIndependent(Spatial):
532
532
origin: Iterable of float, optional
533
533
coordinates (x0, y0, z0) of the center of the cylindrical reference
534
534
frame. Defaults to (0.0, 0.0, 0.0)
535
+ r_dir : Iterable of float, optional
536
+ Unit vector of the cylinder r axis at phi=0. Defaults to (1.0, 0.0, 0.0).
537
+ z_dir : Iterable of float, optional
538
+ Unit vector of the cylinder z axis direction. Defaults to (0.0, 0.0, 1.0).
535
539
536
540
Attributes
537
541
----------
@@ -545,14 +549,20 @@ class CylindricalIndependent(Spatial):
545
549
origin: Iterable of float, optional
546
550
coordinates (x0, y0, z0) of the center of the cylindrical reference
547
551
frame. Defaults to (0.0, 0.0, 0.0)
552
+ r_dir : Iterable of float, optional
553
+ Unit vector of the cylinder r axis at phi=0. Defaults to (1.0, 0.0, 0.0).
554
+ z_dir : Iterable of float, optional
555
+ Unit vector of the cylinder z axis direction. Defaults to (0.0, 0.0, 1.0).
548
556
549
557
"""
550
558
551
- def __init__ (self , r , phi , z , origin = (0.0 , 0.0 , 0.0 )):
559
+ def __init__ (self , r , phi , z , origin = (0.0 , 0.0 , 0.0 ), r_dir = ( 1.0 , 0.0 , 0.0 ), z_dir = ( 0.0 , 0.0 , 1.0 ) ):
552
560
self .r = r
553
561
self .phi = phi
554
562
self .z = z
555
563
self .origin = origin
564
+ self .z_dir = z_dir
565
+ self .r_dir = r_dir
556
566
557
567
@property
558
568
def r (self ):
@@ -590,6 +600,33 @@ def origin(self, origin):
590
600
cv .check_type ('origin coordinates' , origin , Iterable , Real )
591
601
origin = np .asarray (origin )
592
602
self ._origin = origin
603
+
604
+ @property
605
+ def z_dir (self ):
606
+ return self ._z_dir
607
+
608
+ @z_dir .setter
609
+ def z_dir (self , z_dir ):
610
+ cv .check_type ('z-axis direction' , z_dir , Iterable , Real )
611
+ z_dir = np .asarray (z_dir )
612
+ norm2 = np .dot (z_dir ,z_dir )
613
+ cv .check_greater_than ('z-axis direction magnitude' , norm2 , 0.0 )
614
+ z_dir /= np .sqrt (norm2 )
615
+ self ._z_dir = z_dir
616
+
617
+ @property
618
+ def r_dir (self ):
619
+ return self ._r_dir
620
+
621
+ @r_dir .setter
622
+ def r_dir (self , r_dir ):
623
+ cv .check_type ('r-axis direction' , r_dir , Iterable , Real )
624
+ r_dir = np .asarray (r_dir )
625
+ r_dir -= np .dot (r_dir ,self .z_dir )* self .z_dir
626
+ norm2 = np .dot (r_dir ,r_dir )
627
+ cv .check_greater_than ('r-axis direction magnitude' , norm2 ,0.0 )
628
+ r_dir /= np .sqrt (norm2 )
629
+ self ._r_dir = r_dir
593
630
594
631
def to_xml_element (self ):
595
632
"""Return XML representation of the spatial distribution
@@ -606,6 +643,8 @@ def to_xml_element(self):
606
643
element .append (self .phi .to_xml_element ('phi' ))
607
644
element .append (self .z .to_xml_element ('z' ))
608
645
element .set ("origin" , ' ' .join (map (str , self .origin )))
646
+ element .set ("r_dir" , ' ' .join (map (str , self .r_dir )))
647
+ element .set ("z_dir" , ' ' .join (map (str , self .z_dir )))
609
648
return element
610
649
611
650
@classmethod
@@ -627,7 +666,9 @@ def from_xml_element(cls, elem: ET.Element):
627
666
phi = Univariate .from_xml_element (elem .find ('phi' ))
628
667
z = Univariate .from_xml_element (elem .find ('z' ))
629
668
origin = get_elem_list (elem , "origin" , float )
630
- return cls (r , phi , z , origin = origin )
669
+ r_dir = get_elem_list (elem , "r_dir" , float ) or [1.0 , 0.0 , 0.0 ]
670
+ z_dir = get_elem_list (elem , "z_dir" , float ) or [0.0 , 0.0 , 1.0 ]
671
+ return cls (r , phi , z , origin = origin , r_dir = r_dir , z_dir = z_dir )
631
672
632
673
633
674
class MeshSpatial (Spatial ):
@@ -1086,3 +1127,95 @@ def spherical_uniform(
1086
1127
phis_dist = Uniform (phis [0 ], phis [1 ])
1087
1128
1088
1129
return SphericalIndependent (r_dist , cos_thetas_dist , phis_dist , origin )
1130
+
1131
+
1132
+ def cylindrical_uniform (
1133
+ r_outer : float ,
1134
+ height : float ,
1135
+ r_inner : float = 0.0 ,
1136
+ phis : Sequence [float ] = (0. , 2 * pi ),
1137
+ origin : Sequence [float ] = (0. , 0. , 0. ),
1138
+ r_dir : Sequence [float ] = (1. , 0. , 0. ),
1139
+ z_dir : Sequence [float ] = (0. , 0. , 1. ),
1140
+ ):
1141
+ """Return a uniform spatial distribution over a cylindrical shell.
1142
+
1143
+ This function provides a uniform spatial distribution over a cylindrical
1144
+ shell between `r_inner` and `r_outer`. Optionally, the range of angles
1145
+ can be restricted by the `phis` arguments.
1146
+
1147
+
1148
+ Parameters
1149
+ ----------
1150
+ r_outer : float
1151
+ Outer radius of the cylindrical shell in [cm]
1152
+ height : float
1153
+ Height of the cylindrical shell in [cm]
1154
+ r_inner : float
1155
+ Inner radius of the cylindrical shell in [cm]
1156
+ phis : iterable of float
1157
+ Starting and ending phi coordinates (azimuthal angle) in
1158
+ radians in a reference frame centered at `origin`
1159
+ origin: iterable of float
1160
+ Coordinates (x0, y0, z0) of the center of the cylindrical
1161
+ reference frame for the distribution. Defaults to (0.0, 0.0, 0.0)
1162
+ r_dir : iterable of float
1163
+ Direction of the r-axis at phi=0. Defaults to (1.0, 0.0, 0.0)
1164
+ z_dir :
1165
+ Direction of the z-axis. Defaults to (0.0, 0.0, 1.0)
1166
+
1167
+ Returns
1168
+ -------
1169
+ openmc.stats.CylindricalIndependent
1170
+ Uniform distribution over the cylindrical shell
1171
+ """
1172
+
1173
+ r_dist = PowerLaw (r_inner , r_outer , 1 )
1174
+ phis_dist = Uniform (phis [0 ], phis [1 ])
1175
+ z_dist = Uniform (- height / 2 , height / 2 )
1176
+
1177
+ return CylindricalIndependent (r_dist , phis_dist , z_dist , origin , r_dir , z_dir )
1178
+
1179
+ def ring_uniform (
1180
+ r_outer : float ,
1181
+ r_inner : float = 0.0 ,
1182
+ phis : Sequence [float ] = (0. , 2 * pi ),
1183
+ origin : Sequence [float ] = (0. , 0. , 0. ),
1184
+ r_dir : Sequence [float ] = (1. , 0. , 0. ),
1185
+ z_dir : Sequence [float ] = (0. , 0. , 1. ),
1186
+ ):
1187
+ """Return a uniform spatial distribution over a ring.
1188
+
1189
+ This function provides a uniform spatial distribution over a ring
1190
+ shell between `r_inner` and `r_outer`. Optionally, the range of angles
1191
+ can be restricted by the `phis` arguments.
1192
+
1193
+
1194
+ Parameters
1195
+ ----------
1196
+ r_outer : float
1197
+ Outer radius of the ring in [cm]
1198
+ r_inner : float
1199
+ Inner radius of the ring in [cm]
1200
+ phis : iterable of float
1201
+ Starting and ending phi coordinates (azimuthal angle) in
1202
+ radians in a reference frame centered at `origin`
1203
+ origin: iterable of float
1204
+ Coordinates (x0, y0, z0) of the center of the cylindrical
1205
+ reference frame for the distribution. Defaults to (0.0, 0.0, 0.0)
1206
+ r_dir : iterable of float
1207
+ Direction of the r-axis at phi=0. Defaults to (1.0, 0.0, 0.0)
1208
+ z_dir :
1209
+ Direction of the z-axis. Defaults to (0.0, 0.0, 1.0)
1210
+
1211
+ Returns
1212
+ -------
1213
+ openmc.stats.CylindricalIndependent
1214
+ Uniform distribution over the ring
1215
+ """
1216
+
1217
+ r_dist = PowerLaw (r_inner , r_outer , 1 )
1218
+ phis_dist = Uniform (phis [0 ], phis [1 ])
1219
+ z_dist = delta_function (np .dot (origin ,z_dir ))
1220
+
1221
+ return CylindricalIndependent (r_dist , phis_dist , z_dist , origin , r_dir , z_dir )
0 commit comments