diff --git a/docs/source/quickinstall.rst b/docs/source/quickinstall.rst index 4d22d15d3c..653ac3d863 100644 --- a/docs/source/quickinstall.rst +++ b/docs/source/quickinstall.rst @@ -8,69 +8,47 @@ This quick install guide outlines the basic steps needed to install OpenMC on your computer. For more detailed instructions on configuring and installing OpenMC, see :ref:`usersguide_install` in the User's Manual. -------------- -Prerequisites -------------- +-------------------------------- +Installing on Ubuntu through PPA +-------------------------------- -In order to compile and run OpenMC, a number of prerequisite software packages -and libraries may be needed. These include: - -- A Fortran compiler such as gfortran_ -- git_ version control software for obtaining source code (*optional*) -- An MPI implementation for parallel runs (*optional*) -- HDF5_ Library for portable binary output format (*optional*) -- PETSc_ for CMFD acceleration (*optional*) - -.. _gfortran: http://gcc.gnu.org/wiki/GFortran -.. _git: http://git-scm.com -.. _HDF5: http://www.hdfgroup.org/HDF5/ -.. _PETSc: http://www.mcs.anl.gov/petsc/ - --------------------- -Obtaining the Source --------------------- - -All OpenMC source code is hosted on GitHub_. The latest version of the OpenMC -source code can be downloaded from GitHub with the following command:: - - git clone git@github.com:mit-crpg/openmc.git - -If you don't have git installed, you can download the source as a zip or tar -file directly from GitHub. - -.. _GitHub: https://github.com/mit-crpg/openmc - -------------------------------- -Compiling on Linux and Mac OS X -------------------------------- - -To compile OpenMC on Linux or Max OS X, run the following commands from within -the root directory of the source code: +For users with Ubuntu 11.10 or later, a binary package for OpenMC is available +through a `Personal Package Archive`_ (PPA) and can be installed through the `APT +package manager`_. Simply enter the following commands into the terminal: .. code-block:: sh - cd src + sudo apt-add-repository ppa:paulromano/staging + sudo apt-get update + sudo apt-get install openmc + +Currently, the binary package does not allow for parallel simulations, HDF5_, or +CMFD acceleration through PETSc_. Users who need such capabilities should build +OpenMC from source as is described in :ref:`usersguide_install`. + +.. _Personal Package Archive: https://launchpad.net/~paulromano/+archive/staging +.. _APT package manager: https://help.ubuntu.com/community/AptGet/Howto +.. _HDF5: http://www.hdfgroup.org/HDF5/ +.. _PETSc: http://www.mcs.anl.gov/petsc/ + +------------------------------------------- +Installing from Source on Linux or Mac OS X +------------------------------------------- + +All OpenMC source code is hosted on GitHub_. If you have git_ and the gfortran_ +compiler installed, you can download and install OpenMC be entering the +following commands in a terminal: + +.. code-block:: sh + + git clone git@github.com:mit-crpg/openmc.git + cd openmc/src make sudo make install This will build an executable named ``openmc`` and install it (by default in /usr/local/bin). --------------------- -Compiling on Windows --------------------- - -To compile OpenMC on a Windows operating system, you will need to first install -Cygwin_, a Linux-like environment for Windows. When configuring Cygwin, make -sure you install both the gfortran compiler as well as git. Once you have -obtained the source code, run the following commands from within the source code -root directory: - -.. code-block:: sh - - cd src - make - -This will build an executable named ``openmc``. - -.. _Cygwin: http://www.cygwin.com/ +.. _GitHub: https://github.com/mit-crpg/openmc +.. _git: http://git-scm.com +.. _gfortran: http://gcc.gnu.org/wiki/GFortran diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 791fcd314a..b701fc3da2 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -4,38 +4,82 @@ Installation and Configuration ============================== -------------- +----------------------------- +Installing on Ubuntu with PPA +----------------------------- + +For users with Ubuntu 11.10 or later, a binary package for OpenMC is available +through a Personal Package Archive (PPA) and can be installed through the APT +package manager. First, add the following PPA to the repository sources: + +.. code-block:: sh + + sudo apt-add-repository ppa:paulromano/staging + +Next, resynchronize the package index files: + +.. code-block:: sh + + sudo apt-get update + +Now OpenMC should be recognized within the repository and can be installed: + +.. code-block:: sh + + sudo apt-get install openmc + +-------------------- +Building from Source +-------------------- + Prerequisites ------------- -In order to compile OpenMC, you will need to have a Fortran compiler installed -on your machine. Since a number of Fortran 2003/2008 features are used in the -code, it is recommended that you use the latest version of whatever compiler you -choose. For gfortran_, it is necessary to use version 4.6.0 or above. +.. admonition:: Required -If you are using Debian or a Debian derivative such as Ubuntu, you can install -the gfortran compiler using the following command:: + * A Fortran compiler such as gfortran_ - sudo apt-get install gfortran + In order to compile OpenMC, you will need to have a Fortran compiler + installed on your machine. Since a number of Fortran 2003/2008 features + are used in the code, it is recommended that you use the latest version of + whatever compiler you choose. For gfortran_, it is necessary to use + version 4.6.0 or above. -To compile with support for parallel runs on a distributed-memory architecture, -you will need to have a valid implementation of MPI installed on your -machine. The code has been tested and is known to work with the latest versions -of both OpenMPI_ and MPICH2_. Note that if using OpenMPI, make sure that ---with-mpi-f90-size is not set to medium or large since this may prevent MPI -calls from completing successfully in OpenMC. OpenMPI and/or MPICH2 can be -installed on Debian derivatives with:: + If you are using Debian or a Debian derivative such as Ubuntu, you can + install the gfortran compiler using the following command:: - sudo apt-get install mpich2 - sudo apt-get install openmpi-bin + sudo apt-get install gfortran -To compile with support for HDF5_ output (highly recommended), you will need to -have HDF5 installed on your computer. The installed version will need to have -been compiled with the same compiler you intend to compile OpenMC with. +.. admonition:: Optional -To enable CMFD acceleration, you will need to have PETSc_ installed on your -computer. The installed version will need to have been compiled with the same -compiler you intend to compile OpenMC with. + * An MPI implementation for distributed-memory parallel runs + + To compile with support for parallel runs on a distributed-memory + architecture, you will need to have a valid implementation of MPI + installed on your machine. The code has been tested and is known to work + with the latest versions of both OpenMPI_ and MPICH2_. Note that if using + OpenMPI, make sure that --with-mpi-f90-size is not set to medium or large + since this may prevent MPI calls from completing successfully in + OpenMC. OpenMPI and/or MPICH2 can be installed on Debian derivatives + with:: + + sudo apt-get install mpich2 + sudo apt-get install openmpi-bin + + * HDF5_ Library for portable binary output format + + To compile with support for HDF5_ output (highly recommended), you will + need to have HDF5 installed on your computer. The installed version will + need to have been compiled with the same compiler you intend to compile + OpenMC with. + + * PETSc_ for CMFD acceleration + + To enable CMFD acceleration, you will need to have PETSc_ installed on + your computer. The installed version will need to have been compiled with + the same compiler you intend to compile OpenMC with. + + * git_ version control software for obtaining source code .. _gfortran: http://gcc.gnu.org/wiki/GFortran .. _OpenMPI: http://www.open-mpi.org @@ -43,7 +87,6 @@ compiler you intend to compile OpenMC with. .. _HDF5: http://www.hdfgroup.org/HDF5/ .. _PETSc: http://www.mcs.anl.gov/petsc/ --------------------- Obtaining the Source -------------------- @@ -63,7 +106,6 @@ repository:: .. _git: http://git-scm.com .. _ssh: http://en.wikipedia.org/wiki/Secure_Shell -------------------- Build Configuration ------------------- @@ -108,7 +150,6 @@ Makefile, you can enter the following from a terminal:: make DEBUG=yes -------------------------------- Compiling on Linux and Mac OS X ------------------------------- @@ -124,12 +165,11 @@ the root directory of the source code: This will build an executable named ``openmc`` and install it (by default in /usr/local/bin). --------------------- Compiling on Windows -------------------- Using Cygwin ------------- +++++++++++++ One option for compiling OpenMC on a Windows operating system is to use Cygwin_, a Linux-like environment for Windows. You will need to first `install @@ -167,7 +207,7 @@ This will build an executable named ``openmc``. .. _install Cygwin: http://cygwin.com/setup.exe Using MinGW ------------ ++++++++++++ An alternate option for installing OpenMC on Windows is using MinGW_, which stands for Minimalist GNU for Windows. An executable for installing the MinGW diff --git a/signal.patch b/signal.patch index b2f34d5752..6ac8ad411c 100644 --- a/signal.patch +++ b/signal.patch @@ -1,5 +1,5 @@ diff --git a/.gitignore b/.gitignore -index 99ecbed..6e86cf7 100644 +index 8aa7c1f..4c50efb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ @@ -11,10 +11,10 @@ index 99ecbed..6e86cf7 100644 # Compiler python objects *.pyc diff --git a/src/Makefile b/src/Makefile -index a5c9237..d6c1bba 100644 +index bab47d2..92f3228 100644 --- a/src/Makefile +++ b/src/Makefile -@@ -33,6 +33,7 @@ GIT_SHA1 = $(shell git log -1 | head -n 1 | awk '{print $$2}') +@@ -43,6 +43,7 @@ GIT_SHA1 = $(shell git log -1 2>/dev/null | head -n 1 | awk '{print $$2}') #=============================================================================== ifeq ($(COMPILER),gnu) @@ -22,7 +22,7 @@ index a5c9237..d6c1bba 100644 F90 = gfortran F90FLAGS := -cpp -fbacktrace -DNO_F2008 LDFLAGS = -@@ -61,6 +62,7 @@ endif +@@ -71,6 +72,7 @@ endif #=============================================================================== ifeq ($(COMPILER),intel) @@ -30,7 +30,7 @@ index a5c9237..d6c1bba 100644 F90 = ifort F90FLAGS := -cpp -warn -assume byterecl -traceback LDFLAGS = -@@ -88,6 +90,7 @@ endif +@@ -98,6 +100,7 @@ endif #=============================================================================== ifeq ($(COMPILER),pgi) @@ -38,7 +38,7 @@ index a5c9237..d6c1bba 100644 F90 = pgf90 F90FLAGS := -Mpreprocess -DNO_F2008 -Minform=inform -traceback LDFLAGS = -@@ -115,6 +118,7 @@ endif +@@ -125,6 +128,7 @@ endif #=============================================================================== ifeq ($(COMPILER),ibm) @@ -46,18 +46,18 @@ index a5c9237..d6c1bba 100644 F90 = xlf2003 F90FLAGS := -WF,-DNO_F2008 -O2 -@@ -206,7 +210,7 @@ distclean: clean +@@ -235,7 +239,7 @@ distclean: clean cd xml-fortran; make clean - cd xml-fortran/templates; make clean + cd templates; make clean clean: - @rm -f *.o *.mod $(program) + @rm -f *.o *.mod *__genmod.f90 $(program) neat: @rm -f *.o *.mod -@@ -220,6 +224,9 @@ neat: +@@ -249,6 +253,9 @@ neat: %.o: %.F90 - $(F90) $(F90FLAGS) -DGIT_SHA1="\"$(GIT_SHA1)\"" -Ixml-fortran -Ixml-fortran/templates -c $< + $(F90) $(F90FLAGS) -DGIT_SHA1="\"$(GIT_SHA1)\"" -Ixml-fortran -Itemplates -c $< +csignal.o: csignal.c + $(CC) -c $< @@ -66,25 +66,25 @@ index a5c9237..d6c1bba 100644 # Dependencies #=============================================================================== diff --git a/src/OBJECTS b/src/OBJECTS -index 0daf0f1..a476eb6 100644 +index d53f0a5..b2a7f52 100644 --- a/src/OBJECTS +++ b/src/OBJECTS -@@ -4,6 +4,7 @@ ace_header.o \ - bank_header.o \ +@@ -15,6 +15,7 @@ cmfd_prod_operator.o \ + cmfd_snes_solver.o \ + constants.o \ cross_section.o \ - criticality.o \ +csignal.o \ - datatypes.o \ - datatypes_header.o \ + dict_header.o \ doppler.o \ -@@ -17,6 +18,7 @@ fixed_source.o \ + eigenvalue.o \ +@@ -28,6 +29,7 @@ fixed_source.o \ geometry.o \ geometry_header.o \ global.o \ +handle_sigint.o \ hdf5_interface.o \ initialize.o \ - intercycle.o \ + interpolation.o \ diff --git a/src/csignal.c b/src/csignal.c new file mode 100644 index 0000000..96bfdb5 @@ -132,10 +132,10 @@ index 0000000..b2f7d1b + +end subroutine handle_sigint diff --git a/src/initialize.F90 b/src/initialize.F90 -index 60c0806..8cac6a5 100644 +index ff3a209..fd2e222 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 -@@ -46,6 +46,10 @@ contains +@@ -42,6 +42,10 @@ contains subroutine initialize_run() @@ -144,5 +144,5 @@ index 60c0806..8cac6a5 100644 + call signal(2, handle_sigint) + ! Start total and initialization timer - call timer_start(time_total) - call timer_start(time_initialize) + call time_total % start() + call time_initialize % start() diff --git a/src/DEPENDENCIES b/src/DEPENDENCIES index b560c374db..7226ecc1c7 100644 --- a/src/DEPENDENCIES +++ b/src/DEPENDENCIES @@ -44,6 +44,7 @@ cmfd_input.o: output.o cmfd_input.o: string.o cmfd_input.o: tally.o cmfd_input.o: tally_header.o +cmfd_input.o: tally_initialize.o cmfd_input.o: templates/cmfd_t.o cmfd_jacobian_operator.o: cmfd_loss_operator.o @@ -161,12 +162,12 @@ global.o: bank_header.o global.o: cmfd_header.o global.o: constants.o global.o: dict_header.o -global.o: list_header.o global.o: geometry_header.o global.o: material_header.o global.o: mesh_header.o global.o: particle_header.o global.o: plot_header.o +global.o: set_header.o global.o: source_header.o global.o: tally_header.o global.o: timer_header.o @@ -214,6 +215,7 @@ input_xml.o: plot_header.o input_xml.o: random_lcg.o input_xml.o: string.o input_xml.o: tally_header.o +input_xml.o: tally_initialize.o input_xml.o: templates/cross_sections_t.o input_xml.o: templates/geometry_t.o input_xml.o: templates/materials_t.o diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index 211d0e1489..d36a234daa 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -57,8 +57,7 @@ contains FILTER_SURFACE, IN_RIGHT, OUT_RIGHT, IN_FRONT, & OUT_FRONT, IN_TOP, OUT_TOP, CMFD_NOACCEL, ZERO, ONE use error, only: fatal_error - use global, only: cmfd, message, n_user_tallies, n_tallies, tallies, & - meshes + use global, only: cmfd, message, n_cmfd_tallies, cmfd_tallies, meshes use mesh, only: mesh_indices_to_bin use mesh_header, only: StructuredMesh use tally_header, only: TallyObject @@ -95,7 +94,7 @@ contains cmfd % openmc_src = ZERO ! associate tallies and mesh - t => tallies(n_user_tallies + 1) + t => cmfd_tallies(1) i_mesh = t % filters(t % find_filter(FILTER_MESH)) % int_bins(1) m => meshes(i_mesh) @@ -105,10 +104,10 @@ contains cmfd % hxyz(3,:,:,:) = m % width(3) ! set z width ! begin loop around tallies - TAL: do ital = n_user_tallies + 1, n_tallies + TAL: do ital = 1, n_cmfd_tallies ! associate tallies and mesh - t => tallies(ital) + t => cmfd_tallies(ital) i_mesh = t % filters(t % find_filter(FILTER_MESH)) % int_bins(1) m => meshes(i_mesh) @@ -135,7 +134,7 @@ contains OUTGROUP: do h = 1,ng ! start tally 1 - TALLY: if (ital == n_user_tallies + 1) then + TALLY: if (ital == 1) then ! reset all bins to 1 t % matching_bins = 1 @@ -180,7 +179,7 @@ contains cmfd % p1scattxs(h,i,j,k))) ! cmfd % diffcof(h,i,j,k) = cmfd % diffusion(h,i,j,k) - else if (ital == n_user_tallies + 2) then + else if (ital == 2) then ! begin loop to get energy out tallies INGROUP: do g = 1, ng @@ -219,7 +218,7 @@ contains end do INGROUP - else + else if (ital == 3) then ! initialize and filter for energy t % matching_bins = 1 diff --git a/src/cmfd_execute.F90 b/src/cmfd_execute.F90 index c9b543d6f9..69a344c48a 100644 --- a/src/cmfd_execute.F90 +++ b/src/cmfd_execute.F90 @@ -469,7 +469,7 @@ contains subroutine cmfd_tally_reset() - use global, only: n_user_tallies, n_tallies, tallies, message + use global, only: n_cmfd_tallies, cmfd_tallies, message use output, only: write_message use tally, only: reset_result @@ -480,11 +480,11 @@ contains call write_message(7) ! begin loop around CMFD tallies - do i = n_user_tallies + 1, n_tallies + do i = 1, n_cmfd_tallies ! reset that tally - tallies(i) % n_realizations = 0 - call reset_result(tallies(i) % results) + cmfd_tallies(i) % n_realizations = 0 + call reset_result(cmfd_tallies(i) % results) end do diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index d2e8fc360b..18e7d1a638 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -188,12 +188,13 @@ contains subroutine create_cmfd_tally() - use error, only: fatal_error, warning + use error, only: fatal_error, warning use global - use mesh_header, only: StructuredMesh + use mesh_header, only: StructuredMesh use string - use tally, only: setup_active_cmfdtallies - use tally_header, only: TallyObject, TallyFilter + use tally, only: setup_active_cmfdtallies + use tally_header, only: TallyObject, TallyFilter + use tally_initialize, only: add_tallies use xml_data_cmfd_t integer :: i ! loop counter @@ -212,22 +213,7 @@ contains ! set global variables if they are 0 (this can happen if there is no tally ! file) - if (n_meshes == 0 .or. n_tallies == 0) then - n_meshes = n_user_meshes + n_cmfd_meshes - n_tallies = n_user_tallies + n_cmfd_tallies - n_analog_tallies = n_user_analog_tallies + n_cmfd_analog_tallies - n_tracklength_tallies = n_user_tracklength_tallies + & - n_cmfd_tracklength_tallies - n_current_tallies = n_user_current_tallies + n_cmfd_current_tallies - end if - - ! Allocate list of pointers for tallies by type - if (.not. allocated(analog_tallies) .and. n_analog_tallies > 0) & - allocate(analog_tallies(n_analog_tallies)) - if (.not. allocated(tracklength_tallies) .and. n_tracklength_tallies > 0) & - allocate(tracklength_tallies(n_tracklength_tallies)) - if (.not. allocated(current_tallies) .and. n_current_tallies > 0) & - allocate(current_tallies(n_current_tallies)) + if (n_meshes == 0) n_meshes = n_user_meshes + n_cmfd_meshes ! allocate mesh if (.not. allocated(meshes)) allocate(meshes(n_meshes)) @@ -332,13 +318,13 @@ contains call mesh_dict % add_key(m % id, n_user_meshes + 1) ! allocate tallies - if (.not. allocated(tallies)) allocate(tallies(n_tallies)) + call add_tallies("cmfd", n_cmfd_tallies) ! begin loop around tallies - do i = n_user_tallies+1, n_tallies + do i = 1, n_cmfd_tallies ! point t to tally variable - t => tallies(i) + t => cmfd_tallies(i) ! set reset property call lower_case(reset_) @@ -369,9 +355,9 @@ contains t % n_nuclide_bins = 1 ! record tally id which is equivalent to loop number - t % id = i + t % id = i_cmfd_tallies + i - if (i == n_user_tallies + 1) then + if (i == 1) then ! set label t % label = "CMFD flux, total, scatter-1, diffusion" @@ -403,10 +389,7 @@ contains t % scatt_order(3) = 1 t % score_bins(4) = SCORE_DIFFUSION - ! Increment the appropriate index and set pointer - analog_tallies(n_user_analog_tallies + 1) = i - - else if (i == n_user_tallies + 2) then + else if (i == 2) then ! set label t % label = "CMFD neutron production" @@ -450,10 +433,7 @@ contains t % score_bins(1) = SCORE_NU_SCATTER t % score_bins(2) = SCORE_NU_FISSION - ! Increment the appropriate index and set pointer - analog_tallies(n_user_analog_tallies + 2) = i - - else if (i == n_user_tallies + 3) then + else if (i == 3) then ! set label t % label = "CMFD surface currents" @@ -501,9 +481,6 @@ contains i_filter_mesh = t % find_filter(FILTER_MESH) t % filters(i_filter_mesh) % n_bins = product(m % dimension + 1) - ! Increment the appropriate index and set pointer - current_tallies(n_user_current_tallies + 1) = i - end if ! deallocate filter bins diff --git a/src/global.F90 b/src/global.F90 index d2e80dfa76..d3cdc58e2f 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -6,12 +6,12 @@ module global use cmfd_header use constants use dict_header, only: DictCharInt, DictIntInt - use list_header, only: ListInt use geometry_header, only: Cell, Universe, Lattice, Surface use material_header, only: Material use mesh_header, only: StructuredMesh use particle_header, only: Particle use plot_header, only: Plot + use set_header, only: SetInt use source_header, only: ExtSource use tally_header, only: TallyObject, TallyMap, TallyResult use timer_header, only: Timer @@ -100,10 +100,19 @@ module global type(StructuredMesh), allocatable, target :: meshes(:) type(TallyObject), allocatable, target :: tallies(:) - ! Pointers for analog, track-length, and surface-current tallies - integer, allocatable :: analog_tallies(:) - integer, allocatable :: tracklength_tallies(:) - integer, allocatable :: current_tallies(:) + ! Pointers for different tallies + type(TallyObject), pointer :: user_tallies(:) => null() + type(TallyObject), pointer :: cmfd_tallies(:) => null() + + ! Starting index (minus 1) in tallies for each tally group + integer :: i_user_tallies = -1 + integer :: i_cmfd_tallies = -1 + + ! Active tally lists + type(SetInt) :: active_analog_tallies + type(SetInt) :: active_tracklength_tallies + type(SetInt) :: active_current_tallies + type(SetInt) :: active_tallies ! Global tallies ! 1) collision estimate of k-eff @@ -115,11 +124,10 @@ module global ! Tally map structure type(TallyMap), allocatable :: tally_maps(:) - integer :: n_meshes = 0 ! # of structured meshes - integer :: n_tallies = 0 ! # of tallies - integer :: n_analog_tallies = 0 ! # of analog tallies - integer :: n_tracklength_tallies = 0 ! # of track-length tallies - integer :: n_current_tallies = 0 ! # of surface current tallies + integer :: n_meshes = 0 ! # of structured meshes + integer :: n_user_meshes = 0 ! # of structured user meshes + integer :: n_tallies = 0 ! # of tallies + integer :: n_user_tallies = 0 ! # of user tallies ! Normalization for statistics integer :: n_realizations = 0 ! # of independent realizations @@ -135,23 +143,6 @@ module global ! Use confidence intervals for results instead of standard deviations logical :: confidence_intervals = .false. - ! ============================================================================ - ! USER TALLY-RELATED VARIABLES - - integer :: n_user_meshes = 0 ! # of structured user meshes - integer :: n_user_tallies = 0 ! # of user tallies - integer :: n_user_analog_tallies = 0 ! # of user analog tallies - integer :: n_user_tracklength_tallies = 0 ! # of user tracklength tallies - integer :: n_user_current_tallies = 0 ! # of user current tallies - - !============================================================================= - ! ACTIVE TALLY-RELATED VARIABLES - - type(ListInt) :: active_analog_tallies - type(ListInt) :: active_tracklength_tallies - type(ListInt) :: active_current_tallies - type(ListInt) :: active_tallies - ! ============================================================================ ! EIGENVALUE SIMULATION VARIABLES @@ -314,9 +305,6 @@ module global ! user-defined tally information integer :: n_cmfd_meshes = 1 ! # of structured meshes integer :: n_cmfd_tallies = 3 ! # of user-defined tallies - integer :: n_cmfd_analog_tallies = 2 ! # of analog tallies - integer :: n_cmfd_tracklength_tallies = 0 ! # of track-length tallies - integer :: n_cmfd_current_tallies = 1 ! # of surface current tallies ! overwrite with 2grp xs logical :: cmfd_run_2grp = .false. @@ -399,9 +387,6 @@ contains ! Deallocate tally-related arrays if (allocated(meshes)) deallocate(meshes) if (allocated(tallies)) deallocate(tallies) - if (allocated(analog_tallies)) deallocate(analog_tallies) - if (allocated(tracklength_tallies)) deallocate(tracklength_tallies) - if (allocated(current_tallies)) deallocate(current_tallies) if (allocated(tally_maps)) deallocate(tally_maps) ! Deallocate energy grid diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 34b8268694..6d3775363b 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -13,6 +13,7 @@ module input_xml use string, only: lower_case, to_str, str_to_int, str_to_real, & starts_with, ends_with use tally_header, only: TallyObject, TallyFilter + use tally_initialize, only: add_tallies implicit none @@ -1228,9 +1229,6 @@ contains integer :: j ! loop over words integer :: k ! another loop index integer :: l ! another loop index - integer :: i_analog ! index in analog_tallies array - integer :: i_tracklength ! index in tracklength_tallies array - integer :: i_current ! index in current_tallies array integer :: id ! user-specified identifier integer :: i_mesh ! index in meshes array integer :: n ! size of arrays in mesh specification @@ -1290,15 +1288,12 @@ contains call warning() else n_user_tallies = size(tally_) - if (cmfd_run) then - n_tallies = n_user_tallies + n_cmfd_tallies - else - n_tallies = n_user_tallies - end if end if ! Allocate tally array - if (n_tallies > 0) allocate(tallies(n_tallies)) + if (n_user_tallies > 0) then + call add_tallies("user", n_user_tallies) + end if ! Check for setting if (separate_ == 'yes') assume_separate = .true. @@ -1986,62 +1981,8 @@ contains end select end if - ! Count number of tallies by type - if (t % type == TALLY_VOLUME) then - if (t % estimator == ESTIMATOR_ANALOG) then - n_user_analog_tallies = n_user_analog_tallies + 1 - elseif (t % estimator == ESTIMATOR_TRACKLENGTH) then - n_user_tracklength_tallies = n_user_tracklength_tallies + 1 - end if - elseif (t % type == TALLY_SURFACE_CURRENT) then - n_user_current_tallies = n_user_current_tallies + 1 - end if - - end do READ_TALLIES - ! ========================================================================== - ! LISTS FOR ANALOG, TRACKLENGTH, CURRENT TALLIES - - ! Determine number of types of tallies - if (cmfd_run) then - n_analog_tallies = n_user_analog_tallies + n_cmfd_analog_tallies - n_tracklength_tallies = n_user_tracklength_tallies + n_cmfd_tracklength_tallies - n_current_tallies = n_user_current_tallies + n_cmfd_current_tallies - else - n_analog_tallies = n_user_analog_tallies - n_tracklength_tallies = n_user_tracklength_tallies - n_current_tallies = n_user_current_tallies - end if - - ! Allocate list of pointers for tallies by type - allocate(analog_tallies(n_analog_tallies)) - allocate(tracklength_tallies(n_tracklength_tallies)) - allocate(current_tallies(n_current_tallies)) - - ! Set indices for tally pointer lists to zero - i_analog = 0 - i_tracklength = 0 - i_current = 0 - - do i = 1, n_user_tallies - t => tallies(i) - - ! Increment the appropriate index and set pointer - if (t % type == TALLY_VOLUME) then - if (t % estimator == ESTIMATOR_ANALOG) then - i_analog = i_analog + 1 - analog_tallies(i_analog) = i - elseif (t % estimator == ESTIMATOR_TRACKLENGTH) then - i_tracklength = i_tracklength + 1 - tracklength_tallies(i_tracklength) = i - end if - elseif (t % type == TALLY_SURFACE_CURRENT) then - i_current = i_current + 1 - current_tallies(i_current) = i - end if - end do - end subroutine read_tallies_xml !=============================================================================== diff --git a/src/set_header.F90 b/src/set_header.F90 index d6358f4178..5180d5b142 100644 --- a/src/set_header.F90 +++ b/src/set_header.F90 @@ -26,6 +26,7 @@ module set_header type(ListInt) :: elements contains procedure :: add => set_add_int + procedure :: clear => set_clear_int procedure :: contains => set_contains_int procedure :: get_item => set_get_item_int procedure :: remove => set_remove_int @@ -37,6 +38,7 @@ module set_header type(ListChar) :: elements contains procedure :: add => set_add_char + procedure :: clear => set_clear_char procedure :: contains => set_contains_char procedure :: get_item => set_get_item_char procedure :: remove => set_remove_char @@ -69,6 +71,24 @@ contains end subroutine set_add_char +!=============================================================================== +! SET_CLEAR removes all items in a set +!=============================================================================== + + subroutine set_clear_int(this) + class(SetInt) :: this + + call this % elements % clear() + + end subroutine set_clear_int + + subroutine set_clear_char(this) + class(SetChar) :: this + + call this % elements % clear() + + end subroutine set_clear_char + !=============================================================================== ! SET_CONTAINS determines if a specified item is in a set !=============================================================================== diff --git a/src/tally.F90 b/src/tally.F90 index 8ecc5a9feb..cf0bc77708 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -65,12 +65,12 @@ contains TALLY_LOOP: do i = 1, active_analog_tallies % size() ! Get index of tally and pointer to tally i_tally = active_analog_tallies % get_item(i) - t => tallies(analog_tallies(i_tally)) + t => tallies(i_tally) ! ======================================================================= ! DETERMINE SCORING BIN COMBINATION - call get_scoring_bins(analog_tallies(i_tally), found_bin) + call get_scoring_bins(i_tally, found_bin) if (.not. found_bin) cycle ! ======================================================================= @@ -466,20 +466,20 @@ contains TALLY_LOOP: do i = 1, active_tracklength_tallies % size() ! Get index of tally and pointer to tally i_tally = active_tracklength_tallies % get_item(i) - t => tallies(tracklength_tallies(i_tally)) + t => tallies(i_tally) ! Check if this tally has a mesh filter -- if so, we treat it separately ! since multiple bins can be scored to with a single track if (t % find_filter(FILTER_MESH) > 0) then - call score_tl_on_mesh(tracklength_tallies(i_tally), distance) + call score_tl_on_mesh(i_tally, distance) cycle end if ! ======================================================================= ! DETERMINE SCORING BIN COMBINATION - call get_scoring_bins(tracklength_tallies(i_tally), found_bin) + call get_scoring_bins(i_tally, found_bin) if (.not. found_bin) cycle ! ======================================================================= @@ -493,8 +493,7 @@ contains filter_index = sum((t % matching_bins - 1) * t % stride) + 1 if (t % all_nuclides) then - call score_all_nuclides(tracklength_tallies(i_tally), flux, & - filter_index) + call score_all_nuclides(i_tally, flux, filter_index) else NUCLIDE_BIN_LOOP: do k = 1, t % n_nuclide_bins @@ -1400,7 +1399,7 @@ contains ! Get pointer to tally i_tally = active_current_tallies % get_item(i) - t => tallies(current_tallies(i_tally)) + t => tallies(i_tally) ! Get index for mesh and surface filters i_filter_mesh = t % find_filter(FILTER_MESH) @@ -1950,22 +1949,20 @@ contains integer :: i ! loop counter - ! append all analog tallies - do i = 1, n_user_analog_tallies - call active_analog_tallies % append(i) - call active_tallies % append(analog_tallies(i)) - end do + do i = 1, n_user_tallies + ! Add tally to active tallies + call active_tallies % add(i_user_tallies + i) - ! append all tracklength tallies - do i = 1, n_user_tracklength_tallies - call active_tracklength_tallies % append(i) - call active_tallies % append(tracklength_tallies(i)) - end do - - ! append all current tallies - do i = 1, n_user_current_tallies - call active_current_tallies % append(i) - call active_tallies % append(current_tallies(i)) + ! Check what type of tally this is and add it to the appropriate list + if (user_tallies(i) % type == TALLY_VOLUME) then + if (user_tallies(i) % estimator == ESTIMATOR_ANALOG) then + call active_analog_tallies % add(i_user_tallies + i) + elseif (user_tallies(i) % estimator == ESTIMATOR_TRACKLENGTH) then + call active_tracklength_tallies % add(i_user_tallies + i) + end if + elseif (user_tallies(i) % type == TALLY_SURFACE_CURRENT) then + call active_current_tallies % add(i_user_tallies + i) + end if end do end subroutine setup_active_usertallies @@ -1978,47 +1975,36 @@ contains integer :: i ! loop counter - ! check to see if actives tallies has been allocated + ! check to see if any of the active tally lists has been allocated if (active_tallies % size() > 0) then message = "Active tallies should not exist before CMFD tallies!" call fatal_error() - end if - - ! check to see if analog tallies have already been allocated - if (active_analog_tallies % size() > 0) then + else if (active_analog_tallies % size() > 0) then message = 'Active analog tallies should not exist before CMFD tallies!' call fatal_error() - end if - - do i = n_user_analog_tallies + 1, & - n_user_analog_tallies + n_cmfd_analog_tallies - call active_analog_tallies % append(i) - call active_tallies % append(analog_tallies(i)) - end do - - ! check to see if tracklength tallies have already been allocated - if (active_tracklength_tallies % size() > 0) then + else if (active_tracklength_tallies % size() > 0) then message = "Active tracklength tallies should not exist before CMFD & &tallies!" call fatal_error() - end if - - do i = n_user_tracklength_tallies + 1, & - n_user_tracklength_tallies + n_cmfd_tracklength_tallies - call active_tracklength_tallies % append(i) - call active_tallies % append(tracklength_tallies(i)) - end do - - ! check to see if current tallies have already been allocated - if (active_current_tallies % size() > 0) then + else if (active_current_tallies % size() > 0) then message = "Active current tallies should not exist before CMFD tallies!" call fatal_error() end if - do i = n_user_current_tallies + 1, & - n_user_current_tallies + n_cmfd_current_tallies - call active_current_tallies % append(i) - call active_tallies % append(current_tallies(i)) + do i = 1, n_cmfd_tallies + ! Add CMFD tally to active tallies + call active_tallies % add(i_cmfd_tallies + i) + + ! Check what type of tally this is and add it to the appropriate list + if (cmfd_tallies(i) % type == TALLY_VOLUME) then + if (cmfd_tallies(i) % estimator == ESTIMATOR_ANALOG) then + call active_analog_tallies % add(i_cmfd_tallies + i) + elseif (cmfd_tallies(i) % estimator == ESTIMATOR_TRACKLENGTH) then + call active_tracklength_tallies % add(i_cmfd_tallies + i) + end if + elseif (cmfd_tallies(i) % type == TALLY_SURFACE_CURRENT) then + call active_current_tallies % add(i_cmfd_tallies + i) + end if end do end subroutine setup_active_cmfdtallies diff --git a/src/tally_initialize.F90 b/src/tally_initialize.F90 index d8e503a85c..04928499e7 100644 --- a/src/tally_initialize.F90 +++ b/src/tally_initialize.F90 @@ -7,6 +7,7 @@ module tally_initialize implicit none private public :: configure_tallies + public :: add_tallies contains @@ -155,4 +156,54 @@ contains end subroutine add_map_element +!=============================================================================== +! ADD_TALLIES extends the tallies array with a new group of tallies and assigns +! pointers to each group. This is called once for user tallies, once for CMFD +! tallies, etc. +!=============================================================================== + + subroutine add_tallies(tally_group, n) + + character(*), intent(in) :: tally_group ! name of tally group + integer, intent(in) :: n ! number of tallies to add + + type(TallyObject), allocatable :: temp(:) ! temporary tallies array + + if (n_tallies == 0) then + ! Allocate tallies array + allocate(tallies(n)) + else + ! Allocate tallies array with increased size + allocate(temp(n_tallies + n)) + + ! Copy original tallies to temporary array + temp(1:n_tallies) = tallies + + ! Move allocation from temporary array + call move_alloc(FROM=temp, TO=tallies) + + end if + + ! Set index for ths tally group + select case(tally_group) + case ("user") + i_user_tallies = n_tallies + case ("cmfd") + i_cmfd_tallies = n_tallies + end select + + ! Set n_tallies + n_tallies = size(tallies) + + ! Reassign pointers for each group -- after the call to move_alloc, any + ! pointers that were associated with tallies before become unassociated + if (i_user_tallies >= 0) then + user_tallies => tallies(i_user_tallies+1 : i_user_tallies+n_user_tallies) + end if + if (i_cmfd_tallies >= 0) then + cmfd_tallies => tallies(i_cmfd_tallies+1 : i_cmfd_tallies+n_cmfd_tallies) + end if + + end subroutine add_tallies + end module tally_initialize