diff --git a/docs/img/Tracks.png b/docs/img/Tracks.png new file mode 100644 index 0000000000..39c83cd595 Binary files /dev/null and b/docs/img/Tracks.png differ diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index d9b43c8214..fcd4bb73c3 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -390,6 +390,15 @@ integers: the batch number, generation number, and particle number. *Default*: None +.. _track: + +```` Element +------------------- + +The ```` element specifies particles for which OpenMC will output binary files describing particle position at every step of its transport. This element should be followed by triplets of integers. Each triplet describes one particle. The integers in each triplet specify the batch number, generation number, and particle number, respectively. + + *Default*: None + ```` Element ------------------------ diff --git a/docs/source/usersguide/processing.rst b/docs/source/usersguide/processing.rst index 7105e9f7d1..94b8a71be0 100644 --- a/docs/source/usersguide/processing.rst +++ b/docs/source/usersguide/processing.rst @@ -345,15 +345,34 @@ Getting Data into MATLAB ------------------------ There is currently no front-end utility to dump tally data to MATLAB files, but -the process is straightforward. First extract the data using a custom Python -script with statepoint.py, put the data into appropriately-shaped numpy arrays, +the process is straightforward. First extract the data using a custom Python script with statepoint.py, put the data into appropriately-shaped numpy arrays, and then use the `Scipy MATLAB IO routines `_ to save to a MAT file. Note that the data contained in the output from ``StatePoint.extract_result`` is already in a Numpy array that can be reshaped and dumped to MATLAB in one step. - +---------------------------- +Particle Track Visualization +---------------------------- + +.. image:: ../../img/Tracks.png + :height: 200px + +OpenMC can dump particle tracks—the position of particles as they are transported through the geometry. There are two ways to make OpenMC output tracks: all particle tracks through a commandline argument or specific particle tracks through settings.xml. + +Running OpenMC with the argument "-tr", "-track", or "--track" will cause a track file to be created for every particle transported in the code. + +The settings.xml file can dictate that specific particle tracks are output. These particles are specified withen a ''track'' element. The ''track'' element should contain triplets of integers specifying the batch, generation, and particle numbers, respectively. For example, to output the tracks for particles 3 and 4 of batch 1 and generation 2 the settings.xml file should contain: + +.. code-block:: xml + + + 1 2 3 + 1 2 4 + + +After running OpenMC, the directory should contain a file of the form "track_(batch #)_(work #).binary" for each particle tracked. These binary track files can be converted into VTK poly data files with the "track.py" utility. The usage of track.py is of the form "track.py [-o OUT] IN" where OUT is the optional output filename and IN is one or more filenames describing track binary files. The default output name is "track.pvtp". A common usage of track.py is "track.py track*.binary" which will use the data from all binary track files in the directory to write a "track.pvtp" VTK output file. The .pvtp file can then be read and plotted by 3d visualization programs such as Paraview. diff --git a/src/global.F90 b/src/global.F90 index a45704f399..79e6ecf71a 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -284,12 +284,14 @@ module global integer :: trace_gen integer(8) :: trace_particle + ! Particle tracks + logical :: write_track = .false. + logical :: write_all_tracks = .false. + integer, allocatable :: track_identifiers(:,:) + ! Particle restart run logical :: particle_restart_run = .false. - ! Particle track output - logical :: write_track = .false. - ! ============================================================================ ! CMFD VARIABLES diff --git a/src/initialize.F90 b/src/initialize.F90 index ce5c457e80..7038544daf 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -378,7 +378,7 @@ contains ! Handle options that would be based to PETSC i = i + 1 case ('-tr', '-track', '--track') - write_track = .true. + write_all_tracks = .true. case default message = "Unknown command line option: " // argv(i) call fatal_error() diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 45abaf9a2e..4ce0512139 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -52,6 +52,7 @@ contains integer :: i ! loop index integer :: n integer :: coeffs_reqd + integer :: n_tracks logical :: file_exists character(MAX_FILE_LEN) :: env_variable character(MAX_WORD_LEN) :: type @@ -383,6 +384,22 @@ contains trace_particle = trace_(3) end if + ! Particle tracks + if (associated(track_)) then + n_tracks = size(track_) + ! Make sure that there are three values per particle + if (mod(n_tracks, 3) /= 0) then + message = "Number of integers specified in 'track' is not divisible & + &by 3. Please provide 3 integers per particle to be tracked." + call fatal_error() + end if + n_tracks = n_tracks/3 + allocate(track_identifiers(3,n_tracks)) + do i=1, n_tracks + track_identifiers(1:3,i) = track_(3*(i-1)+1 : 3*(i-1)+4) + end do + end if + ! Shannon Entropy mesh if (size(entropy_) > 0) then ! Check to make sure enough values were supplied diff --git a/src/output.F90 b/src/output.F90 index 504630d799..c10891f265 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -1994,7 +1994,8 @@ contains character(MAX_FILE_LEN) :: filename filename = trim(path_output) // 'track_' // trim(to_str(current_batch)) & - // '_' // trim(to_str(current_work)) // '.binary' + // '_' // trim(to_str(current_gen)) // '_' // trim(to_str(p % id)) & + // '.binary' open(UNIT=UNIT_TRACK, FILE=filename, STATUS='replace', & ACCESS='stream') diff --git a/src/source.F90 b/src/source.F90 index 9ffea50089..02e1c3b997 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -152,6 +152,7 @@ contains subroutine get_source_particle(index_source) integer(8), intent(in) :: index_source + integer :: i ! iterator index integer(8) :: particle_seed ! unique index for particle type(Bank), pointer :: src => null() @@ -175,6 +176,21 @@ contains if (current_batch == trace_batch .and. current_gen == trace_gen .and. & p % id == trace_particle) trace = .true. + ! Set particle track. + write_track = .false. + if (write_all_tracks) then + write_track = .true. + else if (allocated(track_identifiers)) then + do i=1, size(track_identifiers(1,:)) + if (current_batch == track_identifiers(1,i) .and. & + ¤t_gen == track_identifiers(2,i) .and. & + &p % id == track_identifiers(3,i)) then + write_track = .true. + exit + end if + end do + end if + end subroutine get_source_particle !=============================================================================== diff --git a/src/templates/settings_t.xml b/src/templates/settings_t.xml index 3afa61745e..3903a35143 100644 --- a/src/templates/settings_t.xml +++ b/src/templates/settings_t.xml @@ -59,6 +59,7 @@ +