1212! Full instructions on compiling and using MCNP5 with this subroutine are found
1313! in the PyNE user manual.
1414
15- function find_cell () result(icl_tmp)
16- ! This function to determines the current MCNP cell index location and exits if
17- ! no valid cell is found. This only works if there are no repeated geometries or
18- ! universes present in the model.
15+ function find_cell (cell_list , cell_list_size ) result(icl_tmp)
16+ ! This function determines the current MCNP cell index location.
17+ ! Return a positive integer if a valid cell is found, otherwise it returns -1.
18+ ! This only works if there are no repeated geometries or universes present in
19+ ! the model.
20+ ! Parameters:
21+ ! cell_list: array of integers. Contains cell numbers that the source
22+ ! particle possiblely located.
23+ ! cell_list_size: integer. Size of the cell_list.
24+ !
25+ ! There are 3 types of not found icl_tmp (icl_tmp == -1):
26+ ! - Type 1: Sorce particle is located in a cell that exist in neutron transport
27+ ! but removed in photon transport. Therefore, the cell number does
28+ ! not exist in the ncl list.
29+ ! This is not an error, happens with small frequency.
30+ ! Skip it and resample next particle without warning message.
31+ ! - Type 2: Source particle is not located in the given cell_list for HEX
32+ ! mesh cases (both voxel and sub-voxel). Because cell_list from
33+ ! discretize_geom() missed some cells with very small volume
34+ ! fractions.
35+ ! This is caused by random error, happens with small frequency.
36+ ! Skip it andd resample next particle with warning message.
37+ ! - Type 3: Source partilce with a specific coordinates can't be found in any
38+ ! cell from ncl(1) to ncl(mxa).
39+ ! This is an error. When this error happens, it means that there is
40+ ! something wrong in either the source.F90 file or the DAGMC
41+ ! geometry representation. It happens with low frenquency for some
42+ ! complex geometry. The results is suspicious under this condition.
43+ ! Skip it and resample next particle with error message.
44+
1945
2046 use mcnp_global
2147 use mcnp_debug
2248 ! xxx,yyy,zzz are global variables
2349 ! mxa is global
2450 integer :: i ! iterator variable
25- integer :: j ! tempory cell test
51+ integer :: j ! temporary cell test
2652 integer :: icl_tmp ! temporary cell variable
53+ integer , intent (in ) :: cell_list_size
54+ integer , dimension (cell_list_size), intent (in ) :: cell_list
55+ integer :: cidx ! cell index
56+
2757 icl_tmp = - 1
58+ ! If the cell_list is given (for HEX mesh),
59+ ! use it to find cell first
60+ if (cell_list_size > 0 ) then
61+ ! HEX mesh. VOXEL/SUBVOXEL
62+ do i = 1 , cell_list_size
63+ if (cell_list(i) .le. 0 ) then
64+ ! not a valid cell number (-1)
65+ exit
66+ endif
67+ cidx = namchg(1 , cell_list(i))
68+ if (cidx .eq. 0 ) then
69+ ! Type 1: cell index not found, skip and resampling
70+ exit
71+ endif
72+ call chkcel(cidx, 0 , j)
73+ if (j .eq. 0 ) then
74+ ! valid cell found
75+ icl_tmp = cidx
76+ exit
77+ endif
78+ enddo
79+ endif
2880
29- do i = 1 , mxa
30- call chkcel(i, 0 , j)
31- if (j .eq. 0 ) then
32- ! valid cel set
33- icl_tmp = i
34- ! icl now set to be valid cell
35- exit
81+ ! If the icl_tmp is not found yet (for HEX mesh), type 2 or type 3 happens,
82+ ! or the cell_list is not given (for TET mesh),
83+ ! find it in the entire list of cells
84+ if ((icl_tmp == - 1 ) .or. (cell_list_size .eq. 0 )) then
85+ do i = 1 , mxa
86+ call chkcel(i, 0 , j)
87+ if (j .eq. 0 ) then
88+ ! valid cell found
89+ icl_tmp = i
90+ if (cell_list_size > 0 ) then
91+ ! this is a type 2 problem, skip
92+ ! reset the icl_tmp to -1 because of the type 2 not found
93+ icl_tmp = - 1
94+ endif
95+ exit
96+ endif
97+ enddo
98+ ! icl now is -1, it is a type 3 error.
99+ ! Skip and print error message
100+ if (icl_tmp .le. 0 ) then
101+ write (* ,* ) ' ERROR: history ' , nps, ' at position ' , xxx, yyy, zzz, ' not in any cell'
102+ write (* ,* ) ' Skipping and resampling the source particle'
36103 endif
37- enddo
38-
39- ! icl now is -1
40- if (icl_tmp .le. 0 ) then
41- write (* ,* ) ' history ' , nps, ' at position ' , xxx, yyy, zzz, ' not in any cell'
42- write (* ,* ) ' Skipping and resampling the source particle'
43104 endif
44-
45105end function find_cell
46106
47107subroutine source
@@ -52,16 +112,19 @@ subroutine source
52112 implicit real (dknd) (a- h,o- z)
53113 logical , save :: first_run = .true.
54114 real (dknd), dimension (6 ) :: rands
55- integer :: icl_tmp ! temporary cell variable
115+ integer :: icl_tmp ! temporary cell index variable
56116 integer :: find_cell
57117 integer :: tries
58- integer :: cell_num
118+ integer , save :: cell_list_size = 0
119+ integer , dimension (:), allocatable , save :: cell_list
59120
60121 if (first_run .eqv. .true. ) then
61- call sampling_setup(idum(1 ))
122+ ! set up, and return cell_list_size to create a cell_list
123+ call sampling_setup(idum(1 ), cell_list_size)
124+ allocate (cell_list(cell_list_size))
62125 first_run = .false.
63126 endif
64-
127+
65128100 continue
66129 tries = 0
67130 rands(1 ) = rang() ! sample alias table
@@ -72,31 +135,31 @@ subroutine source
72135 rands(4 ) = rang() ! sample y
73136 rands(5 ) = rang() ! sample z
74137
75- cell_num = - 1
76- call particle_birth(rands, xxx, yyy, zzz, erg, wgt, cell_num)
77- icl_tmp = find_cell()
138+ call particle_birth(rands, xxx, yyy, zzz, erg, wgt, cell_list)
139+ ! Loop over cell_list to find icl_tmp
140+ icl_tmp = find_cell(cell_list, cell_list_size )
78141
79- ! update tries and resampling if icl_tmp == -1
80- if (icl_tmp .eq. - 1 ) then
81- tries = tries + 1
82- goto 200
142+ ! check whether this is a valid cell
143+ if (icl_tmp .le. 0 ) then
144+ goto 300
83145 endif
84-
85- if (idum( 1 ) > 2 ) then
86- if (cell_num .ne. ncl (icl_tmp) .and. tries < idum( 2 ) ) then
87- tries = tries + 1
88- goto 200
89- endif
146+
147+ ! check whether the material of sampled cell is void
148+ if (mat (icl_tmp).eq. 0 ) then
149+ goto 300
150+ else
151+ goto 400
90152 endif
91- if (mat(icl_tmp).eq. 0 .and. tries < idum(2 )) then
92- tries = tries + 1
93- goto 200
94- end if
95153
96- if (tries.eq. idum(2 )) then
154+ 300 continue
155+ tries = tries + 1
156+ if (tries < idum(2 )) then
157+ goto 200
158+ else
97159 goto 100
98- end if
160+ endif
99161
162+ 400 continue
100163 icl = icl_tmp
101164 tme = 0.0
102165 ipt = idum(3 )
0 commit comments