From 62d18e89fb65b6735a53fa211a2465a79d74e4f4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 13:40:16 -0400 Subject: [PATCH 01/84] Extended particle types to have CE and MG types, propogated changes necessary to rest of code so it works as it used to for CE .... at least its supposed to --- src/cross_section.F90 | 4 +- src/eigenvalue.F90 | 2 +- src/geometry.F90 | 39 +++---- src/mesh.F90 | 1 - src/output.F90 | 11 +- src/particle_header.F90 | 120 +++++++++++++++++--- src/particle_restart.F90 | 20 +++- src/particle_restart_write.F90 | 4 +- src/physics.F90 | 201 +++++++++++++++++---------------- src/plot.F90 | 16 +-- src/simulation.F90 | 10 +- src/source.F90 | 4 +- src/tally.F90 | 70 ++++++------ src/track_output.F90 | 6 +- src/tracking.F90 | 31 +++-- 15 files changed, 330 insertions(+), 209 deletions(-) diff --git a/src/cross_section.F90 b/src/cross_section.F90 index 1c56d961e1..1586912a96 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -8,7 +8,7 @@ module cross_section use global use list_header, only: ListElemInt use material_header, only: Material - use particle_header, only: Particle + use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: prn use search, only: binary_search @@ -27,7 +27,7 @@ contains subroutine calculate_xs(p) - type(Particle), intent(inout) :: p + type(Particle_CE), intent(in) :: p integer :: i ! loop index over nuclides integer :: i_nuclide ! index into nuclides array diff --git a/src/eigenvalue.F90 b/src/eigenvalue.F90 index 403347caa1..50d6cabc5e 100644 --- a/src/eigenvalue.F90 +++ b/src/eigenvalue.F90 @@ -10,7 +10,7 @@ module eigenvalue use math, only: t_percentile use mesh, only: count_bank_sites use mesh_header, only: RegularMesh - use particle_header, only: Particle + ! use particle_header, only: Particle_Base use random_lcg, only: prn, set_particle_seed, prn_skip use search, only: binary_search use string, only: to_str diff --git a/src/geometry.F90 b/src/geometry.F90 index e922479b1d..e3058d6e00 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -6,7 +6,8 @@ module geometry &RectLattice, HexLattice use global use output, only: write_message - use particle_header, only: LocalCoord, Particle + use particle_header, only: LocalCoord, Particle_Base, Particle_CE, & + Particle_MG use particle_restart_write, only: write_particle_restart use surface_header use string, only: to_str @@ -32,7 +33,7 @@ contains pure function cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p logical :: in_cell if (c%simple) then @@ -44,7 +45,7 @@ contains pure function simple_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p logical :: in_cell integer :: i @@ -78,7 +79,7 @@ contains pure function complex_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p logical :: in_cell integer :: i @@ -139,7 +140,7 @@ contains subroutine check_cell_overlap(p) - type(Particle), intent(inout) :: p + class(Particle_Base), intent(inout) :: p integer :: i ! cell loop index on a level integer :: j ! coordinate level index @@ -187,9 +188,9 @@ contains recursive subroutine find_cell(p, found, search_cells) - type(Particle), intent(inout) :: p - logical, intent(inout) :: found - integer, optional :: search_cells(:) + class(Particle_Base), intent(inout) :: p + logical, intent(inout) :: found + integer, optional :: search_cells(:) integer :: i ! index over cells integer :: j ! coordinate level index integer :: i_xyz(3) ! indices in lattice @@ -339,8 +340,8 @@ contains !=============================================================================== subroutine cross_surface(p, last_cell) - type(Particle), intent(inout) :: p - integer, intent(in) :: last_cell ! last cell particle was in + class(Particle_Base), intent(inout) :: p + integer, intent(in) :: last_cell ! last cell particle was in real(8) :: u ! x-component of direction real(8) :: v ! y-component of direction @@ -501,8 +502,8 @@ contains subroutine cross_lattice(p, lattice_translation) - type(Particle), intent(inout) :: p - integer, intent(in) :: lattice_translation(3) + class(Particle_Base), intent(inout) :: p + integer, intent(in) :: lattice_translation(3) integer :: j integer :: i_xyz(3) ! indices in lattice logical :: found ! particle found in cell? @@ -574,11 +575,11 @@ contains subroutine distance_to_boundary(p, dist, surface_crossed, lattice_translation, & next_level) - type(Particle), intent(inout) :: p - real(8), intent(out) :: dist - integer, intent(out) :: surface_crossed - integer, intent(out) :: lattice_translation(3) - integer, intent(out) :: next_level + class(Particle_Base), intent(inout) :: p + real(8), intent(out) :: dist + integer, intent(out) :: surface_crossed + integer, intent(out) :: lattice_translation(3) + integer, intent(out) :: next_level integer :: i ! index for surface in cell integer :: j @@ -954,8 +955,8 @@ contains subroutine handle_lost_particle(p, message) - type(Particle), intent(inout) :: p - character(*) :: message + class(Particle_Base), intent(inout) :: p + character(*) :: message ! Print warning and write lost particle file call warning(message) diff --git a/src/mesh.F90 b/src/mesh.F90 index 3d0235d189..9cb8dc5969 100644 --- a/src/mesh.F90 +++ b/src/mesh.F90 @@ -3,7 +3,6 @@ module mesh use constants use global use mesh_header - use particle_header, only: Particle use search, only: binary_search #ifdef MPI diff --git a/src/output.F90 b/src/output.F90 index 55cd5b2a5b..5bb90343c4 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -12,7 +12,7 @@ module output use math, only: t_percentile use mesh_header, only: RegularMesh use mesh, only: mesh_indices_to_bin, bin_to_mesh_indices - use particle_header, only: LocalCoord, Particle + use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use plot_header use string, only: to_upper, to_str use tally_header, only: TallyObject @@ -251,7 +251,7 @@ contains subroutine print_particle(p) - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p integer :: i ! index for coordinate levels type(Cell), pointer :: c @@ -308,7 +308,12 @@ contains ! Display weight, energy, grid index, and interpolation factor write(ou,*) ' Weight = ' // to_str(p % wgt) - write(ou,*) ' Energy = ' // to_str(p % E) + select type(p) + type is (Particle_CE) + write(ou,*) ' Energy = ' // to_str(p % E) + type is (Particle_MG) + write(ou,*) ' Energy Group = ' // to_str(p % g) + end select write(ou,*) ' Delayed Group = ' // to_str(p % delayed_group) write(ou,*) diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 0b9b251ee5..6b4d38845a 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -38,7 +38,7 @@ module particle_header ! geometry !=============================================================================== - type Particle + type, abstract :: Particle_Base ! Basic data integer(8) :: id ! Unique ID integer :: type ! Particle type (n, p, e, etc) @@ -49,7 +49,6 @@ module particle_header ! Other physical data real(8) :: wgt ! particle weight - real(8) :: E ! energy real(8) :: mu ! angle of scatter logical :: alive ! is particle alive? @@ -57,7 +56,6 @@ module particle_header real(8) :: last_xyz(3) ! previous coordinates real(8) :: last_uvw(3) ! previous direction coordinates real(8) :: last_wgt ! pre-collision particle weight - real(8) :: last_E ! pre-collision energy real(8) :: absorb_wgt ! weight absorbed for survival biasing ! What event last took place @@ -92,9 +90,54 @@ module particle_header contains procedure :: initialize => initialize_particle procedure :: clear => clear_particle - procedure :: initialize_from_source - procedure :: create_secondary - end type Particle + procedure(initialize_from_source_), deferred, pass :: initialize_from_source + procedure(create_secondary_), deferred, pass :: create_secondary + end type Particle_Base + + type, extends(Particle_Base) :: Particle_CE + ! Energy Data + real(8) :: E ! post-collision energy + real(8) :: last_E ! pre-collision energy + + contains + procedure :: initialize_from_source => initialize_from_source_ce + procedure :: create_secondary => create_secondary_ce + end type Particle_CE + + type, extends(Particle_Base) :: Particle_MG + ! Energy Data + integer :: g ! post-collision energy group + integer :: last_g ! pre-collision energy group + + contains + procedure :: initialize_from_source => initialize_from_source_mg + procedure :: create_secondary => create_secondary_mg + end type Particle_MG + + abstract interface + +!=============================================================================== +! INITIALIZE_FROM_SOURCE_ returns .true. if the given lattice indices fit within the +! bounds of the lattice. Returns false otherwise. + + subroutine initialize_from_source_(this, src) + import Particle_Base + import Bank + class(Particle_Base), intent(inout) :: this + type(Bank), intent(in) :: src + end subroutine initialize_from_source_ + +!=============================================================================== +! CREATE_SECONDARY_ Generates a secondary particle from this + + subroutine create_secondary_(this, uvw, type) + import Particle_Base + class(Particle_Base), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type + end subroutine create_secondary_ + + end interface contains @@ -105,7 +148,7 @@ contains subroutine initialize_particle(this) - class(Particle) :: this + class(Particle_Base) :: this ! Clear coordinate lists call this % clear() @@ -141,7 +184,7 @@ contains subroutine clear_particle(this) - class(Particle) :: this + class(Particle_Base) :: this integer :: i ! remove any coordinate levels @@ -174,9 +217,9 @@ contains ! fission, or simply as a secondary particle. !=============================================================================== - subroutine initialize_from_source(this, src) - class(Particle), intent(inout) :: this - type(Bank), intent(in) :: src + subroutine initialize_from_source_ce(this, src) + class(Particle_CE), intent(inout) :: this + type(Bank), intent(in) :: src ! set defaults call this % initialize() @@ -191,17 +234,37 @@ contains this % E = src % E this % last_E = src % E - end subroutine initialize_from_source + end subroutine initialize_from_source_ce + + subroutine initialize_from_source_mg(this, src) + class(Particle_MG), intent(inout) :: this + type(Bank), intent(in) :: src + + ! set defaults + call this % initialize() + + ! copy attributes from source bank site + this % wgt = src % wgt + this % last_wgt = src % wgt + this % coord(1) % xyz = src % xyz + this % coord(1) % uvw = src % uvw + this % last_xyz = src % xyz + this % last_uvw = src % uvw + !!! The following requires a MG version of Bank + this % g = src % E + this % last_g = src % E + + end subroutine initialize_from_source_mg !=============================================================================== ! CREATE_SECONDARY stores the current phase space attributes of the particle in ! the secondary bank and increments the number of sites in the secondary bank. !=============================================================================== - subroutine create_secondary(this, uvw, type) - class(Particle), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type + subroutine create_secondary_ce(this, uvw, type) + class(Particle_CE), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type integer :: n @@ -218,6 +281,29 @@ contains this % secondary_bank(n) % E = this % E this % n_secondary = n - end subroutine create_secondary + end subroutine create_secondary_ce + + subroutine create_secondary_mg(this, uvw, type) + class(Particle_MG), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type + + integer :: n + + ! Check to make sure that the hard-limit on secondary particles is not + ! exceeded. + if (this % n_secondary == MAX_SECONDARY) then + call fatal_error("Too many secondary particles created.") + end if + + n = this % n_secondary + 1 + this % secondary_bank(n) % wgt = this % wgt + this % secondary_bank(n) % xyz(:) = this % coord(1) % xyz + this % secondary_bank(n) % uvw(:) = uvw + !!! The following requires a MG version of Bank + this % secondary_bank(n) % E = this % g + this % n_secondary = n + + end subroutine create_secondary_mg end module particle_header diff --git a/src/particle_restart.F90 b/src/particle_restart.F90 index 2e0523d484..fc3eb4393e 100644 --- a/src/particle_restart.F90 +++ b/src/particle_restart.F90 @@ -8,7 +8,7 @@ module particle_restart use global use hdf5_interface, only: file_open, file_close, read_dataset use output, only: write_message, print_particle - use particle_header, only: Particle + use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: set_particle_seed use tracking, only: transport @@ -28,7 +28,7 @@ contains integer(8) :: particle_seed integer :: previous_run_mode - type(Particle) :: p + class(Particle_Base), pointer :: p ! Set verbosity high verbosity = 10 @@ -66,7 +66,7 @@ contains !=============================================================================== subroutine read_particle_restart(p, previous_run_mode) - type(Particle), intent(inout) :: p + class(Particle_Base), intent(inout) :: p integer, intent(inout) :: previous_run_mode integer :: int_scalar @@ -96,7 +96,12 @@ contains end select call read_dataset(file_id, 'id', p%id) call read_dataset(file_id, 'weight', p%wgt) - call read_dataset(file_id, 'energy', p%E) + select type(p) + type is (Particle_CE) + call read_dataset(file_id, 'energy', p%E) + type is (Particle_MG) + call read_dataset(file_id, 'energy_group', p%g) + end select call read_dataset(file_id, 'xyz', p%coord(1)%xyz) call read_dataset(file_id, 'uvw', p%coord(1)%uvw) @@ -104,7 +109,12 @@ contains p%last_wgt = p%wgt p%last_xyz = p%coord(1)%xyz p%last_uvw = p%coord(1)%uvw - p%last_E = p%E + select type(p) + type is (Particle_CE) + p%last_E = p%E + type is (Particle_MG) + p%last_g = p%g + end select ! Close hdf5 file call file_close(file_id) diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index edd779df09..9dff7e5f3b 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -3,7 +3,7 @@ module particle_restart_write use bank_header, only: Bank use global use hdf5_interface - use particle_header, only: Particle + use particle_header, only: Particle_Base use string, only: to_str use hdf5 @@ -19,7 +19,7 @@ contains !=============================================================================== subroutine write_particle_restart(p) - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p integer(HID_T) :: file_id character(MAX_FILE_LEN) :: filename diff --git a/src/physics.F90 b/src/physics.F90 index 581cb04c9d..aae7027bae 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -12,7 +12,7 @@ module physics use math, only: maxwell_spectrum, watt_spectrum use mesh, only: get_mesh_indices use output, only: write_message - use particle_header, only: Particle + use particle_header, only: Particle_Base, Particle_CE, Particle_MG use particle_restart_write, only: write_particle_restart use random_lcg, only: prn use search, only: binary_search @@ -32,7 +32,7 @@ contains subroutine collision(p) - type(Particle), intent(inout) :: p + type(Particle_CE), intent(inout) :: p ! Store pre-collision particle properties p % last_wgt = p % wgt @@ -70,7 +70,7 @@ contains subroutine sample_reaction(p) - type(Particle), intent(inout) :: p + type(Particle_CE), intent(inout) :: p integer :: i_nuclide ! index in nuclides array integer :: i_reaction ! index in nuc % reactions array @@ -123,9 +123,9 @@ contains function sample_nuclide(p, base) result(i_nuclide) - type(Particle), intent(in) :: p - character(7), intent(in) :: base ! which reaction to sample based on - integer :: i_nuclide + class(Particle_Base), intent(in) :: p + character(7), intent(in) :: base ! which reaction to sample based on + integer :: i_nuclide integer :: i real(8) :: prob @@ -240,8 +240,8 @@ contains subroutine absorption(p, i_nuclide) - type(Particle), intent(inout) :: p - integer, intent(in) :: i_nuclide + class(Particle_Base), intent(inout) :: p + integer, intent(in) :: i_nuclide if (survival_biasing) then ! Determine weight absorbed in survival biasing @@ -281,7 +281,7 @@ contains subroutine russian_roulette(p) - type(Particle), intent(inout) :: p + class(Particle_Base), intent(inout) :: p if (p % wgt < weight_cutoff) then if (prn() < p % wgt / weight_survive) then @@ -302,8 +302,8 @@ contains subroutine scatter(p, i_nuclide) - type(Particle), intent(inout) :: p - integer, intent(in) :: i_nuclide + type(Particle_CE), intent(inout) :: p + integer, intent(in) :: i_nuclide integer :: i integer :: i_grid @@ -1059,9 +1059,9 @@ contains subroutine create_fission_sites(p, i_nuclide, i_reaction) - type(Particle), intent(inout) :: p - integer, intent(in) :: i_nuclide - integer, intent(in) :: i_reaction + class(Particle_Base), intent(inout) :: p + integer, intent(in) :: i_nuclide + integer, intent(in) :: i_reaction integer :: nu_d(MAX_DELAYED_GROUPS) ! number of delayed neutrons born integer :: i ! loop index @@ -1175,10 +1175,10 @@ contains function sample_fission_energy(nuc, rxn, p) result(E_out) - type(Nuclide), pointer :: nuc - type(Reaction), pointer :: rxn - type(Particle), intent(inout) :: p ! Particle causing fission - real(8) :: E_out ! outgoing energy of fission neutron + type(Nuclide), pointer :: nuc + type(Reaction), pointer :: rxn + class(Particle_Base), intent(inout) :: p ! Particle causing fission + real(8) :: E_out ! outgoing E of fission neutron integer :: j ! index on nu energy grid / precursor group integer :: lc ! index before start of energies/nu values @@ -1195,103 +1195,106 @@ contains real(8) :: prob ! cumulative probability type(DistEnergy), pointer :: edist - ! Determine total nu - nu_t = nu_total(nuc, p % E) + select type(p) + type is (Particle_CE) + ! Determine total nu + nu_t = nu_total(nuc, p % E) - ! Determine delayed nu - nu_d = nu_delayed(nuc, p % E) + ! Determine delayed nu + nu_d = nu_delayed(nuc, p % E) - ! Determine delayed neutron fraction - beta = nu_d / nu_t + ! Determine delayed neutron fraction + beta = nu_d / nu_t - if (prn() < beta) then - ! ==================================================================== - ! DELAYED NEUTRON SAMPLED + if (prn() < beta) then + ! ==================================================================== + ! DELAYED NEUTRON SAMPLED - ! sampled delayed precursor group - xi = prn() - lc = 1 - prob = ZERO - do j = 1, nuc % n_precursor - ! determine number of interpolation regions and energies - NR = int(nuc % nu_d_precursor_data(lc + 1)) - NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR)) + ! sampled delayed precursor group + xi = prn() + lc = 1 + prob = ZERO + do j = 1, nuc % n_precursor + ! determine number of interpolation regions and energies + NR = int(nuc % nu_d_precursor_data(lc + 1)) + NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR)) - ! determine delayed neutron precursor yield for group j - yield = interpolate_tab1(nuc % nu_d_precursor_data( & - lc+1:lc+2+2*NR+2*NE), p % E) + ! determine delayed neutron precursor yield for group j + yield = interpolate_tab1(nuc % nu_d_precursor_data( & + lc+1:lc+2+2*NR+2*NE), p % E) - ! Check if this group is sampled - prob = prob + yield - if (xi < prob) exit + ! Check if this group is sampled + prob = prob + yield + if (xi < prob) exit - ! advance pointer - lc = lc + 2 + 2*NR + 2*NE + 1 - end do + ! advance pointer + lc = lc + 2 + 2*NR + 2*NE + 1 + end do - ! if the sum of the probabilities is slightly less than one and the - ! random number is greater, j will be greater than nuc % - ! n_precursor -- check for this condition - j = min(j, nuc % n_precursor) + ! if the sum of the probabilities is slightly less than one and the + ! random number is greater, j will be greater than nuc % + ! n_precursor -- check for this condition + j = min(j, nuc % n_precursor) - ! set the delayed group for the particle born from fission - p % delayed_group = j + ! set the delayed group for the particle born from fission + p % delayed_group = j - ! select energy distribution for group j - law = nuc % nu_d_edist(j) % law - edist => nuc % nu_d_edist(j) + ! select energy distribution for group j + law = nuc % nu_d_edist(j) % law + edist => nuc % nu_d_edist(j) - ! sample from energy distribution - n_sample = 0 - do - if (law == 44 .or. law == 61) then - call sample_energy(edist, p % E, E_out, mu) - else - call sample_energy(edist, p % E, E_out) - end if + ! sample from energy distribution + n_sample = 0 + do + if (law == 44 .or. law == 61) then + call sample_energy(edist, p % E, E_out, mu) + else + call sample_energy(edist, p % E, E_out) + end if - ! resample if energy is greater than maximum neutron energy - if (E_out < energy_max_neutron) exit + ! resample if energy is greater than maximum neutron energy + if (E_out < energy_max_neutron) exit - ! check for large number of resamples - n_sample = n_sample + 1 - if (n_sample == MAX_SAMPLE) then - ! call write_particle_restart(p) - call fatal_error("Resampled energy distribution maximum number of " & - &// "times for nuclide " // nuc % name) - end if - end do + ! check for large number of resamples + n_sample = n_sample + 1 + if (n_sample == MAX_SAMPLE) then + ! call write_particle_restart(p) + call fatal_error("Resampled energy distribution maximum number of " & + &// "times for nuclide " // nuc % name) + end if + end do - else - ! ==================================================================== - ! PROMPT NEUTRON SAMPLED + else + ! ==================================================================== + ! PROMPT NEUTRON SAMPLED - ! set the delayed group for the particle born from fission to 0 - p % delayed_group = 0 + ! set the delayed group for the particle born from fission to 0 + p % delayed_group = 0 - ! sample from prompt neutron energy distribution - law = rxn % edist % law - n_sample = 0 - do - if (law == 44 .or. law == 61) then - call sample_energy(rxn%edist, p % E, E_out, prob) - else - call sample_energy(rxn%edist, p % E, E_out) - end if + ! sample from prompt neutron energy distribution + law = rxn % edist % law + n_sample = 0 + do + if (law == 44 .or. law == 61) then + call sample_energy(rxn%edist, p % E, E_out, prob) + else + call sample_energy(rxn%edist, p % E, E_out) + end if - ! resample if energy is greater than maximum neutron energy - if (E_out < energy_max_neutron) exit + ! resample if energy is greater than maximum neutron energy + if (E_out < energy_max_neutron) exit - ! check for large number of resamples - n_sample = n_sample + 1 - if (n_sample == MAX_SAMPLE) then - ! call write_particle_restart(p) - call fatal_error("Resampled energy distribution maximum number of " & - &// "times for nuclide " // nuc % name) - end if - end do + ! check for large number of resamples + n_sample = n_sample + 1 + if (n_sample == MAX_SAMPLE) then + ! call write_particle_restart(p) + call fatal_error("Resampled energy distribution maximum number of " & + &// "times for nuclide " // nuc % name) + end if + end do - end if + end if + end select end function sample_fission_energy @@ -1301,9 +1304,9 @@ contains !=============================================================================== subroutine inelastic_scatter(nuc, rxn, p) - type(Nuclide), pointer :: nuc - type(Reaction), pointer :: rxn - type(Particle), intent(inout) :: p + type(Nuclide), pointer :: nuc + type(Reaction), pointer :: rxn + type(Particle_CE), intent(inout) :: p integer :: i ! loop index integer :: law ! secondary energy distribution law diff --git a/src/plot.F90 b/src/plot.F90 index a5497bc203..6ac2da2c14 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -9,7 +9,7 @@ module plot use mesh, only: get_mesh_indices use mesh_header, only: RegularMesh use output, only: write_message - use particle_header, only: Particle, LocalCoord + use particle_header, only: LocalCoord, Particle_Base use plot_header use ppmlib, only: Image, init_image, allocate_image, & deallocate_image, set_pixel @@ -56,7 +56,7 @@ contains subroutine position_rgb(p, pl, rgb, id) - type(Particle), intent(inout) :: p + class(Particle_Base), intent(inout) :: p type(ObjectPlot), pointer, intent(in) :: pl integer, intent(out) :: rgb(3) integer, intent(out) :: id @@ -123,9 +123,9 @@ contains real(8) :: in_pixel real(8) :: out_pixel real(8) :: xyz(3) - type(Image) :: img - type(Particle) :: p - type(ProgressBar) :: progress + type(Image) :: img + class(Particle_Base), pointer :: p + type(ProgressBar) :: progress ! Initialize and allocate space for image call init_image(img) @@ -362,9 +362,9 @@ contains integer(HSIZE_T) :: offset(3) real(8) :: vox(3) ! x, y, and z voxel widths real(8) :: ll(3) ! lower left starting point for each sweep direction - type(Particle) :: p - type(ProgressBar) :: progress - type(c_ptr) :: f_ptr + class(Particle_Base), pointer :: p + type(ProgressBar) :: progress + type(c_ptr) :: f_ptr ! compute voxel widths in each direction vox = pl % width/dble(pl % pixels) diff --git a/src/simulation.F90 b/src/simulation.F90 index cc230d645b..a674a18df4 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -15,7 +15,7 @@ module simulation use global use output, only: write_message, header, print_columns, & print_batch_keff, print_generation - use particle_header, only: Particle + use particle_header, only: Particle_Base use random_lcg, only: set_particle_seed use source, only: initialize_source use state_point, only: write_state_point, write_source_point @@ -39,8 +39,8 @@ contains subroutine run_simulation() - type(Particle) :: p - integer(8) :: i_work + class(Particle_Base), pointer :: p + integer(8) :: i_work if (.not. restart_run) call initialize_source() @@ -124,8 +124,8 @@ contains subroutine initialize_history(p, index_source) - type(Particle), intent(inout) :: p - integer(8), intent(in) :: index_source + class(Particle_Base), intent(inout) :: p + integer(8), intent(in) :: index_source integer(8) :: particle_seed ! unique index for particle integer :: i diff --git a/src/source.F90 b/src/source.F90 index 6226517f3e..e8cb420083 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -9,7 +9,7 @@ module source use hdf5_interface, only: file_create, file_open, file_close, read_dataset use math, only: maxwell_spectrum, watt_spectrum use output, only: write_message - use particle_header, only: Particle + use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: prn, set_particle_seed, prn_set_stream use state_point, only: read_source_bank, write_source_bank use string, only: to_str @@ -108,7 +108,7 @@ contains real(8) :: a ! Arbitrary parameter 'a' real(8) :: b ! Arbitrary parameter 'b' logical :: found ! Does the source particle exist within geometry? - type(Particle) :: p ! Temporary particle for using find_cell + class(Particle_Base), pointer :: p ! Temporary particle for using find_cell integer, save :: num_resamples = 0 ! Number of resamples encountered ! Set weight to one by default diff --git a/src/tally.F90 b/src/tally.F90 index 0586860191..248f87c6a7 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -11,7 +11,8 @@ module tally mesh_intersects_2d, mesh_intersects_3d use mesh_header, only: RegularMesh use output, only: header - use particle_header, only: LocalCoord, Particle + use particle_header, only: LocalCoord, Particle_Base, Particle_CE, & + Particle_MG use search, only: binary_search use string, only: to_str use tally_header, only: TallyResult, TallyMapItem, TallyMapElement @@ -37,7 +38,7 @@ contains subroutine score_general(p, t, start_index, filter_index, i_nuclide, & atom_density, flux) - type(Particle), intent(in) :: p + type(Particle_CE), intent(in) :: p type(TallyObject), pointer, intent(inout) :: t integer, intent(in) :: start_index integer, intent(in) :: i_nuclide @@ -837,10 +838,10 @@ contains subroutine score_all_nuclides(p, i_tally, flux, filter_index) - type(Particle), intent(in) :: p - integer, intent(in) :: i_tally - real(8), intent(in) :: flux - integer, intent(in) :: filter_index + type(Particle_CE), intent(in) :: p + integer, intent(in) :: i_tally + real(8), intent(in) :: flux + integer, intent(in) :: filter_index integer :: i ! loop index for nuclides in material integer :: i_nuclide ! index in nuclides array @@ -891,7 +892,7 @@ contains subroutine score_analog_tally(p) - type(Particle), intent(in) :: p + type(Particle_CE), intent(in) :: p integer :: i integer :: i_tally @@ -999,9 +1000,9 @@ contains subroutine score_fission_eout(p, t, i_score) - type(Particle), intent(in) :: p - type(TallyObject), pointer :: t - integer, intent(in) :: i_score ! index for score + type(Particle_CE), intent(in) :: p + type(TallyObject), pointer :: t + integer, intent(in) :: i_score ! index for score integer :: i ! index of outgoing energy filter integer :: n ! number of energies on filter @@ -1061,7 +1062,7 @@ contains subroutine score_fission_delayed_eout(p, t, i_score) - type(Particle), intent(in) :: p + type(Particle_CE), intent(in) :: p type(TallyObject), intent(inout) :: t integer, intent(in) :: i_score ! index for score @@ -1187,8 +1188,8 @@ contains subroutine score_tracklength_tally(p, distance) - type(Particle), intent(in) :: p - real(8), intent(in) :: distance + type(Particle_CE), intent(in) :: p + real(8), intent(in) :: distance integer :: i integer :: i_tally @@ -1300,9 +1301,9 @@ contains subroutine score_tl_on_mesh(p, i_tally, d_track) - type(Particle), intent(in) :: p - integer, intent(in) :: i_tally - real(8), intent(in) :: d_track + type(Particle_CE), intent(in) :: p + integer, intent(in) :: i_tally + real(8), intent(in) :: d_track integer :: i ! loop index for filter/score bins integer :: j ! loop index for direction @@ -1585,7 +1586,7 @@ contains subroutine score_collision_tally(p) - type(Particle), intent(in) :: p + type(Particle_CE), intent(in) :: p integer :: i integer :: i_tally @@ -1694,9 +1695,9 @@ contains subroutine get_scoring_bins(p, i_tally, found_bin) - type(Particle), intent(in) :: p - integer, intent(in) :: i_tally - logical, intent(out) :: found_bin + type(Particle_CE), intent(in) :: p + integer, intent(in) :: i_tally + logical, intent(out) :: found_bin integer :: i ! loop index for filters integer :: j @@ -1902,7 +1903,7 @@ contains subroutine score_surface_current(p) - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p integer :: i integer :: i_tally @@ -1967,19 +1968,22 @@ contains uvw = p % coord(1) % uvw ! determine incoming energy bin - j = t % find_filter(FILTER_ENERGYIN) - if (j > 0) then - n = t % filters(j) % n_bins - ! check if energy of the particle is within energy bins - if (p % E < t % filters(j) % real_bins(1) .or. & - p % E > t % filters(j) % real_bins(n + 1)) then - cycle - end if + select type(p) + type is (Particle_CE) + j = t % find_filter(FILTER_ENERGYIN) + if (j > 0) then + n = t % filters(j) % n_bins + ! check if energy of the particle is within energy bins + if (p % E < t % filters(j) % real_bins(1) .or. & + p % E > t % filters(j) % real_bins(n + 1)) then + cycle + end if - ! search to find incoming energy bin - matching_bins(j) = binary_search(t % filters(j) % real_bins, & - n + 1, p % E) - end if + ! search to find incoming energy bin + matching_bins(j) = binary_search(t % filters(j) % real_bins, & + n + 1, p % E) + end if + end select ! ======================================================================= ! SPECIAL CASES WHERE TWO INDICES ARE THE SAME diff --git a/src/track_output.F90 b/src/track_output.F90 index 1665ac25ea..867cd4a787 100644 --- a/src/track_output.F90 +++ b/src/track_output.F90 @@ -7,7 +7,7 @@ module track_output use global use hdf5_interface - use particle_header, only: Particle + use particle_header, only: Particle_Base use string, only: to_str use hdf5 @@ -43,7 +43,7 @@ contains !=============================================================================== subroutine write_particle_track(p) - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p real(8), allocatable :: new_coords(:, :) integer :: i @@ -93,7 +93,7 @@ contains !=============================================================================== subroutine finalize_particle_track(p) - type(Particle), intent(in) :: p + class(Particle_Base), intent(in) :: p integer :: i integer :: n_particle_tracks diff --git a/src/tracking.F90 b/src/tracking.F90 index 2e4503e139..8dc8c7772e 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -8,7 +8,7 @@ module tracking use geometry_header, only: Universe, BASE_UNIVERSE use global use output, only: write_message - use particle_header, only: LocalCoord, Particle + use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use physics, only: collision use random_lcg, only: prn use string, only: to_str @@ -27,7 +27,7 @@ contains subroutine transport(p) - type(Particle), intent(inout) :: p + class(Particle_Base), intent(inout) :: p integer :: j ! coordinate level integer :: next_level ! next coordinate level to check @@ -83,7 +83,10 @@ contains ! material is the same as the last material and the energy of the ! particle hasn't changed, we don't need to lookup cross sections again. - if (p % material /= p % last_material) call calculate_xs(p) + select type(p) + type is (Particle_CE) + if (p % material /= p % last_material) call calculate_xs(p) + end select ! Find the distance to the nearest boundary call distance_to_boundary(p, d_boundary, surface_crossed, & @@ -105,8 +108,13 @@ contains end do ! Score track-length tallies - if (active_tracklength_tallies % size() > 0) & - call score_tracklength_tally(p, distance) + if (active_tracklength_tallies % size() > 0) then + select type(p) + type is (Particle_CE) + call score_tracklength_tally(p, distance) + end select + end if + ! Score track-length estimate of k-eff if (run_mode == MODE_EIGENVALUE) then @@ -151,14 +159,19 @@ contains ! Clear surface component p % surface = NONE - call collision(p) + select type(p) + type is (Particle_CE) + call collision(p) + end select ! Score collision estimator tallies -- this is done after a collision ! has occurred rather than before because we need information on the ! outgoing energy for any tallies with an outgoing energy filter - - if (active_collision_tallies % size() > 0) call score_collision_tally(p) - if (active_analog_tallies % size() > 0) call score_analog_tally(p) + select type(p) + type is (Particle_CE) + if (active_collision_tallies % size() > 0) call score_collision_tally(p) + if (active_analog_tallies % size() > 0) call score_analog_tally(p) + end select ! Reset banked weight during collision p % n_bank = 0 From 6ab37ed3b4a3390a1a19ccc67cae0a71c1acdce5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 16:22:41 -0400 Subject: [PATCH 02/84] MG-ified the Bank Type. Not happy with the way this is done - adding group attrib to normal class - but the BIND(C) attribute is really not allowing me to do extended types. The other fix is to create a completely separate type for Bank_MG, which in the end I suspect will result in way to much duplicated code --- src/bank_header.F90 | 3 ++- src/particle_header.F90 | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bank_header.F90 b/src/bank_header.F90 index 0cb49af35d..ad829341f0 100644 --- a/src/bank_header.F90 +++ b/src/bank_header.F90 @@ -5,7 +5,7 @@ module bank_header implicit none !=============================================================================== -! BANK is used for storing fission sites in eigenvalue calculations. Since all +! BANK* is used for storing fission sites in eigenvalue calculations. Since all ! the state information of a neutron is not needed, this type allows sites to be ! stored with less memory !=============================================================================== @@ -15,6 +15,7 @@ module bank_header real(C_DOUBLE) :: xyz(3) ! location of bank particle real(C_DOUBLE) :: uvw(3) ! diretional cosines real(C_DOUBLE) :: E ! energy + integer(C_INT) :: g ! energy group integer(C_INT) :: delayed_group ! delayed group end type Bank diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 6b4d38845a..40d7499015 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -250,9 +250,8 @@ contains this % coord(1) % uvw = src % uvw this % last_xyz = src % xyz this % last_uvw = src % uvw - !!! The following requires a MG version of Bank - this % g = src % E - this % last_g = src % E + this % g = src % g + this % last_g = src % g end subroutine initialize_from_source_mg @@ -300,8 +299,7 @@ contains this % secondary_bank(n) % wgt = this % wgt this % secondary_bank(n) % xyz(:) = this % coord(1) % xyz this % secondary_bank(n) % uvw(:) = uvw - !!! The following requires a MG version of Bank - this % secondary_bank(n) % E = this % g + this % secondary_bank(n) % g = this % g this % n_secondary = n end subroutine create_secondary_mg From a2d7bb96a6c86cd334c187c0f37f514650e770d7 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 16:52:56 -0400 Subject: [PATCH 03/84] Able to read in materials.xml file including new macroscopic identifier --- src/global.F90 | 6 +- src/input_xml.F90 | 251 +++++++++++++++++++++++++++++++--------------- 2 files changed, 173 insertions(+), 84 deletions(-) diff --git a/src/global.F90 b/src/global.F90 index a4c80daa79..98c3a6ed66 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -59,7 +59,11 @@ module global integer :: n_lost_particles ! ============================================================================ - ! CROSS SECTION RELATED VARIABLES + ! ENERGY TREATMENT RELATED VARIABLES + logical :: run_CE = .true. ! Run in CE mode? + + ! ============================================================================ + ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES ! Cross section arrays type(Nuclide), allocatable, target :: nuclides(:) ! Nuclide cross-sections diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 58e4013355..dda1b90837 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -121,6 +121,17 @@ contains end if end if + ! Find if a multi-group or continuous-energy simulation is desired + if (check_for_node(doc, "energy_mode")) then + call get_node_value(doc, "energy_mode", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == "mg" .or. temp_str == "multi-group") then + run_CE = .false. + else if (temp_str == "ce" .or. temp_str == "continuous") then + run_CE = .true. + end if + end if + ! Set output directory if a path has been specified on the ! element if (check_for_node(doc, "output_path")) then @@ -1784,6 +1795,7 @@ contains type(Node), pointer :: node_sab => null() type(NodeList), pointer :: node_mat_list => null() type(NodeList), pointer :: node_nuc_list => null() + type(NodeList), pointer :: node_macro_list => null() type(NodeList), pointer :: node_ele_list => null() type(NodeList), pointer :: node_sab_list => null() @@ -1841,6 +1853,7 @@ contains ! Copy material name if (check_for_node(node_mat, "name")) then call get_node_value(node_mat, "name", mat % name) + mat % name = to_lower(mat % name) end if if (run_mode == MODE_PLOTTING) then @@ -1873,6 +1886,19 @@ contains sum_density = .true. + else if (units == 'macro') then + if (check_for_node(node_dens, "value")) then + ! Copy value + call get_node_value(node_dens, "value", val) + else + val = ONE + end if + + ! Set density + mat % density = val + + sum_density = .false. + else ! Copy value call get_node_value(node_dens, "value", val) @@ -1904,66 +1930,122 @@ contains ! READ AND PARSE TAGS ! Check to ensure material has at least one nuclide - if (.not. check_for_node(node_mat, "nuclide") .and. & - .not. check_for_node(node_mat, "element")) then - call fatal_error("No nuclides or natural elements specified on & - &material " // trim(to_str(mat % id))) + if ((.not. check_for_node(node_mat, "nuclide") .and. & + .not. check_for_node(node_mat, "element")) .and. & + (.not. check_for_node(node_mat, "macroscopic"))) then + call fatal_error("No macroscopic data, nuclides or natural elements & + &specified on material " // trim(to_str(mat % id))) end if + ! Create list of macroscopic x/s based on those specified, just treat + ! them as nuclides. This is all really a facade so the user thinks they + ! are entering in macroscopic data but the code treats them the same + ! as nuclides internally. ! Get pointer list of XML - call get_node_list(node_mat, "nuclide", node_nuc_list) + call get_node_list(node_mat, "macroscopic", node_macro_list) + if (get_list_size(node_macro_list) > 1) then + call fatal_error("Only one macroscopic data permitted per material, " & + &// trim(to_str(mat % id))) + else if (get_list_size(node_macro_list) == 1) then - ! Create list of nuclides based on those specified plus natural elements - INDIVIDUAL_NUCLIDES: do j = 1, get_list_size(node_nuc_list) - ! Combine nuclide identifier and cross section and copy into names - call get_list_item(node_nuc_list, j, node_nuc) + call get_list_item(node_macro_list, 1, node_nuc) ! Check for empty name on nuclide if (.not.check_for_node(node_nuc, "name")) then - call fatal_error("No name specified on nuclide in material " & + call fatal_error("No name specified on macroscopic data in material " & &// trim(to_str(mat % id))) end if ! Check for cross section if (.not.check_for_node(node_nuc, "xs")) then if (default_xs == '') then - call fatal_error("No cross section specified for nuclide in & - &material " // trim(to_str(mat % id))) + call fatal_error("No cross section specified for macroscopic data & + & in material " // trim(to_str(mat % id))) else - name = trim(default_xs) + name = to_lower(trim(default_xs)) end if end if ! store full name call get_node_value(node_nuc, "name", temp_str) if (check_for_node(node_nuc, "xs")) & - call get_node_value(node_nuc, "xs", name) + call get_node_value(node_nuc, "xs", name) name = trim(temp_str) // "." // trim(name) + name = to_lower(name) ! save name and density to list call list_names % append(name) ! Check if no atom/weight percents were specified or if both atom and ! weight percents were specified - if (.not.check_for_node(node_nuc, "ao") .and. & - .not.check_for_node(node_nuc, "wo")) then - call fatal_error("No atom or weight percent specified for nuclide " & - &// trim(name)) - elseif (check_for_node(node_nuc, "ao") .and. & - check_for_node(node_nuc, "wo")) then - call fatal_error("Cannot specify both atom and weight percents for a & - &nuclide: " // trim(name)) - end if - - ! Copy atom/weight percents - if (check_for_node(node_nuc, "ao")) then - call get_node_value(node_nuc, "ao", temp_dble) - call list_density % append(temp_dble) + if (units == 'macro') then + call list_density % append(ONE) else - call get_node_value(node_nuc, "wo", temp_dble) - call list_density % append(-temp_dble) + call fatal_error("Units can only be macro for macroscopic data " & + &// trim(name)) end if - end do INDIVIDUAL_NUCLIDES + else + + ! Get pointer list of XML + call get_node_list(node_mat, "nuclide", node_nuc_list) + + ! Create list of nuclides based on those specified plus natural elements + INDIVIDUAL_NUCLIDES: do j = 1, get_list_size(node_nuc_list) + ! Combine nuclide identifier and cross section and copy into names + call get_list_item(node_nuc_list, j, node_nuc) + + ! Check for empty name on nuclide + if (.not.check_for_node(node_nuc, "name")) then + call fatal_error("No name specified on nuclide in material " & + &// trim(to_str(mat % id))) + end if + + ! Check for cross section + if (.not.check_for_node(node_nuc, "xs")) then + if (default_xs == '') then + call fatal_error("No cross section specified for nuclide in & + &material " // trim(to_str(mat % id))) + else + name = to_lower(trim(default_xs)) + end if + end if + + ! store full name + call get_node_value(node_nuc, "name", temp_str) + if (check_for_node(node_nuc, "xs")) & + call get_node_value(node_nuc, "xs", name) + name = trim(temp_str) // "." // trim(name) + name = to_lower(name) + + ! save name and density to list + call list_names % append(name) + + ! Check if no atom/weight percents were specified or if both atom and + ! weight percents were specified + if (units == 'macro') then + call list_density % append(ONE) + else + if (.not.check_for_node(node_nuc, "ao") .and. & + .not.check_for_node(node_nuc, "wo")) then + call fatal_error("No atom or weight percent specified for nuclide " & + &// trim(name)) + elseif (check_for_node(node_nuc, "ao") .and. & + check_for_node(node_nuc, "wo")) then + call fatal_error("Cannot specify both atom and weight percents for a & + &nuclide: " // trim(name)) + end if + + ! Copy atom/weight percents + if (check_for_node(node_nuc, "ao")) then + call get_node_value(node_nuc, "ao", temp_dble) + call list_density % append(temp_dble) + else + call get_node_value(node_nuc, "wo", temp_dble) + call list_density % append(-temp_dble) + end if + end if + end do INDIVIDUAL_NUCLIDES + end if ! ======================================================================= ! READ AND PARSE TAGS @@ -1989,7 +2071,7 @@ contains call fatal_error("No cross section specified for nuclide in & &material " // trim(to_str(mat % id))) else - temp_str = trim(default_xs) + temp_str = to_lower(trim(default_xs)) end if end if @@ -2031,14 +2113,16 @@ contains name = trim(list_names % get_item(j)) if (.not. xs_listing_dict % has_key(to_lower(name))) then call fatal_error("Could not find nuclide " // trim(name) & - &// " in cross_sections.xml file!") + &// " in cross_sections data file!") end if - ! Check to make sure cross-section is continuous energy neutron table - n = len_trim(name) - if (name(n:n) /= 'c') then - call fatal_error("Cross-section table " // trim(name) & - &// " is not a continuous-energy neutron table.") + if (run_CE) then + ! Check to make sure cross-section is continuous energy neutron table + n = len_trim(name) + if (name(n:n) /= 'c') then + call fatal_error("Cross-section table " // trim(name) & + &// " is not a continuous-energy neutron table.") + end if end if ! Find xs_listing and set the name/alias according to the listing @@ -2080,59 +2164,60 @@ contains ! ======================================================================= ! READ AND PARSE TAG FOR S(a,b) DATA + if (run_CE) then + ! Get pointer list to XML + call get_node_list(node_mat, "sab", node_sab_list) - ! Get pointer list to XML - call get_node_list(node_mat, "sab", node_sab_list) + n_sab = get_list_size(node_sab_list) + if (n_sab > 0) then + ! Set number of S(a,b) tables + mat % n_sab = n_sab - n_sab = get_list_size(node_sab_list) - if (n_sab > 0) then - ! Set number of S(a,b) tables - mat % n_sab = n_sab + ! Allocate names and indices for nuclides and tables + allocate(mat % sab_names(n_sab)) + allocate(mat % i_sab_nuclides(n_sab)) + allocate(mat % i_sab_tables(n_sab)) - ! Allocate names and indices for nuclides and tables - allocate(mat % sab_names(n_sab)) - allocate(mat % i_sab_nuclides(n_sab)) - allocate(mat % i_sab_tables(n_sab)) + ! Initialize i_sab_nuclides + mat % i_sab_nuclides = NONE - ! Initialize i_sab_nuclides - mat % i_sab_nuclides = NONE + do j = 1, n_sab + ! Get pointer to S(a,b) table + call get_list_item(node_sab_list, j, node_sab) - do j = 1, n_sab - ! Get pointer to S(a,b) table - call get_list_item(node_sab_list, j, node_sab) + ! Determine name of S(a,b) table + if (.not.check_for_node(node_sab, "name") .or. & + .not.check_for_node(node_sab, "xs")) then + call fatal_error("Need to specify and for S(a,b) & + &table.") + end if + call get_node_value(node_sab, "name", name) + call get_node_value(node_sab, "xs", temp_str) + name = trim(name) // "." // trim(temp_str) + mat % sab_names(j) = name - ! Determine name of S(a,b) table - if (.not.check_for_node(node_sab, "name") .or. & - .not.check_for_node(node_sab, "xs")) then - call fatal_error("Need to specify and for S(a,b) & - &table.") - end if - call get_node_value(node_sab, "name", name) - call get_node_value(node_sab, "xs", temp_str) - name = trim(name) // "." // trim(temp_str) - mat % sab_names(j) = name + ! Check that this nuclide is listed in the cross_sections.xml file + if (.not. xs_listing_dict % has_key(to_lower(name))) then + call fatal_error("Could not find S(a,b) table " // trim(name) & + &// " in cross_sections.xml file!") + end if - ! Check that this nuclide is listed in the cross_sections.xml file - if (.not. xs_listing_dict % has_key(to_lower(name))) then - call fatal_error("Could not find S(a,b) table " // trim(name) & - &// " in cross_sections.xml file!") - end if + ! Find index in xs_listing and set the name and alias according to the + ! listing + index_list = xs_listing_dict % get_key(to_lower(name)) + name = xs_listings(index_list) % name - ! Find index in xs_listing and set the name and alias according to the - ! listing - index_list = xs_listing_dict % get_key(to_lower(name)) - name = xs_listings(index_list) % name - - ! If this S(a,b) table hasn't been encountered yet, we need to add its - ! name and alias to the sab_dict - if (.not. sab_dict % has_key(to_lower(name))) then - index_sab = index_sab + 1 - mat % i_sab_tables(j) = index_sab - call sab_dict % add_key(to_lower(name), index_sab) - else - mat % i_sab_tables(j) = sab_dict % get_key(to_lower(name)) - end if - end do + ! If this S(a,b) table hasn't been encountered yet, we need to add its + ! name and alias to the sab_dict + if (.not. sab_dict % has_key(to_lower(name))) then + index_sab = index_sab + 1 + mat % i_sab_tables(j) = index_sab + call sab_dict % add_key(to_lower(name), index_sab) + else + mat % i_sab_tables(j) = sab_dict % get_key(to_lower(name)) + end if + end do + end if end if ! Add material to dictionary From 8ec4c917817f18a9683a2c068a599bd9ce8497d9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 20:25:32 -0400 Subject: [PATCH 04/84] Worked on the old ace_header and split it up into nuclide and sab_header to make more sense when the MGXS version of nuclide gets put in' --- src/ace.F90 | 23 ++-- src/ace_header.F90 | 263 ----------------------------------------- src/cross_section.F90 | 18 +-- src/energy_grid.F90 | 6 +- src/fission.F90 | 28 ++--- src/global.F90 | 6 +- src/nuclide_header.F90 | 248 ++++++++++++++++++++++++++++++++++++++ src/output.F90 | 10 +- src/physics.F90 | 21 ++-- src/sab_header.F90 | 62 ++++++++++ src/summary.F90 | 3 +- src/tally.F90 | 2 +- 12 files changed, 372 insertions(+), 318 deletions(-) create mode 100644 src/nuclide_header.F90 create mode 100644 src/sab_header.F90 diff --git a/src/ace.F90 b/src/ace.F90 index 22fcc6b3d5..a93f722958 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -1,7 +1,6 @@ module ace - use ace_header, only: Nuclide, Reaction, SAlphaBeta, XsListing, & - DistEnergy + use ace_header, only: Reaction, DistEnergy use constants use endf, only: reaction_name, is_fission, is_disappearance use error, only: fatal_error, warning @@ -9,7 +8,9 @@ module ace use global use list_header, only: ListInt use material_header, only: Material + use nuclide_header use output, only: write_message + use sab_header, only: SAlphaBeta use set_header, only: SetChar use string, only: to_str, to_lower @@ -46,7 +47,7 @@ contains character(12) :: name ! name of isotope, e.g. 92235.03c character(12) :: alias ! alias of nuclide, e.g. U-235.03c type(Material), pointer :: mat => null() - type(Nuclide), pointer :: nuc => null() + type(Nuclide_CE), pointer :: nuc => null() type(SAlphaBeta), pointer :: sab => null() type(SetChar) :: already_read @@ -258,7 +259,7 @@ contains character(10) :: mat ! material identifier character(70) :: comment ! comment for ACE table character(MAX_FILE_LEN) :: filename ! path to ACE cross section library - type(Nuclide), pointer :: nuc => null() + type(Nuclide_CE), pointer :: nuc => null() type(SAlphaBeta), pointer :: sab => null() type(XsListing), pointer :: listing => null() @@ -418,7 +419,7 @@ contains subroutine read_esz(nuc, data_0K) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc logical :: data_0K ! are we reading 0K data? @@ -508,7 +509,7 @@ contains subroutine read_nu_data(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: i ! loop index integer :: JXS2 ! location for fission nu data @@ -708,7 +709,7 @@ contains subroutine read_reactions(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: i ! loop indices integer :: i_fission ! index in nuc % index_fission @@ -891,7 +892,7 @@ contains subroutine read_angular_dist(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: JXS8 ! location of angular distribution locators integer :: JXS9 ! location of angular distributions @@ -986,7 +987,7 @@ contains subroutine read_energy_dist(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: LED ! location of energy distribution locators integer :: LOCC ! location of energy distributions for given MT @@ -1302,7 +1303,7 @@ contains subroutine read_unr_res(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: JXS23 ! location of URR data integer :: lc ! locator @@ -1391,7 +1392,7 @@ contains subroutine generate_nu_fission(nuc) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer :: i ! index on nuclide energy grid real(8) :: E ! energy diff --git a/src/ace_header.F90 b/src/ace_header.F90 index 467887c193..1fb444b1ae 100644 --- a/src/ace_header.F90 +++ b/src/ace_header.F90 @@ -85,212 +85,6 @@ module ace_header procedure :: clear => urrdata_clear ! Deallocates UrrData end type UrrData -!=============================================================================== -! NUCLIDE contains all the data for an ACE-format continuous-energy cross -! section. The ACE format (A Compact ENDF format) is used in MCNP and several -! other Monte Carlo codes. -!=============================================================================== - - type Nuclide - character(10) :: name ! name of nuclide, e.g. 92235.03c - integer :: zaid ! Z and A identifier, e.g. 92235 - integer :: listing ! index in xs_listings - real(8) :: awr ! weight of nucleus in neutron masses - real(8) :: kT ! temperature in MeV (k*T) - - ! Linked list of indices in nuclides array of instances of this same nuclide - type(ListInt) :: nuc_list - - ! Energy grid information - integer :: n_grid ! # of nuclide grid points - integer, allocatable :: grid_index(:) ! log grid mapping indices - real(8), allocatable :: energy(:) ! energy values corresponding to xs - - ! Microscopic cross sections - real(8), allocatable :: total(:) ! total cross section - real(8), allocatable :: elastic(:) ! elastic scattering - real(8), allocatable :: fission(:) ! fission - real(8), allocatable :: nu_fission(:) ! neutron production - real(8), allocatable :: absorption(:) ! absorption (MT > 100) - real(8), allocatable :: heating(:) ! heating - - ! Resonance scattering info - logical :: resonant = .false. ! resonant scatterer? - character(10) :: name_0K = '' ! name of 0K nuclide, e.g. 92235.00c - character(16) :: scheme ! target velocity sampling scheme - integer :: n_grid_0K ! number of 0K energy grid points - real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs - real(8), allocatable :: elastic_0K(:) ! Microscopic elastic cross section - real(8), allocatable :: xs_cdf(:) ! CDF of v_rel times cross section - real(8) :: E_min ! lower cutoff energy for res scattering - real(8) :: E_max ! upper cutoff energy for res scattering - - ! Fission information - logical :: fissionable ! nuclide is fissionable? - logical :: has_partial_fission ! nuclide has partial fission reactions? - integer :: n_fission ! # of fission reactions - integer, allocatable :: index_fission(:) ! indices in reactions - - ! Total fission neutron emission - integer :: nu_t_type - real(8), allocatable :: nu_t_data(:) - - ! Prompt fission neutron emission - integer :: nu_p_type - real(8), allocatable :: nu_p_data(:) - - ! Delayed fission neutron emission - integer :: nu_d_type - integer :: n_precursor ! # of delayed neutron precursors - real(8), allocatable :: nu_d_data(:) - real(8), allocatable :: nu_d_precursor_data(:) - type(DistEnergy), pointer :: nu_d_edist(:) => null() - - ! Unresolved resonance data - logical :: urr_present - integer :: urr_inelastic - type(UrrData), pointer :: urr_data => null() - - ! Reactions - integer :: n_reaction ! # of reactions - type(Reaction), pointer :: reactions(:) => null() - - ! Type-Bound procedures - contains - procedure :: clear => nuclide_clear ! Deallocates Nuclide - end type Nuclide - -!=============================================================================== -! NUCLIDE0K temporarily contains all 0K cross section data and other parameters -! needed to treat resonance scattering before transferring them to NUCLIDE -!=============================================================================== - - type Nuclide0K - - character(10) :: nuclide ! name of nuclide, e.g. U-238 - character(16) :: scheme = 'ares' ! target velocity sampling scheme - character(10) :: name ! name of nuclide, e.g. 92235.03c - character(10) :: name_0K ! name of 0K nuclide, e.g. 92235.00c - real(8) :: E_min = 0.01e-6_8 ! lower cutoff energy for res scattering - real(8) :: E_max = 1000.0e-6_8 ! upper cutoff energy for res scattering - - end type Nuclide0K - -!=============================================================================== -! DISTENERGYSAB contains the secondary energy/angle distributions for inelastic -! thermal scattering collisions which utilize a continuous secondary energy -! representation. -!=============================================================================== - - type DistEnergySab - integer :: n_e_out - real(8), allocatable :: e_out(:) - real(8), allocatable :: e_out_pdf(:) - real(8), allocatable :: e_out_cdf(:) - real(8), allocatable :: mu(:,:) - end type DistEnergySab - -!=============================================================================== -! SALPHABETA contains S(a,b) data for thermal neutron scattering, typically off -! of light isotopes such as water, graphite, Be, etc -!=============================================================================== - - type SAlphaBeta - character(10) :: name ! name of table, e.g. lwtr.10t - real(8) :: awr ! weight of nucleus in neutron masses - real(8) :: kT ! temperature in MeV (k*T) - integer :: n_zaid ! Number of valid zaids - integer, allocatable :: zaid(:) ! List of valid Z and A identifiers, e.g. 6012 - - ! threshold for S(a,b) treatment (usually ~4 eV) - real(8) :: threshold_inelastic - real(8) :: threshold_elastic = ZERO - - ! Inelastic scattering data - integer :: n_inelastic_e_in ! # of incoming E for inelastic - integer :: n_inelastic_e_out ! # of outgoing E for inelastic - integer :: n_inelastic_mu ! # of outgoing angles for inelastic - integer :: secondary_mode ! secondary mode (equal/skewed/continuous) - real(8), allocatable :: inelastic_e_in(:) - real(8), allocatable :: inelastic_sigma(:) - ! The following are used only if secondary_mode is 0 or 1 - real(8), allocatable :: inelastic_e_out(:,:) - real(8), allocatable :: inelastic_mu(:,:,:) - ! The following is used only if secondary_mode is 3 - ! The different implementation is necessary because the continuous - ! representation has a variable number of outgoing energy points for each - ! incoming energy - type(DistEnergySab), allocatable :: inelastic_data(:) ! One for each Ein - - ! Elastic scattering data - integer :: elastic_mode ! elastic mode (discrete/exact) - integer :: n_elastic_e_in ! # of incoming E for elastic - integer :: n_elastic_mu ! # of outgoing angles for elastic - real(8), allocatable :: elastic_e_in(:) - real(8), allocatable :: elastic_P(:) - real(8), allocatable :: elastic_mu(:,:) - end type SAlphaBeta - -!=============================================================================== -! XSLISTING contains data read from a cross_sections.xml file -!=============================================================================== - - type XsListing - character(12) :: name ! table name, e.g. 92235.70c - character(12) :: alias ! table alias, e.g. U-235.70c - integer :: type ! type of table (cont-E neutron, S(A,b), etc) - integer :: zaid ! ZAID identifier = 1000*Z + A - integer :: filetype ! ASCII or BINARY - integer :: location ! location of table within library - integer :: recl ! record length for library - integer :: entries ! number of entries per record - real(8) :: awr ! atomic weight ratio (# of neutron masses) - real(8) :: kT ! Boltzmann constant * temperature (MeV) - logical :: metastable ! is this nuclide metastable? - character(MAX_FILE_LEN) :: path ! path to library containing table - end type XsListing - -!=============================================================================== -! NUCLIDEMICROXS contains cached microscopic cross sections for a -! particular nuclide at the current energy -!=============================================================================== - - type NuclideMicroXS - integer :: index_grid ! index on nuclide energy grid - integer :: index_temp ! temperature index for nuclide - real(8) :: last_E = ZERO ! last evaluated energy - real(8) :: interp_factor ! interpolation factor on nuc. energy grid - real(8) :: total ! microscropic total xs - real(8) :: elastic ! microscopic elastic scattering xs - real(8) :: absorption ! microscopic absorption xs - real(8) :: fission ! microscopic fission xs - real(8) :: nu_fission ! microscopic production xs - real(8) :: kappa_fission ! microscopic energy-released from fission - - ! Information for S(a,b) use - integer :: index_sab ! index in sab_tables (zero means no table) - integer :: last_index_sab = 0 ! index in sab_tables last used by this nuclide - real(8) :: elastic_sab ! microscopic elastic scattering on S(a,b) table - - ! Information for URR probability table use - logical :: use_ptable ! in URR range with probability tables? - real(8) :: last_prn - end type NuclideMicroXS - -!=============================================================================== -! MATERIALMACROXS contains cached macroscopic cross sections for the material a -! particle is traveling through -!=============================================================================== - - type MaterialMacroXS - real(8) :: total ! macroscopic total xs - real(8) :: elastic ! macroscopic elastic scattering xs - real(8) :: absorption ! macroscopic absorption xs - real(8) :: fission ! macroscopic fission xs - real(8) :: nu_fission ! macroscopic production xs - real(8) :: kappa_fission ! macroscopic energy-released from fission - end type MaterialMacroXS - contains !=============================================================================== @@ -362,62 +156,5 @@ module ace_header end subroutine urrdata_clear -!=============================================================================== -! NUCLIDE_CLEAR resets and deallocates data in Nuclide. -!=============================================================================== - - subroutine nuclide_clear(this) - - class(Nuclide), intent(inout) :: this ! The Nuclide object to clear - - integer :: i ! Loop counter - - if (allocated(this % energy)) & - deallocate(this % energy, this % total, this % elastic, & - & this % fission, this % nu_fission, this % absorption) - - if (allocated(this % energy_0K)) & - deallocate(this % energy_0K) - - if (allocated(this % elastic_0K)) & - deallocate(this % elastic_0K) - - if (allocated(this % xs_cdf)) & - deallocate(this % xs_cdf) - - if (allocated(this % heating)) & - deallocate(this % heating) - - if (allocated(this % index_fission)) deallocate(this % index_fission) - - if (allocated(this % nu_t_data)) deallocate(this % nu_t_data) - if (allocated(this % nu_p_data)) deallocate(this % nu_p_data) - if (allocated(this % nu_d_data)) deallocate(this % nu_d_data) - - if (allocated(this % nu_d_precursor_data)) & - deallocate(this % nu_d_precursor_data) - - if (associated(this % nu_d_edist)) then - do i = 1, size(this % nu_d_edist) - call this % nu_d_edist(i) % clear() - end do - deallocate(this % nu_d_edist) - end if - - if (associated(this % urr_data)) then - call this % urr_data % clear() - deallocate(this % urr_data) - end if - - if (associated(this % reactions)) then - do i = 1, size(this % reactions) - call this % reactions(i) % clear() - end do - deallocate(this % reactions) - end if - - call this % nuc_list % clear() - - end subroutine nuclide_clear end module ace_header diff --git a/src/cross_section.F90 b/src/cross_section.F90 index 1586912a96..4e75970733 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -1,6 +1,6 @@ module cross_section - use ace_header, only: Nuclide, SAlphaBeta, Reaction, UrrData + use ace_header, only: Reaction, UrrData use constants use energy_grid, only: grid_method, log_spacing use error, only: fatal_error @@ -8,8 +8,10 @@ module cross_section use global use list_header, only: ListElemInt use material_header, only: Material + use nuclide_header use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: prn + use sab_header, only: SAlphaBeta use search, only: binary_search implicit none @@ -154,7 +156,7 @@ contains integer :: i_high ! upper logarithmic mapping index real(8), intent(in) :: E ! energy real(8) :: f ! interp factor on nuclide energy grid - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Material), pointer :: mat ! Set pointer to nuclide and material @@ -381,7 +383,7 @@ contains real(8) :: inelastic ! inelastic cross section logical :: same_nuc ! do we know the xs for this nuclide at this energy? type(UrrData), pointer :: urr - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn micro_xs(i_nuclide) % use_ptable = .true. @@ -553,11 +555,11 @@ contains function elastic_xs_0K(E, nuc) result(xs_out) - type(Nuclide), pointer :: nuc ! target nuclide at temperature - integer :: i_grid ! index on nuclide energy grid - real(8) :: f ! interp factor on nuclide energy grid - real(8), intent(inout) :: E ! trial energy - real(8) :: xs_out ! 0K xs at trial energy + type(Nuclide_CE), pointer :: nuc ! target nuclide at temperature + integer :: i_grid ! index on nuclide energy grid + real(8) :: f ! interp factor on nuclide energy grid + real(8), intent(inout) :: E ! trial energy + real(8) :: xs_out ! 0K xs at trial energy ! Determine index on nuclide energy grid if (E < nuc % energy_0K(1)) then diff --git a/src/energy_grid.F90 b/src/energy_grid.F90 index 66419f83cc..fa56b04956 100644 --- a/src/energy_grid.F90 +++ b/src/energy_grid.F90 @@ -27,7 +27,7 @@ contains integer :: i ! index in nuclides array integer :: j ! index in materials array type(ListReal) :: list - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Material), pointer :: mat call write_message("Creating unionized energy grid...", 5) @@ -70,7 +70,7 @@ contains real(8) :: E_max ! Maximum energy in MeV real(8) :: E_min ! Minimum energy in MeV real(8), allocatable :: umesh(:) ! Equally log-spaced energy grid - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc ! Set minimum/maximum energies E_max = energy_max_neutron @@ -179,7 +179,7 @@ contains integer :: index_e ! index on union energy grid real(8) :: union_energy ! energy on union grid real(8) :: energy ! energy on nuclide grid - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Material), pointer :: mat do k = 1, n_materials diff --git a/src/fission.F90 b/src/fission.F90 index 7b2911997b..5669080b75 100644 --- a/src/fission.F90 +++ b/src/fission.F90 @@ -1,10 +1,10 @@ module fission - use ace_header, only: Nuclide + use nuclide_header, only: Nuclide_CE use constants - use error, only: fatal_error - use interpolation, only: interpolate_tab1 - use search, only: binary_search + use error, only: fatal_error + use interpolation, only: interpolate_tab1 + use search, only: binary_search implicit none @@ -17,9 +17,9 @@ contains function nu_total(nuc, E) result(nu) - type(Nuclide), pointer :: nuc ! nuclide from which to find nu - real(8), intent(in) :: E ! energy of incoming neutron - real(8) :: nu ! number of total neutrons emitted per fission + type(Nuclide_CE), pointer :: nuc ! nuclide from which to find nu + real(8), intent(in) :: E ! energy of incoming neutron + real(8) :: nu ! number of total neutrons emitted per fission integer :: i ! loop index integer :: NC ! number of polynomial coefficients @@ -51,9 +51,9 @@ contains function nu_prompt(nuc, E) result(nu) - type(Nuclide), pointer :: nuc ! nuclide from which to find nu - real(8), intent(in) :: E ! energy of incoming neutron - real(8) :: nu ! number of prompt neutrons emitted per fission + type(Nuclide_CE), pointer :: nuc ! nuclide from which to find nu + real(8), intent(in) :: E ! energy of incoming neutron + real(8) :: nu ! number of prompt neutrons emitted per fission integer :: i ! loop index integer :: NC ! number of polynomial coefficients @@ -89,9 +89,9 @@ contains function nu_delayed(nuc, E) result(nu) - type(Nuclide), intent(in) :: nuc ! nuclide from which to find nu - real(8), intent(in) :: E ! energy of incoming neutron - real(8) :: nu ! number of delayed neutrons emitted per fission + type(Nuclide_CE) :: nuc ! nuclide from which to find nu + real(8), intent(in) :: E ! energy of incoming neutron + real(8) :: nu ! number of delayed neutrons emitted per fission if (nuc % nu_d_type == NU_NONE) then ! since no prompt or delayed data is present, this means all neutron @@ -113,7 +113,7 @@ contains function yield_delayed(nuc, E, g) result(yield) - type(Nuclide), intent(in) :: nuc ! nuclide from which to find nu + type(Nuclide_CE), pointer :: nuc ! nuclide from which to find nu real(8), intent(in) :: E ! energy of incoming neutron real(8) :: yield ! delayed neutron precursor yield integer, intent(in) :: g ! the delayed neutron precursor group diff --git a/src/global.F90 b/src/global.F90 index 98c3a6ed66..6ac5be3423 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -1,7 +1,5 @@ module global - use ace_header, only: Nuclide, SAlphaBeta, xsListing, NuclideMicroXS, & - MaterialMacroXS, Nuclide0K use bank_header, only: Bank use cmfd_header use constants @@ -9,7 +7,9 @@ module global use geometry_header, only: Cell, Universe, Lattice, LatticeContainer use material_header, only: Material use mesh_header, only: RegularMesh + use nuclide_header use plot_header, only: ObjectPlot + use sab_header, only: SAlphaBeta use set_header, only: SetInt use surface_header, only: SurfaceContainer use source_header, only: ExtSource @@ -66,7 +66,7 @@ module global ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES ! Cross section arrays - type(Nuclide), allocatable, target :: nuclides(:) ! Nuclide cross-sections + type(Nuclide_CE), allocatable, target :: nuclides(:) ! Nuclide cross-sections type(SAlphaBeta), allocatable, target :: sab_tables(:) ! S(a,b) tables type(XsListing), allocatable, target :: xs_listings(:) ! cross_sections.xml listings diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 new file mode 100644 index 0000000000..47baf96e37 --- /dev/null +++ b/src/nuclide_header.F90 @@ -0,0 +1,248 @@ +module nuclide_header + + use ace_header + use constants + use list_header, only: ListInt + ! use math, only: calc_pn, calc_rn!, expand_harmonic + !use scattdata_header + ! use xml_interface + + implicit none + +!=============================================================================== +! NUCLIDE_BASE contains the base nuclidic data for a nuclide, which does not depend +! upon how the nuclear data is represented (i.e., CE, or any variant of MG). +! The extended types, Nuclide_CE and Nuclide_MG deal with the rest +!=============================================================================== + + type, abstract :: Nuclide_Base + character(12) :: name ! name of nuclide, e.g. 92235.03c + integer :: zaid ! Z and A identifier, e.g. 92235 + real(8) :: awr ! Atomic Weight Ratio + integer :: listing ! index in xs_listings + real(8) :: kT ! temperature in MeV (k*T) + + ! Linked list of indices in nuclides array of instances of this same nuclide + type(ListInt) :: nuc_list + + ! Fission information + logical :: fissionable ! nuclide is fissionable? + + contains + procedure(nuclide_base_clear_), deferred, pass :: clear ! Deallocates Nuclide + end type Nuclide_Base + + type, extends(Nuclide_Base) :: Nuclide_CE + ! Energy grid information + integer :: n_grid ! # of nuclide grid points + integer, allocatable :: grid_index(:) ! log grid mapping indices + real(8), allocatable :: energy(:) ! energy values corresponding to xs + + ! Microscopic cross sections + real(8), allocatable :: total(:) ! total cross section + real(8), allocatable :: elastic(:) ! elastic scattering + real(8), allocatable :: fission(:) ! fission + real(8), allocatable :: nu_fission(:) ! neutron production + real(8), allocatable :: absorption(:) ! absorption (MT > 100) + real(8), allocatable :: heating(:) ! heating + + ! Resonance scattering info + logical :: resonant = .false. ! resonant scatterer? + character(10) :: name_0K = '' ! name of 0K nuclide, e.g. 92235.00c + character(16) :: scheme ! target velocity sampling scheme + integer :: n_grid_0K ! number of 0K energy grid points + real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs + real(8), allocatable :: elastic_0K(:) ! Microscopic elastic cross section + real(8), allocatable :: xs_cdf(:) ! CDF of v_rel times cross section + real(8) :: E_min ! lower cutoff energy for res scattering + real(8) :: E_max ! upper cutoff energy for res scattering + + ! Fission information + logical :: has_partial_fission ! nuclide has partial fission reactions? + integer :: n_fission ! # of fission reactions + integer, allocatable :: index_fission(:) ! indices in reactions + + ! Total fission neutron emission + integer :: nu_t_type + real(8), allocatable :: nu_t_data(:) + + ! Prompt fission neutron emission + integer :: nu_p_type + real(8), allocatable :: nu_p_data(:) + + ! Delayed fission neutron emission + integer :: nu_d_type + integer :: n_precursor ! # of delayed neutron precursors + real(8), allocatable :: nu_d_data(:) + real(8), allocatable :: nu_d_precursor_data(:) + type(DistEnergy), pointer :: nu_d_edist(:) => null() + + ! Unresolved resonance data + logical :: urr_present + integer :: urr_inelastic + type(UrrData), pointer :: urr_data => null() + + ! Reactions + integer :: n_reaction ! # of reactions + type(Reaction), pointer :: reactions(:) => null() + + ! Type-Bound procedures + contains + procedure, pass :: clear => nuclide_ce_clear + end type Nuclide_CE + +!=============================================================================== +! NUCLIDECONTAINER pointer array for storing Nuclides +!=============================================================================== + + type NuclideContainer + class(Nuclide_Base), pointer :: obj + end type NuclideContainer + +!=============================================================================== +! NUCLIDE0K temporarily contains all 0K cross section data and other parameters +! needed to treat resonance scattering before transferring them to NUCLIDE_CE +!=============================================================================== + + type Nuclide0K + + character(10) :: nuclide ! name of nuclide, e.g. U-238 + character(16) :: scheme = 'ares' ! target velocity sampling scheme + character(10) :: name ! name of nuclide, e.g. 92235.03c + character(10) :: name_0K ! name of 0K nuclide, e.g. 92235.00c + real(8) :: E_min = 0.01e-6_8 ! lower cutoff energy for res scattering + real(8) :: E_max = 1000.0e-6_8 ! upper cutoff energy for res scattering + + end type Nuclide0K + +!=============================================================================== +! NUCLIDEMICROXS contains cached microscopic cross sections for a +! particular nuclide at the current energy +!=============================================================================== + + type NuclideMicroXS + integer :: index_grid ! index on nuclide energy grid + integer :: index_temp ! temperature index for nuclide + real(8) :: last_E = ZERO ! last evaluated energy + real(8) :: interp_factor ! interpolation factor on nuc. energy grid + real(8) :: total ! microscropic total xs + real(8) :: elastic ! microscopic elastic scattering xs + real(8) :: absorption ! microscopic absorption xs + real(8) :: fission ! microscopic fission xs + real(8) :: nu_fission ! microscopic production xs + real(8) :: kappa_fission ! microscopic energy-released from fission + + ! Information for S(a,b) use + integer :: index_sab ! index in sab_tables (zero means no table) + integer :: last_index_sab = 0 ! index in sab_tables last used by this nuclide + real(8) :: elastic_sab ! microscopic elastic scattering on S(a,b) table + + ! Information for URR probability table use + logical :: use_ptable ! in URR range with probability tables? + real(8) :: last_prn + end type NuclideMicroXS + +!=============================================================================== +! MATERIALMACROXS contains cached macroscopic cross sections for the material a +! particle is traveling through +!=============================================================================== + + type MaterialMacroXS + real(8) :: total ! macroscopic total xs + real(8) :: elastic ! macroscopic elastic scattering xs + real(8) :: absorption ! macroscopic absorption xs + real(8) :: fission ! macroscopic fission xs + real(8) :: nu_fission ! macroscopic production xs + real(8) :: kappa_fission ! macroscopic energy-released from fission + end type MaterialMacroXS + +!=============================================================================== +! XSLISTING contains data read from a CE or MG cross_sections.xml file +! (or equivalent) +!=============================================================================== + + type XsListing + character(12) :: name ! table name, e.g. 92235.70c + character(12) :: alias ! table alias, e.g. U-235.70c + integer :: type ! type of table (cont-E neutron, S(A,b), etc) + integer :: zaid ! ZAID identifier = 1000*Z + A + integer :: filetype ! ASCII or BINARY + integer :: location ! location of table within library + integer :: recl ! record length for library + integer :: entries ! number of entries per record + real(8) :: awr ! atomic weight ratio (# of neutron masses) + real(8) :: kT ! Boltzmann constant * temperature (MeV) + logical :: metastable ! is this nuclide metastable? + character(MAX_FILE_LEN) :: path ! path to library containing table + end type XsListing + + contains + + +!=============================================================================== +! NUCLIDE_*_CLEAR resets and deallocates data in Nuclide_Base, Nuclide_Iso +! or Nuclide_Angle +!=============================================================================== + + subroutine nuclide_base_clear_(this) + + class(Nuclide_Base), intent(inout) :: this + + call this % nuc_list % clear() + end subroutine nuclide_base_clear_ + + subroutine nuclide_ce_clear(this) + + class(Nuclide_CE), intent(inout) :: this ! The Nuclide object to clear + + integer :: i ! Loop counter + + if (allocated(this % energy)) & + deallocate(this % energy, this % total, this % elastic, & + & this % fission, this % nu_fission, this % absorption) + + if (allocated(this % energy_0K)) & + deallocate(this % energy_0K) + + if (allocated(this % elastic_0K)) & + deallocate(this % elastic_0K) + + if (allocated(this % xs_cdf)) & + deallocate(this % xs_cdf) + + if (allocated(this % heating)) & + deallocate(this % heating) + + if (allocated(this % index_fission)) deallocate(this % index_fission) + + if (allocated(this % nu_t_data)) deallocate(this % nu_t_data) + if (allocated(this % nu_p_data)) deallocate(this % nu_p_data) + if (allocated(this % nu_d_data)) deallocate(this % nu_d_data) + + if (allocated(this % nu_d_precursor_data)) & + deallocate(this % nu_d_precursor_data) + + if (associated(this % nu_d_edist)) then + do i = 1, size(this % nu_d_edist) + call this % nu_d_edist(i) % clear() + end do + deallocate(this % nu_d_edist) + end if + + if (associated(this % urr_data)) then + call this % urr_data % clear() + deallocate(this % urr_data) + end if + + if (associated(this % reactions)) then + do i = 1, size(this % reactions) + call this % reactions(i) % clear() + end do + deallocate(this % reactions) + end if + + call nuclide_base_clear_(this) + + end subroutine nuclide_ce_clear + + end module nuclide_header \ No newline at end of file diff --git a/src/output.F90 b/src/output.F90 index 5bb90343c4..f933a2eb87 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -2,7 +2,7 @@ module output use, intrinsic :: ISO_FORTRAN_ENV - use ace_header, only: Nuclide, Reaction, UrrData + use ace_header, only: Reaction, UrrData use constants use endf, only: reaction_name use error, only: fatal_error, warning @@ -12,8 +12,10 @@ module output use math, only: t_percentile use mesh_header, only: RegularMesh use mesh, only: mesh_indices_to_bin, bin_to_mesh_indices + use nuclide_header use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use plot_header + use sab_header, only: SAlphaBeta use string, only: to_upper, to_str use tally_header, only: TallyObject @@ -326,7 +328,7 @@ contains subroutine print_nuclide(nuc, unit) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc integer, optional :: unit integer :: i ! loop index over nuclides @@ -531,8 +533,8 @@ contains integer :: i ! loop index integer :: unit_xs ! cross_sections.out file unit character(MAX_FILE_LEN) :: path ! path of summary file - type(Nuclide), pointer :: nuc => null() - type(SAlphaBeta), pointer :: sab => null() + type(Nuclide_CE), pointer :: nuc => null() + type(SAlphaBeta), pointer :: sab => null() ! Create filename for log file path = trim(path_output) // "cross_sections.out" diff --git a/src/physics.F90 b/src/physics.F90 index aae7027bae..b298fde9ce 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -1,6 +1,6 @@ module physics - use ace_header, only: Nuclide, Reaction, DistEnergy + use ace_header, only: Reaction, DistEnergy use constants use cross_section, only: elastic_xs_0K use endf, only: reaction_name @@ -11,6 +11,7 @@ module physics use material_header, only: Material use math, only: maxwell_spectrum, watt_spectrum use mesh, only: get_mesh_indices + use nuclide_header use output, only: write_message use particle_header, only: Particle_Base, Particle_CE, Particle_MG use particle_restart_write, only: write_particle_restart @@ -74,7 +75,7 @@ contains integer :: i_nuclide ! index in nuclides array integer :: i_reaction ! index in nuc % reactions array - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc i_nuclide = sample_nuclide(p, 'total ') @@ -193,7 +194,7 @@ contains real(8) :: f real(8) :: prob real(8) :: cutoff - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn ! Get pointer to nuclide @@ -310,7 +311,7 @@ contains real(8) :: f real(8) :: prob real(8) :: cutoff - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn ! Get pointer to nuclide and grid index/interpolation factor @@ -413,7 +414,7 @@ contains real(8) :: v_cm(3) ! velocity of center-of-mass real(8) :: v_t(3) ! velocity of target nucleus real(8) :: uvw_cm(3) ! directional cosines in center-of-mass - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc ! get pointer to nuclide nuc => nuclides(i_nuclide) @@ -738,7 +739,7 @@ contains subroutine sample_target_velocity(nuc, v_target, E, uvw, v_neut, wgt, xs_eff) - type(Nuclide), pointer :: nuc ! target nuclide at temperature T + type(Nuclide_CE), pointer :: nuc ! target nuclide at temperature T real(8), intent(out) :: v_target(3) ! target velocity real(8), intent(in) :: v_neut(3) ! neutron velocity @@ -985,7 +986,7 @@ contains subroutine sample_cxs_target_velocity(nuc, v_target, E, uvw) - type(Nuclide), pointer :: nuc ! target nuclide at temperature + type(Nuclide_CE), pointer :: nuc ! target nuclide at temperature real(8), intent(out) :: v_target(3) real(8), intent(in) :: E real(8), intent(in) :: uvw(3) @@ -1072,7 +1073,7 @@ contains real(8) :: phi ! fission neutron azimuthal angle real(8) :: weight ! weight adjustment for ufs method logical :: in_mesh ! source site in ufs mesh? - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn ! Get pointers @@ -1175,7 +1176,7 @@ contains function sample_fission_energy(nuc, rxn, p) result(E_out) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn class(Particle_Base), intent(inout) :: p ! Particle causing fission real(8) :: E_out ! outgoing E of fission neutron @@ -1304,7 +1305,7 @@ contains !=============================================================================== subroutine inelastic_scatter(nuc, rxn, p) - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn type(Particle_CE), intent(inout) :: p diff --git a/src/sab_header.F90 b/src/sab_header.F90 new file mode 100644 index 0000000000..99b5fb7843 --- /dev/null +++ b/src/sab_header.F90 @@ -0,0 +1,62 @@ +module sab_header + + use constants + + implicit none + +!=============================================================================== +! DISTENERGYSAB contains the secondary energy/angle distributions for inelastic +! thermal scattering collisions which utilize a continuous secondary energy +! representation. +!=============================================================================== + + type DistEnergySab + integer :: n_e_out + real(8), allocatable :: e_out(:) + real(8), allocatable :: e_out_pdf(:) + real(8), allocatable :: e_out_cdf(:) + real(8), allocatable :: mu(:,:) + end type DistEnergySab + +!=============================================================================== +! SALPHABETA contains S(a,b) data for thermal neutron scattering, typically off +! of light isotopes such as water, graphite, Be, etc +!=============================================================================== + + type SAlphaBeta + character(10) :: name ! name of table, e.g. lwtr.10t + real(8) :: awr ! weight of nucleus in neutron masses + real(8) :: kT ! temperature in MeV (k*T) + integer :: n_zaid ! Number of valid zaids + integer, allocatable :: zaid(:) ! List of valid Z and A identifiers, e.g. 6012 + + ! threshold for S(a,b) treatment (usually ~4 eV) + real(8) :: threshold_inelastic + real(8) :: threshold_elastic = ZERO + + ! Inelastic scattering data + integer :: n_inelastic_e_in ! # of incoming E for inelastic + integer :: n_inelastic_e_out ! # of outgoing E for inelastic + integer :: n_inelastic_mu ! # of outgoing angles for inelastic + integer :: secondary_mode ! secondary mode (equal/skewed/continuous) + real(8), allocatable :: inelastic_e_in(:) + real(8), allocatable :: inelastic_sigma(:) + ! The following are used only if secondary_mode is 0 or 1 + real(8), allocatable :: inelastic_e_out(:,:) + real(8), allocatable :: inelastic_mu(:,:,:) + ! The following is used only if secondary_mode is 3 + ! The different implementation is necessary because the continuous + ! representation has a variable number of outgoing energy points for each + ! incoming energy + type(DistEnergySab), allocatable :: inelastic_data(:) ! One for each Ein + + ! Elastic scattering data + integer :: elastic_mode ! elastic mode (discrete/exact) + integer :: n_elastic_e_in ! # of incoming E for elastic + integer :: n_elastic_mu ! # of outgoing angles for elastic + real(8), allocatable :: elastic_e_in(:) + real(8), allocatable :: elastic_P(:) + real(8), allocatable :: elastic_mu(:,:) + end type SAlphaBeta + +end module sab_header diff --git a/src/summary.F90 b/src/summary.F90 index f2c261ec75..0e5a591aa9 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -1,6 +1,6 @@ module summary - use ace_header, only: Reaction, UrrData, Nuclide + use ace_header, only: Reaction, UrrData use constants use endf, only: reaction_name use geometry_header, only: Cell, Universe, Lattice, RectLattice, & @@ -9,6 +9,7 @@ module summary use hdf5_interface use material_header, only: Material use mesh_header, only: RegularMesh + use nuclide_header use output, only: time_stamp use surface_header use string, only: to_str diff --git a/src/tally.F90 b/src/tally.F90 index 248f87c6a7..5336f69bda 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -68,7 +68,7 @@ contains real(8) :: uvw(3) ! particle direction type(Material), pointer :: mat type(Reaction), pointer :: rxn - type(Nuclide), pointer :: nuc + type(Nuclide_CE), pointer :: nuc i = 0 SCORE_LOOP: do q = 1, t % n_user_score_bins From 3310e84d0ae794a7db713cefc30ac706692ec0f0 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 21:17:19 -0400 Subject: [PATCH 05/84] Separated string to simple_string and string; the former has no dependency on error which really reduces circular dependencies. Then, added ability to nuclide and salphabeta to print their own data. This will be useful when multiple nuclide types exist --- src/ace.F90 | 2 +- src/cmfd_data.F90 | 22 +-- src/cmfd_execute.F90 | 22 +-- src/cmfd_input.F90 | 6 +- src/eigenvalue.F90 | 16 +- src/endf.F90 | 2 +- src/geometry.F90 | 2 +- src/initialize.F90 | 3 +- src/input_xml.F90 | 4 +- src/interpolation.F90 | 8 +- src/nuclide_header.F90 | 135 +++++++++++++++- src/output.F90 | 206 +----------------------- src/particle_restart_write.F90 | 2 +- src/physics.F90 | 2 +- src/plot.F90 | 2 +- src/sab_header.F90 | 92 +++++++++++ src/simulation.F90 | 32 ++-- src/source.F90 | 2 +- src/state_point.F90 | 3 +- src/string.F90 | 281 +++------------------------------ src/summary.F90 | 2 +- src/tally.F90 | 2 +- src/track_output.F90 | 2 +- src/tracking.F90 | 2 +- src/trigger.F90 | 2 +- 25 files changed, 324 insertions(+), 530 deletions(-) diff --git a/src/ace.F90 b/src/ace.F90 index a93f722958..729b78b323 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -12,7 +12,7 @@ module ace use output, only: write_message use sab_header, only: SAlphaBeta use set_header, only: SetChar - use string, only: to_str, to_lower + use simple_string, only: to_str, to_lower implicit none diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index 19fe395728..b624e839d7 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -49,17 +49,17 @@ contains subroutine compute_xs() - use constants, only: FILTER_MESH, FILTER_ENERGYIN, FILTER_ENERGYOUT, & + use constants, only: FILTER_MESH, FILTER_ENERGYIN, FILTER_ENERGYOUT, & FILTER_SURFACE, IN_RIGHT, OUT_RIGHT, IN_FRONT, & OUT_FRONT, IN_TOP, OUT_TOP, CMFD_NOACCEL, ZERO, & ONE, TINY_BIT - use error, only: fatal_error - use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,& + use error, only: fatal_error + use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,& matching_bins - use mesh, only: mesh_indices_to_bin - use mesh_header, only: RegularMesh - use string, only: to_str - use tally_header, only: TallyObject + use mesh, only: mesh_indices_to_bin + use mesh_header, only: RegularMesh + use simple_string, only: to_str + use tally_header, only: TallyObject integer :: nx ! number of mesh cells in x direction integer :: ny ! number of mesh cells in y direction @@ -625,10 +625,10 @@ contains subroutine compute_dhat() - use constants, only: CMFD_NOACCEL, ZERO - use global, only: cmfd, cmfd_coremap, dhat_reset - use output, only: write_message - use string, only: to_str + use constants, only: CMFD_NOACCEL, ZERO + use global, only: cmfd, cmfd_coremap, dhat_reset + use output, only: write_message + use simple_string, only: to_str integer :: nx ! maximum number of cells in x direction integer :: ny ! maximum number of cells in y direction diff --git a/src/cmfd_execute.F90 b/src/cmfd_execute.F90 index 4dfe99d770..af6991e47d 100644 --- a/src/cmfd_execute.F90 +++ b/src/cmfd_execute.F90 @@ -89,9 +89,9 @@ contains subroutine calc_fission_source() - use constants, only: CMFD_NOACCEL, ZERO, TWO - use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch - use string, only: to_str + use constants, only: CMFD_NOACCEL, ZERO, TWO + use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch + use simple_string, only: to_str #ifdef MPI use global, only: mpi_err @@ -213,14 +213,14 @@ contains subroutine cmfd_reweight(new_weights) - use constants, only: ZERO, ONE - use error, only: warning, fatal_error - use global, only: meshes, source_bank, work, n_user_meshes, cmfd, & - master - use mesh_header, only: RegularMesh - use mesh, only: count_bank_sites, get_mesh_indices - use search, only: binary_search - use string, only: to_str + use constants, only: ZERO, ONE + use error, only: warning, fatal_error + use global, only: meshes, source_bank, work, n_user_meshes, cmfd, & + master + use mesh_header, only: RegularMesh + use mesh, only: count_bank_sites, get_mesh_indices + use search, only: binary_search + use simple_string, only: to_str #ifdef MPI use global, only: mpi_err diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index dac74c9c39..c15c250e64 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -45,10 +45,10 @@ contains subroutine read_cmfd_xml() use constants, only: ZERO, ONE - use error, only: fatal_error, warning + use error, only: fatal_error, warning use global - use output, only: write_message - use string, only: to_lower + use output, only: write_message + use simple_string, only: to_lower use xml_interface use, intrinsic :: ISO_FORTRAN_ENV diff --git a/src/eigenvalue.F90 b/src/eigenvalue.F90 index 50d6cabc5e..83f8989cc0 100644 --- a/src/eigenvalue.F90 +++ b/src/eigenvalue.F90 @@ -4,16 +4,16 @@ module eigenvalue use message_passing #endif - use constants, only: ZERO - use error, only: fatal_error, warning + use constants, only: ZERO + use error, only: fatal_error, warning use global - use math, only: t_percentile - use mesh, only: count_bank_sites - use mesh_header, only: RegularMesh + use math, only: t_percentile + use mesh, only: count_bank_sites + use mesh_header, only: RegularMesh ! use particle_header, only: Particle_Base - use random_lcg, only: prn, set_particle_seed, prn_skip - use search, only: binary_search - use string, only: to_str + use random_lcg, only: prn, set_particle_seed, prn_skip + use search, only: binary_search + use simple_string, only: to_str implicit none diff --git a/src/endf.F90 b/src/endf.F90 index fb85262b20..6251e989c6 100644 --- a/src/endf.F90 +++ b/src/endf.F90 @@ -1,7 +1,7 @@ module endf use constants - use string, only: to_str + use simple_string, only: to_str implicit none diff --git a/src/geometry.F90 b/src/geometry.F90 index e3058d6e00..ee23a4e36e 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -10,7 +10,7 @@ module geometry Particle_MG use particle_restart_write, only: write_particle_restart use surface_header - use string, only: to_str + use simple_string, only: to_str use tally, only: score_surface_current implicit none diff --git a/src/initialize.F90 b/src/initialize.F90 index 9d63eb4e93..44ec98a882 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -21,7 +21,8 @@ module initialize print_usage, write_xs_summary, print_plot use random_lcg, only: initialize_prng use state_point, only: load_state_point - use string, only: to_str, str_to_int, starts_with, ends_with + use simple_string, only: to_str, starts_with, ends_with + use string, only: str_to_int use summary, only: write_summary use tally_header, only: TallyObject, TallyResult, TallyFilter use tally_initialize, only: configure_tallies diff --git a/src/input_xml.F90 b/src/input_xml.F90 index dda1b90837..a9c5a8e221 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -14,8 +14,8 @@ module input_xml use random_lcg, only: prn use surface_header use stl_vector, only: VectorInt - use string, only: to_lower, to_str, str_to_int, str_to_real, & - starts_with, ends_with, tokenize + use simple_string, only: to_lower, to_str, starts_with, ends_with + use string, only: str_to_int, str_to_real, tokenize use tally_header, only: TallyObject, TallyFilter use tally_initialize, only: add_tallies use xml_interface diff --git a/src/interpolation.F90 b/src/interpolation.F90 index 5c44ed7c3d..03561ba13b 100644 --- a/src/interpolation.F90 +++ b/src/interpolation.F90 @@ -1,10 +1,10 @@ module interpolation use constants - use endf_header, only: Tab1 - use error, only: fatal_error - use search, only: binary_search - use string, only: to_str + use endf_header, only: Tab1 + use error, only: fatal_error + use search, only: binary_search + use simple_string, only: to_str implicit none diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 47baf96e37..cd83402a07 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -1,10 +1,14 @@ module nuclide_header + use, intrinsic :: ISO_FORTRAN_ENV + use ace_header use constants - use list_header, only: ListInt + use endf, only: reaction_name + use list_header, only: ListInt ! use math, only: calc_pn, calc_rn!, expand_harmonic !use scattdata_header + use simple_string ! use xml_interface implicit none @@ -30,8 +34,18 @@ module nuclide_header contains procedure(nuclide_base_clear_), deferred, pass :: clear ! Deallocates Nuclide + procedure(print_nuclide_), deferred, pass :: print ! Writes nuclide info end type Nuclide_Base + abstract interface + subroutine print_nuclide_(this, unit) + import Nuclide_Base + class(Nuclide_Base),intent(in) :: this + integer, optional, intent(in) :: unit + end subroutine print_nuclide_ + + end interface + type, extends(Nuclide_Base) :: Nuclide_CE ! Energy grid information integer :: n_grid ! # of nuclide grid points @@ -89,6 +103,7 @@ module nuclide_header ! Type-Bound procedures contains procedure, pass :: clear => nuclide_ce_clear + procedure, pass :: print => nuclide_ce_print end type Nuclide_CE !=============================================================================== @@ -245,4 +260,122 @@ module nuclide_header end subroutine nuclide_ce_clear +!=============================================================================== +! PRINT_NUCLIDE_* displays information about a continuous-energy neutron +! cross_section table and its reactions and secondary angle/energy distributions +!=============================================================================== + + subroutine nuclide_ce_print(this, unit) + + class(Nuclide_CE), intent(in) :: this + integer, optional, intent(in) :: unit + + integer :: i ! loop index over nuclides + integer :: unit_ ! unit to write to + integer :: size_total ! memory used by nuclide (bytes) + integer :: size_angle_total ! total memory used for angle dist. (bytes) + integer :: size_energy_total ! total memory used for energy dist. (bytes) + integer :: size_xs ! memory used for cross-sections (bytes) + integer :: size_angle ! memory used for an angle distribution (bytes) + integer :: size_energy ! memory used for a energy distributions (bytes) + integer :: size_urr ! memory used for probability tables (bytes) + character(11) :: law ! secondary energy distribution law + type(Reaction), pointer :: rxn => null() + type(UrrData), pointer :: urr => null() + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Initialize totals + size_angle_total = 0 + size_energy_total = 0 + size_urr = 0 + size_xs = 0 + + ! Basic nuclide information + write(unit_,*) 'Nuclide ' // trim(this % name) + write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid)) + write(unit_,*) ' Fissionable = ', this % fissionable + write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission)) + write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction)) + + ! Information on each reaction + write(unit_,*) ' Reaction Q-value COM Law IE size(angle) size(energy)' + do i = 1, this % n_reaction + rxn => this % reactions(i) + + ! Determine size of angle distribution + if (rxn % has_angle_dist) then + size_angle = rxn % adist % n_energy * 16 + size(rxn % adist % data) * 8 + else + size_angle = 0 + end if + + ! Determine size of energy distribution and law + if (rxn % has_energy_dist) then + size_energy = size(rxn % edist % data) * 8 + law = to_str(rxn % edist % law) + else + size_energy = 0 + law = 'None' + end if + + write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,A4,1X,I6,1X,I11,1X,I11)') & + reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, & + law(1:4), rxn % threshold, size_angle, size_energy + + ! Accumulate data size + size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8 + size_angle_total = size_angle_total + size_angle + size_energy_total = size_energy_total + size_energy + end do + + ! Add memory required for summary reactions (total, absorption, fission, + ! nu-fission) + size_xs = 8 * this % n_grid * 4 + + ! Write information about URR probability tables + size_urr = 0 + if (this % urr_present) then + urr => this % urr_data + write(unit_,*) ' Unresolved resonance probability table:' + write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy)) + write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob)) + write(unit_,*) ' Interpolation = ' // trim(to_str(urr % interp)) + write(unit_,*) ' Inelastic flag = ' // trim(to_str(urr % inelastic_flag)) + write(unit_,*) ' Absorption flag = ' // trim(to_str(urr % absorption_flag)) + write(unit_,*) ' Multiply by smooth? ', urr % multiply_smooth + write(unit_,*) ' Min energy = ', trim(to_str(urr % energy(1))) + write(unit_,*) ' Max energy = ', trim(to_str(urr % energy(urr % n_energy))) + + ! Calculate memory used by probability tables and add to total + size_urr = urr % n_energy * (urr % n_prob * 6 + 1) * 8 + end if + + ! Calculate total memory + size_total = size_xs + size_angle_total + size_energy_total + size_urr + + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes' + write(unit_,*) ' Secondary angle distributions = ' // & + trim(to_str(size_angle_total)) // ' bytes' + write(unit_,*) ' Secondary energy distributions = ' // & + trim(to_str(size_energy_total)) // ' bytes' + write(unit_,*) ' Probability Tables = ' // & + trim(to_str(size_urr)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' + + ! Blank line at end of nuclide + write(unit_,*) + + end subroutine nuclide_ce_print + end module nuclide_header \ No newline at end of file diff --git a/src/output.F90 b/src/output.F90 index f933a2eb87..3dba183148 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -16,7 +16,7 @@ module output use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use plot_header use sab_header, only: SAlphaBeta - use string, only: to_upper, to_str + use simple_string, only: to_upper, to_str use tally_header, only: TallyObject implicit none @@ -321,206 +321,6 @@ contains end subroutine print_particle -!=============================================================================== -! PRINT_NUCLIDE displays information about a continuous-energy neutron -! cross_section table and its reactions and secondary angle/energy distributions -!=============================================================================== - - subroutine print_nuclide(nuc, unit) - - type(Nuclide_CE), pointer :: nuc - integer, optional :: unit - - integer :: i ! loop index over nuclides - integer :: unit_ ! unit to write to - integer :: size_total ! memory used by nuclide (bytes) - integer :: size_angle_total ! total memory used for angle dist. (bytes) - integer :: size_energy_total ! total memory used for energy dist. (bytes) - integer :: size_xs ! memory used for cross-sections (bytes) - integer :: size_angle ! memory used for an angle distribution (bytes) - integer :: size_energy ! memory used for a energy distributions (bytes) - integer :: size_urr ! memory used for probability tables (bytes) - character(11) :: law ! secondary energy distribution law - type(Reaction), pointer :: rxn => null() - type(UrrData), pointer :: urr => null() - - ! set default unit for writing information - if (present(unit)) then - unit_ = unit - else - unit_ = OUTPUT_UNIT - end if - - ! Initialize totals - size_angle_total = 0 - size_energy_total = 0 - size_urr = 0 - size_xs = 0 - - ! Basic nuclide information - write(unit_,*) 'Nuclide ' // trim(nuc % name) - write(unit_,*) ' zaid = ' // trim(to_str(nuc % zaid)) - write(unit_,*) ' awr = ' // trim(to_str(nuc % awr)) - write(unit_,*) ' kT = ' // trim(to_str(nuc % kT)) - write(unit_,*) ' # of grid points = ' // trim(to_str(nuc % n_grid)) - write(unit_,*) ' Fissionable = ', nuc % fissionable - write(unit_,*) ' # of fission reactions = ' // trim(to_str(nuc % n_fission)) - write(unit_,*) ' # of reactions = ' // trim(to_str(nuc % n_reaction)) - - ! Information on each reaction - write(unit_,*) ' Reaction Q-value COM Law IE size(angle) size(energy)' - do i = 1, nuc % n_reaction - rxn => nuc % reactions(i) - - ! Determine size of angle distribution - if (rxn % has_angle_dist) then - size_angle = rxn % adist % n_energy * 16 + size(rxn % adist % data) * 8 - else - size_angle = 0 - end if - - ! Determine size of energy distribution and law - if (rxn % has_energy_dist) then - size_energy = size(rxn % edist % data) * 8 - law = to_str(rxn % edist % law) - else - size_energy = 0 - law = 'None' - end if - - write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,A4,1X,I6,1X,I11,1X,I11)') & - reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, & - law(1:4), rxn % threshold, size_angle, size_energy - - ! Accumulate data size - size_xs = size_xs + (nuc % n_grid - rxn%threshold + 1) * 8 - size_angle_total = size_angle_total + size_angle - size_energy_total = size_energy_total + size_energy - end do - - ! Add memory required for summary reactions (total, absorption, fission, - ! nu-fission) - size_xs = 8 * nuc % n_grid * 4 - - ! Write information about URR probability tables - size_urr = 0 - if (nuc % urr_present) then - urr => nuc % urr_data - write(unit_,*) ' Unresolved resonance probability table:' - write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy)) - write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob)) - write(unit_,*) ' Interpolation = ' // trim(to_str(urr % interp)) - write(unit_,*) ' Inelastic flag = ' // trim(to_str(urr % inelastic_flag)) - write(unit_,*) ' Absorption flag = ' // trim(to_str(urr % absorption_flag)) - write(unit_,*) ' Multiply by smooth? ', urr % multiply_smooth - write(unit_,*) ' Min energy = ', trim(to_str(urr % energy(1))) - write(unit_,*) ' Max energy = ', trim(to_str(urr % energy(urr % n_energy))) - - ! Calculate memory used by probability tables and add to total - size_urr = urr % n_energy * (urr % n_prob * 6 + 1) * 8 - end if - - ! Calculate total memory - size_total = size_xs + size_angle_total + size_energy_total + size_urr - - ! Write memory used - write(unit_,*) ' Memory Requirements' - write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes' - write(unit_,*) ' Secondary angle distributions = ' // & - trim(to_str(size_angle_total)) // ' bytes' - write(unit_,*) ' Secondary energy distributions = ' // & - trim(to_str(size_energy_total)) // ' bytes' - write(unit_,*) ' Probability Tables = ' // & - trim(to_str(size_urr)) // ' bytes' - write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' - - ! Blank line at end of nuclide - write(unit_,*) - - end subroutine print_nuclide - -!=============================================================================== -! PRINT_SAB_TABLE displays information about a S(a,b) table containing data -! describing thermal scattering from bound materials such as hydrogen in water. -!=============================================================================== - - subroutine print_sab_table(sab, unit) - - type(SAlphaBeta), pointer :: sab - integer, optional :: unit - - integer :: size_sab ! memory used by S(a,b) table - integer :: unit_ ! unit to write to - integer :: i ! Loop counter for parsing through sab % zaid - integer :: char_count ! Counter for the number of characters on a line - - ! set default unit for writing information - if (present(unit)) then - unit_ = unit - else - unit_ = OUTPUT_UNIT - end if - - ! Basic S(a,b) table information - write(unit_,*) 'S(a,b) Table ' // trim(sab % name) - write(unit_,'(A)',advance="no") ' zaids = ' - ! Initialize the counter based on the above string - char_count = 11 - do i = 1, sab % n_zaid - ! Deal with a line thats too long - if (char_count >= 73) then ! 73 = 80 - (5 ZAID chars + 1 space + 1 comma) - ! End the line - write(unit_,*) "" - ! Add 11 leading blanks - write(unit_,'(A)', advance="no") " " - ! reset the counter to 11 - char_count = 11 - end if - if (i < sab % n_zaid) then - ! Include a comma - write(unit_,'(A)',advance="no") trim(to_str(sab % zaid(i))) // ", " - char_count = char_count + len(trim(to_str(sab % zaid(i)))) + 2 - else - ! Don't include a comma, since we are all done - write(unit_,'(A)',advance="no") trim(to_str(sab % zaid(i))) - end if - - end do - write(unit_,*) "" ! Move to next line - write(unit_,*) ' awr = ' // trim(to_str(sab % awr)) - write(unit_,*) ' kT = ' // trim(to_str(sab % kT)) - - ! Inelastic data - write(unit_,*) ' # of Incoming Energies (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_e_in)) - write(unit_,*) ' # of Outgoing Energies (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_e_out)) - write(unit_,*) ' # of Outgoing Angles (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_mu)) - write(unit_,*) ' Threshold for Inelastic = ' // & - trim(to_str(sab % threshold_inelastic)) - - ! Elastic data - if (sab % n_elastic_e_in > 0) then - write(unit_,*) ' # of Incoming Energies (Elastic) = ' // & - trim(to_str(sab % n_elastic_e_in)) - write(unit_,*) ' # of Outgoing Angles (Elastic) = ' // & - trim(to_str(sab % n_elastic_mu)) - write(unit_,*) ' Threshold for Elastic = ' // & - trim(to_str(sab % threshold_elastic)) - end if - - ! Determine memory used by S(a,b) table and write out - size_sab = 8 * (sab % n_inelastic_e_in * (2 + sab % n_inelastic_e_out * & - (1 + sab % n_inelastic_mu)) + sab % n_elastic_e_in * & - (2 + sab % n_elastic_mu)) - write(unit_,*) ' Memory Used = ' // trim(to_str(size_sab)) // ' bytes' - - ! Blank line at end - write(unit_,*) - - end subroutine print_sab_table - !=============================================================================== ! WRITE_XS_SUMMARY writes information about each nuclide and S(a,b) table to a ! file called cross_sections.out. This file shows the list of reactions as well @@ -550,7 +350,7 @@ contains nuc => nuclides(i) ! Print information about nuclide - call print_nuclide(nuc, unit=unit_xs) + call nuc % print(unit=unit_xs) end do NUCLIDE_LOOP SAB_TABLES_LOOP: do i = 1, n_sab_tables @@ -558,7 +358,7 @@ contains sab => sab_tables(i) ! Print information about S(a,b) table - call print_sab_table(sab, unit=unit_xs) + call sab % print(unit=unit_xs) end do SAB_TABLES_LOOP ! Close cross section summary file diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index 9dff7e5f3b..a7341d71ec 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -4,7 +4,7 @@ module particle_restart_write use global use hdf5_interface use particle_header, only: Particle_Base - use string, only: to_str + use simple_string, only: to_str use hdf5 diff --git a/src/physics.F90 b/src/physics.F90 index b298fde9ce..a24ab8de4d 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -17,7 +17,7 @@ module physics use particle_restart_write, only: write_particle_restart use random_lcg, only: prn use search, only: binary_search - use string, only: to_str + use simple_string, only: to_str implicit none diff --git a/src/plot.F90 b/src/plot.F90 index 6ac2da2c14..e46742ea1a 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -14,7 +14,7 @@ module plot use ppmlib, only: Image, init_image, allocate_image, & deallocate_image, set_pixel use progress_header, only: ProgressBar - use string, only: to_str + use simple_string, only: to_str use hdf5 diff --git a/src/sab_header.F90 b/src/sab_header.F90 index 99b5fb7843..a70a280cfb 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -1,6 +1,9 @@ module sab_header + use, intrinsic :: ISO_FORTRAN_ENV + use constants + use simple_string, only: to_str implicit none @@ -57,6 +60,95 @@ module sab_header real(8), allocatable :: elastic_e_in(:) real(8), allocatable :: elastic_P(:) real(8), allocatable :: elastic_mu(:,:) + contains + procedure, pass :: print => print_sab_table end type SAlphaBeta + contains + + +!=============================================================================== +! PRINT_SAB_TABLE displays information about a S(a,b) table containing data +! describing thermal scattering from bound materials such as hydrogen in water. +!=============================================================================== + + subroutine print_sab_table(this, unit) + + class(SAlphaBeta), intent(in) :: this + integer, optional, intent(in) :: unit + + integer :: size_sab ! memory used by S(a,b) table + integer :: unit_ ! unit to write to + integer :: i ! Loop counter for parsing through sab % zaid + integer :: char_count ! Counter for the number of characters on a line + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Basic S(a,b) table information + write(unit_,*) 'S(a,b) Table ' // trim(this % name) + write(unit_,'(A)',advance="no") ' zaids = ' + ! Initialize the counter based on the above string + char_count = 11 + do i = 1, this % n_zaid + ! Deal with a line thats too long + if (char_count >= 73) then ! 73 = 80 - (5 ZAID chars + 1 space + 1 comma) + ! End the line + write(unit_,*) "" + ! Add 11 leading blanks + write(unit_,'(A)', advance="no") " " + ! reset the counter to 11 + char_count = 11 + end if + if (i < this % n_zaid) then + ! Include a comma + write(unit_,'(A)',advance="no") trim(to_str(this % zaid(i))) // ", " + char_count = char_count + len(trim(to_str(this % zaid(i)))) + 2 + else + ! Don't include a comma, since we are all done + write(unit_,'(A)',advance="no") trim(to_str(this % zaid(i))) + end if + + end do + write(unit_,*) "" ! Move to next line + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + + ! Inelastic data + write(unit_,*) ' # of Incoming Energies (Inelastic) = ' // & + trim(to_str(this % n_inelastic_e_in)) + write(unit_,*) ' # of Outgoing Energies (Inelastic) = ' // & + trim(to_str(this % n_inelastic_e_out)) + write(unit_,*) ' # of Outgoing Angles (Inelastic) = ' // & + trim(to_str(this % n_inelastic_mu)) + write(unit_,*) ' Threshold for Inelastic = ' // & + trim(to_str(this % threshold_inelastic)) + + ! Elastic data + if (this % n_elastic_e_in > 0) then + write(unit_,*) ' # of Incoming Energies (Elastic) = ' // & + trim(to_str(this % n_elastic_e_in)) + write(unit_,*) ' # of Outgoing Angles (Elastic) = ' // & + trim(to_str(this % n_elastic_mu)) + write(unit_,*) ' Threshold for Elastic = ' // & + trim(to_str(this % threshold_elastic)) + end if + + ! Determine memory used by S(a,b) table and write out + size_sab = 8 * (this % n_inelastic_e_in * (2 + this % n_inelastic_e_out * & + (1 + this % n_inelastic_mu)) + this % n_elastic_e_in * & + (2 + this % n_elastic_mu)) + write(unit_,*) ' Memory Used = ' // trim(to_str(size_sab)) // ' bytes' + + ! Blank line at end + write(unit_,*) + + end subroutine print_sab_table + + + end module sab_header diff --git a/src/simulation.F90 b/src/simulation.F90 index a674a18df4..c31b1d6fa7 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -4,26 +4,26 @@ module simulation use mpi #endif - use cmfd_execute, only: cmfd_init_batch, execute_cmfd - use constants, only: ZERO - use eigenvalue, only: count_source_for_ufs, calculate_average_keff, & - calculate_combined_keff, calculate_generation_keff, & - shannon_entropy, synchronize_bank, keff_generation + use cmfd_execute, only: cmfd_init_batch, execute_cmfd + use constants, only: ZERO + use eigenvalue, only: count_source_for_ufs, calculate_average_keff, & + calculate_combined_keff, calculate_generation_keff, & + shannon_entropy, synchronize_bank, keff_generation #ifdef _OPENMP - use eigenvalue, only: join_bank_from_threads + use eigenvalue, only: join_bank_from_threads #endif use global - use output, only: write_message, header, print_columns, & - print_batch_keff, print_generation + use output, only: write_message, header, print_columns, & + print_batch_keff, print_generation use particle_header, only: Particle_Base - use random_lcg, only: set_particle_seed - use source, only: initialize_source - use state_point, only: write_state_point, write_source_point - use string, only: to_str - use tally, only: synchronize_tallies, setup_active_usertallies, & - reset_result - use trigger, only: check_triggers - use tracking, only: transport + use random_lcg, only: set_particle_seed + use source, only: initialize_source + use state_point, only: write_state_point, write_source_point + use simple_string, only: to_str + use tally, only: synchronize_tallies, setup_active_usertallies, & + reset_result + use trigger, only: check_triggers + use tracking, only: transport implicit none private diff --git a/src/source.F90 b/src/source.F90 index e8cb420083..b83bf766e6 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -12,7 +12,7 @@ module source use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: prn, set_particle_seed, prn_set_stream use state_point, only: read_source_bank, write_source_bank - use string, only: to_str + use simple_string, only: to_str #ifdef MPI use message_passing diff --git a/src/state_point.F90 b/src/state_point.F90 index 046e7e6669..7a414f4574 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -18,7 +18,8 @@ module state_point use global use hdf5_interface use output, only: write_message, time_stamp - use string, only: to_str, zero_padded, count_digits + use simple_string, only: to_str, count_digits + use string, only: zero_padded use tally_header, only: TallyObject use mesh_header, only: RegularMesh use dict_header, only: ElemKeyValueII, ElemKeyValueCI diff --git a/src/string.F90 b/src/string.F90 index 45db59c875..3fbc9e1d79 100644 --- a/src/string.F90 +++ b/src/string.F90 @@ -1,17 +1,14 @@ module string - use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & - OP_LEFT_PAREN, OP_RIGHT_PAREN, OP_COMPLEMENT, OP_INTERSECTION, OP_UNION - use error, only: fatal_error, warning - use global, only: master + use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & + OP_LEFT_PAREN, OP_RIGHT_PAREN, OP_COMPLEMENT, & + OP_INTERSECTION, OP_UNION + use error, only: fatal_error, warning + use global, only: master use stl_vector, only: VectorInt implicit none - interface to_str - module procedure int4_to_str, int8_to_str, real_to_str - end interface - contains !=============================================================================== @@ -182,51 +179,7 @@ contains end function concatenate -!=============================================================================== -! TO_LOWER converts a string to all lower case characters -!=============================================================================== - function to_lower(word) result(word_lower) - - character(*), intent(in) :: word - character(len=len(word)) :: word_lower - - integer :: i - integer :: ic - - do i = 1, len(word) - ic = ichar(word(i:i)) - if (ic >= 65 .and. ic <= 90) then - word_lower(i:i) = char(ic+32) - else - word_lower(i:i) = word(i:i) - end if - end do - - end function to_lower - -!=============================================================================== -! TO_UPPER converts a string to all upper case characters -!=============================================================================== - - function to_upper(word) result(word_upper) - - character(*), intent(in) :: word - character(len=len(word)) :: word_upper - - integer :: i - integer :: ic - - do i = 1, len(word) - ic = ichar(word(i:i)) - if (ic >= 97 .and. ic <= 122) then - word_upper(i:i) = char(ic-32) - else - word_upper(i:i) = word(i:i) - end if - end do - - end function to_upper !=============================================================================== ! ZERO_PADDED returns a string of the input integer padded with zeros to the @@ -234,163 +187,32 @@ contains ! integers. !=============================================================================== -function zero_padded(num, n_digits) result(str) - integer, intent(in) :: num - integer, intent(in) :: n_digits - character(11) :: str + function zero_padded(num, n_digits) result(str) + integer, intent(in) :: num + integer, intent(in) :: n_digits + character(11) :: str - character(8) :: zp_form + character(8) :: zp_form - ! Make sure n_digits is reasonable. 10 digits is the maximum needed for the - ! largest integer(4). - if (n_digits > 10) then - call fatal_error('zero_padded called with an unreasonably large & - &n_digits (>10)') - end if - - ! Write a format string of the form '(In.m)' where n is the max width and - ! m is the min width. If a sign is present, then n must be one greater - ! than m. - if (num < 0) then - write(zp_form, '("(I", I0, ".", I0, ")")') n_digits+1, n_digits - else - write(zp_form, '("(I", I0, ".", I0, ")")') n_digits, n_digits - end if - - ! Format the number. - write(str, zp_form) num -end function zero_padded - -!=============================================================================== -! IS_NUMBER determines whether a string of characters is all 0-9 characters -!=============================================================================== - - function is_number(word) result(number) - - character(*), intent(in) :: word - logical :: number - - integer :: i - integer :: ic - - number = .true. - do i = 1, len_trim(word) - ic = ichar(word(i:i)) - if (ic < 48 .or. ic >= 58) number = .false. - end do - - end function is_number - -!=============================================================================== -! STARTS_WITH determines whether a string starts with a certain -! sequence of characters -!=============================================================================== - - logical function starts_with(str, seq) - - character(*) :: str ! string to check - character(*) :: seq ! sequence of characters - - integer :: i - integer :: i_start - integer :: str_len - integer :: seq_len - - str_len = len_trim(str) - seq_len = len_trim(seq) - - ! determine how many spaces are at beginning of string - i_start = 0 - do i = 1, str_len - if (str(i:i) == ' ' .or. str(i:i) == achar(9)) cycle - i_start = i - exit - end do - - ! Check if string starts with sequence using INDEX intrinsic - if (index(str(1:str_len), seq(1:seq_len)) == i_start) then - starts_with = .true. - else - starts_with = .false. + ! Make sure n_digits is reasonable. 10 digits is the maximum needed for the + ! largest integer(4). + if (n_digits > 10) then + call fatal_error('zero_padded called with an unreasonably large & + &n_digits (>10)') end if - end function starts_with - -!=============================================================================== -! ENDS_WITH determines whether a string ends with a certain sequence -! of characters -!=============================================================================== - - logical function ends_with(str, seq) - - character(*) :: str ! string to check - character(*) :: seq ! sequence of characters - - integer :: i_start - integer :: str_len - integer :: seq_len - - str_len = len_trim(str) - seq_len = len_trim(seq) - - ! determine how many spaces are at beginning of string - i_start = str_len - seq_len + 1 - - ! Check if string starts with sequence using INDEX intrinsic - if (index(str(1:str_len), seq(1:seq_len), .true.) == i_start) then - ends_with = .true. + ! Write a format string of the form '(In.m)' where n is the max width and + ! m is the min width. If a sign is present, then n must be one greater + ! than m. + if (num < 0) then + write(zp_form, '("(I", I0, ".", I0, ")")') n_digits+1, n_digits else - ends_with = .false. + write(zp_form, '("(I", I0, ".", I0, ")")') n_digits, n_digits end if - end function ends_with - -!=============================================================================== -! COUNT_DIGITS returns the number of digits needed to represent the input -! integer. -!=============================================================================== - - function count_digits(num) result(n_digits) - integer, intent(in) :: num - integer :: n_digits - - n_digits = 1 - do while (num / 10**(n_digits) /= 0 .and. abs(num / 10 **(n_digits-1)) /= 1& - &.and. n_digits /= 10) - ! Note that 10 digits is the maximum needed to represent an integer(4) so - ! the loop automatically exits when n_digits = 10. - n_digits = n_digits + 1 - end do - - end function count_digits - -!=============================================================================== -! INT4_TO_STR converts an integer(4) to a string. -!=============================================================================== - - function int4_to_str(num) result(str) - - integer, intent(in) :: num - character(11) :: str - - write (str, '(I11)') num - str = adjustl(str) - - end function int4_to_str - -!=============================================================================== -! INT8_TO_STR converts an integer(8) to a string. -!=============================================================================== - - function int8_to_str(num) result(str) - - integer(8), intent(in) :: num - character(21) :: str - - write (str, '(I21)') num - str = adjustl(str) - - end function int8_to_str + ! Format the number. + write(str, zp_form) num + end function zero_padded !=============================================================================== ! STR_TO_INT converts a string to an integer. @@ -434,59 +256,4 @@ end function zero_padded end function str_to_real -!=============================================================================== -! REAL_TO_STR converts a real(8) to a string based on how large the value is and -! how many significant digits are desired. By default, six significants digits -! are used. -!=============================================================================== - - function real_to_str(num, sig_digits) result(string) - - real(8), intent(in) :: num ! number to convert - integer, optional, intent(in) :: sig_digits ! # of significant digits - character(15) :: string ! string returned - - integer :: decimal ! number of places after decimal - integer :: width ! total field width - real(8) :: num2 ! absolute value of number - character(9) :: fmt ! format specifier for writing number - - ! set default field width - width = 15 - - ! set number of places after decimal - if (present(sig_digits)) then - decimal = sig_digits - else - decimal = 6 - end if - - ! Create format specifier for writing character - num2 = abs(num) - if (num2 == 0.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, 1 - elseif (num2 < 1.0e-1_8) then - write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 - elseif (num2 >= 1.0e-1_8 .and. num2 < 1.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, decimal - elseif (num2 >= 1.0_8 .and. num2 < 10.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-1, 0) - elseif (num2 >= 10.0_8 .and. num2 < 100.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-2, 0) - elseif (num2 >= 100.0_8 .and. num2 < 1000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-3, 0) - elseif (num2 >= 100.0_8 .and. num2 < 10000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-4, 0) - elseif (num2 >= 10000.0_8 .and. num2 < 100000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-5, 0) - else - write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 - end if - - ! Write string and left adjust - write(string, fmt) num - string = adjustl(string) - - end function real_to_str - end module string diff --git a/src/summary.F90 b/src/summary.F90 index 0e5a591aa9..1b0797fc9b 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -12,7 +12,7 @@ module summary use nuclide_header use output, only: time_stamp use surface_header - use string, only: to_str + use simple_string, only: to_str use tally_header, only: TallyObject use hdf5 diff --git a/src/tally.F90 b/src/tally.F90 index 5336f69bda..1954aebb9d 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -14,7 +14,7 @@ module tally use particle_header, only: LocalCoord, Particle_Base, Particle_CE, & Particle_MG use search, only: binary_search - use string, only: to_str + use simple_string, only: to_str use tally_header, only: TallyResult, TallyMapItem, TallyMapElement use fission, only: nu_total, nu_delayed, yield_delayed use interpolation, only: interpolate_tab1 diff --git a/src/track_output.F90 b/src/track_output.F90 index 867cd4a787..ec09932758 100644 --- a/src/track_output.F90 +++ b/src/track_output.F90 @@ -8,7 +8,7 @@ module track_output use global use hdf5_interface use particle_header, only: Particle_Base - use string, only: to_str + use simple_string, only: to_str use hdf5 diff --git a/src/tracking.F90 b/src/tracking.F90 index 8dc8c7772e..fcb746ccc8 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -11,7 +11,7 @@ module tracking use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use physics, only: collision use random_lcg, only: prn - use string, only: to_str + use simple_string, only: to_str use tally, only: score_analog_tally, score_tracklength_tally, & score_collision_tally, score_surface_current use track_output, only: initialize_particle_track, write_particle_track, & diff --git a/src/trigger.F90 b/src/trigger.F90 index 73cb0c7efe..967d74b14e 100644 --- a/src/trigger.F90 +++ b/src/trigger.F90 @@ -6,7 +6,7 @@ module trigger use constants use global - use string, only: to_str + use simple_string, only: to_str use output, only: warning, write_message use mesh, only: mesh_indices_to_bin use mesh_header, only: RegularMesh From 4e84c64620cf4ec9a4bb1acb18e2ed7ec9208a7d Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 30 Oct 2015 21:17:34 -0400 Subject: [PATCH 06/84] Helps if i add simple_string to the commit --- src/simple_string.F90 | 245 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 src/simple_string.F90 diff --git a/src/simple_string.F90 b/src/simple_string.F90 new file mode 100644 index 0000000000..a2205ffbc3 --- /dev/null +++ b/src/simple_string.F90 @@ -0,0 +1,245 @@ +module simple_string + + use constants, only: ERROR_REAL, ERROR_INT + + implicit none + + interface to_str + module procedure int4_to_str, int8_to_str, real_to_str + end interface + +contains + +!=============================================================================== +! TO_LOWER converts a string to all lower case characters +!=============================================================================== + + function to_lower(word) result(word_lower) + + character(*), intent(in) :: word + character(len=len(word)) :: word_lower + + integer :: i + integer :: ic + + do i = 1, len(word) + ic = ichar(word(i:i)) + if (ic >= 65 .and. ic <= 90) then + word_lower(i:i) = char(ic+32) + else + word_lower(i:i) = word(i:i) + end if + end do + + end function to_lower + +!=============================================================================== +! TO_UPPER converts a string to all upper case characters +!=============================================================================== + + function to_upper(word) result(word_upper) + + character(*), intent(in) :: word + character(len=len(word)) :: word_upper + + integer :: i + integer :: ic + + do i = 1, len(word) + ic = ichar(word(i:i)) + if (ic >= 97 .and. ic <= 122) then + word_upper(i:i) = char(ic-32) + else + word_upper(i:i) = word(i:i) + end if + end do + + end function to_upper + +!=============================================================================== +! IS_NUMBER determines whether a string of characters is all 0-9 characters +!=============================================================================== + + function is_number(word) result(number) + + character(*), intent(in) :: word + logical :: number + + integer :: i + integer :: ic + + number = .true. + do i = 1, len_trim(word) + ic = ichar(word(i:i)) + if (ic < 48 .or. ic >= 58) number = .false. + end do + + end function is_number + +!=============================================================================== +! STARTS_WITH determines whether a string starts with a certain +! sequence of characters +!=============================================================================== + + logical function starts_with(str, seq) + + character(*) :: str ! string to check + character(*) :: seq ! sequence of characters + + integer :: i + integer :: i_start + integer :: str_len + integer :: seq_len + + str_len = len_trim(str) + seq_len = len_trim(seq) + + ! determine how many spaces are at beginning of string + i_start = 0 + do i = 1, str_len + if (str(i:i) == ' ' .or. str(i:i) == achar(9)) cycle + i_start = i + exit + end do + + ! Check if string starts with sequence using INDEX intrinsic + if (index(str(1:str_len), seq(1:seq_len)) == i_start) then + starts_with = .true. + else + starts_with = .false. + end if + + end function starts_with + +!=============================================================================== +! ENDS_WITH determines whether a string ends with a certain sequence +! of characters +!=============================================================================== + + logical function ends_with(str, seq) + + character(*) :: str ! string to check + character(*) :: seq ! sequence of characters + + integer :: i_start + integer :: str_len + integer :: seq_len + + str_len = len_trim(str) + seq_len = len_trim(seq) + + ! determine how many spaces are at beginning of string + i_start = str_len - seq_len + 1 + + ! Check if string starts with sequence using INDEX intrinsic + if (index(str(1:str_len), seq(1:seq_len), .true.) == i_start) then + ends_with = .true. + else + ends_with = .false. + end if + + end function ends_with + +!=============================================================================== +! COUNT_DIGITS returns the number of digits needed to represent the input +! integer. +!=============================================================================== + + function count_digits(num) result(n_digits) + integer, intent(in) :: num + integer :: n_digits + + n_digits = 1 + do while (num / 10**(n_digits) /= 0 .and. abs(num / 10 **(n_digits-1)) /= 1& + &.and. n_digits /= 10) + ! Note that 10 digits is the maximum needed to represent an integer(4) so + ! the loop automatically exits when n_digits = 10. + n_digits = n_digits + 1 + end do + + end function count_digits + +!=============================================================================== +! INT4_TO_STR converts an integer(4) to a string. +!=============================================================================== + + function int4_to_str(num) result(str) + + integer, intent(in) :: num + character(11) :: str + + write (str, '(I11)') num + str = adjustl(str) + + end function int4_to_str + +!=============================================================================== +! INT8_TO_STR converts an integer(8) to a string. +!=============================================================================== + + function int8_to_str(num) result(str) + + integer(8), intent(in) :: num + character(21) :: str + + write (str, '(I21)') num + str = adjustl(str) + + end function int8_to_str + +!=============================================================================== +! REAL_TO_STR converts a real(8) to a string based on how large the value is and +! how many significant digits are desired. By default, six significants digits +! are used. +!=============================================================================== + + function real_to_str(num, sig_digits) result(string) + + real(8), intent(in) :: num ! number to convert + integer, optional, intent(in) :: sig_digits ! # of significant digits + character(15) :: string ! string returned + + integer :: decimal ! number of places after decimal + integer :: width ! total field width + real(8) :: num2 ! absolute value of number + character(9) :: fmt ! format specifier for writing number + + ! set default field width + width = 15 + + ! set number of places after decimal + if (present(sig_digits)) then + decimal = sig_digits + else + decimal = 6 + end if + + ! Create format specifier for writing character + num2 = abs(num) + if (num2 == 0.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, 1 + elseif (num2 < 1.0e-1_8) then + write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 + elseif (num2 >= 1.0e-1_8 .and. num2 < 1.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, decimal + elseif (num2 >= 1.0_8 .and. num2 < 10.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-1, 0) + elseif (num2 >= 10.0_8 .and. num2 < 100.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-2, 0) + elseif (num2 >= 100.0_8 .and. num2 < 1000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-3, 0) + elseif (num2 >= 100.0_8 .and. num2 < 10000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-4, 0) + elseif (num2 >= 10000.0_8 .and. num2 < 100000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-5, 0) + else + write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 + end if + + ! Write string and left adjust + write(string, fmt) num + string = adjustl(string) + + end function real_to_str + +end module simple_string \ No newline at end of file From 478a2f4de842c885055d25c911a590b958d2451f Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 31 Oct 2015 12:42:49 -0400 Subject: [PATCH 07/84] Added ability to read the meta data for MG cross sections xml file --- src/global.F90 | 47 ++++++++++-- src/initialize.F90 | 3 +- src/input_xml.F90 | 181 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 192 insertions(+), 39 deletions(-) diff --git a/src/global.F90 b/src/global.F90 index 6ac5be3423..adc132e2c0 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -62,40 +62,71 @@ module global ! ENERGY TREATMENT RELATED VARIABLES logical :: run_CE = .true. ! Run in CE mode? + ! ============================================================================ + ! CROSS SECTION RELATED VARIABLES NEEDED REGARDLESS OF CE OR MG + + ! Cross section arrays + type(XsListing), allocatable, target :: xs_listings(:) ! cross_sections.xml listings + + integer :: n_nuclides_total ! Number of nuclide cross section tables + integer :: n_listings ! Number of listings in cross_sections.xml + + ! Dictionaries to look up cross sections and listings + type(DictCharInt) :: nuclide_dict + type(DictCharInt) :: xs_listing_dict + + ! Default xs identifier (e.g. 70c) + character(3):: default_xs + ! ============================================================================ ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES ! Cross section arrays type(Nuclide_CE), allocatable, target :: nuclides(:) ! Nuclide cross-sections type(SAlphaBeta), allocatable, target :: sab_tables(:) ! S(a,b) tables - type(XsListing), allocatable, target :: xs_listings(:) ! cross_sections.xml listings ! Cross section caches type(NuclideMicroXS), allocatable :: micro_xs(:) ! Cache for each nuclide type(MaterialMacroXS) :: material_xs ! Cache for current material - integer :: n_nuclides_total ! Number of nuclide cross section tables integer :: n_sab_tables ! Number of S(a,b) thermal scattering tables - integer :: n_listings ! Number of listings in cross_sections.xml ! Minimum/maximum energies real(8) :: energy_min_neutron = ZERO real(8) :: energy_max_neutron = INFINITY ! Dictionaries to look up cross sections and listings - type(DictCharInt) :: nuclide_dict type(DictCharInt) :: sab_dict - type(DictCharInt) :: xs_listing_dict ! Unreoslved resonance probablity tables logical :: urr_ptables_on = .true. - ! Default xs identifier (e.g. 70c) - character(3):: default_xs - ! What to assume for expanding natural elements integer :: default_expand = ENDF_BVII1 + ! ============================================================================ + ! MULTI-GROUP CROSS SECTION RELATED VARIABLES + + ! Cross section arrays + ! type(Nuclide_MG), allocatable, target :: nuclides_MG(:) + + ! Number of energy groups + integer :: energy_groups + + ! Energy group structure + real(8), allocatable :: energy_bins(:) + + ! Maximum Data Order + integer :: max_order + + ! Scattering Treatment (if Legendre) + integer :: legendre_mu_points + + ! MGXS for current working particle (equivalent to material_xs, but simpler) + real(8) :: particle_xs(5) + +!$omp threadprivate(particle_xs) + ! ============================================================================ ! TALLY-RELATED VARIABLES diff --git a/src/initialize.F90 b/src/initialize.F90 index 44ec98a882..9a689455bb 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -14,8 +14,7 @@ module initialize use global use hdf5_interface, only: file_open, read_dataset, file_close, hdf5_bank_t,& hdf5_tallyresult_t, hdf5_integer8_t - use input_xml, only: read_input_xml, read_cross_sections_xml, & - cells_in_univ_dict, read_plots_xml + use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml use material_header, only: Material use output, only: title, header, print_version, write_message, & print_usage, write_xs_summary, print_plot diff --git a/src/input_xml.F90 b/src/input_xml.F90 index a9c5a8e221..29fdc11783 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -36,7 +36,13 @@ contains subroutine read_input_xml() call read_settings_xml() - if (run_mode /= MODE_PLOTTING) call read_cross_sections_xml() + if (run_mode /= MODE_PLOTTING) then + if (run_CE) then + call read_ce_cross_sections_xml() + else + call read_mg_cross_sections_xml() + end if + end if call read_geometry_xml() call read_materials_xml() call read_tallies_xml() @@ -97,30 +103,6 @@ contains ! Parse settings.xml file call open_xmldoc(doc, filename) - ! Find cross_sections.xml file -- the first place to look is the - ! settings.xml file. If no file is found there, then we check the - ! CROSS_SECTIONS environment variable - if (run_mode /= MODE_PLOTTING) then - if (.not. check_for_node(doc, "cross_sections") .and. & - run_mode /= MODE_PLOTTING) then - ! No cross_sections.xml file specified in settings.xml, check - ! environment variable - call get_environment_variable("CROSS_SECTIONS", env_variable) - if (len_trim(env_variable) == 0) then - call fatal_error("No cross_sections.xml file was specified in & - &settings.xml or in the CROSS_SECTIONS environment variable. & - &OpenMC needs a cross_sections.xml file to identify where to & - &find ACE cross section libraries. Please consult the user's & - &guide at http://mit-crpg.github.io/openmc for information on & - &how to set up ACE cross section libraries.") - else - path_cross_sections = trim(env_variable) - end if - else - call get_node_value(doc, "cross_sections", path_cross_sections) - end if - end if - ! Find if a multi-group or continuous-energy simulation is desired if (check_for_node(doc, "energy_mode")) then call get_node_value(doc, "energy_mode", temp_str) @@ -132,6 +114,44 @@ contains end if end if + ! Find cross_sections.xml file -- the first place to look is the + ! settings.xml file. If no file is found there, then we check the + ! CROSS_SECTIONS environment variable + if (run_mode /= MODE_PLOTTING) then + if (.not. check_for_node(doc, "cross_sections") .and. & + run_mode /= MODE_PLOTTING) then + ! No cross_sections.xml file specified in settings.xml, check + ! environment variable + if (run_CE) then + call get_environment_variable("CROSS_SECTIONS", env_variable) + if (len_trim(env_variable) == 0) then + call fatal_error("No cross_sections.xml file was specified in & + &settings.xml or in the CROSS_SECTIONS environment variable. & + &OpenMC needs such a file to identify where to & + &find ACE cross section libraries. Please consult the user's & + &guide at http://mit-crpg.github.io/openmc for information on & + &how to set up ACE cross section libraries.") + else + path_cross_sections = trim(env_variable) + end if + else + call get_environment_variable("MG_CROSS_SECTIONS", env_variable) + if (len_trim(env_variable) == 0) then + call fatal_error("No cross_sections.xml file was specified in & + &settings.xml or in the MG_CROSS_SECTIONS environment variable. & + &OpenMC needs such a file to identify where to & + &find the cross section libraries. Please consult the user's & + &guide at http://mit-crpg.github.io/openmc for information on & + &how to set up the cross section libraries.") + else + path_cross_sections = trim(env_variable) + end if + end if + else + call get_node_value(doc, "cross_sections", path_cross_sections) + end if + end if + ! Set output directory if a path has been specified on the ! element if (check_for_node(doc, "output_path")) then @@ -4084,11 +4104,11 @@ contains end subroutine read_plots_xml !=============================================================================== -! READ_CROSS_SECTIONS_XML reads information from a cross_sections.xml file. This -! file contains a listing of the ACE cross sections that may be used. +! READ_*_CROSS_SECTIONS_XML reads information from a cross_sections.xml file. This +! file contains a listing of the CE and MG cross sections that may be used. !=============================================================================== - subroutine read_cross_sections_xml() + subroutine read_ce_cross_sections_xml() integer :: i ! loop index integer :: filetype ! default file type @@ -4243,7 +4263,110 @@ contains ! Close cross sections XML file call close_xmldoc(doc) - end subroutine read_cross_sections_xml + end subroutine read_ce_cross_sections_xml + + subroutine read_mg_cross_sections_xml() + + integer :: i ! loop index + logical :: file_exists ! does cross_sections.xml exist? + type(XsListing), pointer :: listing => null() + type(Node), pointer :: doc => null() + type(Node), pointer :: node_xsdata => null() + type(NodeList), pointer :: node_xsdata_list => null() + ! character(MAX_LINE_LEN) :: temp_str + + ! Check if cross_sections.xml exists + inquire(FILE=path_cross_sections, EXIST=file_exists) + if (.not. file_exists) then + ! Could not find cross_sections.xml file + call fatal_error("Cross sections XML file '" & + &// trim(path_cross_sections) // "' does not exist!") + end if + + call write_message("Reading cross sections XML file...", 5) + + ! Parse cross_sections.xml file + call open_xmldoc(doc, path_cross_sections) + + if (check_for_node(doc, "groups")) then + ! Get neutron group count + call get_node_value(doc, "groups", energy_groups) + else + call fatal_error("groups element must exist!") + end if + + allocate(energy_bins(energy_groups + 1)) + if (check_for_node(doc, "group_structure")) then + ! Get neutron group structure + call get_node_array(doc, "group_structure", energy_bins) + else + call fatal_error("group_structures element must exist!") + end if + + if (check_for_node(doc, "legendre_mu_points")) then + ! Get scattering treatment + call get_node_value(doc, "legendre_mu_points", legendre_mu_points) + if (legendre_mu_points <= 0) then + call fatal_error("legendre_mu_points element must be positive and non-zero!") + end if + legendre_mu_points = -1 * legendre_mu_points + else + ! One will say 'dont do it' + legendre_mu_points = 1 + end if + + ! Get node list of all + call get_node_list(doc, "xsdata", node_xsdata_list) + n_listings = get_list_size(node_xsdata_list) + + ! Allocate xs_listings array + if (n_listings == 0) then + call fatal_error("No XSDATA listings present in cross_sections.xml & + &file!") + else + allocate(xs_listings(n_listings)) + end if + + do i = 1, n_listings + listing => xs_listings(i) + + ! Get pointer to xsdata table XML node + call get_list_item(node_xsdata_list, i, node_xsdata) + + ! copy a number of attributes + call get_node_value(node_xsdata, "name", listing % name) + listing % name = to_lower(listing % name) + listing % alias = listing % name + if (check_for_node(node_xsdata, "alias")) & + call get_node_value(node_xsdata, "alias", listing % alias) + listing % alias = to_lower(listing % alias) + if (check_for_node(node_xsdata, "zaid")) then + call get_node_value(node_xsdata, "zaid", listing % zaid) + else + listing % zaid = 100 + end if + if (check_for_node(node_xsdata, "kT")) & + call get_node_value(node_xsdata, "kT", listing % kT) + if (check_for_node(node_xsdata, "awr")) then + call get_node_value(node_xsdata, "awr", listing % awr) + else + listing % awr = ONE + end if + + ! determine type of cross section + if (ends_with(listing % name, 'c')) then + listing % type = NEUTRON + end if + + ! create dictionary entry for both name and alias + call xs_listing_dict % add_key(to_lower(listing % name), i) + call xs_listing_dict % add_key(to_lower(listing % alias), i) + end do + + ! Close cross sections XML file + call close_xmldoc(doc) + + end subroutine read_mg_cross_sections_xml !=============================================================================== ! EXPAND_NATURAL_ELEMENT converts natural elements specified using an From 52f472c99c9029f3301e2b7b05f26d3c9ed85934 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 13:20:36 -0500 Subject: [PATCH 08/84] Moved maxwell and watt spectra to spectra.F90 from math.F90 to avoid math needing to pull in prn and all that entails (to avoid circular dependencies), added macroxs information for MG data, fixed memory leaks due to allocation of particle at to low a level --- src/ace.F90 | 4 +- src/constants.F90 | 24 +- src/global.F90 | 6 +- src/initialize.F90 | 45 +- src/macroxs_header.F90 | 969 +++++++++++++++++++++++++++++++++++++++ src/math.F90 | 65 ++- src/mgxs_data.F90 | 650 ++++++++++++++++++++++++++ src/nuclide_header.F90 | 465 ++++++++++++++----- src/particle_header.F90 | 95 ++-- src/physics.F90 | 2 +- src/scattdata_header.F90 | 355 ++++++++++++++ src/simulation.F90 | 15 +- src/source.F90 | 18 +- src/spectra.F90 | 58 +++ 14 files changed, 2545 insertions(+), 226 deletions(-) create mode 100644 src/macroxs_header.F90 create mode 100644 src/mgxs_data.F90 create mode 100644 src/scattdata_header.F90 create mode 100644 src/spectra.F90 diff --git a/src/ace.F90 b/src/ace.F90 index 729b78b323..e51c2b3a0e 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -32,7 +32,7 @@ contains ! nuclides and sab_tables arrays !=============================================================================== - subroutine read_xs() + subroutine read_ace_xs() integer :: i ! index in materials array integer :: j ! index over nuclides in material @@ -226,7 +226,7 @@ contains end if end do - end subroutine read_xs + end subroutine read_ace_xs !=============================================================================== ! READ_ACE_TABLE reads a single cross section table in either ASCII or binary diff --git a/src/constants.F90 b/src/constants.F90 index 375c517e76..9bb62f62eb 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -157,9 +157,22 @@ module constants ! Angular distribution type integer, parameter :: & - ANGLE_ISOTROPIC = 1, & ! Isotropic angular distribution - ANGLE_32_EQUI = 2, & ! 32 equiprobable bins - ANGLE_TABULAR = 3 ! Tabular angular distribution + ANGLE_ISOTROPIC = 1, & ! Isotropic angular distribution (CE) + ANGLE_32_EQUI = 2, & ! 32 equiprobable bins (CE) + ANGLE_TABULAR = 3, & ! Tabular angular distribution (CE or MG) + ANGLE_LEGENDRE = 4, & ! Legendre angular distribution (MG) + ANGLE_HISTOGRAM = 5 ! Histogram angular distribution (MG) + + ! Number of mu bins to use when converting Legendres to tabular type + integer, parameter :: DEFAULT_NMU = 33 + + ! Location within pre-computed cross section data (particle_xs) + integer, parameter :: & + TOTAL = 1, & + ABSORB = 2, & + NUFISS = 3, & + FISS = 4, & + SCATT = 5 ! Secondary energy mode for S(a,b) inelastic scattering integer, parameter :: & @@ -203,6 +216,11 @@ module constants ACE_THERMAL = 2, & ! thermal S(a,b) scattering data ACE_DOSIMETRY = 3 ! dosimetry cross sections + ! MGXS Table Types + integer, parameter :: & + ISOTROPIC = 1, & ! Isotropically Weighted Data + ANGLE = 2 ! Data by Angular Bins + ! Fission neutron emission (nu) type integer, parameter :: & NU_NONE = 0, & ! No nu values (non-fissionable) diff --git a/src/global.F90 b/src/global.F90 index adc132e2c0..c5dbec5da9 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -5,6 +5,7 @@ module global use constants use dict_header, only: DictCharInt, DictIntInt use geometry_header, only: Cell, Universe, Lattice, LatticeContainer + use macroxs_header, only: MacroXS_Base, MacroXSContainer use material_header, only: Material use mesh_header, only: RegularMesh use nuclide_header @@ -108,7 +109,10 @@ module global ! MULTI-GROUP CROSS SECTION RELATED VARIABLES ! Cross section arrays - ! type(Nuclide_MG), allocatable, target :: nuclides_MG(:) + type(NuclideMGContainer), allocatable, target :: nuclides_MG(:) + + ! Cross section caches + type(MacroXSContainer), target, allocatable :: macro_xs(:) ! Number of energy groups integer :: energy_groups diff --git a/src/initialize.F90 b/src/initialize.F90 index 9a689455bb..01a8038070 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -1,6 +1,6 @@ module initialize - use ace, only: read_xs, same_nuclide_list + use ace, only: read_ace_xs, same_nuclide_list use bank_header, only: Bank use constants use dict_header, only: DictIntInt, ElemKeyValueII @@ -16,6 +16,7 @@ module initialize hdf5_tallyresult_t, hdf5_integer8_t use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml use material_header, only: Material + use mgxs_data use output, only: title, header, print_version, write_message, & print_usage, write_xs_summary, print_plot use random_lcg, only: initialize_prng @@ -114,23 +115,37 @@ contains ! Read ACE-format cross sections call time_read_xs%start() - call read_xs() + if (run_CE) then + call read_ace_xs() + else + call read_mgxs() + end if call time_read_xs%stop() ! Create linked lists for multiple instances of the same nuclide - call same_nuclide_list() + if (run_CE) then + call same_nuclide_list() + else + call same_nuclide_mg_list() + end if - ! Construct unionized or log energy grid for cross-sections - select case (grid_method) - case (GRID_NUCLIDE) - continue - case (GRID_MAT_UNION) - call time_unionize%start() - call unionized_grid() - call time_unionize%stop() - case (GRID_LOGARITHM) - call logarithmic_grid() - end select + ! Construct information needed for nuclear data + if (run_CE) then + ! Construct unionized or log energy grid for cross-sections + select case (grid_method) + case (GRID_NUCLIDE) + continue + case (GRID_MAT_UNION) + call time_unionize%start() + call unionized_grid() + call time_unionize%stop() + case (GRID_LOGARITHM) + call logarithmic_grid() + end select + else + ! Create material macroscopic data for MGXS + call create_macro_xs() + end if ! Allocate and setup tally stride, matching_bins, and tally maps call configure_tallies() @@ -307,6 +322,8 @@ contains c_loc(tmpb(1)%uvw)), coordinates_t, hdf5_err) call h5tinsert_f(hdf5_bank_t, "E", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%E)), H5T_NATIVE_DOUBLE, hdf5_err) + call h5tinsert_f(hdf5_bank_t, "group", h5offsetof(c_loc(tmpb(1)), & + c_loc(tmpb(1)%group)), H5T_NATIVE_INTEGER, hdf5_err) call h5tinsert_f(hdf5_bank_t, "delayed_group", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%delayed_group)), H5T_NATIVE_INTEGER, hdf5_err) diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 new file mode 100644 index 0000000000..ed768b2430 --- /dev/null +++ b/src/macroxs_header.F90 @@ -0,0 +1,969 @@ +module macroxs_header + + use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI + use list_header, only: ListInt + use material_header, only: material + use math, only: calc_pn, calc_rn, expand_harmonic + use nuclide_header + use scattdata_header + + implicit none + +!=============================================================================== +! MACROXS_* contains cached macroscopic cross sections for the material a +! particle is traveling through +!=============================================================================== + + type, abstract :: MacroXS_Base + ! Data Order + integer :: order + + ! Type-Bound procedures + contains + procedure(macroxs_init_), deferred, pass :: init ! initializes object + procedure(macroxs_clear_), deferred, pass :: clear ! Deallocates object + procedure(macroxs_size_), deferred, pass :: get_size ! Finds size of object + procedure(macroxs_get_xs_), deferred, pass :: get_xs ! Return xs + end type MacroXS_Base + + abstract interface + subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, & + max_order, scatt_type, legendre_mu_points, & + error_code, error_text) + + import MacroXS_Base + import Material + import NuclideMGContainer + import MAX_LINE_LEN + class(MacroXS_Base), intent(inout) :: this ! The MacroXS to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + logical, intent(in) :: get_kfiss ! Should we get kfiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? + integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + end subroutine macroxs_init_ + + function macroxs_get_xs_(this, g, xstype, uvw) result(xs) + import MacroXS_Base + class(MacroXS_Base), intent(in) :: this ! The MacroXS to initialize + integer, intent(in) :: g ! Incoming Energy group + character(*) , intent(in) :: xstype ! Cross Section Type + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Resultant xs + + end function macroxs_get_xs_ + + subroutine macroxs_clear_(this) + + import MacroXS_Base + class(MacroXS_Base), intent(inout) :: this ! The MacroXS to clear + + end subroutine macroxs_clear_ + + subroutine macroxs_size_(this, size_total, size_scatt, size_fission) + import MacroXS_Base + class(MacroXS_Base), intent(in) :: this + integer, intent(out) :: size_total ! Total Data Size + integer, intent(out) :: size_scatt ! Scattering Data Size + integer, intent(out) :: size_fission ! Fission Data Size + + end subroutine macroxs_size_ + end interface + + type, extends(MacroXS_Base) :: MacroXS_Iso + ! Microscopic cross sections + real(8), allocatable :: total(:) ! total cross section + real(8), allocatable :: absorption(:) ! absorption cross section + class(ScattData_Base), allocatable :: scatter ! scattering information + real(8), allocatable :: nu_fission(:) ! nu-fission + real(8), allocatable :: k_fission(:) ! kappa-fission + real(8), allocatable :: fission(:) ! fission x/s + real(8), allocatable :: scattxs(:) ! scattering xs + real(8), allocatable :: chi(:,:) ! fission spectra + + ! Type-Bound procedures + contains + procedure, pass :: init => macroxs_iso_init ! inits object + procedure, pass :: clear => macroxs_iso_clear ! Deallocates object + procedure, pass :: get_size => macroxs_iso_size ! Finds size of object + procedure, pass :: get_xs => macroxs_iso_get_xs ! Returns xs + end type MacroXS_Iso + + type, extends(MacroXS_Base) :: MacroXS_Angle + ! Macroscopic cross sections + real(8), allocatable :: total(:,:,:) ! total cross section + real(8), allocatable :: absorption(:,:,:) ! absorption cross section + type(ScattDataContainer), allocatable :: scatter(:,:) ! scattering information + real(8), allocatable :: nu_fission(:,:,:) ! nu-fission + real(8), allocatable :: k_fission(:,:,:) ! kappa-fission + real(8), allocatable :: fission(:,:,:) ! fission x/s + real(8), allocatable :: chi(:,:,:,:) ! fission spectra + real(8), allocatable :: scattxs(:,:,:) ! scattering xs + real(8), allocatable :: polar(:) ! polar angles + real(8), allocatable :: azimuthal(:) ! azimuthal angles + + ! Type-Bound procedures + contains + procedure, pass :: init => macroxs_angle_init ! inits object + procedure, pass :: clear => macroxs_angle_clear ! Deallocates object + procedure, pass :: get_size => macroxs_angle_size ! Finds size of object + procedure, pass :: get_xs => macroxs_angle_get_xs ! Returns xs + end type MacroXS_Angle + +!=============================================================================== +! MACROXSCONTAINER pointer array for storing MacroXS objects. +!=============================================================================== + + type MacroXSContainer + class(MacroXS_Base), allocatable :: obj + end type MacroXSContainer + +contains + +!=============================================================================== +! MACROXS*_INIT sets the MacroXS Data +!=============================================================================== + + subroutine macroxs_iso_init(this, mat, nuclides, groups, get_kfiss, & + max_order, scatt_type, legendre_mu_points, error_code, error_text) + + class(MacroXS_Iso), intent(inout) :: this ! The MacroXS to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + logical, intent(in) :: get_kfiss ! Should we get kfiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! How is data presented + integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + integer :: i ! loop index over nuclides + integer :: gin, gout ! group indices + real(8) :: atom_density ! atom density of a nuclide + ! class(Nuclide_Base), pointer :: nuc ! current nuclide + integer :: imu + real(8) :: norm + integer :: mat_max_order, order, l + real(8), allocatable :: temp_mult(:,:) + real(8), allocatable :: temp_energy(:,:) + real(8), allocatable :: scatt_coeffs(:,:,:) + + ! Initialize error data + error_code = 0 + error_text = '' + + ! If we have tabular only data, then make sure all datasets have same size + if (scatt_type == ANGLE_HISTOGRAM) then + ! Check all scattering data of same size + order = nuclides(mat % nuclide(1)) % obj % order + do i = 2, mat % n_nuclides + if (order /= nuclides(mat % nuclide(i)) % obj % order) then + error_code = 1 + error_text = "All Histogram Scattering Entries Must Be Same Length!" + return + end if + end do + ! Ok, got our order, store it + this % order = order + + ! Allocate stuff for later + allocate(scatt_coeffs(order, groups, groups)) + scatt_coeffs = ZERO + allocate(ScattData_Histogram :: this % scatter) + + else if (scatt_type == ANGLE_TABULAR) then + ! Check all scattering data of same size + order = nuclides(mat % nuclide(1)) % obj % order + do i = 2, mat % n_nuclides + if (order /= nuclides(mat % nuclide(i)) % obj % order) then + error_code = 1 + error_text = "All Tabular Scattering Entries Must Be Same Length!" + return + end if + end do + ! Ok, got our order, store it + this % order = order + + ! Allocate stuff for later + allocate(scatt_coeffs(order, groups, groups)) + scatt_coeffs = ZERO + allocate(ScattData_Histogram :: this % scatter) + + else if (scatt_type == ANGLE_LEGENDRE) then + ! Otherwise find the maximum scattering order + ! Need to determine the maximum scattering order of all data in this material + mat_max_order = 0 + do i = 1, mat % n_nuclides + if (nuclides(mat % nuclide(i)) % obj % order > mat_max_order) then + mat_max_order = nuclides(mat % nuclide(i)) % obj % order + end if + end do + + ! Now need to compare this material maximum scattering order with + ! the problem wide max scatt order and use whichever is lower + order = min(mat_max_order, max_order) + this % order = order + 1 + + ! Now we can allocate our scatt_coeffs object accordingly + allocate(scatt_coeffs(order + 1, groups, groups)) + scatt_coeffs = ZERO + if (legendre_mu_points == 1) then + allocate(ScattData_Legendre :: this % scatter) + else + allocate(ScattData_Tabular :: this % scatter) + end if + end if + + ! Allocate and initialize data within macro_xs(i_mat) object + allocate(this % total(groups)) + this % total = ZERO + allocate(this % absorption(groups)) + this % absorption = ZERO + allocate(this % fission(groups)) + this % fission = ZERO + if (get_kfiss) then + allocate(this % k_fission(groups)) + this % k_fission = ZERO + end if + allocate(this % nu_fission(groups)) + this % nu_fission = ZERO + allocate(this % chi(groups, groups)) + this % chi = ZERO + allocate(temp_energy(groups, groups)) + temp_energy = ZERO + allocate(temp_mult(groups, groups)) + temp_mult = ZERO + allocate(this % scattxs(groups)) + + ! Add contribution from each nuclide in material + do i = 1, mat % n_nuclides + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + ! Perform our operations which depend upon the type + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (Nuclide_Iso) + + ! Add contributions to total, absorption, and fission data (if necessary) + this % total = this % total + atom_density * nuc % total + this % absorption = this % absorption + & + atom_density * nuc % absorption + if (nuc % fissionable) then + if (allocated(nuc % chi)) then + do gin = 1, groups + do gout = 1, groups + this % chi(gout,gin) = this % chi(gout,gin) + atom_density * & + nuc % chi(gout) * nuc % nu_fission(gin,1) + end do + end do + this % nu_fission = this % nu_fission + atom_density * & + nuc % nu_fission(:,1) + else + this % chi = this % chi + atom_density * nuc % nu_fission + do gin = 1, groups + this % nu_fission(gin) = this % nu_fission(gin) + atom_density * & + sum(nuc % nu_fission(:,gin)) + end do + end if + this % fission = this % fission + atom_density * nuc % fission + if (get_kfiss) then + this % k_fission = this % k_fission + atom_density * nuc % k_fission + end if + end if + + ! Now time to do the scattering + do gin = 1, groups + do gout = 1, groups + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + ! Transfer matrix + temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & + sum(nuc % scatter(gout,gin,:)) + + ! Determine the angular distribution + do imu = 1, order + scatt_coeffs(imu, gout, gin) = scatt_coeffs(imu, gout, gin) + & + nuc % scatter(gout,gin,imu) * & + atom_density + end do + + else if (scatt_type == ANGLE_LEGENDRE) then + ! Transfer matrix + temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & + nuc % scatter(gout,gin,1) + + ! Determine the angular distribution coefficients so we can later + ! expand do the complete distribution + do l = 1, min(nuc % order, order) + 1 + scatt_coeffs(l, gout, gin) = scatt_coeffs(l, gout, gin) + & + nuc % scatter(gout,gin,l) * & + atom_density + end do + + end if + + ! Multiplicity matrix + temp_mult(gout,gin) = temp_mult(gout,gin) + atom_density * & + nuc % mult(gout,gin) + end do + end do + type is (Nuclide_Angle) + error_code = 1 + error_text = "Invalid Passing of Nuclide_Angle to MacroXS_Iso Object" + return + end select + end do + + ! Store the scattering xs + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + this % scattxs(:) = sum(sum(scatt_coeffs(:,:,:),dim=1),dim=1) + else if (scatt_type == ANGLE_LEGENDRE) then + this % scattxs(:) = sum(scatt_coeffs(1,:,:),dim=1) + end if + + ! Normalize the scatt_coeffs + do gin = 1, groups + do gout = 1, groups + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + norm = sum(scatt_coeffs(:,gout,gin)) + else if (scatt_type == ANGLE_LEGENDRE) then + norm = scatt_coeffs(1,gout,gin) + end if + if (norm /= ZERO) then + scatt_coeffs(:, gout, gin) = scatt_coeffs(:, gout,gin) / norm + end if + end do + ! Now normalize temp_energy (outgoing scattering energy probabilities) + norm = sum(temp_energy(:,gin)) + if (norm > ZERO) then + temp_energy(:,gin) = temp_energy(:,gin) / norm + end if + end do + + if (scatt_type == ANGLE_LEGENDRE .and. legendre_mu_points /= 1) then + call this % scatter % init(legendre_mu_points, temp_energy, temp_mult, & + scatt_coeffs) + else + call this % scatter % init(this % order, temp_energy, temp_mult, & + scatt_coeffs) + end if + + ! Now normalize chi + if (mat % fissionable) then + do gin = 1, groups + ! Normalize Chi + norm = sum(this % chi(:,gin)) + if (norm > ZERO) then + this % chi(:,gin) = this % chi(:,gin) / norm + end if + end do + end if + + ! Deallocate temporaries for the next material + deallocate(scatt_coeffs, temp_energy, temp_mult) + + end subroutine macroxs_iso_init + + subroutine macroxs_angle_init(this, mat, nuclides, groups, get_kfiss, & + max_order, scatt_type, legendre_mu_points, error_code, error_text) + + class(MacroXS_Angle), intent(inout) :: this ! The MacroXS to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + logical, intent(in) :: get_kfiss ! Should we get kfiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? + integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + integer :: i ! loop index over nuclides + integer :: gin, gout ! group indices + real(8) :: atom_density ! atom density of a nuclide + integer :: ipol, iazi, npol, nazi + integer :: imu + real(8) :: norm + integer :: mat_max_order, order, l + real(8), allocatable :: temp_mult(:,:,:,:) + real(8), allocatable :: temp_energy(:,:,:,:) + real(8), allocatable :: scatt_coeffs(:,:,:,:,:) + + ! Initialize error data + error_code = 0 + error_text = '' + + ! Get the number of each polar and azi angles and make sure all the + ! Nuclide_Angle types have the same number of these angles + npol = -1 + nazi = -1 + do i = 1, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (Nuclide_Angle) + if (npol == -1) then + npol = nuc % Npol + nazi = nuc % Nazi + allocate(this % polar(npol)) + this % polar = nuc % polar + allocate(this % azimuthal(nazi)) + this % azimuthal = nuc % azimuthal + else + if ((npol /= nuc % Npol) .or. (nazi /= nuc % Nazi)) then + error_code = 1 + error_text = "All Angular Data Must Be Same Length!" + end if + end if + end select + end do + + ! If we have tabular only data, then make sure all datasets have same size + if (scatt_type == ANGLE_HISTOGRAM) then + ! Check all scattering data of same size + order = nuclides(mat % nuclide(1)) % obj % order + do i = 2, mat % n_nuclides + if (order /= nuclides(mat % nuclide(i)) % obj % order) then + error_code = 1 + error_text = "All Histogram Scattering Entries Must Be Same Length!" + return + end if + end do + ! Ok, got our order, store it + this % order = order + + ! Allocate stuff for later + allocate(scatt_coeffs(order, groups, groups, nazi, npol)) + scatt_coeffs = ZERO + allocate(this % scatter(nazi, npol)) + do ipol = 1, npol + do iazi = 1, nazi + allocate(ScattData_Histogram :: this % scatter(iazi, ipol) % obj) + end do + end do + + else if (scatt_type == ANGLE_TABULAR) then + ! Check all scattering data of same size + order = nuclides(mat % nuclide(1)) % obj % order + do i = 2, mat % n_nuclides + if (order /= nuclides(mat % nuclide(i)) % obj % order) then + error_code = 1 + error_text = "All Tabular Scattering Entries Must Be Same Length!" + return + end if + end do + ! Ok, got our order, store it + this % order = order + + ! Allocate stuff for later + allocate(scatt_coeffs(order, groups, groups, nazi, npol)) + scatt_coeffs = ZERO + allocate(this % scatter(nazi, npol)) + do ipol = 1, npol + do iazi = 1, nazi + allocate(ScattData_Tabular :: this % scatter(iazi, ipol) % obj) + end do + end do + + else if (scatt_type == ANGLE_LEGENDRE) then + ! Otherwise find the maximum scattering order + ! Need to determine the maximum scattering order of all data in this material + mat_max_order = 0 + do i = 1, mat % n_nuclides + if (nuclides(mat % nuclide(i)) % obj % order > mat_max_order) then + mat_max_order = nuclides(mat % nuclide(i)) % obj % order + end if + end do + + ! Now need to compare this material maximum scattering order with + ! the problem wide max scatt order and use whichever is lower + order = min(mat_max_order, max_order) + this % order = order + 1 + + ! Now we can allocate our scatt_coeffs object accordingly + allocate(scatt_coeffs(order + 1, groups, groups, nazi, npol)) + scatt_coeffs = ZERO + allocate(this % scatter(nazi, npol)) + do ipol = 1, npol + do iazi = 1, nazi + if (legendre_mu_points == 1) then + allocate(ScattData_Legendre :: this % scatter(iazi, ipol) % obj) + else + allocate(ScattData_Tabular :: this % scatter(iazi, ipol) % obj) + end if + end do + end do + end if + + ! Allocate and initialize data within macro_xs(i_mat) object + allocate(this % total(groups,nazi,npol)) + this % total = ZERO + allocate(this % absorption(groups,nazi,npol)) + this % absorption = ZERO + allocate(this % fission(groups,nazi,npol)) + this % fission = ZERO + if (get_kfiss) then + allocate(this % k_fission(groups,nazi,npol)) + this % k_fission = ZERO + end if + allocate(this % nu_fission(groups,nazi,npol)) + this % nu_fission = ZERO + allocate(this % chi(groups, groups, nazi, npol)) + this % chi = ZERO + allocate(temp_energy(groups,groups,nazi,npol)) + temp_energy = ZERO + allocate(temp_mult(groups,groups,nazi,npol)) + temp_mult = ZERO + allocate(this % scattxs(groups,nazi,npol)) + + ! Add contribution from each nuclide in material + do i = 1, mat % n_nuclides + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + ! Perform our operations which depend upon the type + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (Nuclide_Iso) + error_code = 1 + error_text = "Invalid Passing of Nuclide_Iso to MacroXS_Angle Object" + return + type is (Nuclide_Angle) + ! Add contributions to total, absorption, and fission data (if necessary) + this % total = this % total + atom_density * nuc % total + this % absorption = this % absorption + & + atom_density * nuc % absorption + if (nuc % fissionable) then + if (allocated(nuc % chi)) then + do gin = 1, groups + do gout = 1, groups + this % chi(gout,gin,:,:) = this % chi(gout,gin,:,:) + atom_density * & + nuc % chi(gout,:,:) * nuc % nu_fission(gin,1,:,:) + end do + end do + this % nu_fission = this % nu_fission + atom_density * & + nuc % nu_fission(:,1,:,:) + else + this % chi = this % chi + atom_density * nuc % nu_fission + do gin = 1, groups + this % nu_fission(gin,:,:) = this % nu_fission(gin,:,:) + atom_density * & + sum(nuc % nu_fission(:,gin,:,:),dim=1) + end do + end if + this % fission = this % fission + atom_density * nuc % fission + if (get_kfiss) then + this % k_fission = this % k_fission + atom_density * nuc % k_fission + end if + end if + + ! Now time to do the scattering + do gin = 1, groups + do gout = 1, groups + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + ! Transfer matrix + temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & + sum(nuc % scatter(gout,gin,:,:,:),dim=1) + + ! Determine the angular distribution + do imu = 1, order + scatt_coeffs(imu,gout,gin,:,:) = scatt_coeffs(imu,gout,gin,:,:) + & + nuc % scatter(gout,gin,imu,:,:) * & + atom_density + end do + else if (scatt_type == ANGLE_LEGENDRE) then + ! Transfer matrix + temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & + nuc % scatter(gout,gin,1,:,:) + + ! Determine the angular distribution coefficients so we can later + ! expand do the complete distribution + do l = 1, min(nuc % order, order) + 1 + scatt_coeffs(l, gout, gin,:,:) = scatt_coeffs(l, gout, gin,:,:) + & + nuc % scatter(gout,gin,l,:,:) * & + atom_density + end do + end if + + ! Multiplicity matrix + temp_mult(gout,gin,:,:) = temp_mult(gout,gin,:,:) + atom_density * & + nuc % mult(gout,gin,:,:) + end do + end do + end select + end do + + ! Store the scattering xs + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + this % scattxs(:,:,:) = sum(sum(scatt_coeffs(:,:,:,:,:),dim=1),dim=1) + else if (scatt_type == ANGLE_LEGENDRE) then + this % scattxs(:,:,:) = sum(scatt_coeffs(1,:,:,:,:),dim=1) + end if + + ! Normalize the scatt_coeffs + do ipol = 1, npol + do iazi = 1, nazi + do gin = 1, groups + do gout = 1, groups + if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then + norm = sum(scatt_coeffs(:,gout,gin,iazi,ipol)) + else if (scatt_type == ANGLE_LEGENDRE) then + norm = scatt_coeffs(1,gout,gin,iazi,ipol) + end if + if (norm /= ZERO) then + scatt_coeffs(:,gout,gin,iazi,ipol) = & + scatt_coeffs(:,gout,gin,iazi,ipol) / norm + end if + end do + ! Now normalize temp_energy (outgoing scattering energy probabilities) + norm = sum(temp_energy(:,gin,iazi,ipol)) + if (norm > ZERO) then + temp_energy(:,gin,iazi,ipol) = temp_energy(:,gin,iazi,ipol) / norm + end if + end do + + if (scatt_type == ANGLE_LEGENDRE .and. legendre_mu_points /= 1) then + call this % scatter(iazi, ipol) % obj % init(legendre_mu_points, & + temp_energy(:,:,iazi,ipol), temp_mult(:,:,iazi,ipol), & + scatt_coeffs(:,:,:,iazi,ipol)) + else + call this % scatter(iazi, ipol) % obj % init(this % order, & + temp_energy(:,:,iazi,ipol), temp_mult(:,:,iazi,ipol), & + scatt_coeffs(:,:,:,iazi,ipol)) + end if + + end do + end do + + ! Now go through and normalize chi + if (mat % fissionable) then + do ipol = 1, npol + do iazi = 1, nazi + do gin = 1, groups + ! Normalize Chi + norm = sum(this % chi(:,gin,iazi,ipol)) + if (norm > ZERO) then + this % chi(:,gin,iazi,ipol) = this % chi(:,gin,iazi,ipol) / norm + end if + end do + end do + end do + end if + + ! Deallocate temporaries for the next material + deallocate(scatt_coeffs, temp_energy, temp_mult) + + end subroutine macroxs_angle_init + +!=============================================================================== +! MACROXS*_CLEAR resets and deallocates data in MacroXS. +!=============================================================================== + + subroutine macroxs_iso_clear(this) + + class(MacroXS_Iso), intent(inout) :: this ! The MacroXS to clear + + if (allocated(this % total)) then + deallocate(this % total, this % absorption, & + this % nu_fission, this % fission) + end if + + if (allocated(this % k_fission)) then + deallocate(this % k_fission) + end if + + call this % scatter % clear() + + if (allocated(this % chi)) then + deallocate(this % chi) + end if + + end subroutine macroxs_iso_clear + + subroutine macroxs_angle_clear(this) + + class(MacroXS_Angle), intent(inout) :: this ! The MacroXS to clear + integer :: i, j + + if (allocated(this % total)) then + deallocate(this % total, this % absorption, & + this % nu_fission, this % fission) + end if + + if (allocated(this % k_fission)) then + deallocate(this % k_fission) + end if + + do i = 1, size(this % scatter,dim=2) + do j = 1, size(this % scatter,dim=1) + call this % scatter(j,i) % obj % clear() + end do + end do + if (allocated(this % scatter)) then + deallocate(this % scatter) + end if + + if (allocated(this % chi)) then + deallocate(this % chi) + end if + + end subroutine macroxs_angle_clear + +!=============================================================================== +! MACROXS_*_SIZE Finds the size of the data in MacroXS_Base, MacroXS_Iso, +! or MacroXS_Angle +!=============================================================================== + + subroutine macroxs_iso_size(this, size_total, size_scatt, size_fission) + class(MacroXS_Iso), intent(in) :: this + integer, intent(out) :: size_total ! Total Data Size + integer, intent(out) :: size_scatt ! Scattering Data Size + integer, intent(out) :: size_fission ! Fission Data Size + + integer :: groups + + groups = size(this % total, dim=1) + + ! Size Information On Each Reaction + ! Sum up for total, absorption, nu_scatter, nu_fission, fission + size_total = groups * 8 * (1 + 1 + 1 + 1 + 1) + ! Now do k_fission + ! Check k_fission + if (allocated (this % k_fission)) then + size_total = size_total + groups * 8 + end if + + ! Calculate chi data size + size_fission = 0 + if (allocated(this % chi)) then + size_fission = size_fission + 8 * size(this % chi) + end if + + ! Calculate Scatter Data Size + size_scatt = size(this % scatter % energy) + + ! Calculate Total Memory + size_total = size_total + size_fission + size_scatt + + end subroutine macroxs_iso_size + + subroutine macroxs_angle_size(this, size_total, size_scatt, size_fission) + class(MacroXS_Angle), intent(in) :: this + integer, intent(out) :: size_total ! Total Data Size + integer, intent(out) :: size_scatt ! Scattering Data Size + integer, intent(out) :: size_fission ! Fission Data Size + + integer :: groups + integer :: tot_angle + + groups = size(this % total, dim=2) + tot_angle = size(this % total, dim=1) + + ! Size Information On Each Reaction + ! Sum up for total, absorption, nu_scatter, nu_fission, fission + size_total = groups * 8 * (1 + 1 + 1 + 1 + 1) * tot_angle + ! Now do k_fission + ! Check k_fission + if (allocated (this % k_fission)) then + size_total = size_total + groups * 8 * tot_angle + end if + + ! Calculate chi data size + size_fission = 0 + if (allocated(this % chi)) then + size_fission = size_fission + 8 * size(this % chi) + end if + + ! Calculate Scatter Data Size + size_scatt = 0 + + ! Calculate Total Memory + size_total = size_total + size_fission + size_scatt + + end subroutine macroxs_angle_size + +!=============================================================================== +! MACROXS_*_GET_XS returns the requested data type +!=============================================================================== + + function macroxs_iso_get_xs(this, g, xstype, uvw) result(xs) + class(MacroXS_Iso), intent(in) :: this ! The MacroXS to initialize + integer, intent(in) :: g ! Incoming Energy group + character(*) , intent(in) :: xstype ! Type of xs requested + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Requested x/s + + select case(xstype) + case('total') + xs = this % total(g) + case('absorption') + xs = this % absorption(g) + case('fission') + xs = this % fission(g) + case('k_fission') + xs = this % k_fission(g) + case('nu_fission') + xs = this % nu_fission(g) + case('scatter') + xs = this % scattxs(g) + end select + + end function macroxs_iso_get_xs + + function macroxs_angle_get_xs(this, g, xstype, uvw) result(xs) + class(MacroXS_Angle), intent(in) :: this ! The MacroXS to initialize + integer, intent(in) :: g ! Incoming Energy group + character(*) , intent(in) :: xstype ! Type of xs requested + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Requested x/s + + integer :: iazi, ipol + + if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + select case(xstype) + case('total') + xs = this % total(g,iazi,ipol) + case('absorption') + xs = this % absorption(g,iazi,ipol) + case('fission') + xs = this % fission(g,iazi,ipol) + case('k_fission') + xs = this % k_fission(g,iazi,ipol) + case('nu_fission') + xs = this % nu_fission(g,iazi,ipol) + case('scatter') + xs = this % scattxs(g,iazi,ipol) + end select + end if + + end function macroxs_angle_get_xs + +!=============================================================================== +! THIN_GRID thins an (x,y) set while also thinning an associated y2 +!=============================================================================== + + subroutine thin_grid(xout, yout, yout2, tol, compression, maxerr) + real(8), allocatable, intent(inout) :: xout(:) ! Resultant x grid + real(8), allocatable, intent(inout) :: yout(:) ! Resultant y values + real(8), allocatable, intent(inout) :: yout2(:) ! Secondary y values + real(8), intent(in) :: tol ! Desired fractional error to maintain + real(8), intent(out) :: compression ! Data reduction fraction + real(8), intent(inout) :: maxerr ! Maximum error due to compression + + real(8), allocatable :: xin(:) ! Incoming x grid + real(8), allocatable :: yin(:) ! Incoming y values + real(8), allocatable :: yin2(:) ! Secondary Incoming y values + integer :: k, klo, khi + integer :: all_ok + real(8) :: x1, y1, x2, y2, x, y, testval + integer :: num_keep, remove_it + real(8) :: initial_size + real(8) :: error + real(8) :: x_frac + + initial_size = real(size(xout), 8) + + allocate(xin(size(xout))) + xin = xout + allocate(yin(size(yout))) + yin = yout + allocate(yin2(size(yout2))) + yin2 = yout2 + + all_ok = size(yin) + maxerr = 0.0_8 + + ! This loop will step through each entry in dim==3 and check to see if + ! all of the values in other 2 dims can be replaced with linear interp. + ! If not, the value will be saved to a new array, if so, it will be + ! skipped. + + xout = 0.0_8 + yout = 0.0_8 + + ! Keep first point's data + xout(1) = xin(1) + yout(1) = yin(1) + yout2(1) = yin2(1) + + ! Initialize data + num_keep = 1 + klo = 1 + khi = 3 + k = 2 + do while (khi <= size(xin)) + remove_it = 0 + x1 = xin(klo) + x2 = xin(khi) + x = xin(k) + x_frac = 1.0_8 / (x2 - x1) * (x - x1) ! Linear interp. + + ! Check for removal. Otherwise, it stays. This is accomplished by leaving + ! remove_it as 0, entering the else portion of if(remove_it==all_ok) + y1 = yin(klo) + y2 = yin(khi) + y = yin(k) + + testval = y1 + (y2 - y1) * x_frac + error = abs(testval - y) + if (y /= 0.0_8) then + error = error / y + end if + if (error <= tol) then + remove_it = remove_it + 1 + if (error > maxerr) then + maxerr = abs(testval - y) + end if + end if + ! Now place the point in to the proper bin and advance iterators. + if (remove_it /= 0) then + ! Then don't put it in the new grid but advance iterators + k = k + 1 + khi = khi + 1 + else + ! Put it in new grid and advance iterators accordingly + num_keep = num_keep + 1 + xout(num_keep) = xin(k) + yout(num_keep) = yin(k) + yout2(num_keep) = yin2(k) + klo = k + k = k + 1 + khi = khi + 1 + end if + end do + ! Save the last point's data + num_keep = num_keep + 1 + xout(num_keep) = xin(size(xin)) + yout(num_keep) = yin(size(xin)) + yout2(num_keep) = yin2(size(xin)) + + ! Finally, xout and yout were sized to match xin and yin since we knew + ! they would be no larger than those. Now we must resize these arrays + ! and copy only the useful data in. Will use xin/yin for temp arrays. + xin = xout(1:num_keep) + yin = yout(1:num_keep) + yin2 = yout2(1:num_keep) + + deallocate(xout) + deallocate(yout) + deallocate(yout2) + allocate(xout(num_keep)) + allocate(yout(size(yin))) + allocate(yout2(size(yin2))) + + xout = xin(1:num_keep) + yout = yin(1:num_keep) + yout2 = yin2(1:num_keep) + + ! Clean up + deallocate(xin) + deallocate(yin) + deallocate(yin2) + + compression = (initial_size - real(size(xout),8)) / initial_size + + end subroutine thin_grid + +end module macroxs_header diff --git a/src/math.F90 b/src/math.F90 index 6b96baa0d9..9ca7a30c7c 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -1,7 +1,6 @@ module math use constants - use random_lcg, only: prn implicit none @@ -558,51 +557,43 @@ contains end function calc_rn !=============================================================================== -! MAXWELL_SPECTRUM samples an energy from the Maxwell fission distribution based -! on a direct sampling scheme. The probability distribution function for a -! Maxwellian is given as p(x) = 2/(T*sqrt(pi))*sqrt(x/T)*exp(-x/T). This PDF can -! be sampled using rule C64 in the Monte Carlo Sampler LA-9721-MS. +! EXPAND_HARMONIC expands a given series of harmonics !=============================================================================== + pure function expand_harmonic(data, order, uvw) result(val) + real(8), intent(in) :: data(:) + integer, intent(in) :: order + real(8), intent(in) :: uvw(3) + real(8) :: val - function maxwell_spectrum(T) result(E_out) + integer :: l, lm_lo, lm_hi - real(8), intent(in) :: T ! tabulated function of incoming E - real(8) :: E_out ! sampled energy + val = data(1) + lm_lo = 2 + lm_hi = 4 + do l = 1, order - 1 + val = val + sqrt(TWO * real(l,8) + ONE) * & + dot_product(calc_rn(l,uvw), data(lm_lo:lm_hi)) + lm_lo = lm_hi + 1 + lm_hi = lm_lo + 2 * (l + 1) + end do - real(8) :: r1, r2, r3 ! random numbers - real(8) :: c ! cosine of pi/2*r3 - - r1 = prn() - r2 = prn() - r3 = prn() - - ! determine cosine of pi/2*r - c = cos(PI/TWO*r3) - - ! determine outgoing energy - E_out = -T*(log(r1) + log(r2)*c*c) - - end function maxwell_spectrum + end function expand_harmonic !=============================================================================== -! WATT_SPECTRUM samples the outgoing energy from a Watt energy-dependent fission -! spectrum. Although fitted parameters exist for many nuclides, generally the -! continuous tabular distributions (LAW 4) should be used in lieu of the Watt -! spectrum. This direct sampling scheme is an unpublished scheme based on the -! original Watt spectrum derivation (See F. Brown's MC lectures). +! EVALUATE_LEGENDRE !=============================================================================== + pure function evaluate_legendre(data, x) result(val) + real(8), intent(in) :: data(:) + real(8), intent(in) :: x + real(8) :: val - function watt_spectrum(a, b) result(E_out) + integer :: l - real(8), intent(in) :: a ! Watt parameter a - real(8), intent(in) :: b ! Watt parameter b - real(8) :: E_out ! energy of emitted neutron + val = 0.5_8 * data(1) + do l = 1, size(data) - 1 + val = val + (real(l,8) + 0.5_8) * data(l + 1) * calc_pn(l,x) + end do - real(8) :: w ! sampled from Maxwellian - - w = maxwell_spectrum(a) - E_out = w + a*a*b/4. + (TWO*prn() - ONE)*sqrt(a*a*b*w) - - end function watt_spectrum + end function evaluate_legendre end module math diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 new file mode 100644 index 0000000000..64c5dcce7d --- /dev/null +++ b/src/mgxs_data.F90 @@ -0,0 +1,650 @@ +module mgxs_data + +use constants + use error, only: fatal_error, warning + use global + use list_header, only: ListInt + use macroxs_header + use material_header, only: Material + use nuclide_header + use output, only: write_message + use set_header, only: SetChar + use simple_string, only: to_lower + use xml_interface + + implicit none + +contains + +!=============================================================================== +! READ_XS reads all the cross sections for the problem and stores them in +! nuclides and sab_tables arrays +!=============================================================================== + + subroutine read_mgxs() + + integer :: i ! index in materials array + integer :: j ! index over nuclides in material + integer :: i_listing ! index in xs_listings array + integer :: i_nuclide ! index in nuclides + character(12) :: name ! name of isotope, e.g. 92235.03c + character(12) :: alias ! alias of isotope, e.g. U-235.03c + integer :: representation ! Data representation + type(Material), pointer :: mat + class(Nuclide_MG), pointer :: nuc + type(SetChar) :: already_read + type(Node), pointer :: doc => null() + type(Node), pointer :: node_xsdata + type(NodeList), pointer :: node_xsdata_list => null() + logical :: file_exists + integer :: error_code + character(MAX_LINE_LEN) :: error_text, temp_str + logical :: get_kfiss + integer :: l + + ! Check if cross_sections.xml exists + inquire(FILE=path_cross_sections, EXIST=file_exists) + if (.not. file_exists) then + ! Could not find cross_sections.xml file + call fatal_error("Cross sections XML file '" & + &// trim(path_cross_sections) // "' does not exist!") + end if + + call write_message("Loading Cross Section Data...", 5) + + ! Parse cross_sections.xml file + call open_xmldoc(doc, path_cross_sections) + + ! Get node list of all + call get_node_list(doc, "xsdata", node_xsdata_list) + n_listings = get_list_size(node_xsdata_list) + + ! allocate arrays for ACE table storage and cross section cache + allocate(nuclides_MG(n_nuclides_total)) + + ! Find out if we need kappa fission (are there any k_fiss tallies?) + get_kfiss = .false. + do i = 1, n_tallies + do l = 1, tallies(i) % n_score_bins + if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then + get_kfiss = .true. + exit + end if + end do + if (get_kfiss) & + exit + end do + + ! ========================================================================== + ! READ ALL ACE CROSS SECTION TABLES + + ! Loop over all files + MATERIAL_LOOP: do i = 1, n_materials + mat => materials(i) + + NUCLIDE_LOOP: do j = 1, mat % n_nuclides + name = mat % names(j) + + if (.not. already_read % contains(name)) then + i_listing = xs_listing_dict % get_key(to_lower(name)) + i_nuclide = mat % nuclide(j) + name = xs_listings(i_listing) % name + alias = xs_listings(i_listing) % alias + + ! Keep track of what listing is associated with this nuclide + nuc => nuclides_MG(i_nuclide) % obj + + ! Get pointer to xsdata table XML node + call get_list_item(node_xsdata_list, i_listing, node_xsdata) + + call write_message("Loading " // trim(name) // " Data...", 5) + + ! First find out the data representation + if (check_for_node(node_xsdata, "representation")) then + call get_node_value(node_xsdata, "representation", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'isotropic' .or. temp_str == 'iso') then + representation = ISOTROPIC + else if (temp_str == 'angle') then + representation = ANGLE + else + call fatal_error("Invalid Data Representation!") + end if + else + ! Default to isotropic representation + representation = ISOTROPIC + end if + + ! Now allocate accordingly + select case(representation) + case(ISOTROPIC) + allocate(Nuclide_Iso :: nuclides_MG(i_nuclide) % obj) + case(ANGLE) + allocate(Nuclide_Angle :: nuclides_MG(i_nuclide) % obj) + end select + + ! Now read in the data specific to the type we just declared + call nuclide_mg_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & + energy_groups, get_kfiss, error_code, & + error_text) + + ! Handle any errors + if (error_code /= 0) then + call fatal_error(trim(error_text)) + end if + + ! Add name and alias to dictionary + call already_read % add(name) + call already_read % add(alias) + end if + end do NUCLIDE_LOOP + end do MATERIAL_LOOP + + ! Avoid some valgrind leak errors + call already_read % clear() + + ! Loop around material + MATERIAL_LOOP3: do i = 1, n_materials + + ! Get material + mat => materials(i) + + ! Loop around nuclides in material + NUCLIDE_LOOP2: do j = 1, mat % n_nuclides + ! Get nuclide + nuc => nuclides_MG(mat % nuclide(j)) % obj + if (nuc % fissionable) then + mat % fissionable = .true. + end if + if (mat % fissionable) then + exit NUCLIDE_LOOP2 + end if + + end do NUCLIDE_LOOP2 + end do MATERIAL_LOOP3 + + end subroutine read_mgxs + +!=============================================================================== +! SAME_NUCLIDE_LIST creates a linked list for each nuclide containing the +! indices in the nuclides array of all other instances of that nuclide. For +! example, the same nuclide may exist at multiple temperatures resulting +! in multiple entries in the nuclides array for a single zaid number. +!=============================================================================== + + subroutine same_nuclide_mg_list() + + integer :: i ! index in nuclides array + integer :: j ! index in nuclides array + + do i = 1, n_nuclides_total + do j = 1, n_nuclides_total + if (nuclides_MG(i) % obj % zaid == nuclides_MG(j) % obj % zaid) then + call nuclides_MG(i) % obj % nuc_list % append(j) + end if + end do + end do + + end subroutine same_nuclide_mg_list + +!=============================================================================== +! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed +!=============================================================================== + + subroutine nuclide_mg_init(this, node_xsdata, groups, get_kfiss, & + error_code, error_text) + class(Nuclide_MG), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + character(MAX_LINE_LEN) :: temp_str + + ! Initialize error data + error_code = 0 + error_text = '' + + ! Load the data + if (check_for_node(node_xsdata, "awr")) then + call get_node_value(node_xsdata, "awr", this % awr) + else + this % awr = ONE + end if + if (check_for_node(node_xsdata, "zaid")) then + call get_node_value(node_xsdata, "zaid", this % zaid) + else + this % zaid = -1 + end if + if (check_for_node(node_xsdata, "scatt_type")) then + call get_node_value(node_xsdata, "scatt_type", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'legendre') then + this % scatt_type = ANGLE_LEGENDRE + else if (temp_str == 'tabular') then + this % scatt_type = ANGLE_HISTOGRAM + else + error_code = 1 + error_text = "Invalid Scatt Type Option!" + return + end if + else + this % scatt_type = ANGLE_LEGENDRE + end if + if (check_for_node(node_xsdata, "order")) then + call get_node_value(node_xsdata, "order", this % order) + else + error_code = 1 + error_text = "Order Must Be Provided!" + return + end if + if (check_for_node(node_xsdata, "fissionable")) then + call get_node_value(node_xsdata, "fissionable", temp_str) + temp_str = to_lower(temp_str) + if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then + this % fissionable = .true. + else + this % fissionable = .false. + end if + else + error_code = 1 + error_text = "Fissionable element must be set!" + return + end if + + select type(this) + type is (Nuclide_Iso) + call nuclide_iso_init(this, node_xsdata, groups, get_kfiss, & + error_code, error_text) + type is (Nuclide_Angle) + call nuclide_angle_init(this, node_xsdata, groups, get_kfiss, & + error_code, error_text) + end select + + end subroutine nuclide_mg_init + + subroutine nuclide_iso_init(this, node_xsdata, groups, get_kfiss, & + error_code, error_text) + class(Nuclide_Iso), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + real(8), allocatable :: temp_arr(:) + integer :: arr_len + integer :: order_dim + + ! Load the more specific data + if (this % fissionable) then + allocate(this % fission(groups)) + + if (check_for_node(node_xsdata, "chi")) then + ! Get chi + allocate(this % chi(groups)) + call get_node_array(node_xsdata, "chi", this % chi) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * 1)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, 1)) + this % nu_fission = reshape(temp_arr, (/groups, 1/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "If fissionable, must provide nu_fission!" + return + end if + + else + ! Get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + + allocate(temp_arr(groups*groups)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, groups)) + this % nu_fission = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "If fissionable, must provide nu_fission!" + return + end if + end if + if (check_for_node(node_xsdata, "fission")) then + call get_node_array(node_xsdata, "fission", this % fission) + else + error_code = 1 + error_text = "If fissionable, must provide fission!" + return + end if + if (get_kfiss) then + allocate(this % k_fission(groups)) + if (check_for_node(node_xsdata, "k_fission")) then + call get_node_array(node_xsdata, "k_fission", this % k_fission) + else + error_code = 1 + error_text = "k_fission data missing, required due to kappa-fission& + & tallies in tallies.xml file!" + return + end if + end if + end if + + allocate(this % absorption(groups)) + if (check_for_node(node_xsdata, "absorption")) then + call get_node_array(node_xsdata, "absorption", this % absorption) + else + error_code = 1 + error_text = "Must provide absorption!" + return + end if + + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = this % order + 1 + else if (this % scatt_type == ANGLE_HISTOGRAM) then + order_dim = this % order + end if + + allocate(this % scatter(groups, groups, order_dim)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim)) + call get_node_array(node_xsdata, "scatter", temp_arr) + this % scatter = reshape(temp_arr, (/groups, groups, order_dim/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Must provide scatter!" + return + end if + + + allocate(this % total(groups)) + if (check_for_node(node_xsdata, "total")) then + call get_node_array(node_xsdata, "total", this % total) + else + this % total = this % absorption + sum(this%scatter(:,:,1),dim=1) + end if + + ! Get Mult Data + allocate(this % mult(groups, groups)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + this % mult = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Multiplicity Length Not Same as number of groups squared!" + return + end if + else + this % mult = ONE + end if + + end subroutine nuclide_iso_init + + subroutine nuclide_angle_init(this, node_xsdata, groups, get_kfiss, & + error_code, error_text) + class(Nuclide_Angle), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + + real(8), allocatable :: temp_arr(:) + integer :: arr_len + real(8) :: dangle + integer :: iangle + integer :: order_dim + + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = this % order + 1 + else if (this % scatt_type == ANGLE_HISTOGRAM) then + order_dim = this % order + end if + + if (check_for_node(node_xsdata, "num_polar")) then + call get_node_value(node_xsdata, "num_polar", this % Npol) + else + error_code = 1 + error_text = "num_polar Must Be Provided!" + return + end if + + if (check_for_node(node_xsdata, "num_azimuthal")) then + call get_node_value(node_xsdata, "num_azimuthal", this % Nazi) + else + error_code = 1 + error_text = "num_azimuthal Must Be Provided!" + return + end if + + ! Load angle data, if present (else equally spaced) + allocate(this % polar(this % Npol)) + allocate(this % azimuthal(this % Nazi)) + if (check_for_node(node_xsdata, "polar")) then + error_code = 1 + error_text = "User-Specified polar angle bins not yet supported!" + return + call get_node_array(node_xsdata, "polar", this % polar) + else + dangle = PI / (real(this % Npol,8)) + do iangle = 1, this % Npol + this % polar(iangle) = (real(iangle,8) - 0.5_8) * dangle + end do + end if + if (check_for_node(node_xsdata, "azimuthal")) then + error_code = 1 + error_text = "User-Specified azimuthal angle bins not yet supported!" + return + call get_node_array(node_xsdata, "azimuthal", this % azimuthal) + else + dangle = TWO * PI / (real(this % Nazi,8)) + do iangle = 1, this % Nazi + this % azimuthal(iangle) = -PI + (real(iangle,8) - 0.5_8) * dangle + end do + end if + + ! Load the more specific data + if (this % fissionable) then + + if (check_for_node(node_xsdata, "chi")) then + ! Get chi + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "chi", temp_arr) + allocate(this % chi(groups, this % Nazi, this % Npol)) + this % chi = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, 1, this % Nazi, this % Npol)) + this % nu_fission = reshape(temp_arr, (/groups, 1, this % Nazi, & + this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "If fissionable, must provide nu_fission!" + return + end if + + else + ! Get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, groups, this % Nazi, this % Npol)) + this % nu_fission = reshape(temp_arr, (/groups, groups, & + this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "If fissionable, must provide nu_fission!" + return + end if + end if + if (check_for_node(node_xsdata, "fission")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "fission", temp_arr) + allocate(this % fission(groups, this % Nazi, this % Npol)) + this % fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "If fissionable, must provide fission!" + return + end if + if (get_kfiss) then + if (check_for_node(node_xsdata, "k_fission")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "k_fission", temp_arr) + allocate(this % k_fission(groups, this % Nazi, this % Npol)) + this % k_fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "k_fission data missing, required due to kappa-fission& + & tallies in tallies.xml file!" + return + end if + end if + end if + + if (check_for_node(node_xsdata, "absorption")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "absorption", temp_arr) + allocate(this % absorption(groups, this % Nazi, this % Npol)) + this % absorption = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Must provide absorption!" + return + end if + + allocate(this % scatter(groups, groups, order_dim, this % Nazi, this % Npol)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim * this % Nazi * this%Npol)) + call get_node_array(node_xsdata, "scatter", temp_arr) + this % scatter = reshape(temp_arr, (/groups, groups, order_dim, & + this%Nazi,this%Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Must provide scatter!" + return + end if + + if (check_for_node(node_xsdata, "total")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "total", temp_arr) + allocate(this % total(groups, this % Nazi, this % Npol)) + this % total = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + this % total = this % absorption + sum(this%scatter(:,:,1,:,:),dim=1) + end if + + ! Get Mult Data + allocate(this % mult(groups, groups, this % Nazi, this % Npol)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups * this % Nazi * this % Npol) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + this % mult = reshape(temp_arr, (/groups, groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Multiplicity Length Does Not Match!" + return + end if + else + this % mult = ONE + end if + + end subroutine nuclide_angle_init + + +!=============================================================================== +! CREATE_MACRO_XS generates the macroscopic x/s from the microscopic input data +!=============================================================================== + + subroutine create_macro_xs() + integer :: i_mat ! index in materials array + integer :: i ! loop index over nuclides + integer :: l ! Loop over score bins + type(Material), pointer :: mat ! current material + logical :: get_kfiss + integer :: error_code + character(MAX_LINE_LEN) :: error_text + integer :: representation + integer :: scatt_type + + ! Find out if we need kappa fission (are there any k_fiss tallies?) + get_kfiss = .false. + do i = 1, n_tallies + do l = 1, tallies(i) % n_score_bins + if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then + get_kfiss = .true. + exit + end if + end do + if (get_kfiss) & + exit + end do + + allocate(macro_xs(n_materials)) + + do i_mat = 1, n_materials + mat => materials(i_mat) + + ! Check to see how our nuclides are represented + ! For now assume all are the same type + ! Therefore type(nuclides(1) % obj) dictates type(macroxs) + ! At the same time, we will find the scattering type, as that will dictate + ! how we allocate the scatter object within macroxs + scatt_type = ANGLE_LEGENDRE + select type(nuc => nuclides_MG(1) % obj) + type is (Nuclide_Iso) + representation = ISOTROPIC + if (nuc % scatt_type == ANGLE_HISTOGRAM) then + scatt_type = ANGLE_HISTOGRAM + end if + type is (Nuclide_Angle) + representation = ANGLE + if (nuc % scatt_type == ANGLE_HISTOGRAM) then + scatt_type = ANGLE_HISTOGRAM + end if + end select + + ! Now allocate accordingly + select case(representation) + case(ISOTROPIC) + allocate(MacroXS_Iso :: macro_xs(i_mat) % obj) + case(ANGLE) + allocate(MacroXS_Angle :: macro_xs(i_mat) % obj) + end select + + call macro_xs(i_mat) % obj % init(mat, nuclides_MG, energy_groups, & + get_kfiss, max_order, scatt_type, & + legendre_mu_points, error_code, & + error_text) + ! Handle any errors + if (error_code /= 0) then + call fatal_error(trim(error_text)) + end if + end do + end subroutine create_macro_xs + +end module mgxs_data \ No newline at end of file diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index cd83402a07..2910f63b19 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -9,7 +9,6 @@ module nuclide_header ! use math, only: calc_pn, calc_rn!, expand_harmonic !use scattdata_header use simple_string - ! use xml_interface implicit none @@ -106,13 +105,90 @@ module nuclide_header procedure, pass :: print => nuclide_ce_print end type Nuclide_CE -!=============================================================================== -! NUCLIDECONTAINER pointer array for storing Nuclides + type, abstract, extends(Nuclide_Base) :: Nuclide_MG + ! Scattering Order Information + integer :: order ! Order of data (Scattering for Nuclide_Iso, + ! Number of angles for all in Nuclide_Angle) + integer :: scatt_type ! either legendre or tabular. + + ! Type-Bound procedures + contains + procedure(nuclide_mg_get_xs_), deferred, pass :: get_xs ! Get the xs + end type Nuclide_MG + + abstract interface + function nuclide_mg_get_xs_(this, g, xstype, gout, uvw) result(xs) + import Nuclide_MG + class(Nuclide_MG), intent(in) :: this + integer, intent(in) :: g ! Incoming Energy group + character(*), intent(in) :: xstype ! Cross Section Type + integer, optional, intent(in) :: gout ! Outgoing Group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Resultant xs + end function nuclide_mg_get_xs_ + end interface + + !=============================================================================== +! NUCLIDE_ISO contains the base MGXS data for a nuclide specifically for +! isotropically weighted MGXS !=============================================================================== - type NuclideContainer - class(Nuclide_Base), pointer :: obj - end type NuclideContainer + type, extends(Nuclide_MG) :: Nuclide_Iso + + ! Microscopic cross sections + real(8), allocatable :: total(:) ! total cross section + real(8), allocatable :: absorption(:) ! absorption cross section + real(8), allocatable :: scatter(:,:,:) ! scattering information + real(8), allocatable :: nu_fission(:,:) ! fission matrix (Gout x Gin) + real(8), allocatable :: k_fission(:) ! kappa-fission + real(8), allocatable :: fission(:) ! neutron production + real(8), allocatable :: chi(:) ! Fission Spectra + real(8), allocatable :: mult(:,:) ! Scatter multiplicity (Gout x Gin) + + ! Type-Bound procedures + contains + procedure, pass :: clear => nuclide_iso_clear ! Deallocates Nuclide + procedure, pass :: print => nuclide_iso_print ! Writes nuclide info + procedure, pass :: get_xs => nuclide_iso_get_xs ! Gets Size of Data w/in Object + end type Nuclide_Iso + +!=============================================================================== +! NUCLIDE_ANGLE contains the base MGXS data for a nuclide specifically for +! explicit angle-dependent weighted MGXS +!=============================================================================== + + type, extends(Nuclide_MG) :: Nuclide_Angle + + ! Microscopic cross sections. Dimensions are: (Npol, Nazi, Nl, Ng, Ng) + real(8), allocatable :: total(:,:,:) ! total cross section + real(8), allocatable :: absorption(:,:,:) ! absorption cross section + real(8), allocatable :: scatter(:,:,:,:,:) ! scattering information + real(8), allocatable :: nu_fission(:,:,:,:) ! fission matrix (Gout x Gin) + real(8), allocatable :: k_fission(:,:,:) ! kappa-fission + real(8), allocatable :: fission(:,:,:) ! neutron production + real(8), allocatable :: chi(:,:,:) ! Fission Spectra + real(8), allocatable :: mult(:,:,:,:) ! Scatter multiplicity (Gout x Gin) + + ! In all cases, right-most indices are theta, phi + integer :: Npol ! Number of polar angles + integer :: Nazi ! Number of azimuthal angles + real(8), allocatable :: polar(:) ! polar angles + real(8), allocatable :: azimuthal(:) ! azimuthal angles + + ! Type-Bound procedures + contains + procedure, pass :: clear => nuclide_angle_clear ! Deallocates Nuclide + procedure, pass :: print => nuclide_angle_print ! Gets Size of Data w/in Object + procedure, pass :: get_xs => nuclide_angle_get_xs ! Gets Size of Data w/in Object + end type Nuclide_Angle + +!=============================================================================== +! NUCLIDEMGCONTAINER pointer array for storing Nuclides +!=============================================================================== + + type NuclideMGContainer + class(Nuclide_MG), pointer :: obj + end type NuclideMGContainer !=============================================================================== ! NUCLIDE0K temporarily contains all 0K cross section data and other parameters @@ -193,7 +269,6 @@ module nuclide_header contains - !=============================================================================== ! NUCLIDE_*_CLEAR resets and deallocates data in Nuclide_Base, Nuclide_Iso ! or Nuclide_Angle @@ -260,122 +335,304 @@ module nuclide_header end subroutine nuclide_ce_clear + subroutine nuclide_iso_clear(this) + + class(Nuclide_Iso), intent(inout) :: this ! The Nuclide object to clear + + ! Clear the base object + call nuclide_base_clear_(this) + + ! Cler the extended information + if (allocated(this % total)) then + deallocate(this % total, this % absorption, this % scatter) + end if + if (allocated(this % fission)) then + deallocate(this % fission, this % nu_fission) + end if + if (allocated(this % k_fission)) then + deallocate(this % k_fission) + end if + if (allocated(this % chi)) then + deallocate(this % chi) + end if + if (allocated(this % mult)) then + deallocate(this % mult) + end if + + end subroutine nuclide_iso_clear + + subroutine nuclide_angle_clear(this) + + class(Nuclide_Angle), intent(inout) :: this ! The Nuclide object to clear + + ! Clear the base object + call nuclide_base_clear_(this) + + ! Cler the extended information + if (allocated(this % total)) then + deallocate(this % total, this % absorption, this % scatter) + end if + if (allocated(this % fission)) then + deallocate(this % fission, this % nu_fission) + end if + if (allocated(this % k_fission)) then + deallocate(this % k_fission) + end if + if (allocated(this % chi)) then + deallocate(this % chi) + end if + + if (allocated(this % polar)) then + deallocate(this % polar) + end if + if (allocated(this % azimuthal)) then + deallocate(this % azimuthal) + end if + if (allocated(this % mult)) then + deallocate(this % mult) + end if + + end subroutine nuclide_angle_clear + !=============================================================================== ! PRINT_NUCLIDE_* displays information about a continuous-energy neutron ! cross_section table and its reactions and secondary angle/energy distributions !=============================================================================== - subroutine nuclide_ce_print(this, unit) + subroutine nuclide_ce_print(this, unit) - class(Nuclide_CE), intent(in) :: this - integer, optional, intent(in) :: unit + class(Nuclide_CE), intent(in) :: this + integer, optional, intent(in) :: unit - integer :: i ! loop index over nuclides - integer :: unit_ ! unit to write to - integer :: size_total ! memory used by nuclide (bytes) - integer :: size_angle_total ! total memory used for angle dist. (bytes) - integer :: size_energy_total ! total memory used for energy dist. (bytes) - integer :: size_xs ! memory used for cross-sections (bytes) - integer :: size_angle ! memory used for an angle distribution (bytes) - integer :: size_energy ! memory used for a energy distributions (bytes) - integer :: size_urr ! memory used for probability tables (bytes) - character(11) :: law ! secondary energy distribution law - type(Reaction), pointer :: rxn => null() - type(UrrData), pointer :: urr => null() + integer :: i ! loop index over nuclides + integer :: unit_ ! unit to write to + integer :: size_total ! memory used by nuclide (bytes) + integer :: size_angle_total ! total memory used for angle dist. (bytes) + integer :: size_energy_total ! total memory used for energy dist. (bytes) + integer :: size_xs ! memory used for cross-sections (bytes) + integer :: size_angle ! memory used for an angle distribution (bytes) + integer :: size_energy ! memory used for a energy distributions (bytes) + integer :: size_urr ! memory used for probability tables (bytes) + character(11) :: law ! secondary energy distribution law + type(Reaction), pointer :: rxn => null() + type(UrrData), pointer :: urr => null() - ! set default unit for writing information - if (present(unit)) then - unit_ = unit - else - unit_ = OUTPUT_UNIT - end if - - ! Initialize totals - size_angle_total = 0 - size_energy_total = 0 - size_urr = 0 - size_xs = 0 - - ! Basic nuclide information - write(unit_,*) 'Nuclide ' // trim(this % name) - write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) - write(unit_,*) ' awr = ' // trim(to_str(this % awr)) - write(unit_,*) ' kT = ' // trim(to_str(this % kT)) - write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid)) - write(unit_,*) ' Fissionable = ', this % fissionable - write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission)) - write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction)) - - ! Information on each reaction - write(unit_,*) ' Reaction Q-value COM Law IE size(angle) size(energy)' - do i = 1, this % n_reaction - rxn => this % reactions(i) - - ! Determine size of angle distribution - if (rxn % has_angle_dist) then - size_angle = rxn % adist % n_energy * 16 + size(rxn % adist % data) * 8 + ! set default unit for writing information + if (present(unit)) then + unit_ = unit else - size_angle = 0 + unit_ = OUTPUT_UNIT end if - ! Determine size of energy distribution and law - if (rxn % has_energy_dist) then - size_energy = size(rxn % edist % data) * 8 - law = to_str(rxn % edist % law) - else - size_energy = 0 - law = 'None' + ! Initialize totals + size_angle_total = 0 + size_energy_total = 0 + size_urr = 0 + size_xs = 0 + + ! Basic nuclide information + write(unit_,*) 'Nuclide ' // trim(this % name) + write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid)) + write(unit_,*) ' Fissionable = ', this % fissionable + write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission)) + write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction)) + + ! Information on each reaction + write(unit_,*) ' Reaction Q-value COM Law IE size(angle) size(energy)' + do i = 1, this % n_reaction + rxn => this % reactions(i) + + ! Determine size of angle distribution + if (rxn % has_angle_dist) then + size_angle = rxn % adist % n_energy * 16 + size(rxn % adist % data) * 8 + else + size_angle = 0 + end if + + ! Determine size of energy distribution and law + if (rxn % has_energy_dist) then + size_energy = size(rxn % edist % data) * 8 + law = to_str(rxn % edist % law) + else + size_energy = 0 + law = 'None' + end if + + write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,A4,1X,I6,1X,I11,1X,I11)') & + reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, & + law(1:4), rxn % threshold, size_angle, size_energy + + ! Accumulate data size + size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8 + size_angle_total = size_angle_total + size_angle + size_energy_total = size_energy_total + size_energy + end do + + ! Add memory required for summary reactions (total, absorption, fission, + ! nu-fission) + size_xs = 8 * this % n_grid * 4 + + ! Write information about URR probability tables + size_urr = 0 + if (this % urr_present) then + urr => this % urr_data + write(unit_,*) ' Unresolved resonance probability table:' + write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy)) + write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob)) + write(unit_,*) ' Interpolation = ' // trim(to_str(urr % interp)) + write(unit_,*) ' Inelastic flag = ' // trim(to_str(urr % inelastic_flag)) + write(unit_,*) ' Absorption flag = ' // trim(to_str(urr % absorption_flag)) + write(unit_,*) ' Multiply by smooth? ', urr % multiply_smooth + write(unit_,*) ' Min energy = ', trim(to_str(urr % energy(1))) + write(unit_,*) ' Max energy = ', trim(to_str(urr % energy(urr % n_energy))) + + ! Calculate memory used by probability tables and add to total + size_urr = urr % n_energy * (urr % n_prob * 6 + 1) * 8 end if - write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,A4,1X,I6,1X,I11,1X,I11)') & - reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, & - law(1:4), rxn % threshold, size_angle, size_energy + ! Calculate total memory + size_total = size_xs + size_angle_total + size_energy_total + size_urr - ! Accumulate data size - size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8 - size_angle_total = size_angle_total + size_angle - size_energy_total = size_energy_total + size_energy - end do + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes' + write(unit_,*) ' Secondary angle distributions = ' // & + trim(to_str(size_angle_total)) // ' bytes' + write(unit_,*) ' Secondary energy distributions = ' // & + trim(to_str(size_energy_total)) // ' bytes' + write(unit_,*) ' Probability Tables = ' // & + trim(to_str(size_urr)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' - ! Add memory required for summary reactions (total, absorption, fission, - ! nu-fission) - size_xs = 8 * this % n_grid * 4 + ! Blank line at end of nuclide + write(unit_,*) - ! Write information about URR probability tables - size_urr = 0 - if (this % urr_present) then - urr => this % urr_data - write(unit_,*) ' Unresolved resonance probability table:' - write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy)) - write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob)) - write(unit_,*) ' Interpolation = ' // trim(to_str(urr % interp)) - write(unit_,*) ' Inelastic flag = ' // trim(to_str(urr % inelastic_flag)) - write(unit_,*) ' Absorption flag = ' // trim(to_str(urr % absorption_flag)) - write(unit_,*) ' Multiply by smooth? ', urr % multiply_smooth - write(unit_,*) ' Min energy = ', trim(to_str(urr % energy(1))) - write(unit_,*) ' Max energy = ', trim(to_str(urr % energy(urr % n_energy))) + end subroutine nuclide_ce_print - ! Calculate memory used by probability tables and add to total - size_urr = urr % n_energy * (urr % n_prob * 6 + 1) * 8 - end if + subroutine nuclide_iso_print(this, unit) - ! Calculate total memory - size_total = size_xs + size_angle_total + size_energy_total + size_urr + class(Nuclide_Iso), intent(in) :: this + integer, optional, intent(in) :: unit - ! Write memory used - write(unit_,*) ' Memory Requirements' - write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes' - write(unit_,*) ' Secondary angle distributions = ' // & - trim(to_str(size_angle_total)) // ' bytes' - write(unit_,*) ' Secondary energy distributions = ' // & - trim(to_str(size_energy_total)) // ' bytes' - write(unit_,*) ' Probability Tables = ' // & - trim(to_str(size_urr)) // ' bytes' - write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' - ! Blank line at end of nuclide - write(unit_,*) + end subroutine nuclide_iso_print - end subroutine nuclide_ce_print + subroutine nuclide_angle_print(this, unit) - end module nuclide_header \ No newline at end of file + class(Nuclide_Angle), intent(in) :: this + integer, optional, intent(in) :: unit + + + end subroutine nuclide_angle_print + +!=============================================================================== +! NUCLIDE_*_GET_XS Returns the requested data type +!=============================================================================== + + function nuclide_iso_get_xs(this, g, xstype, gout, uvw) result(xs) + class(Nuclide_Iso), intent(in) :: this + integer, intent(in) :: g ! Incoming Energy group + character(*), intent(in) :: xstype ! Cross Section Type + integer, optional, intent(in) :: gout ! Outgoing Group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Resultant xs + + if (present(gout)) then + select case(xstype) + case('mult') + xs = this % mult(gout,g) + case('nu_fission') + xs = this % nu_fission(gout,g) + end select + else + select case(xstype) + case('total') + xs = this % total(g) + case('absorption') + xs = this % absorption(g) + case('fission') + xs = this % fission(g) + case('k_fission') + xs = this % k_fission(g) + case('chi') + xs = this % chi(g) + case('scatter') + xs = this % total(g) - this % absorption(g) + end select + end if + end function nuclide_iso_get_xs + + function nuclide_angle_get_xs(this, g, xstype, gout, uvw) result(xs) + class(Nuclide_Angle), intent(in) :: this + integer, intent(in) :: g ! Incoming Energy group + character(*), intent(in) :: xstype ! Cross Section Type + integer, optional, intent(in) :: gout ! Outgoing Group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8) :: xs ! Resultant xs + + integer :: i_pol, i_azi + + call find_angle(this % polar, this % azimuthal, uvw, i_azi, i_pol) + + if (present(gout)) then + select case(xstype) + case('mult') + xs = this % mult(gout,g,i_azi,i_pol) + case('nu_fission') + xs = this % nu_fission(gout,g,i_azi,i_pol) + case('chi') + xs = this % chi(gout,i_azi,i_pol) + end select + else + select case(xstype) + case('total') + xs = this % total(g,i_azi,i_pol) + case('absorption') + xs = this % absorption(g,i_azi,i_pol) + case('fission') + xs = this % fission(g,i_azi,i_pol) + case('k_fission') + xs = this % k_fission(g,i_azi,i_pol) + case('chi') + xs = this % chi(g,i_azi,i_pol) + case('scatter') + xs = this % total(g,i_azi,i_pol) - this % absorption(g,i_azi,i_pol) + end select + end if + + end function nuclide_angle_get_xs + +!=============================================================================== +! find_angle finds the closest angle on the data grid and returns that index +!=============================================================================== + + subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) + real(8), intent(in) :: polar(:) ! Polar angles [0,pi] + real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] + real(8), intent(in) :: uvw(3) ! Direction of motion + integer, intent(inout) :: i_pol ! Closest polar bin + integer, intent(inout) :: i_azi ! Closest azi bin + + real(8) my_pol, my_azi, dangle + + ! Convert uvw to polar and azi + + my_pol = acos(uvw(3)) + my_azi = atan2(uvw(2), uvw(1)) + + ! Quick and clear (but slower): + ! i_pol = minloc(abs(polar - my_pol),dim=1) + ! i_azi = minloc(abs(azimuthal - my_azi),dim=1) + + ! Fast search for equi-binned angles + dangle = PI / (real(size(polar),8)) + i_pol = floor(my_pol / dangle + ONE) + dangle = TWO * PI / (real(size(azimuthal),8)) + i_azi = floor((my_azi + PI) / dangle + ONE) + + end subroutine find_angle + +end module nuclide_header \ No newline at end of file diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 40d7499015..f661e73c14 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -88,10 +88,10 @@ module particle_header type(Bank) :: secondary_bank(MAX_SECONDARY) contains - procedure :: initialize => initialize_particle - procedure :: clear => clear_particle - procedure(initialize_from_source_), deferred, pass :: initialize_from_source - procedure(create_secondary_), deferred, pass :: create_secondary + procedure, pass :: initialize => initialize_particle + procedure, pass :: clear => clear_particle + procedure, pass :: initialize_from_source => initialize_from_source_base + procedure, pass :: create_secondary => create_secondary_base end type Particle_Base type, extends(Particle_Base) :: Particle_CE @@ -114,31 +114,6 @@ module particle_header procedure :: create_secondary => create_secondary_mg end type Particle_MG - abstract interface - -!=============================================================================== -! INITIALIZE_FROM_SOURCE_ returns .true. if the given lattice indices fit within the -! bounds of the lattice. Returns false otherwise. - - subroutine initialize_from_source_(this, src) - import Particle_Base - import Bank - class(Particle_Base), intent(inout) :: this - type(Bank), intent(in) :: src - end subroutine initialize_from_source_ - -!=============================================================================== -! CREATE_SECONDARY_ Generates a secondary particle from this - - subroutine create_secondary_(this, uvw, type) - import Particle_Base - class(Particle_Base), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type - end subroutine create_secondary_ - - end interface - contains !=============================================================================== @@ -217,9 +192,9 @@ contains ! fission, or simply as a secondary particle. !=============================================================================== - subroutine initialize_from_source_ce(this, src) - class(Particle_CE), intent(inout) :: this - type(Bank), intent(in) :: src + subroutine initialize_from_source_base(this, src) + class(Particle_Base), intent(inout) :: this + type(Bank), intent(in) :: src ! set defaults call this % initialize() @@ -231,6 +206,17 @@ contains this % coord(1) % uvw = src % uvw this % last_xyz = src % xyz this % last_uvw = src % uvw + + end subroutine initialize_from_source_base + + subroutine initialize_from_source_ce(this, src) + class(Particle_CE), intent(inout) :: this + type(Bank), intent(in) :: src + + ! set defaults a nd init base + call initialize_from_source_base(this, src) + + ! copy attributes from source bank site this % E = src % E this % last_E = src % E @@ -240,16 +226,10 @@ contains class(Particle_MG), intent(inout) :: this type(Bank), intent(in) :: src - ! set defaults - call this % initialize() + ! set defaults and init base + call initialize_from_source_base(this, src) ! copy attributes from source bank site - this % wgt = src % wgt - this % last_wgt = src % wgt - this % coord(1) % xyz = src % xyz - this % coord(1) % uvw = src % uvw - this % last_xyz = src % xyz - this % last_uvw = src % uvw this % g = src % g this % last_g = src % g @@ -260,10 +240,10 @@ contains ! the secondary bank and increments the number of sites in the secondary bank. !=============================================================================== - subroutine create_secondary_ce(this, uvw, type) - class(Particle_CE), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type + subroutine create_secondary_base(this, uvw, type) + class(Particle_Base), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type integer :: n @@ -277,9 +257,19 @@ contains this % secondary_bank(n) % wgt = this % wgt this % secondary_bank(n) % xyz(:) = this % coord(1) % xyz this % secondary_bank(n) % uvw(:) = uvw - this % secondary_bank(n) % E = this % E this % n_secondary = n + end subroutine create_secondary_base + + subroutine create_secondary_ce(this, uvw, type) + class(Particle_CE), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type + + call create_secondary_base(this, uvw, type) + + this % secondary_bank(this % n_secondary) % E = this % E + end subroutine create_secondary_ce subroutine create_secondary_mg(this, uvw, type) @@ -287,20 +277,9 @@ contains real(8), intent(in) :: uvw(3) integer, intent(in) :: type - integer :: n + call create_secondary_base(this, uvw, type) - ! Check to make sure that the hard-limit on secondary particles is not - ! exceeded. - if (this % n_secondary == MAX_SECONDARY) then - call fatal_error("Too many secondary particles created.") - end if - - n = this % n_secondary + 1 - this % secondary_bank(n) % wgt = this % wgt - this % secondary_bank(n) % xyz(:) = this % coord(1) % xyz - this % secondary_bank(n) % uvw(:) = uvw - this % secondary_bank(n) % g = this % g - this % n_secondary = n + this % secondary_bank(this % n_secondary) % g = this % g end subroutine create_secondary_mg diff --git a/src/physics.F90 b/src/physics.F90 index a24ab8de4d..9bbed576dc 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -9,7 +9,6 @@ module physics use global use interpolation, only: interpolate_tab1 use material_header, only: Material - use math, only: maxwell_spectrum, watt_spectrum use mesh, only: get_mesh_indices use nuclide_header use output, only: write_message @@ -18,6 +17,7 @@ module physics use random_lcg, only: prn use search, only: binary_search use simple_string, only: to_str + use spectra implicit none diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 new file mode 100644 index 0000000000..63a428717b --- /dev/null +++ b/src/scattdata_header.F90 @@ -0,0 +1,355 @@ +module scattdata_header + + use math + use constants + + implicit none + +!=============================================================================== +! SCATTDATA contains all the data to describe the scattering energy and +! angular distribution +!=============================================================================== + + type, abstract :: ScattData_Base + ! p0 matrix on its own for sampling energy + real(8), allocatable :: energy(:,:) ! (Gout x Gin) + real(8), allocatable :: mult(:,:) ! (Gout x Gin) + real(8), allocatable :: data(:,:,:) ! (Order/Nmu x Gout x Gin) + + ! Type-Bound procedures + contains + procedure(init_), deferred, pass :: init ! Initializes ScattData + procedure(calc_f_), deferred, pass :: calc_f ! Calculates f, given mu + procedure(clear_), deferred, pass :: clear ! Deallocates ScattData + end type ScattData_Base + + abstract interface + subroutine init_(this, order, energy, mult, coeffs) + import ScattData_Base + class(ScattData_Base), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + end subroutine init_ + + pure function calc_f_(this, gin, gout, mu) result(f) + import ScattData_Base + class(ScattData_Base), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + + end function calc_f_ + + subroutine clear_(this) + import ScattData_Base + class(ScattData_Base), intent(inout) :: this ! The ScattData to clear + end subroutine clear_ + end interface + + type, extends(ScattData_Base) :: ScattData_Legendre + contains + procedure, pass :: init => scattdata_legendre_init + procedure, pass :: calc_f => scattdata_legendre_calc_f + procedure, pass :: clear => scattdata_legendre_clear + end type ScattData_Legendre + + type, extends(ScattData_Base) :: ScattData_Histogram + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing + contains + procedure, pass :: init => scattdata_histogram_init + procedure, pass :: calc_f => scattdata_histogram_calc_f + procedure, pass :: clear => scattdata_histogram_clear + end type ScattData_Histogram + + type, extends(ScattData_Base) :: ScattData_Tabular + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing + real(8), allocatable :: fmu(:,:,:) ! PDF of f(mu) + contains + procedure, pass :: init => scattdata_tabular_init + procedure, pass :: calc_f => scattdata_tabular_calc_f + procedure, pass :: clear => scattdata_tabular_clear + end type ScattData_Tabular + +!=============================================================================== +! SCATTDATACONTAINER allocatable array for storing ScattData Objects (for angle) +!=============================================================================== + + type ScattDataContainer + class(ScattData_Base), allocatable :: obj + end type ScattDataContainer + +contains + +!=============================================================================== +! SCATTDATA_INIT builds the scattdata object +!=============================================================================== + + subroutine scattdata_base_init(this, order, energy, mult) + class(ScattData_Base), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + + integer :: groups + + groups = size(energy, dim=1) + + allocate(this % energy(groups, groups)) + this % energy = energy + allocate(this % mult(groups, groups)) + this % mult = mult + allocate(this % data(order, groups, groups)) + this % data = ZERO + + end subroutine scattdata_base_init + + subroutine scattdata_legendre_init(this, order, energy, mult, coeffs) + class(ScattData_Legendre), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + + call scattdata_base_init(this, order, energy, mult) + + this % data = coeffs + + end subroutine scattdata_legendre_init + + subroutine scattdata_histogram_init(this, order, energy, mult, coeffs) + class(ScattData_Histogram), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + + integer :: imu, gin, gout, groups + real(8) :: norm + + groups = size(energy,dim=1) + + call scattdata_base_init(this, order, energy, mult) + + allocate(this % mu(order)) + this % dmu = TWO / (real(order,8)) + this % mu(1) = -ONE + do imu = 2, order + this % mu(imu) = -ONE + (imu - 1) * this % dmu + end do + + ! Best to integrate this histogram so we can avoid rejection sampling + do gin = 1, groups + do gout = 1, groups + if (energy(gout,gin) > ZERO) then + ! Integrate the histogram + this % data(1,gout,gin) = this % dmu * coeffs(1,gout,gin) + do imu = 2, order + this % data(imu,gout,gin) = this % dmu * coeffs(imu,gout,gin) + & + this % data(imu-1,gout,gin) + end do + ! Now make sure integral norms to zero + norm = this % data(order,gout,gin) + if (norm > ZERO) then + this % data(:,gout,gin) = this % data(:,gout,gin) / norm + end if + end if + end do + end do + + end subroutine scattdata_histogram_init + + subroutine scattdata_tabular_init(this, order, energy, mult, coeffs) + class(ScattData_Tabular), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + + integer :: imu, gin, gout, groups + real(8) :: norm + logical :: legendre_flag + integer :: this_order + + if (order < 0) then + legendre_flag = .true. + this_order = -1 * order + else + legendre_flag = .false. + this_order = order + end if + + groups = size(energy,dim=1) + + call scattdata_base_init(this, this_order, energy, mult) + + allocate(this % mu(this_order)) + this % dmu = TWO / (real(this_order,8) - 1) + do imu = 1, this_order - 1 + this % mu(imu) = -ONE + real(imu - 1, 8) * this % dmu + end do + this % mu(this_order) = ONE + + ! Best to integrate this histogram so we can avoid rejection sampling + allocate(this % fmu(this_order,groups,groups)) + do gin = 1, groups + do gout = 1, groups + if (energy(gout,gin) > ZERO) then + if (legendre_flag) then + ! Coeffs are legendre coeffs. Need to build f(mu) then integrate + ! and store the integral in this % data + ! Ensure the coeffs are normalized + norm = ONE / coeffs(1,gout,gin) + do imu = 1, this_order + this % fmu(imu,gout,gin) = evaluate_legendre(norm * coeffs(:,gout,gin), this % mu(imu)) + ! Force positivity + if (this % fmu(imu,gout,gin) < ZERO) then + this % fmu(imu,gout,gin) = ZERO + end if + end do + else + ! Coeffs contain f(mu), put in f(mu) to save duplicate. + this % fmu(:,gout,gin) = this % data(:,gout,gin) + end if + + ! Re-normalize fmu for numerical integration issues and in case + ! the negative fix-up introduced un-normalized data + norm = ZERO + do imu = 2, this_order + norm = norm + 0.5_8 * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) + end do + if (norm > ZERO) then + this % fmu(:,gout,gin) = this % fmu(:,gout,gin) / norm + end if + + ! Now create CDF from fmu with trapezoidal rule + this % data(1,gout,gin) = ZERO + do imu = 2, this_order - 1 + this % data(imu,gout,gin) = this % data(imu-1,gout,gin) + & + 0.5_8 * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) + end do + this % data(this_order,gout,gin) = ONE + end if + end do + end do + + end subroutine scattdata_tabular_init + +!=============================================================================== +! SCATTDATA_CLEAR resets and deallocates data in ScattData. +!=============================================================================== + + subroutine scattdata_base_clear(this) + class(ScattData_Base), intent(inout) :: this + + if (allocated(this % energy)) then + deallocate(this % energy) + end if + + if (allocated(this % mult)) then + deallocate(this % mult) + end if + + if (allocated(this % data)) then + deallocate(this % data) + end if + + end subroutine scattdata_base_clear + + subroutine scattdata_legendre_clear(this) + class(ScattData_Legendre), intent(inout) :: this + + call scattdata_base_clear(this) + + end subroutine scattdata_legendre_clear + + subroutine scattdata_histogram_clear(this) + class(ScattData_Histogram), intent(inout) :: this + + call scattdata_base_clear(this) + + if (allocated(this % mu)) then + deallocate(this % mu) + end if + + end subroutine scattdata_histogram_clear + + subroutine scattdata_tabular_clear(this) + class(ScattData_Tabular), intent(inout) :: this + + call scattdata_base_clear(this) + + if (allocated(this % mu)) then + deallocate(this % mu) + end if + + end subroutine scattdata_tabular_clear + +!=============================================================================== +! SCATTDATA_*_CALC_F Calculates the value of f given mu (and gin,gout pair) +!=============================================================================== + + pure function scattdata_legendre_calc_f(this, gin, gout, mu) result(f) + class(ScattData_Legendre), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + + ! Plug mu in to the legendre expansion and go from there + f = evaluate_legendre(this % data(:, gout, gin), mu) + + end function scattdata_legendre_calc_f + + pure function scattdata_histogram_calc_f(this, gin, gout, mu) result(f) + class(ScattData_Histogram), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + + integer :: imu + + ! Find mu bin + imu = floor((mu + ONE)/ this % dmu + ONE) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % data, dim=1)) then + imu = imu - 1 + end if + + ! Use histogram interpolation to find f(mu) + f = this % data(imu, gout, gin) + + end function scattdata_histogram_calc_f + + pure function scattdata_tabular_calc_f(this, gin, gout, mu) result(f) + class(ScattData_Tabular), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + + integer :: imu + real(8) :: r + + ! Find mu bin + imu = floor((mu + ONE)/ this % dmu + ONE) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % data, dim=1)) then + imu = imu - 1 + end if + + ! ! Now interpolate to find f(mu) + r = (mu - this % mu(imu)) / (this % mu(imu + 1) - this % mu(imu)) + f = (ONE - r) * this % data(imu, gout, gin) + & + r * this % data(imu + 1, gout, gin) + + end function scattdata_tabular_calc_f + + + +end module scattdata_header \ No newline at end of file diff --git a/src/simulation.F90 b/src/simulation.F90 index c31b1d6fa7..088a764f79 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -15,7 +15,7 @@ module simulation use global use output, only: write_message, header, print_columns, & print_batch_keff, print_generation - use particle_header, only: Particle_Base + use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: set_particle_seed use source, only: initialize_source use state_point, only: write_state_point, write_source_point @@ -42,6 +42,12 @@ contains class(Particle_Base), pointer :: p integer(8) :: i_work + if (run_CE) then + allocate(Particle_CE :: p) + else + allocate(Particle_MG :: p) + end if + if (.not. restart_run) call initialize_source() ! Display header @@ -116,6 +122,9 @@ contains ! Clear particle call p % clear() + if (associated(p)) & + deallocate(p) + end subroutine run_simulation !=============================================================================== @@ -124,8 +133,8 @@ contains subroutine initialize_history(p, index_source) - class(Particle_Base), intent(inout) :: p - integer(8), intent(in) :: index_source + class(Particle_Base), pointer, intent(inout) :: p + integer(8), intent(in) :: index_source integer(8) :: particle_seed ! unique index for particle integer :: i diff --git a/src/source.F90 b/src/source.F90 index b83bf766e6..53ed2e9a3d 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -7,12 +7,13 @@ module source use geometry_header, only: BASE_UNIVERSE use global use hdf5_interface, only: file_create, file_open, file_close, read_dataset - use math, only: maxwell_spectrum, watt_spectrum use output, only: write_message use particle_header, only: Particle_Base, Particle_CE, Particle_MG use random_lcg, only: prn, set_particle_seed, prn_set_stream - use state_point, only: read_source_bank, write_source_bank + use search, only: binary_search use simple_string, only: to_str + use spectra + use state_point, only: read_source_bank, write_source_bank #ifdef MPI use message_passing @@ -108,7 +109,7 @@ contains real(8) :: a ! Arbitrary parameter 'a' real(8) :: b ! Arbitrary parameter 'b' logical :: found ! Does the source particle exist within geometry? - class(Particle_Base), pointer :: p ! Temporary particle for using find_cell + type(Particle_CE) :: p ! Temporary particle for using find_cell integer, save :: num_resamples = 0 ! Number of resamples encountered ! Set weight to one by default @@ -241,6 +242,17 @@ contains call fatal_error("No energy distribution specified for external source!") end select + ! If running in MG, convert site%E to group + if (.not. run_CE) then + if (site%E <= energy_bins(1)) then + site%g = 1 + else if (site%E > energy_bins(energy_groups + 1)) then + site%g = energy_groups + else + site%g = binary_search(energy_bins, energy_groups + 1, site%E) + end if + end if + ! Set the random number generator back to the tracking stream. call prn_set_stream(STREAM_TRACKING) diff --git a/src/spectra.F90 b/src/spectra.F90 new file mode 100644 index 0000000000..acdde78206 --- /dev/null +++ b/src/spectra.F90 @@ -0,0 +1,58 @@ +module spectra + +use constants, only: ONE, TWO, PI +use random_lcg, only: prn + +implicit none + +contains + +!=============================================================================== +! MAXWELL_SPECTRUM samples an energy from the Maxwell fission distribution based +! on a direct sampling scheme. The probability distribution function for a +! Maxwellian is given as p(x) = 2/(T*sqrt(pi))*sqrt(x/T)*exp(-x/T). This PDF can +! be sampled using rule C64 in the Monte Carlo Sampler LA-9721-MS. +!=============================================================================== + + function maxwell_spectrum(T) result(E_out) + + real(8), intent(in) :: T ! tabulated function of incoming E + real(8) :: E_out ! sampled energy + + real(8) :: r1, r2, r3 ! random numbers + real(8) :: c ! cosine of pi/2*r3 + + r1 = prn() + r2 = prn() + r3 = prn() + + ! determine cosine of pi/2*r + c = cos(PI/TWO*r3) + + ! determine outgoing energy + E_out = -T*(log(r1) + log(r2)*c*c) + + end function maxwell_spectrum + +!=============================================================================== +! WATT_SPECTRUM samples the outgoing energy from a Watt energy-dependent fission +! spectrum. Although fitted parameters exist for many nuclides, generally the +! continuous tabular distributions (LAW 4) should be used in lieu of the Watt +! spectrum. This direct sampling scheme is an unpublished scheme based on the +! original Watt spectrum derivation (See F. Brown's MC lectures). +!=============================================================================== + + function watt_spectrum(a, b) result(E_out) + + real(8), intent(in) :: a ! Watt parameter a + real(8), intent(in) :: b ! Watt parameter b + real(8) :: E_out ! energy of emitted neutron + + real(8) :: w ! sampled from Maxwellian + + w = maxwell_spectrum(a) + E_out = w + a*a*b/4.0_8 + (TWO*prn() - ONE)*sqrt(a*a*b*w) + + end function watt_spectrum + +end module spectra \ No newline at end of file From 76921b005ec810724603a0ef7f0032695aeeea62 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 13:44:29 -0500 Subject: [PATCH 09/84] Got to the point where the physics needs to be differentiated. CE answer still consistent with develop branchs answer --- src/constants.F90 | 8 -- src/global.F90 | 13 +-- src/initialize.F90 | 4 +- src/macroxs.F90 | 243 +++++++++++++++++++++++++++++++++++++++++++++ src/tracking.F90 | 8 ++ 5 files changed, 257 insertions(+), 19 deletions(-) create mode 100644 src/macroxs.F90 diff --git a/src/constants.F90 b/src/constants.F90 index 9bb62f62eb..b7eb1d0bec 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -166,14 +166,6 @@ module constants ! Number of mu bins to use when converting Legendres to tabular type integer, parameter :: DEFAULT_NMU = 33 - ! Location within pre-computed cross section data (particle_xs) - integer, parameter :: & - TOTAL = 1, & - ABSORB = 2, & - NUFISS = 3, & - FISS = 4, & - SCATT = 5 - ! Secondary energy mode for S(a,b) inelastic scattering integer, parameter :: & SAB_SECONDARY_EQUAL = 0, & ! Equally-likely outgoing energy bins diff --git a/src/global.F90 b/src/global.F90 index c5dbec5da9..57b242ab22 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -72,6 +72,10 @@ module global integer :: n_nuclides_total ! Number of nuclide cross section tables integer :: n_listings ! Number of listings in cross_sections.xml + ! Cross section caches + type(NuclideMicroXS), allocatable :: micro_xs(:) ! Cache for each nuclide + type(MaterialMacroXS) :: material_xs ! Cache for current material + ! Dictionaries to look up cross sections and listings type(DictCharInt) :: nuclide_dict type(DictCharInt) :: xs_listing_dict @@ -86,10 +90,6 @@ module global type(Nuclide_CE), allocatable, target :: nuclides(:) ! Nuclide cross-sections type(SAlphaBeta), allocatable, target :: sab_tables(:) ! S(a,b) tables - ! Cross section caches - type(NuclideMicroXS), allocatable :: micro_xs(:) ! Cache for each nuclide - type(MaterialMacroXS) :: material_xs ! Cache for current material - integer :: n_sab_tables ! Number of S(a,b) thermal scattering tables ! Minimum/maximum energies @@ -126,11 +126,6 @@ module global ! Scattering Treatment (if Legendre) integer :: legendre_mu_points - ! MGXS for current working particle (equivalent to material_xs, but simpler) - real(8) :: particle_xs(5) - -!$omp threadprivate(particle_xs) - ! ============================================================================ ! TALLY-RELATED VARIABLES diff --git a/src/initialize.F90 b/src/initialize.F90 index 01a8038070..5793b67226 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -322,8 +322,8 @@ contains c_loc(tmpb(1)%uvw)), coordinates_t, hdf5_err) call h5tinsert_f(hdf5_bank_t, "E", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%E)), H5T_NATIVE_DOUBLE, hdf5_err) - call h5tinsert_f(hdf5_bank_t, "group", h5offsetof(c_loc(tmpb(1)), & - c_loc(tmpb(1)%group)), H5T_NATIVE_INTEGER, hdf5_err) + call h5tinsert_f(hdf5_bank_t, "g", h5offsetof(c_loc(tmpb(1)), & + c_loc(tmpb(1)%g)), H5T_NATIVE_INTEGER, hdf5_err) call h5tinsert_f(hdf5_bank_t, "delayed_group", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%delayed_group)), H5T_NATIVE_INTEGER, hdf5_err) diff --git a/src/macroxs.F90 b/src/macroxs.F90 new file mode 100644 index 0000000000..799d3115b8 --- /dev/null +++ b/src/macroxs.F90 @@ -0,0 +1,243 @@ +module macroxs + + use constants + use macroxs_header, only: MacroXS_Base, MacroXS_Iso, MacroXS_Angle, & + expand_harmonic + use math + use nuclide_header, only: find_angle, MaterialMacroXS + use random_lcg, only: prn + use scattdata_header + use search + + implicit none + +contains + +!=============================================================================== +! UPDATE_XS stores the xs to work with +!=============================================================================== + + subroutine calculate_mgxs(this, gin, uvw, xs) + class(MacroXS_Base), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs + + integer :: iazi, ipol + + select type(this) + type is (MacroXS_Iso) + xs % total = this % total(gin) + xs % elastic = this % scattxs(gin) + xs % absorption = this % absorption(gin) + xs % fission = this % fission(gin) + xs % nu_fission = this % nu_fission(gin) + + type is (MacroXS_Angle) + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + xs % total = this % total(gin, iazi, ipol) + xs % elastic = this % scattxs(gin, iazi, ipol) + xs % absorption = this % absorption(gin, iazi, ipol) + xs % fission = this % fission(gin, iazi, ipol) + xs % nu_fission = this % nu_fission(gin, iazi, ipol) + end select + + end subroutine calculate_mgxs + + +!=============================================================================== +! SAMPLE_FISSION_ENERGY acts as a templating code for macroxs_*_sample_fission_energy +!=============================================================================== + + function sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXS_Base), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + + select type(this) + type is (MacroXS_Iso) + gout = macroxs_iso_sample_fission_energy(this, gin, uvw) + type is (MacroXS_Angle) + gout = macroxs_angle_sample_fission_energy(this, gin, uvw) + end select + + end function sample_fission_energy + +!=============================================================================== +! MACROXS_*_SAMPLE_FISSION_ENERGY samples the outgoing energy and mu from a scatter event. +! Implemented as % scatter. +!=============================================================================== + + function macroxs_iso_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXS_Iso), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout,gin) + end do + + end function macroxs_iso_sample_fission_energy + + function macroxs_angle_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXS_Angle), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: iazi, ipol + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout,gin,iazi,ipol) + end do + + end function macroxs_angle_sample_fission_energy + +!=============================================================================== +! SAMPLE_SCATTER acts as a templating code for macroxs_*_sample_scatter +!=============================================================================== + + subroutine sample_scatter(this, uvw, gin, gout, mu, wgt) + class(MacroXS_Base), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + integer :: iazi, ipol ! Angular indices + + select type(this) + type is (MacroXS_Iso) + call macroxs_sample_scatter(this % scatter, gin, gout, mu, wgt) + type is (MacroXS_Angle) + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + call macroxs_sample_scatter(this % scatter(iazi,ipol) % obj,gin,gout,mu,wgt) + end select + + end subroutine sample_scatter + +!=============================================================================== +! MACROXS_SAMPLE_SCATTER performs the work with ScattData to sample outgoing +! energy and change in angle. +!=============================================================================== + + subroutine macroxs_sample_scatter(scatt, gin, gout, mu, wgt) + Class(ScattData_Base), intent(in) :: scatt ! Scattering Object to Use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: imu + real(8) :: u, f, M + real(8) :: mu0, frac, mu1 + real(8) :: c_k, c_k1, p0, p1 + integer :: k, NP, samples + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + scatt % energy(gout,gin) + end do + + select type (scatt) + type is (ScattData_Histogram) + xi = prn() + if (xi < scatt % data(1,gout,gin)) then + imu = 1 + else + imu = binary_search(scatt % data(:,gout,gin), & + size(scatt % data(:,gout,gin)), xi) + end if + + ! Randomly select a mu in this bin. + mu = prn() * scatt % dmu + scatt % mu(imu) + + type is (ScattData_Tabular) + ! determine outgoing cosine bin + NP = size(scatt % data(:,gout,gin)) + xi = prn() + + c_k = scatt % data(1,gout,gin) + do k = 1, NP - 1 + c_k1 = scatt % data(k+1,gout,gin) + if (xi < c_k1) exit + c_k = c_k1 + end do + + ! check to make sure k is <= NP - 1 + k = min(k, NP - 1) + + p0 = scatt % fmu(k,gout,gin) + mu0 = scatt % mu(k) + ! Linear-linear interpolation to find mu value w/in bin. + p1 = scatt % fmu(k+1,gout,gin) + mu1 = scatt % mu(k+1) + + frac = (p1 - p0)/(mu1 - mu0) + + if (frac == ZERO) then + mu = mu0 + (xi - c_k)/p0 + else + mu = mu0 + (sqrt(max(ZERO, p0*p0 + TWO*frac*(xi - c_k))) - p0)/frac + end if + + if (mu <= -ONE) then + mu = -ONE + else if (mu >= ONE) then + mu = ONE + end if + + type is (ScattData_Legendre) + ! Now we can sample mu using the legendre representation of the scattering + ! kernel in data(1:this % order) + + ! Do with rejection sampling + ! Set upper bound (instead of searching for max - though this is inefficient) + M = 4.0_8 + samples = 0 + do + mu = TWO * prn() - ONE + f = scatt % calc_f(gin,gout,mu) + if (f > ZERO) then + u = prn() * M + if (u <= f) then + exit + end if + end if + samples = samples + 1 + if (samples > MAX_SAMPLE) then + ! Exit with an isotropic event. + exit + end if + end do + end select + + wgt = wgt * scatt % mult(gout,gin) + + end subroutine macroxs_sample_scatter + +end module macroxs \ No newline at end of file diff --git a/src/tracking.F90 b/src/tracking.F90 index fcb746ccc8..2ffa45ee0d 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -7,6 +7,7 @@ module tracking cross_lattice, check_cell_overlap use geometry_header, only: Universe, BASE_UNIVERSE use global + use macroxs, only: calculate_mgxs use output, only: write_message use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use physics, only: collision @@ -53,6 +54,8 @@ contains total_weight = total_weight + p % wgt ! Force calculation of cross-sections by setting last energy to zero + ! This is a penalty incurred by MG solver, but id rather have penalties + ! applied there over the CE Solver (i.e., by putting an if-block here) micro_xs % last_E = ZERO ! Prepare to write out particle track. @@ -86,6 +89,11 @@ contains select type(p) type is (Particle_CE) if (p % material /= p % last_material) call calculate_xs(p) + type is (Particle_MG) + if ((p % material /= p % last_material) .or. (p % g /= p % last_g)) then + call calculate_mgxs(macro_xs(p % material) % obj, p % g, & + p % coord(1) % uvw, material_xs) + end if end select ! Find the distance to the nearest boundary From 608aa3569fb90cb9abc0c72e70e9a4ff2775d299 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 14:23:37 -0500 Subject: [PATCH 10/84] Added code for MG physics; included pulling out physics independent info from physics.f90 and putting in physics_common.F90 --- src/particle_header.F90 | 40 +++++++ src/physics.F90 | 253 ++++++++++++++------------------------- src/physics_common.F90 | 82 +++++++++++++ src/physics_mg.F90 | 254 ++++++++++++++++++++++++++++++++++++++++ src/tracking.F90 | 3 + 5 files changed, 470 insertions(+), 162 deletions(-) create mode 100644 src/physics_common.F90 create mode 100644 src/physics_mg.F90 diff --git a/src/particle_header.F90 b/src/particle_header.F90 index f661e73c14..85d83cd3d3 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -92,8 +92,16 @@ module particle_header procedure, pass :: clear => clear_particle procedure, pass :: initialize_from_source => initialize_from_source_base procedure, pass :: create_secondary => create_secondary_base + procedure(collision_), deferred, pass :: pre_collision end type Particle_Base + abstract interface + subroutine collision_(this) + import Particle_Base + class(Particle_Base), intent(inout) :: this + end subroutine collision_ + end interface + type, extends(Particle_Base) :: Particle_CE ! Energy Data real(8) :: E ! post-collision energy @@ -102,6 +110,7 @@ module particle_header contains procedure :: initialize_from_source => initialize_from_source_ce procedure :: create_secondary => create_secondary_ce + procedure :: pre_collision => pre_collision_ce end type Particle_CE type, extends(Particle_Base) :: Particle_MG @@ -112,6 +121,7 @@ module particle_header contains procedure :: initialize_from_source => initialize_from_source_mg procedure :: create_secondary => create_secondary_mg + procedure :: pre_collision => pre_collision_mg end type Particle_MG contains @@ -283,4 +293,34 @@ contains end subroutine create_secondary_mg +!=============================================================================== +! PRE_COLLISION_* Updates pre-collision particle properties +!=============================================================================== + + subroutine pre_collision_ce(this) + class(Particle_CE), intent(inout) :: this + + ! Store pre-collision particle properties + this % last_wgt = this % wgt + this % last_E = this % E + this % last_uvw = this % coord(1) % uvw + + ! Add to collision counter for particle + this % n_collision = this % n_collision + 1 + + end subroutine pre_collision_ce + + subroutine pre_collision_mg(this) + class(Particle_MG), intent(inout) :: this + + ! Store pre-collision particle properties + this % last_wgt = this % wgt + this % last_g = this % g + this % last_uvw = this % coord(1) % uvw + + ! Add to collision counter for particle + this % n_collision = this % n_collision + 1 + + end subroutine pre_collision_mg + end module particle_header diff --git a/src/physics.F90 b/src/physics.F90 index 9bbed576dc..0b0509e1c5 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -12,8 +12,9 @@ module physics use mesh, only: get_mesh_indices use nuclide_header use output, only: write_message - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle_CE use particle_restart_write, only: write_particle_restart + use physics_common use random_lcg, only: prn use search, only: binary_search use simple_string, only: to_str @@ -124,8 +125,8 @@ contains function sample_nuclide(p, base) result(i_nuclide) - class(Particle_Base), intent(in) :: p - character(7), intent(in) :: base ! which reaction to sample based on + type(Particle_CE), intent(in) :: p + character(7), intent(in) :: base ! which reaction to sample based on integer :: i_nuclide integer :: i @@ -241,8 +242,8 @@ contains subroutine absorption(p, i_nuclide) - class(Particle_Base), intent(inout) :: p - integer, intent(in) :: i_nuclide + type(Particle_CE), intent(inout) :: p + integer, intent(in) :: i_nuclide if (survival_biasing) then ! Determine weight absorbed in survival biasing @@ -276,27 +277,6 @@ contains end subroutine absorption -!=============================================================================== -! RUSSIAN_ROULETTE -!=============================================================================== - - subroutine russian_roulette(p) - - class(Particle_Base), intent(inout) :: p - - if (p % wgt < weight_cutoff) then - if (prn() < p % wgt / weight_survive) then - p % wgt = weight_survive - p % last_wgt = p % wgt - else - p % wgt = ZERO - p % last_wgt = ZERO - p % alive = .false. - end if - end if - - end subroutine russian_roulette - !=============================================================================== ! SCATTER !=============================================================================== @@ -1060,9 +1040,9 @@ contains subroutine create_fission_sites(p, i_nuclide, i_reaction) - class(Particle_Base), intent(inout) :: p - integer, intent(in) :: i_nuclide - integer, intent(in) :: i_reaction + type(Particle_CE), intent(inout) :: p + integer, intent(in) :: i_nuclide + integer, intent(in) :: i_reaction integer :: nu_d(MAX_DELAYED_GROUPS) ! number of delayed neutrons born integer :: i ! loop index @@ -1176,10 +1156,10 @@ contains function sample_fission_energy(nuc, rxn, p) result(E_out) - type(Nuclide_CE), pointer :: nuc - type(Reaction), pointer :: rxn - class(Particle_Base), intent(inout) :: p ! Particle causing fission - real(8) :: E_out ! outgoing E of fission neutron + type(Nuclide_CE), pointer :: nuc + type(Reaction), pointer :: rxn + type(Particle_CE), intent(inout) :: p ! Particle causing fission + real(8) :: E_out ! outgoing E of fission neutron integer :: j ! index on nu energy grid / precursor group integer :: lc ! index before start of energies/nu values @@ -1196,106 +1176,103 @@ contains real(8) :: prob ! cumulative probability type(DistEnergy), pointer :: edist - select type(p) - type is (Particle_CE) - ! Determine total nu - nu_t = nu_total(nuc, p % E) + ! Determine total nu + nu_t = nu_total(nuc, p % E) - ! Determine delayed nu - nu_d = nu_delayed(nuc, p % E) + ! Determine delayed nu + nu_d = nu_delayed(nuc, p % E) - ! Determine delayed neutron fraction - beta = nu_d / nu_t + ! Determine delayed neutron fraction + beta = nu_d / nu_t - if (prn() < beta) then - ! ==================================================================== - ! DELAYED NEUTRON SAMPLED + if (prn() < beta) then + ! ==================================================================== + ! DELAYED NEUTRON SAMPLED - ! sampled delayed precursor group - xi = prn() - lc = 1 - prob = ZERO - do j = 1, nuc % n_precursor - ! determine number of interpolation regions and energies - NR = int(nuc % nu_d_precursor_data(lc + 1)) - NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR)) + ! sampled delayed precursor group + xi = prn() + lc = 1 + prob = ZERO + do j = 1, nuc % n_precursor + ! determine number of interpolation regions and energies + NR = int(nuc % nu_d_precursor_data(lc + 1)) + NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR)) - ! determine delayed neutron precursor yield for group j - yield = interpolate_tab1(nuc % nu_d_precursor_data( & - lc+1:lc+2+2*NR+2*NE), p % E) + ! determine delayed neutron precursor yield for group j + yield = interpolate_tab1(nuc % nu_d_precursor_data( & + lc+1:lc+2+2*NR+2*NE), p % E) - ! Check if this group is sampled - prob = prob + yield - if (xi < prob) exit + ! Check if this group is sampled + prob = prob + yield + if (xi < prob) exit - ! advance pointer - lc = lc + 2 + 2*NR + 2*NE + 1 - end do + ! advance pointer + lc = lc + 2 + 2*NR + 2*NE + 1 + end do - ! if the sum of the probabilities is slightly less than one and the - ! random number is greater, j will be greater than nuc % - ! n_precursor -- check for this condition - j = min(j, nuc % n_precursor) + ! if the sum of the probabilities is slightly less than one and the + ! random number is greater, j will be greater than nuc % + ! n_precursor -- check for this condition + j = min(j, nuc % n_precursor) - ! set the delayed group for the particle born from fission - p % delayed_group = j + ! set the delayed group for the particle born from fission + p % delayed_group = j - ! select energy distribution for group j - law = nuc % nu_d_edist(j) % law - edist => nuc % nu_d_edist(j) + ! select energy distribution for group j + law = nuc % nu_d_edist(j) % law + edist => nuc % nu_d_edist(j) - ! sample from energy distribution - n_sample = 0 - do - if (law == 44 .or. law == 61) then - call sample_energy(edist, p % E, E_out, mu) - else - call sample_energy(edist, p % E, E_out) - end if + ! sample from energy distribution + n_sample = 0 + do + if (law == 44 .or. law == 61) then + call sample_energy(edist, p % E, E_out, mu) + else + call sample_energy(edist, p % E, E_out) + end if - ! resample if energy is greater than maximum neutron energy - if (E_out < energy_max_neutron) exit + ! resample if energy is greater than maximum neutron energy + if (E_out < energy_max_neutron) exit - ! check for large number of resamples - n_sample = n_sample + 1 - if (n_sample == MAX_SAMPLE) then - ! call write_particle_restart(p) - call fatal_error("Resampled energy distribution maximum number of " & - &// "times for nuclide " // nuc % name) - end if - end do + ! check for large number of resamples + n_sample = n_sample + 1 + if (n_sample == MAX_SAMPLE) then + ! call write_particle_restart(p) + call fatal_error("Resampled energy distribution maximum number of " & + &// "times for nuclide " // nuc % name) + end if + end do - else - ! ==================================================================== - ! PROMPT NEUTRON SAMPLED + else + ! ==================================================================== + ! PROMPT NEUTRON SAMPLED - ! set the delayed group for the particle born from fission to 0 - p % delayed_group = 0 + ! set the delayed group for the particle born from fission to 0 + p % delayed_group = 0 - ! sample from prompt neutron energy distribution - law = rxn % edist % law - n_sample = 0 - do - if (law == 44 .or. law == 61) then - call sample_energy(rxn%edist, p % E, E_out, prob) - else - call sample_energy(rxn%edist, p % E, E_out) - end if + ! sample from prompt neutron energy distribution + law = rxn % edist % law + n_sample = 0 + do + if (law == 44 .or. law == 61) then + call sample_energy(rxn%edist, p % E, E_out, prob) + else + call sample_energy(rxn%edist, p % E, E_out) + end if - ! resample if energy is greater than maximum neutron energy - if (E_out < energy_max_neutron) exit + ! resample if energy is greater than maximum neutron energy + if (E_out < energy_max_neutron) exit - ! check for large number of resamples - n_sample = n_sample + 1 - if (n_sample == MAX_SAMPLE) then - ! call write_particle_restart(p) - call fatal_error("Resampled energy distribution maximum number of " & - &// "times for nuclide " // nuc % name) - end if - end do + ! check for large number of resamples + n_sample = n_sample + 1 + if (n_sample == MAX_SAMPLE) then + ! call write_particle_restart(p) + call fatal_error("Resampled energy distribution maximum number of " & + &// "times for nuclide " // nuc % name) + end if + end do - end if - end select + end if end function sample_fission_energy @@ -1511,55 +1488,7 @@ contains end function sample_angle -!=============================================================================== -! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is -! mu and through an azimuthal angle sampled uniformly. Note that this is done -! with direct sampling rather than rejection as is done in MCNP and SERPENT. -!=============================================================================== - function rotate_angle(uvw0, mu) result(uvw) - - real(8), intent(in) :: uvw0(3) ! directional cosine - real(8), intent(in) :: mu ! cosine of angle in lab or CM - real(8) :: uvw(3) ! rotated directional cosine - - real(8) :: phi ! azimuthal angle - real(8) :: sinphi ! sine of azimuthal angle - real(8) :: cosphi ! cosine of azimuthal angle - real(8) :: a ! sqrt(1 - mu^2) - real(8) :: b ! sqrt(1 - w^2) - real(8) :: u0 ! original cosine in x direction - real(8) :: v0 ! original cosine in y direction - real(8) :: w0 ! original cosine in z direction - - ! Copy original directional cosines - u0 = uvw0(1) - v0 = uvw0(2) - w0 = uvw0(3) - - ! Sample azimuthal angle in [0,2pi) - phi = TWO * PI * prn() - - ! Precompute factors to save flops - sinphi = sin(phi) - cosphi = cos(phi) - a = sqrt(max(ZERO, ONE - mu*mu)) - b = sqrt(max(ZERO, ONE - w0*w0)) - - ! Need to treat special case where sqrt(1 - w**2) is close to zero by - ! expanding about the v component rather than the w component - if (b > 1e-10) then - uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b - uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b - uvw(3) = mu*w0 - a*b*cosphi - else - b = sqrt(ONE - v0*v0) - uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b - uvw(2) = mu*v0 - a*b*cosphi - uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b - end if - - end function rotate_angle !=============================================================================== ! SAMPLE_ENERGY samples an outgoing energy distribution, either for a secondary diff --git a/src/physics_common.F90 b/src/physics_common.F90 new file mode 100644 index 0000000000..fbd85cc625 --- /dev/null +++ b/src/physics_common.F90 @@ -0,0 +1,82 @@ +module physics_common + + use constants + use global, only: weight_cutoff, weight_survive + use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use random_lcg, only: prn + + implicit none + +contains + +!=============================================================================== +! RUSSIAN_ROULETTE +!=============================================================================== + + subroutine russian_roulette(p) + + class(Particle_Base), intent(inout) :: p + + if (p % wgt < weight_cutoff) then + if (prn() < p % wgt / weight_survive) then + p % wgt = weight_survive + p % last_wgt = p % wgt + else + p % wgt = ZERO + p % last_wgt = ZERO + p % alive = .false. + end if + end if + + end subroutine russian_roulette + +!=============================================================================== +! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is +! mu and through an azimuthal angle sampled uniformly. Note that this is done +! with direct sampling rather than rejection as is done in MCNP and SERPENT. +!=============================================================================== + + function rotate_angle(uvw0, mu) result(uvw) + + real(8), intent(in) :: uvw0(3) ! directional cosine + real(8), intent(in) :: mu ! cosine of angle in lab or CM + real(8) :: uvw(3) ! rotated directional cosine + + real(8) :: phi ! azimuthal angle + real(8) :: sinphi ! sine of azimuthal angle + real(8) :: cosphi ! cosine of azimuthal angle + real(8) :: a ! sqrt(1 - mu^2) + real(8) :: b ! sqrt(1 - w^2) + real(8) :: u0 ! original cosine in x direction + real(8) :: v0 ! original cosine in y direction + real(8) :: w0 ! original cosine in z direction + + ! Copy original directional cosines + u0 = uvw0(1) + v0 = uvw0(2) + w0 = uvw0(3) + + ! Sample azimuthal angle in [0,2pi) + phi = TWO * PI * prn() + + ! Precompute factors to save flops + sinphi = sin(phi) + cosphi = cos(phi) + a = sqrt(max(ZERO, ONE - mu*mu)) + b = sqrt(max(ZERO, ONE - w0*w0)) + + ! Need to treat special case where sqrt(1 - w**2) is close to zero by + ! expanding about the v component rather than the w component + if (b > 1e-10) then + uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b + uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b + uvw(3) = mu*w0 - a*b*cosphi + else + b = sqrt(ONE - v0*v0) + uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b + uvw(2) = mu*v0 - a*b*cosphi + uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b + end if + + end function rotate_angle +end module physics_common \ No newline at end of file diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 new file mode 100644 index 0000000000..c53661086a --- /dev/null +++ b/src/physics_mg.F90 @@ -0,0 +1,254 @@ +module physics_mg + ! This module contains the multi-group specific physics routines so as to not + ! hinder performance of the CE versions with multiple if-thens. + + use constants + use error, only: fatal_error, warning + use global + use interpolation, only: interpolate_tab1 + use macroxs_header, only: MacroXS_Base, MacroXSContainer + use macroxs, only: sample_fission_energy, sample_scatter + use material_header, only: Material + use mesh, only: get_mesh_indices + ! use nuclide_header, only: Nuclide_MG, NuclideMGContainer + use output, only: write_message + use particle_header, only: Particle_Base, Particle_MG + use particle_restart_write, only: write_particle_restart + use physics_common + use random_lcg, only: prn + use scattdata_header + use search, only: binary_search + use simple_string, only: to_str + + implicit none + +contains + +!=============================================================================== +! COLLISION_MG samples a nuclide and reaction and then calls the appropriate +! routine for that reaction +!=============================================================================== + + subroutine collision_mg(p) + + type(Particle_MG), intent(inout) :: p + + ! Store pre-collision particle properties + p % last_wgt = p % wgt + p % last_g = p % g + p % last_uvw = p % coord(1) % uvw + + ! Add to collision counter for particle + p % n_collision = p % n_collision + 1 + + ! Sample nuclide/reaction for the material the particle is in + call sample_reaction(p) + + ! Display information about collision + if (verbosity >= 10 .or. trace) then + call write_message(" " // "Energy Group = " // trim(to_str(p % g))) + end if + + end subroutine collision_mg + +!=============================================================================== +! SAMPLE_REACTION samples a nuclide based on the macroscopic cross sections for +! each nuclide within a material and then samples a reaction for that nuclide +! and calls the appropriate routine to process the physics. Note that there is +! special logic when suvival biasing is turned on since fission and +! disappearance are treated implicitly. +!=============================================================================== + + subroutine sample_reaction(p) + + type(Particle_MG), intent(inout) :: p + + type(Material), pointer :: mat + + mat => materials(p % material) + + ! Create fission bank sites. Note that while a fission reaction is sampled, + ! it never actually "happens", i.e. the weight of the particle does not + ! change when sampling fission sites. The following block handles all + ! absorption (including fission) + + if (mat % fissionable .and. run_mode == MODE_EIGENVALUE) then + call create_fission_sites(p) + end if + + ! If survival biasing is being used, the following subroutine adjusts the + ! weight of the particle. Otherwise, it checks to see if absorption occurs + + if (material_xs % absorption > ZERO) then + call absorption(p) + else + p % absorb_wgt = ZERO + end if + if (.not. p % alive) return + + ! Sample a scattering reaction and determine the secondary energy of the + ! exiting neutron + call scatter(p) + + ! Play russian roulette if survival biasing is turned on + + if (survival_biasing) then + call russian_roulette(p) + if (.not. p % alive) return + end if + + end subroutine sample_reaction + +!=============================================================================== +! ABSORPTION +!=============================================================================== + + subroutine absorption(p) + + type(Particle_MG), intent(inout) :: p + + if (survival_biasing) then + ! Determine weight absorbed in survival biasing + p % absorb_wgt = (p % wgt * & + material_xs % absorption / material_xs % total) + + ! Adjust weight of particle by probability of absorption + p % wgt = p % wgt - p % absorb_wgt + p % last_wgt = p % wgt + + ! Score implicit absorption estimate of keff +!$omp atomic + global_tallies(K_ABSORPTION) % value = & + global_tallies(K_ABSORPTION) % value + p % absorb_wgt * & + material_xs % nu_fission / material_xs % absorption + else + ! See if disappearance reaction happens + if (material_xs % absorption > prn() * material_xs % total) then + ! Score absorption estimate of keff +!$omp atomic + global_tallies(K_ABSORPTION) % value = & + global_tallies(K_ABSORPTION) % value + p % wgt * & + material_xs % nu_fission / material_xs % absorption + + p % alive = .false. + p % event = EVENT_ABSORB + end if + end if + + end subroutine absorption + +!=============================================================================== +! SCATTER +!=============================================================================== + + subroutine scatter(p) + + type(Particle_MG), intent(inout) :: p + + call sample_scatter(macro_xs(p % material) % obj, p % coord(1) % uvw, & + p % last_g, p % g, p % mu, p % wgt) + + p % coord(1) % uvw = rotate_angle(p % coord(1) % uvw, p % mu) + + ! Set event component + p % event = EVENT_SCATTER + + end subroutine scatter + +!=============================================================================== +! CREATE_FISSION_SITES determines the average total, prompt, and delayed +! neutrons produced from fission and creates appropriate bank sites. +!=============================================================================== + + subroutine create_fission_sites(p) + + type(Particle_MG), intent(inout) :: p + + integer :: i ! loop index + integer :: nu ! actual number of neutrons produced + integer :: ijk(3) ! indices in ufs mesh + real(8) :: nu_t ! total nu + real(8) :: mu ! fission neutron angular cosine + real(8) :: phi ! fission neutron azimuthal angle + real(8) :: weight ! weight adjustment for ufs method + logical :: in_mesh ! source site in ufs mesh? + class(MacroXS_Base), pointer :: xs + + ! Get Pointers + xs => macro_xs(p % material) % obj + ! TODO: Heat generation from fission + + ! If uniform fission source weighting is turned on, we increase of decrease + ! the expected number of fission sites produced + + if (ufs) then + ! Determine indices on ufs mesh for current location + call get_mesh_indices(ufs_mesh, p % coord(1) % xyz, ijk, in_mesh) + if (.not. in_mesh) then + call write_particle_restart(p) + call fatal_error("Source site outside UFS mesh!") + end if + + if (source_frac(1,ijk(1),ijk(2),ijk(3)) /= ZERO) then + weight = ufs_mesh % volume_frac / source_frac(1,ijk(1),ijk(2),ijk(3)) + else + weight = ONE + end if + else + weight = ONE + end if + + ! Determine expected number of neutrons produced + nu_t = p % wgt / keff * weight * & + material_xs % nu_fission / material_xs % total + ! Sample number of neutrons produced + if (prn() > nu_t - int(nu_t)) then + nu = int(nu_t) + else + nu = int(nu_t) + 1 + end if + + ! Check for fission bank size getting hit + if (n_bank + nu > size(fission_bank)) then + if (master) call warning("Maximum number of sites in fission bank & + &reached. This can result in irreproducible results using different & + &numbers of processes/threads.") + end if + + ! Bank source neutrons + if (nu == 0 .or. n_bank == size(fission_bank)) return + p % fission = .true. ! Fission neutrons will be banked + do i = int(n_bank,4) + 1, int(min(n_bank + nu, int(size(fission_bank),8)),4) + ! Bank source neutrons by copying particle data + fission_bank(i) % xyz = p % coord(1) % xyz + + ! Set weight of fission bank site + fission_bank(i) % wgt = ONE/weight + + ! Sample cosine of angle -- fission neutrons are always emitted + ! isotropically. Sometimes in ACE data, fission reactions actually have + ! an angular distribution listed, but for those that do, it's simply just + ! a uniform distribution in mu + mu = TWO * prn() - ONE + + ! Sample azimuthal angle uniformly in [0,2*pi) + phi = TWO*PI*prn() + fission_bank(i) % uvw(1) = mu + fission_bank(i) % uvw(2) = sqrt(ONE - mu*mu) * cos(phi) + fission_bank(i) % uvw(3) = sqrt(ONE - mu*mu) * sin(phi) + + ! Sample secondary energy distribution for fission reaction and set energy + ! in fission bank + fission_bank(i) % g = sample_fission_energy(xs, p % g, fission_bank(i) % uvw) + end do + + ! increment number of bank sites + n_bank = min(n_bank + nu, int(size(fission_bank),8)) + + ! Store total weight banked for analog fission tallies + p % n_bank = nu + p % wgt_bank = nu/weight + + end subroutine create_fission_sites + +end module physics_mg diff --git a/src/tracking.F90 b/src/tracking.F90 index 2ffa45ee0d..3ca75e3381 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -11,6 +11,7 @@ module tracking use output, only: write_message use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG use physics, only: collision + use physics_mg, only: collision_mg use random_lcg, only: prn use simple_string, only: to_str use tally, only: score_analog_tally, score_tracklength_tally, & @@ -170,6 +171,8 @@ contains select type(p) type is (Particle_CE) call collision(p) + type is (Particle_MG) + call collision_mg(p) end select ! Score collision estimator tallies -- this is done after a collision From 9d2c3e283665dfde8f2fe5bb787697be8264f3a8 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 14:44:17 -0500 Subject: [PATCH 11/84] Able to calculate MG version, not getting right answer yet. --- src/ace.F90 | 2 +- src/input_xml.F90 | 2 +- src/mgxs_data.F90 | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ace.F90 b/src/ace.F90 index e51c2b3a0e..917876556c 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -28,7 +28,7 @@ module ace contains !=============================================================================== -! READ_XS reads all the cross sections for the problem and stores them in +! READ_CE_XS reads all the cross sections for the problem and stores them in ! nuclides and sab_tables arrays !=============================================================================== diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 29fdc11783..1ed4cc01ee 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4311,7 +4311,7 @@ contains end if legendre_mu_points = -1 * legendre_mu_points else - ! One will say 'dont do it' + ! One means 'don't expand scattering moments to a table, sample via legendre' legendre_mu_points = 1 end if diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 64c5dcce7d..3c80116c82 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -62,6 +62,8 @@ contains ! allocate arrays for ACE table storage and cross section cache allocate(nuclides_MG(n_nuclides_total)) + allocate(micro_xs(1)) + ! Find out if we need kappa fission (are there any k_fiss tallies?) get_kfiss = .false. do i = 1, n_tallies From d1b48a9a1f27817473309f6717a9d6c9a58b3ad5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 15:17:38 -0500 Subject: [PATCH 12/84] Oh, easy fix to get the right answer with MG code. Yay! Have one remaining problem before moving to the next stage. That is that I am having OpenMP issues with both the CE and MG versions. By the way, the next step is to implement the MG for tallies, and to move on to making sure all output is good to go. --- src/global.F90 | 16 ++++++++++++++++ src/input_xml.F90 | 12 ++++++++++++ src/mgxs_data.F90 | 2 -- src/physics_mg.F90 | 3 --- src/tracking.F90 | 6 +++--- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/global.F90 b/src/global.F90 index 57b242ab22..37e442adc6 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -477,6 +477,22 @@ contains deallocate(nuclides_0K) end if + if (allocated(nuclides_MG)) then + ! First call the clear routines + do i = 1, size(nuclides_MG) + call nuclides_MG(i) % obj % clear() + end do + deallocate(nuclides_MG) + end if + + if (allocated(macro_xs)) then + ! First call the clear routines + do i = 1, size(macro_xs) + call macro_xs(i) % obj % clear() + end do + deallocate(macro_xs) + end if + if (allocated(sab_tables)) deallocate(sab_tables) if (allocated(xs_listings)) deallocate(xs_listings) if (allocated(micro_xs)) deallocate(micro_xs) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 1ed4cc01ee..64639b8941 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -152,6 +152,18 @@ contains end if end if + if (.not. run_CE) then + ! Scattering Treatments + if (check_for_node(doc, "max_order")) then + call get_node_value(doc, "max_order", max_order) + else + ! Set to default of largest int, which means to use whatever is contained in library + max_order = huge(0) + end if + else + max_order = 0 + end if + ! Set output directory if a path has been specified on the ! element if (check_for_node(doc, "output_path")) then diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 3c80116c82..64c5dcce7d 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -62,8 +62,6 @@ contains ! allocate arrays for ACE table storage and cross section cache allocate(nuclides_MG(n_nuclides_total)) - allocate(micro_xs(1)) - ! Find out if we need kappa fission (are there any k_fiss tallies?) get_kfiss = .false. do i = 1, n_tallies diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index c53661086a..2aa7e2ee28 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -5,19 +5,16 @@ module physics_mg use constants use error, only: fatal_error, warning use global - use interpolation, only: interpolate_tab1 use macroxs_header, only: MacroXS_Base, MacroXSContainer use macroxs, only: sample_fission_energy, sample_scatter use material_header, only: Material use mesh, only: get_mesh_indices - ! use nuclide_header, only: Nuclide_MG, NuclideMGContainer use output, only: write_message use particle_header, only: Particle_Base, Particle_MG use particle_restart_write, only: write_particle_restart use physics_common use random_lcg, only: prn use scattdata_header - use search, only: binary_search use simple_string, only: to_str implicit none diff --git a/src/tracking.F90 b/src/tracking.F90 index 3ca75e3381..5ba7eb0ac6 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -55,9 +55,9 @@ contains total_weight = total_weight + p % wgt ! Force calculation of cross-sections by setting last energy to zero - ! This is a penalty incurred by MG solver, but id rather have penalties - ! applied there over the CE Solver (i.e., by putting an if-block here) - micro_xs % last_E = ZERO + if (run_CE) then + micro_xs % last_E = ZERO + end if ! Prepare to write out particle track. if (p % write_track) then From a989df44c0925ab73efba56ecc5abcae8ee86931 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 1 Nov 2015 20:08:38 -0500 Subject: [PATCH 13/84] A few fixes related to MG and use of p % coord. Still have no idea whats up with the OpenMP issues --- src/physics_mg.F90 | 8 +++++--- src/simulation.F90 | 2 +- src/tracking.F90 | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 2aa7e2ee28..ca7aebdb36 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -142,10 +142,12 @@ contains type(Particle_MG), intent(inout) :: p - call sample_scatter(macro_xs(p % material) % obj, p % coord(1) % uvw, & - p % last_g, p % g, p % mu, p % wgt) + call sample_scatter(macro_xs(p % material) % obj, & + p % coord(p % n_coord) % uvw, p % last_g, p % g, & + p % mu, p % wgt) - p % coord(1) % uvw = rotate_angle(p % coord(1) % uvw, p % mu) + p % coord(p % n_coord) % uvw = rotate_angle(p % coord(p % n_coord) % uvw, & + p % mu) ! Set event component p % event = EVENT_SCATTER diff --git a/src/simulation.F90 b/src/simulation.F90 index 088a764f79..41330858ff 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -40,7 +40,7 @@ contains subroutine run_simulation() class(Particle_Base), pointer :: p - integer(8) :: i_work + integer(8) :: i_work if (run_CE) then allocate(Particle_CE :: p) diff --git a/src/tracking.F90 b/src/tracking.F90 index 5ba7eb0ac6..17fc9ab3fa 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -93,7 +93,7 @@ contains type is (Particle_MG) if ((p % material /= p % last_material) .or. (p % g /= p % last_g)) then call calculate_mgxs(macro_xs(p % material) % obj, p % g, & - p % coord(1) % uvw, material_xs) + p % coord(p % n_coord) % uvw, material_xs) end if end select From abd227ba323aa2dc4ed549df66824fe321d5718c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 2 Nov 2015 05:28:36 -0500 Subject: [PATCH 14/84] Added in generation of nuclidic xs to make tallying easier. It may end up being the case I need to have a separate tally routine, or at least score_general, for MG and CE. If that is the case, this new nuclidic xs info may not be needed. --- src/macroxs.F90 | 58 ++++++++++++++++++++++++++++++++---------- src/nuclide_header.F90 | 44 +++++++++++++++++++++----------- src/tracking.F90 | 16 +++++++----- 3 files changed, 82 insertions(+), 36 deletions(-) diff --git a/src/macroxs.F90 b/src/macroxs.F90 index 799d3115b8..bfbf83e5c9 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -3,8 +3,10 @@ module macroxs use constants use macroxs_header, only: MacroXS_Base, MacroXS_Iso, MacroXS_Angle, & expand_harmonic + use material_header, only: Material use math - use nuclide_header, only: find_angle, MaterialMacroXS + use nuclide_header, only: find_angle, MaterialMacroXS, NuclideMicroXS, & + Nuclide_MG, NuclideMGContainer use random_lcg, only: prn use scattdata_header use search @@ -17,31 +19,59 @@ contains ! UPDATE_XS stores the xs to work with !=============================================================================== - subroutine calculate_mgxs(this, gin, uvw, xs) + subroutine calculate_mgxs(this, mat, nuclides, gin, uvw, xs, micro_xs) class(MacroXS_Base), intent(in) :: this - integer, intent(in) :: gin ! Incoming neutron group - real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(Material), intent(in) :: mat ! Material of interest + type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs + type(NuclideMicroXS), intent(inout) :: micro_xs(:) integer :: iazi, ipol + integer :: i, i_nuclide + class(Nuclide_MG), pointer :: nuc select type(this) type is (MacroXS_Iso) - xs % total = this % total(gin) - xs % elastic = this % scattxs(gin) - xs % absorption = this % absorption(gin) - xs % fission = this % fission(gin) - xs % nu_fission = this % nu_fission(gin) + xs % total = this % total(gin) + xs % elastic = this % scattxs(gin) + xs % absorption = this % absorption(gin) + xs % fission = this % fission(gin) + xs % nu_fission = this % nu_fission(gin) + xs % kappa_fission = this % k_fission(gin) type is (MacroXS_Angle) call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - xs % total = this % total(gin, iazi, ipol) - xs % elastic = this % scattxs(gin, iazi, ipol) - xs % absorption = this % absorption(gin, iazi, ipol) - xs % fission = this % fission(gin, iazi, ipol) - xs % nu_fission = this % nu_fission(gin, iazi, ipol) + xs % total = this % total(gin, iazi, ipol) + xs % elastic = this % scattxs(gin, iazi, ipol) + xs % absorption = this % absorption(gin, iazi, ipol) + xs % fission = this % fission(gin, iazi, ipol) + xs % nu_fission = this % nu_fission(gin, iazi, ipol) + xs % kappa_fission = this % k_fission(gin, iazi, ipol) end select + ! Place nuclidic xs in micro_xs for tallying purposes + do i = 1, mat % n_nuclides + ! Determine microscopic cross section for this nuclide + i_nuclide = mat % nuclide(i) + + nuc => nuclides(i_nuclide) % obj + micro_xs(i_nuclide) % total = nuc % get_xs(gin, 'total', & + I_AZI=iazi, I_POL=ipol) + micro_xs(i_nuclide) % elastic = nuc % get_xs(gin, 'scatter', & + I_AZI=iazi, I_POL=ipol) + micro_xs(i_nuclide) % absorption = nuc % get_xs(gin, 'absorption', & + I_AZI=iazi, I_POL=ipol) + micro_xs(i_nuclide) % fission = nuc % get_xs(gin, 'fission', & + I_AZI=iazi, I_POL=ipol) + micro_xs(i_nuclide) % nu_fission = nuc % get_xs(gin, 'nu_fission', & + I_AZI=iazi, I_POL=ipol) + micro_xs(i_nuclide) % kappa_fission = nuc % get_xs(gin, 'k_fission', & + I_AZI=iazi, I_POL=ipol) + + end do + end subroutine calculate_mgxs diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 2910f63b19..6f502c11ea 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -117,13 +117,16 @@ module nuclide_header end type Nuclide_MG abstract interface - function nuclide_mg_get_xs_(this, g, xstype, gout, uvw) result(xs) + function nuclide_mg_get_xs_(this, g, xstype, gout, uvw, i_azi, i_pol) & + result(xs) import Nuclide_MG class(Nuclide_MG), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle + integer, optional, intent(in) :: i_azi ! Azimuthal Index + integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs end function nuclide_mg_get_xs_ end interface @@ -532,12 +535,15 @@ module nuclide_header ! NUCLIDE_*_GET_XS Returns the requested data type !=============================================================================== - function nuclide_iso_get_xs(this, g, xstype, gout, uvw) result(xs) + function nuclide_iso_get_xs(this, g, xstype, gout, uvw, i_azi, i_pol) & + result(xs) class(Nuclide_Iso), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group - character(*), intent(in) :: xstype ! Cross Section Type + character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle + integer, optional, intent(in) :: i_azi ! Azimuthal Index + integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs if (present(gout)) then @@ -565,41 +571,49 @@ module nuclide_header end if end function nuclide_iso_get_xs - function nuclide_angle_get_xs(this, g, xstype, gout, uvw) result(xs) + function nuclide_angle_get_xs(this, g, xstype, gout, uvw, i_azi, i_pol) & + result(xs) class(Nuclide_Angle), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle + integer, optional, intent(in) :: i_azi ! Azimuthal Index + integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs - integer :: i_pol, i_azi + integer :: i_azi_, i_pol_ - call find_angle(this % polar, this % azimuthal, uvw, i_azi, i_pol) + if (present(i_azi) .and. present(i_pol)) then + i_azi_ = i_azi + i_pol_ = i_pol + else + call find_angle(this % polar, this % azimuthal, uvw, i_azi_, i_pol_) + end if if (present(gout)) then select case(xstype) case('mult') - xs = this % mult(gout,g,i_azi,i_pol) + xs = this % mult(gout,g,i_azi_,i_pol_) case('nu_fission') - xs = this % nu_fission(gout,g,i_azi,i_pol) + xs = this % nu_fission(gout,g,i_azi_,i_pol_) case('chi') - xs = this % chi(gout,i_azi,i_pol) + xs = this % chi(gout,i_azi_,i_pol_) end select else select case(xstype) case('total') - xs = this % total(g,i_azi,i_pol) + xs = this % total(g,i_azi_,i_pol_) case('absorption') - xs = this % absorption(g,i_azi,i_pol) + xs = this % absorption(g,i_azi_,i_pol_) case('fission') - xs = this % fission(g,i_azi,i_pol) + xs = this % fission(g,i_azi_,i_pol_) case('k_fission') - xs = this % k_fission(g,i_azi,i_pol) + xs = this % k_fission(g,i_azi_,i_pol_) case('chi') - xs = this % chi(g,i_azi,i_pol) + xs = this % chi(g,i_azi_,i_pol_) case('scatter') - xs = this % total(g,i_azi,i_pol) - this % absorption(g,i_azi,i_pol) + xs = this % total(g,i_azi_,i_pol_) - this % absorption(g,i_azi_,i_pol_) end select end if diff --git a/src/tracking.F90 b/src/tracking.F90 index 17fc9ab3fa..1960089c79 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -83,18 +83,20 @@ contains if (check_overlaps) call check_cell_overlap(p) - ! Calculate microscopic and macroscopic cross sections -- note: if the - ! material is the same as the last material and the energy of the - ! particle hasn't changed, we don't need to lookup cross sections again. + ! Calculate microscopic and macroscopic cross sections select type(p) type is (Particle_CE) + ! If the material is the same as the last material and the energy of the + ! particle hasn't changed, we don't need to lookup cross sections again. if (p % material /= p % last_material) call calculate_xs(p) type is (Particle_MG) - if ((p % material /= p % last_material) .or. (p % g /= p % last_g)) then - call calculate_mgxs(macro_xs(p % material) % obj, p % g, & - p % coord(p % n_coord) % uvw, material_xs) - end if + ! Since the MGXS can be angle dependent, this needs to be done + ! After every collision for the MGXS mode + call calculate_mgxs(macro_xs(p % material) % obj, & + materials(p % material), nuclides_MG, p % g, & + p % coord(p % n_coord) % uvw, material_xs, & + micro_xs) end select ! Find the distance to the nearest boundary From f2c3121c1c16319b70cd1ecec612a2692eb8df98 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 2 Nov 2015 21:10:41 -0500 Subject: [PATCH 15/84] Ok new strategy. Removed Particle_Base as abstract and Particle_CE and Particle_MG as extended types. Now, since the memory overhead is low (2 ints per thread), I combined Particle_CE and Particle_MG. This will make life significantly easier when I attack tally.F90, and also fixes my OpenMP issue. Whew. --- src/cross_section.F90 | 4 +- src/eigenvalue.F90 | 1 - src/geometry.F90 | 21 +++-- src/macroxs.F90 | 8 +- src/mgxs_data.F90 | 3 + src/nuclide_header.F90 | 28 ++++-- src/output.F90 | 11 ++- src/particle_header.F90 | 150 +++++++-------------------------- src/particle_restart.F90 | 22 ++--- src/particle_restart_write.F90 | 5 +- src/physics.F90 | 20 ++--- src/physics_common.F90 | 4 +- src/physics_mg.F90 | 12 +-- src/plot.F90 | 16 ++-- src/simulation.F90 | 21 ++--- src/source.F90 | 4 +- src/tally.F90 | 50 +++++------ src/track_output.F90 | 6 +- src/tracking.F90 | 34 +++----- 19 files changed, 160 insertions(+), 260 deletions(-) diff --git a/src/cross_section.F90 b/src/cross_section.F90 index 4e75970733..509fc71d5f 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -9,7 +9,7 @@ module cross_section use list_header, only: ListElemInt use material_header, only: Material use nuclide_header - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle use random_lcg, only: prn use sab_header, only: SAlphaBeta use search, only: binary_search @@ -29,7 +29,7 @@ contains subroutine calculate_xs(p) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer :: i ! loop index over nuclides integer :: i_nuclide ! index into nuclides array diff --git a/src/eigenvalue.F90 b/src/eigenvalue.F90 index 83f8989cc0..7ed6c34f01 100644 --- a/src/eigenvalue.F90 +++ b/src/eigenvalue.F90 @@ -10,7 +10,6 @@ module eigenvalue use math, only: t_percentile use mesh, only: count_bank_sites use mesh_header, only: RegularMesh - ! use particle_header, only: Particle_Base use random_lcg, only: prn, set_particle_seed, prn_skip use search, only: binary_search use simple_string, only: to_str diff --git a/src/geometry.F90 b/src/geometry.F90 index ee23a4e36e..7675c70dc1 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -6,8 +6,7 @@ module geometry &RectLattice, HexLattice use global use output, only: write_message - use particle_header, only: LocalCoord, Particle_Base, Particle_CE, & - Particle_MG + use particle_header, only: LocalCoord, Particle use particle_restart_write, only: write_particle_restart use surface_header use simple_string, only: to_str @@ -33,7 +32,7 @@ contains pure function cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p logical :: in_cell if (c%simple) then @@ -45,7 +44,7 @@ contains pure function simple_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p logical :: in_cell integer :: i @@ -79,7 +78,7 @@ contains pure function complex_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p logical :: in_cell integer :: i @@ -140,7 +139,7 @@ contains subroutine check_cell_overlap(p) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p integer :: i ! cell loop index on a level integer :: j ! coordinate level index @@ -188,7 +187,7 @@ contains recursive subroutine find_cell(p, found, search_cells) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p logical, intent(inout) :: found integer, optional :: search_cells(:) integer :: i ! index over cells @@ -340,7 +339,7 @@ contains !=============================================================================== subroutine cross_surface(p, last_cell) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(in) :: last_cell ! last cell particle was in real(8) :: u ! x-component of direction @@ -502,7 +501,7 @@ contains subroutine cross_lattice(p, lattice_translation) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(in) :: lattice_translation(3) integer :: j integer :: i_xyz(3) ! indices in lattice @@ -575,7 +574,7 @@ contains subroutine distance_to_boundary(p, dist, surface_crossed, lattice_translation, & next_level) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p real(8), intent(out) :: dist integer, intent(out) :: surface_crossed integer, intent(out) :: lattice_translation(3) @@ -955,7 +954,7 @@ contains subroutine handle_lost_particle(p, message) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p character(*) :: message ! Print warning and write lost particle file diff --git a/src/macroxs.F90 b/src/macroxs.F90 index bfbf83e5c9..14980cc6a7 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -39,7 +39,9 @@ contains xs % absorption = this % absorption(gin) xs % fission = this % fission(gin) xs % nu_fission = this % nu_fission(gin) - xs % kappa_fission = this % k_fission(gin) + if (allocated(this % k_fission)) then + xs % kappa_fission = this % k_fission(gin) + end if type is (MacroXS_Angle) call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) @@ -48,7 +50,9 @@ contains xs % absorption = this % absorption(gin, iazi, ipol) xs % fission = this % fission(gin, iazi, ipol) xs % nu_fission = this % nu_fission(gin, iazi, ipol) - xs % kappa_fission = this % k_fission(gin, iazi, ipol) + if (allocated(this % k_fission)) then + xs % kappa_fission = this % k_fission(gin, iazi, ipol) + end if end select ! Place nuclidic xs in micro_xs for tallying purposes diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 64c5dcce7d..d51dfd603e 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -61,6 +61,9 @@ contains ! allocate arrays for ACE table storage and cross section cache allocate(nuclides_MG(n_nuclides_total)) +!$omp parallel + allocate(micro_xs(n_nuclides_total)) +!$omp end parallel ! Find out if we need kappa fission (are there any k_fiss tallies?) get_kfiss = .false. diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 6f502c11ea..1a16c3f5ea 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -546,6 +546,13 @@ module nuclide_header integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs + xs = ZERO + + if ((xstype == 'nu_fission' .or. xstype == 'fission' .or. xstype =='chi' & + .or. xstype =='k_fission') .and. (.not. this % fissionable)) then + return + end if + if (present(gout)) then select case(xstype) case('mult') @@ -562,7 +569,9 @@ module nuclide_header case('fission') xs = this % fission(g) case('k_fission') - xs = this % k_fission(g) + if (allocated(this % k_fission)) then + xs = this % k_fission(g) + end if case('chi') xs = this % chi(g) case('scatter') @@ -584,6 +593,13 @@ module nuclide_header integer :: i_azi_, i_pol_ + xs = ZERO + + if ((xstype == 'nu_fission' .or. xstype == 'fission' .or. xstype =='chi' & + .or. xstype =='k_fission') .and. (.not. this % fissionable)) then + return + end if + if (present(i_azi) .and. present(i_pol)) then i_azi_ = i_azi i_pol_ = i_pol @@ -609,7 +625,9 @@ module nuclide_header case('fission') xs = this % fission(g,i_azi_,i_pol_) case('k_fission') - xs = this % k_fission(g,i_azi_,i_pol_) + if (allocated(this % k_fission)) then + xs = this % k_fission(g,i_azi_,i_pol_) + end if case('chi') xs = this % chi(g,i_azi_,i_pol_) case('scatter') @@ -637,11 +655,7 @@ module nuclide_header my_pol = acos(uvw(3)) my_azi = atan2(uvw(2), uvw(1)) - ! Quick and clear (but slower): - ! i_pol = minloc(abs(polar - my_pol),dim=1) - ! i_azi = minloc(abs(azimuthal - my_azi),dim=1) - - ! Fast search for equi-binned angles + ! Search for equi-binned angles dangle = PI / (real(size(polar),8)) i_pol = floor(my_pol / dangle + ONE) dangle = TWO * PI / (real(size(azimuthal),8)) diff --git a/src/output.F90 b/src/output.F90 index 3dba183148..30039e1181 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -13,7 +13,7 @@ module output use mesh_header, only: RegularMesh use mesh, only: mesh_indices_to_bin, bin_to_mesh_indices use nuclide_header - use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG + use particle_header, only: LocalCoord, Particle use plot_header use sab_header, only: SAlphaBeta use simple_string, only: to_upper, to_str @@ -253,7 +253,7 @@ contains subroutine print_particle(p) - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p integer :: i ! index for coordinate levels type(Cell), pointer :: c @@ -310,12 +310,11 @@ contains ! Display weight, energy, grid index, and interpolation factor write(ou,*) ' Weight = ' // to_str(p % wgt) - select type(p) - type is (Particle_CE) + if (run_CE) then write(ou,*) ' Energy = ' // to_str(p % E) - type is (Particle_MG) + else write(ou,*) ' Energy Group = ' // to_str(p % g) - end select + end if write(ou,*) ' Delayed Group = ' // to_str(p % delayed_group) write(ou,*) diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 85d83cd3d3..3acf02a4af 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -38,7 +38,7 @@ module particle_header ! geometry !=============================================================================== - type, abstract :: Particle_Base + type Particle ! Basic data integer(8) :: id ! Unique ID integer :: type ! Particle type (n, p, e, etc) @@ -47,6 +47,12 @@ module particle_header integer :: n_coord ! number of current coordinates type(LocalCoord) :: coord(MAX_COORD) ! coordinates for all levels + ! Energy Data + real(8) :: E ! post-collision energy + real(8) :: last_E ! pre-collision energy + integer :: g ! post-collision energy group (MG only) + integer :: last_g ! pre-collision energy group (MG only) + ! Other physical data real(8) :: wgt ! particle weight real(8) :: mu ! angle of scatter @@ -90,39 +96,9 @@ module particle_header contains procedure, pass :: initialize => initialize_particle procedure, pass :: clear => clear_particle - procedure, pass :: initialize_from_source => initialize_from_source_base - procedure, pass :: create_secondary => create_secondary_base - procedure(collision_), deferred, pass :: pre_collision - end type Particle_Base - - abstract interface - subroutine collision_(this) - import Particle_Base - class(Particle_Base), intent(inout) :: this - end subroutine collision_ - end interface - - type, extends(Particle_Base) :: Particle_CE - ! Energy Data - real(8) :: E ! post-collision energy - real(8) :: last_E ! pre-collision energy - - contains - procedure :: initialize_from_source => initialize_from_source_ce - procedure :: create_secondary => create_secondary_ce - procedure :: pre_collision => pre_collision_ce - end type Particle_CE - - type, extends(Particle_Base) :: Particle_MG - ! Energy Data - integer :: g ! post-collision energy group - integer :: last_g ! pre-collision energy group - - contains - procedure :: initialize_from_source => initialize_from_source_mg - procedure :: create_secondary => create_secondary_mg - procedure :: pre_collision => pre_collision_mg - end type Particle_MG + procedure, pass :: initialize_from_source => initialize_from_source + procedure, pass :: create_secondary => create_secondary + end type Particle contains @@ -133,7 +109,7 @@ contains subroutine initialize_particle(this) - class(Particle_Base) :: this + class(Particle) :: this ! Clear coordinate lists call this % clear() @@ -169,7 +145,7 @@ contains subroutine clear_particle(this) - class(Particle_Base) :: this + class(Particle) :: this integer :: i ! remove any coordinate levels @@ -202,9 +178,10 @@ contains ! fission, or simply as a secondary particle. !=============================================================================== - subroutine initialize_from_source_base(this, src) - class(Particle_Base), intent(inout) :: this - type(Bank), intent(in) :: src + subroutine initialize_from_source(this, src, run_CE) + class(Particle), intent(inout) :: this + type(Bank), intent(in) :: src + logical, intent(in) :: run_CE ! set defaults call this % initialize() @@ -216,44 +193,25 @@ contains this % coord(1) % uvw = src % uvw this % last_xyz = src % xyz this % last_uvw = src % uvw - - end subroutine initialize_from_source_base - - subroutine initialize_from_source_ce(this, src) - class(Particle_CE), intent(inout) :: this - type(Bank), intent(in) :: src - - ! set defaults a nd init base - call initialize_from_source_base(this, src) - - ! copy attributes from source bank site this % E = src % E this % last_E = src % E + if (.not. run_CE) then + this % g = src % g + this % last_g = src % g + end if - end subroutine initialize_from_source_ce - - subroutine initialize_from_source_mg(this, src) - class(Particle_MG), intent(inout) :: this - type(Bank), intent(in) :: src - - ! set defaults and init base - call initialize_from_source_base(this, src) - - ! copy attributes from source bank site - this % g = src % g - this % last_g = src % g - - end subroutine initialize_from_source_mg + end subroutine initialize_from_source !=============================================================================== ! CREATE_SECONDARY stores the current phase space attributes of the particle in ! the secondary bank and increments the number of sites in the secondary bank. !=============================================================================== - subroutine create_secondary_base(this, uvw, type) - class(Particle_Base), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type + subroutine create_secondary(this, uvw, type, run_CE) + class(Particle), intent(inout) :: this + real(8), intent(in) :: uvw(3) + integer, intent(in) :: type + logical, intent(in) :: run_CE integer :: n @@ -268,59 +226,11 @@ contains this % secondary_bank(n) % xyz(:) = this % coord(1) % xyz this % secondary_bank(n) % uvw(:) = uvw this % n_secondary = n - - end subroutine create_secondary_base - - subroutine create_secondary_ce(this, uvw, type) - class(Particle_CE), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type - - call create_secondary_base(this, uvw, type) - this % secondary_bank(this % n_secondary) % E = this % E + if (.not. run_CE) then + this % secondary_bank(this % n_secondary) % g = this % g + end if - end subroutine create_secondary_ce - - subroutine create_secondary_mg(this, uvw, type) - class(Particle_MG), intent(inout) :: this - real(8), intent(in) :: uvw(3) - integer, intent(in) :: type - - call create_secondary_base(this, uvw, type) - - this % secondary_bank(this % n_secondary) % g = this % g - - end subroutine create_secondary_mg - -!=============================================================================== -! PRE_COLLISION_* Updates pre-collision particle properties -!=============================================================================== - - subroutine pre_collision_ce(this) - class(Particle_CE), intent(inout) :: this - - ! Store pre-collision particle properties - this % last_wgt = this % wgt - this % last_E = this % E - this % last_uvw = this % coord(1) % uvw - - ! Add to collision counter for particle - this % n_collision = this % n_collision + 1 - - end subroutine pre_collision_ce - - subroutine pre_collision_mg(this) - class(Particle_MG), intent(inout) :: this - - ! Store pre-collision particle properties - this % last_wgt = this % wgt - this % last_g = this % g - this % last_uvw = this % coord(1) % uvw - - ! Add to collision counter for particle - this % n_collision = this % n_collision + 1 - - end subroutine pre_collision_mg + end subroutine create_secondary end module particle_header diff --git a/src/particle_restart.F90 b/src/particle_restart.F90 index fc3eb4393e..9d49a4f977 100644 --- a/src/particle_restart.F90 +++ b/src/particle_restart.F90 @@ -8,7 +8,7 @@ module particle_restart use global use hdf5_interface, only: file_open, file_close, read_dataset use output, only: write_message, print_particle - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle use random_lcg, only: set_particle_seed use tracking, only: transport @@ -28,7 +28,7 @@ contains integer(8) :: particle_seed integer :: previous_run_mode - class(Particle_Base), pointer :: p + type(Particle) :: p ! Set verbosity high verbosity = 10 @@ -66,7 +66,7 @@ contains !=============================================================================== subroutine read_particle_restart(p, previous_run_mode) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(inout) :: previous_run_mode integer :: int_scalar @@ -96,12 +96,8 @@ contains end select call read_dataset(file_id, 'id', p%id) call read_dataset(file_id, 'weight', p%wgt) - select type(p) - type is (Particle_CE) - call read_dataset(file_id, 'energy', p%E) - type is (Particle_MG) - call read_dataset(file_id, 'energy_group', p%g) - end select + call read_dataset(file_id, 'energy', p%E) + call read_dataset(file_id, 'energy_group', p%g) call read_dataset(file_id, 'xyz', p%coord(1)%xyz) call read_dataset(file_id, 'uvw', p%coord(1)%uvw) @@ -109,12 +105,8 @@ contains p%last_wgt = p%wgt p%last_xyz = p%coord(1)%xyz p%last_uvw = p%coord(1)%uvw - select type(p) - type is (Particle_CE) - p%last_E = p%E - type is (Particle_MG) - p%last_g = p%g - end select + p%last_E = p%E + p%last_g = p%g ! Close hdf5 file call file_close(file_id) diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index a7341d71ec..324e96bc7a 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -3,7 +3,7 @@ module particle_restart_write use bank_header, only: Bank use global use hdf5_interface - use particle_header, only: Particle_Base + use particle_header, only: Particle use simple_string, only: to_str use hdf5 @@ -19,7 +19,7 @@ contains !=============================================================================== subroutine write_particle_restart(p) - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p integer(HID_T) :: file_id character(MAX_FILE_LEN) :: filename @@ -57,6 +57,7 @@ contains call write_dataset(file_id, 'id', p%id) call write_dataset(file_id, 'weight', src%wgt) call write_dataset(file_id, 'energy', src%E) + call write_dataset(file_id, 'energy_group', src%g) call write_dataset(file_id, 'xyz', src%xyz) call write_dataset(file_id, 'uvw', src%uvw) diff --git a/src/physics.F90 b/src/physics.F90 index 0b0509e1c5..3ea28c2281 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -12,7 +12,7 @@ module physics use mesh, only: get_mesh_indices use nuclide_header use output, only: write_message - use particle_header, only: Particle_CE + use particle_header, only: Particle use particle_restart_write, only: write_particle_restart use physics_common use random_lcg, only: prn @@ -34,7 +34,7 @@ contains subroutine collision(p) - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p ! Store pre-collision particle properties p % last_wgt = p % wgt @@ -72,7 +72,7 @@ contains subroutine sample_reaction(p) - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p integer :: i_nuclide ! index in nuclides array integer :: i_reaction ! index in nuc % reactions array @@ -125,7 +125,7 @@ contains function sample_nuclide(p, base) result(i_nuclide) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p character(7), intent(in) :: base ! which reaction to sample based on integer :: i_nuclide @@ -242,7 +242,7 @@ contains subroutine absorption(p, i_nuclide) - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(in) :: i_nuclide if (survival_biasing) then @@ -283,7 +283,7 @@ contains subroutine scatter(p, i_nuclide) - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(in) :: i_nuclide integer :: i @@ -1040,7 +1040,7 @@ contains subroutine create_fission_sites(p, i_nuclide, i_reaction) - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p integer, intent(in) :: i_nuclide integer, intent(in) :: i_reaction @@ -1158,7 +1158,7 @@ contains type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn - type(Particle_CE), intent(inout) :: p ! Particle causing fission + type(Particle), intent(inout) :: p ! Particle causing fission real(8) :: E_out ! outgoing E of fission neutron integer :: j ! index on nu energy grid / precursor group @@ -1284,7 +1284,7 @@ contains subroutine inelastic_scatter(nuc, rxn, p) type(Nuclide_CE), pointer :: nuc type(Reaction), pointer :: rxn - type(Particle_CE), intent(inout) :: p + type(Particle), intent(inout) :: p integer :: i ! loop index integer :: law ! secondary energy distribution law @@ -1355,7 +1355,7 @@ contains p % wgt = yield * p % wgt else do i = 1, rxn % multiplicity - 1 - call p % create_secondary(p % coord(1) % uvw, NEUTRON) + call p % create_secondary(p % coord(1) % uvw, NEUTRON, run_CE) end do end if diff --git a/src/physics_common.F90 b/src/physics_common.F90 index fbd85cc625..7d5b1cea8b 100644 --- a/src/physics_common.F90 +++ b/src/physics_common.F90 @@ -2,7 +2,7 @@ module physics_common use constants use global, only: weight_cutoff, weight_survive - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle use random_lcg, only: prn implicit none @@ -15,7 +15,7 @@ contains subroutine russian_roulette(p) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p if (p % wgt < weight_cutoff) then if (prn() < p % wgt / weight_survive) then diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index ca7aebdb36..9866b48d20 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -10,7 +10,7 @@ module physics_mg use material_header, only: Material use mesh, only: get_mesh_indices use output, only: write_message - use particle_header, only: Particle_Base, Particle_MG + use particle_header, only: Particle use particle_restart_write, only: write_particle_restart use physics_common use random_lcg, only: prn @@ -28,7 +28,7 @@ contains subroutine collision_mg(p) - type(Particle_MG), intent(inout) :: p + type(Particle), intent(inout) :: p ! Store pre-collision particle properties p % last_wgt = p % wgt @@ -58,7 +58,7 @@ contains subroutine sample_reaction(p) - type(Particle_MG), intent(inout) :: p + type(Particle), intent(inout) :: p type(Material), pointer :: mat @@ -102,7 +102,7 @@ contains subroutine absorption(p) - type(Particle_MG), intent(inout) :: p + type(Particle), intent(inout) :: p if (survival_biasing) then ! Determine weight absorbed in survival biasing @@ -140,7 +140,7 @@ contains subroutine scatter(p) - type(Particle_MG), intent(inout) :: p + type(Particle), intent(inout) :: p call sample_scatter(macro_xs(p % material) % obj, & p % coord(p % n_coord) % uvw, p % last_g, p % g, & @@ -161,7 +161,7 @@ contains subroutine create_fission_sites(p) - type(Particle_MG), intent(inout) :: p + type(Particle), intent(inout) :: p integer :: i ! loop index integer :: nu ! actual number of neutrons produced diff --git a/src/plot.F90 b/src/plot.F90 index e46742ea1a..518cc4f0cf 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -9,7 +9,7 @@ module plot use mesh, only: get_mesh_indices use mesh_header, only: RegularMesh use output, only: write_message - use particle_header, only: LocalCoord, Particle_Base + use particle_header, only: LocalCoord, Particle use plot_header use ppmlib, only: Image, init_image, allocate_image, & deallocate_image, set_pixel @@ -56,7 +56,7 @@ contains subroutine position_rgb(p, pl, rgb, id) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p type(ObjectPlot), pointer, intent(in) :: pl integer, intent(out) :: rgb(3) integer, intent(out) :: id @@ -123,9 +123,9 @@ contains real(8) :: in_pixel real(8) :: out_pixel real(8) :: xyz(3) - type(Image) :: img - class(Particle_Base), pointer :: p - type(ProgressBar) :: progress + type(Image) :: img + type(Particle) :: p + type(ProgressBar) :: progress ! Initialize and allocate space for image call init_image(img) @@ -362,9 +362,9 @@ contains integer(HSIZE_T) :: offset(3) real(8) :: vox(3) ! x, y, and z voxel widths real(8) :: ll(3) ! lower left starting point for each sweep direction - class(Particle_Base), pointer :: p - type(ProgressBar) :: progress - type(c_ptr) :: f_ptr + type(Particle) :: p + type(ProgressBar) :: progress + type(c_ptr) :: f_ptr ! compute voxel widths in each direction vox = pl % width/dble(pl % pixels) diff --git a/src/simulation.F90 b/src/simulation.F90 index 41330858ff..d1b96d8b08 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -15,7 +15,7 @@ module simulation use global use output, only: write_message, header, print_columns, & print_batch_keff, print_generation - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle use random_lcg, only: set_particle_seed use source, only: initialize_source use state_point, only: write_state_point, write_source_point @@ -39,14 +39,8 @@ contains subroutine run_simulation() - class(Particle_Base), pointer :: p - integer(8) :: i_work - - if (run_CE) then - allocate(Particle_CE :: p) - else - allocate(Particle_MG :: p) - end if + type(Particle) :: p + integer(8) :: i_work if (.not. restart_run) call initialize_source() @@ -122,9 +116,6 @@ contains ! Clear particle call p % clear() - if (associated(p)) & - deallocate(p) - end subroutine run_simulation !=============================================================================== @@ -133,14 +124,14 @@ contains subroutine initialize_history(p, index_source) - class(Particle_Base), pointer, intent(inout) :: p - integer(8), intent(in) :: index_source + type(Particle), intent(inout) :: p + integer(8), intent(in) :: index_source integer(8) :: particle_seed ! unique index for particle integer :: i ! set defaults - call p % initialize_from_source(source_bank(index_source)) + call p % initialize_from_source(source_bank(index_source), run_CE) ! set identifier for particle p % id = work_index(rank) + index_source diff --git a/src/source.F90 b/src/source.F90 index 53ed2e9a3d..38df80e8ce 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -8,7 +8,7 @@ module source use global use hdf5_interface, only: file_create, file_open, file_close, read_dataset use output, only: write_message - use particle_header, only: Particle_Base, Particle_CE, Particle_MG + use particle_header, only: Particle use random_lcg, only: prn, set_particle_seed, prn_set_stream use search, only: binary_search use simple_string, only: to_str @@ -109,7 +109,7 @@ contains real(8) :: a ! Arbitrary parameter 'a' real(8) :: b ! Arbitrary parameter 'b' logical :: found ! Does the source particle exist within geometry? - type(Particle_CE) :: p ! Temporary particle for using find_cell + type(Particle) :: p ! Temporary particle for using find_cell integer, save :: num_resamples = 0 ! Number of resamples encountered ! Set weight to one by default diff --git a/src/tally.F90 b/src/tally.F90 index 640cb9f58d..6ec0dee19c 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -11,8 +11,7 @@ module tally mesh_intersects_2d, mesh_intersects_3d use mesh_header, only: RegularMesh use output, only: header - use particle_header, only: LocalCoord, Particle_Base, Particle_CE, & - Particle_MG + use particle_header, only: LocalCoord, Particle use search, only: binary_search use simple_string, only: to_str use tally_header, only: TallyResult, TallyMapItem, TallyMapElement @@ -38,7 +37,7 @@ contains subroutine score_general(p, t, start_index, filter_index, i_nuclide, & atom_density, flux) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p type(TallyObject), pointer, intent(inout) :: t integer, intent(in) :: start_index integer, intent(in) :: i_nuclide @@ -838,7 +837,7 @@ contains subroutine score_all_nuclides(p, i_tally, flux, filter_index) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer, intent(in) :: i_tally real(8), intent(in) :: flux integer, intent(in) :: filter_index @@ -892,7 +891,7 @@ contains subroutine score_analog_tally(p) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer :: i integer :: i_tally @@ -1000,7 +999,7 @@ contains subroutine score_fission_eout(p, t, i_score) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p type(TallyObject), pointer :: t integer, intent(in) :: i_score ! index for score @@ -1062,7 +1061,7 @@ contains subroutine score_fission_delayed_eout(p, t, i_score) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p type(TallyObject), intent(inout) :: t integer, intent(in) :: i_score ! index for score @@ -1188,7 +1187,7 @@ contains subroutine score_tracklength_tally(p, distance) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p real(8), intent(in) :: distance integer :: i @@ -1301,7 +1300,7 @@ contains subroutine score_tl_on_mesh(p, i_tally, d_track) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer, intent(in) :: i_tally real(8), intent(in) :: d_track @@ -1586,7 +1585,7 @@ contains subroutine score_collision_tally(p) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer :: i integer :: i_tally @@ -1695,7 +1694,7 @@ contains subroutine get_scoring_bins(p, i_tally, found_bin) - type(Particle_CE), intent(in) :: p + type(Particle), intent(in) :: p integer, intent(in) :: i_tally logical, intent(out) :: found_bin @@ -1905,7 +1904,7 @@ contains subroutine score_surface_current(p) - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p integer :: i integer :: i_tally @@ -1970,22 +1969,19 @@ contains uvw = p % coord(1) % uvw ! determine incoming energy bin - select type(p) - type is (Particle_CE) - j = t % find_filter(FILTER_ENERGYIN) - if (j > 0) then - n = t % filters(j) % n_bins - ! check if energy of the particle is within energy bins - if (p % E < t % filters(j) % real_bins(1) .or. & - p % E > t % filters(j) % real_bins(n + 1)) then - cycle - end if - - ! search to find incoming energy bin - matching_bins(j) = binary_search(t % filters(j) % real_bins, & - n + 1, p % E) + j = t % find_filter(FILTER_ENERGYIN) + if (j > 0) then + n = t % filters(j) % n_bins + ! check if energy of the particle is within energy bins + if (p % E < t % filters(j) % real_bins(1) .or. & + p % E > t % filters(j) % real_bins(n + 1)) then + cycle end if - end select + + ! search to find incoming energy bin + matching_bins(j) = binary_search(t % filters(j) % real_bins, & + n + 1, p % E) + end if ! ======================================================================= ! SPECIAL CASES WHERE TWO INDICES ARE THE SAME diff --git a/src/track_output.F90 b/src/track_output.F90 index ec09932758..87dbfbfa44 100644 --- a/src/track_output.F90 +++ b/src/track_output.F90 @@ -7,7 +7,7 @@ module track_output use global use hdf5_interface - use particle_header, only: Particle_Base + use particle_header, only: Particle use simple_string, only: to_str use hdf5 @@ -43,7 +43,7 @@ contains !=============================================================================== subroutine write_particle_track(p) - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p real(8), allocatable :: new_coords(:, :) integer :: i @@ -93,7 +93,7 @@ contains !=============================================================================== subroutine finalize_particle_track(p) - class(Particle_Base), intent(in) :: p + type(Particle), intent(in) :: p integer :: i integer :: n_particle_tracks diff --git a/src/tracking.F90 b/src/tracking.F90 index 1960089c79..c761cd5337 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -9,7 +9,7 @@ module tracking use global use macroxs, only: calculate_mgxs use output, only: write_message - use particle_header, only: LocalCoord, Particle_Base, Particle_CE, Particle_MG + use particle_header, only: LocalCoord, Particle use physics, only: collision use physics_mg, only: collision_mg use random_lcg, only: prn @@ -29,7 +29,7 @@ contains subroutine transport(p) - class(Particle_Base), intent(inout) :: p + type(Particle), intent(inout) :: p integer :: j ! coordinate level integer :: next_level ! next coordinate level to check @@ -84,20 +84,18 @@ contains if (check_overlaps) call check_cell_overlap(p) ! Calculate microscopic and macroscopic cross sections - - select type(p) - type is (Particle_CE) + if (run_CE) then ! If the material is the same as the last material and the energy of the ! particle hasn't changed, we don't need to lookup cross sections again. if (p % material /= p % last_material) call calculate_xs(p) - type is (Particle_MG) + else ! Since the MGXS can be angle dependent, this needs to be done ! After every collision for the MGXS mode call calculate_mgxs(macro_xs(p % material) % obj, & materials(p % material), nuclides_MG, p % g, & p % coord(p % n_coord) % uvw, material_xs, & micro_xs) - end select + end if ! Find the distance to the nearest boundary call distance_to_boundary(p, d_boundary, surface_crossed, & @@ -120,10 +118,7 @@ contains ! Score track-length tallies if (active_tracklength_tallies % size() > 0) then - select type(p) - type is (Particle_CE) - call score_tracklength_tally(p, distance) - end select + call score_tracklength_tally(p, distance) end if @@ -170,21 +165,17 @@ contains ! Clear surface component p % surface = NONE - select type(p) - type is (Particle_CE) + if (run_CE) then call collision(p) - type is (Particle_MG) + else call collision_mg(p) - end select + end if ! Score collision estimator tallies -- this is done after a collision ! has occurred rather than before because we need information on the ! outgoing energy for any tallies with an outgoing energy filter - select type(p) - type is (Particle_CE) - if (active_collision_tallies % size() > 0) call score_collision_tally(p) - if (active_analog_tallies % size() > 0) call score_analog_tally(p) - end select + if (active_collision_tallies % size() > 0) call score_collision_tally(p) + if (active_analog_tallies % size() > 0) call score_analog_tally(p) ! Reset banked weight during collision p % n_bank = 0 @@ -226,7 +217,8 @@ contains ! Check for secondary particles if this particle is dead if (.not. p % alive) then if (p % n_secondary > 0) then - call p % initialize_from_source(p % secondary_bank(p % n_secondary)) + call p % initialize_from_source(p % secondary_bank(p % n_secondary), & + run_CE) p % n_secondary = p % n_secondary - 1 ! Enter new particle in particle track file From d7ee342b124a85251a4ad646b134d5002936af92 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 2 Nov 2015 21:18:27 -0500 Subject: [PATCH 16/84] Added code to apply an energy value to the particle when given a group (uses group energy midpoint). This will be useful so that I do not have to change lots of downstream code like CMFD and also will be a future compatability aid. --- src/global.F90 | 1 + src/input_xml.F90 | 5 +++++ src/particle_header.F90 | 2 ++ src/physics_mg.F90 | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/src/global.F90 b/src/global.F90 index 37e442adc6..737aef51f8 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -119,6 +119,7 @@ module global ! Energy group structure real(8), allocatable :: energy_bins(:) + real(8), allocatable :: energy_bin_midpoints(:) ! Maximum Data Order integer :: max_order diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 64639b8941..fd8d5f50f5 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4315,6 +4315,11 @@ contains call fatal_error("group_structures element must exist!") end if + allocate(energy_bin_midpoints(energy_groups)) + do i = 1, energy_groups + energy_bin_midpoints(i) = 0.5_8 * (energy_bins(i) + energy_bins(i + 1)) + end do + if (check_for_node(doc, "legendre_mu_points")) then ! Get scattering treatment call get_node_value(doc, "legendre_mu_points", legendre_mu_points) diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 3acf02a4af..9c0ddfde0d 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -132,6 +132,8 @@ contains this % fission = .false. this % delayed_group = 0 this % n_delayed_bank(:) = 0 + ! Initialize this % g so there is always at least some initialized value + this % g = 1 ! Set up base level coordinates this % coord(1) % universe = BASE_UNIVERSE diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 9866b48d20..7d3448aeaa 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -32,6 +32,7 @@ contains ! Store pre-collision particle properties p % last_wgt = p % wgt + p % last_E = p % E p % last_g = p % g p % last_uvw = p % coord(1) % uvw @@ -146,6 +147,9 @@ contains p % coord(p % n_coord) % uvw, p % last_g, p % g, & p % mu, p % wgt) + ! Update energy value for downstream compatability (in tallying) + p % E = energy_bin_midpoints(p % g) + p % coord(p % n_coord) % uvw = rotate_angle(p % coord(p % n_coord) % uvw, & p % mu) From 8870310492cc3cf32ec3107e7ca00307907bbea7 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 3 Nov 2015 05:06:46 -0500 Subject: [PATCH 17/84] Fine tuning tallies. Got nu-scatter guys to use correct data. Seems like last hurdle is to get the nu fission score done --- src/input_xml.F90 | 76 +++++++++++++++--- src/macroxs_header.F90 | 21 ++++- src/tally.F90 | 174 +++++++++++++++++++++++++---------------- 3 files changed, 192 insertions(+), 79 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index fd8d5f50f5..0c26b841a9 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2573,6 +2573,15 @@ contains else n_words = get_arraysize_integer(node_filt, "bins") end if + else if (temp_str == 'energy' .or. temp_str == 'energyout' .and. & + .not. run_CE) then + ! For MG calculations, dont require the user to put in all the + ! group boundaries, as there could be many. Assume that if no & + ! bins are entered that that means they want group-wise results. + n_words = -1 + call warning("Energy bins not set in filter on tally " & + &// trim(to_str(t % id))) + else call fatal_error("Bins not set in filter on tally " & &// trim(to_str(t % id))) @@ -2683,28 +2692,55 @@ contains ! Set type of filter t % filters(j) % type = FILTER_ENERGYIN - ! Set number of bins - t % filters(j) % n_bins = n_words - 1 + if (n_words > 0) then + ! Set number of bins + t % filters(j) % n_bins = n_words - 1 - ! Allocate and store bins - allocate(t % filters(j) % real_bins(n_words)) - call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! Allocate and store bins + allocate(t % filters(j) % real_bins(n_words)) + call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + else if (n_words == -1) then + ! Set number of bins + t % filters(j) % n_bins = energy_groups + + ! Allocate and store bins + allocate(t % filters(j) % real_bins(energy_groups)) + t % filters(j) % real_bins = energy_bins + end if case ('energyout') ! Set type of filter t % filters(j) % type = FILTER_ENERGYOUT - ! Set number of bins - t % filters(j) % n_bins = n_words - 1 + if (n_words > 0) then + ! Set number of bins + t % filters(j) % n_bins = n_words - 1 - ! Allocate and store bins - allocate(t % filters(j) % real_bins(n_words)) - call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! Allocate and store bins + allocate(t % filters(j) % real_bins(n_words)) + call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + else if (n_words == -1) then + ! Set number of bins + t % filters(j) % n_bins = energy_groups + + ! Allocate and store bins + allocate(t % filters(j) % real_bins(energy_groups)) + t % filters(j) % real_bins = energy_bins + end if ! Set to analog estimator t % estimator = ESTIMATOR_ANALOG case ('delayedgroup') + ! Check to see if running in MG mode, because if so, the current + ! system isnt set up yet to support delayed group data and thus + ! these tallies + if (.not. run_CE) then + call fatal_error("delayedgroup filter on tally " & + // trim(to_str(t % id)) // " not yet supported& + & for multi-group mode.") + end if + ! Set type of filter t % filters(j) % type = FILTER_DELAYEDGROUP @@ -3219,6 +3255,12 @@ contains case ('n4n', '(n,4n)') t % score_bins(j) = N_4N + ! Disallow for MG mode since data not present + if (.not. run_CE) then + call fatal_error("Cannot tally (n,4n) reaction rate in & + &multi-group mode") + end if + case ('absorption') t % score_bins(j) = SCORE_ABSORPTION if (t % find_filter(FILTER_ENERGYOUT) > 0) then @@ -3243,6 +3285,12 @@ contains ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if + + ! Disallow for MG mode since data not present + if (.not. run_CE) then + call fatal_error("Cannot tally delayed nu-fission rate in & + &multi-group mode") + end if case ('kappa-fission') t % score_bins(j) = SCORE_KAPPA_FISSION case ('inverse-velocity') @@ -3398,6 +3446,14 @@ contains end if end select + + ! Do a check at the end (instead of for every case) to make sure + ! the tallies are compatible with MG mode where we have less detailed + ! nuclear data + if (.not. run_CE .and. t % score_bins(j) > 0) then + call fatal_error("Cannot tally " // trim(score_name) // & + " reaction rate in multi-group mode") + end if end do t % n_score_bins = n_scores diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index ed768b2430..d33de9241f 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -48,11 +48,12 @@ module macroxs_header end subroutine macroxs_init_ - function macroxs_get_xs_(this, g, xstype, uvw) result(xs) + function macroxs_get_xs_(this, g, xstype, gout, uvw) result(xs) import MacroXS_Base class(MacroXS_Base), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Cross Section Type + integer, optional, intent(in) :: gout ! Outgoing Energy group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8) :: xs ! Resultant xs @@ -787,10 +788,11 @@ contains ! MACROXS_*_GET_XS returns the requested data type !=============================================================================== - function macroxs_iso_get_xs(this, g, xstype, uvw) result(xs) + function macroxs_iso_get_xs(this, g, xstype, gout, uvw) result(xs) class(MacroXS_Iso), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Type of xs requested + integer, optional, intent(in) :: gout ! Outgoing Energy group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8) :: xs ! Requested x/s @@ -807,14 +809,21 @@ contains xs = this % nu_fission(g) case('scatter') xs = this % scattxs(g) + case('mult') + if (present(gout)) then + xs = this % scatter % mult(gout,g) + else + xs = sum(this % scatter % mult(:,g)) + end if end select end function macroxs_iso_get_xs - function macroxs_angle_get_xs(this, g, xstype, uvw) result(xs) + function macroxs_angle_get_xs(this, g, xstype, gout,uvw) result(xs) class(MacroXS_Angle), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Type of xs requested + integer, optional, intent(in) :: gout ! Outgoing Energy group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8) :: xs ! Requested x/s @@ -835,6 +844,12 @@ contains xs = this % nu_fission(g,iazi,ipol) case('scatter') xs = this % scattxs(g,iazi,ipol) + case('mult') + if (present(gout)) then + xs = this % scatter(iazi,ipol) % obj % mult(gout,g) + else + xs = sum(this % scatter(iazi,ipol) % obj % mult(:,g)) + end if end select end if diff --git a/src/tally.F90 b/src/tally.F90 index 6ec0dee19c..3a258c9d3d 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -201,29 +201,43 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt + if (run_CE) then + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt + else + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity + end if + end if + else + if (i_nuclide > 0) then + score = p % last_wgt * & + nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) + else + score = p % last_wgt * & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) end if end if @@ -238,29 +252,43 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt + if (run_CE) then + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt + else + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity + end if + end if + else + if (i_nuclide > 0) then + score = p % last_wgt * & + nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) + else + score = p % last_wgt * & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) end if end if @@ -275,29 +303,43 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt + if (run_CE) then + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt + else + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity + end if + end if + else + if (i_nuclide > 0) then + score = p % last_wgt * & + nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) + else + score = p % last_wgt * & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % coord(1) % uvw) end if end if From 8d736c7badaa97af957a2eea7a03fde3fecfc694 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 4 Nov 2015 21:09:24 -0500 Subject: [PATCH 18/84] Separated some tally routines, implemented function pointers, removed nuclidic micro_xs calculation for MG mode. made MG closer in speed to the versionof OpenMGMC. --- src/initialize.F90 | 4 + src/input_xml.F90 | 16 +- src/macroxs.F90 | 28 +- src/nuclide_header.F90 | 21 +- src/tally.F90 | 891 +++++++++++++++++++++++++++++++++++------ src/tracking.F90 | 6 +- 6 files changed, 807 insertions(+), 159 deletions(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index 5793b67226..128759e429 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -26,6 +26,7 @@ module initialize use summary, only: write_summary use tally_header, only: TallyObject, TallyResult, TallyFilter use tally_initialize, only: configure_tallies + use tally, only: init_tally_routines #ifdef MPI use message_passing @@ -150,6 +151,9 @@ contains ! Allocate and setup tally stride, matching_bins, and tally maps call configure_tallies() + ! Set up tally procedure pointers + call init_tally_routines() + ! Determine how much work each processor should do call calculate_work() diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 0c26b841a9..65c840ce25 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2569,18 +2569,24 @@ contains if (temp_str == 'energy' .or. temp_str == 'energyout' .or. & temp_str == 'mu' .or. temp_str == 'polar' .or. & temp_str == 'azimuthal') then - n_words = get_arraysize_double(node_filt, "bins") + ! If in MG mode, fail if user provides bins, as we are only + ! allowing for all groups + if (.not. run_CE .and. (temp_str == 'energy' .or. & + temp_str == 'energyout')) then + call fatal_error("No energy or energyout bins needed on tally " & + &// trim(to_str(t % id))) + else + n_words = get_arraysize_double(node_filt, "bins") + end if else n_words = get_arraysize_integer(node_filt, "bins") end if - else if (temp_str == 'energy' .or. temp_str == 'energyout' .and. & - .not. run_CE) then + else if (.not. run_CE .and. (temp_str == 'energy' .or. & + temp_str == 'energyout')) then ! For MG calculations, dont require the user to put in all the ! group boundaries, as there could be many. Assume that if no & ! bins are entered that that means they want group-wise results. n_words = -1 - call warning("Energy bins not set in filter on tally " & - &// trim(to_str(t % id))) else call fatal_error("Bins not set in filter on tally " & diff --git a/src/macroxs.F90 b/src/macroxs.F90 index 14980cc6a7..ac66d6b2ac 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -19,18 +19,13 @@ contains ! UPDATE_XS stores the xs to work with !=============================================================================== - subroutine calculate_mgxs(this, mat, nuclides, gin, uvw, xs, micro_xs) + subroutine calculate_mgxs(this, gin, uvw, xs) class(MacroXS_Base), intent(in) :: this - type(Material), intent(in) :: mat ! Material of interest - type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs - type(NuclideMicroXS), intent(inout) :: micro_xs(:) integer :: iazi, ipol - integer :: i, i_nuclide - class(Nuclide_MG), pointer :: nuc select type(this) type is (MacroXS_Iso) @@ -55,27 +50,6 @@ contains end if end select - ! Place nuclidic xs in micro_xs for tallying purposes - do i = 1, mat % n_nuclides - ! Determine microscopic cross section for this nuclide - i_nuclide = mat % nuclide(i) - - nuc => nuclides(i_nuclide) % obj - micro_xs(i_nuclide) % total = nuc % get_xs(gin, 'total', & - I_AZI=iazi, I_POL=ipol) - micro_xs(i_nuclide) % elastic = nuc % get_xs(gin, 'scatter', & - I_AZI=iazi, I_POL=ipol) - micro_xs(i_nuclide) % absorption = nuc % get_xs(gin, 'absorption', & - I_AZI=iazi, I_POL=ipol) - micro_xs(i_nuclide) % fission = nuc % get_xs(gin, 'fission', & - I_AZI=iazi, I_POL=ipol) - micro_xs(i_nuclide) % nu_fission = nuc % get_xs(gin, 'nu_fission', & - I_AZI=iazi, I_POL=ipol) - micro_xs(i_nuclide) % kappa_fission = nuc % get_xs(gin, 'k_fission', & - I_AZI=iazi, I_POL=ipol) - - end do - end subroutine calculate_mgxs diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 1a16c3f5ea..3e320ab273 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -6,7 +6,7 @@ module nuclide_header use constants use endf, only: reaction_name use list_header, only: ListInt - ! use math, only: calc_pn, calc_rn!, expand_harmonic + use math, only: evaluate_legendre !use scattdata_header use simple_string @@ -117,7 +117,7 @@ module nuclide_header end type Nuclide_MG abstract interface - function nuclide_mg_get_xs_(this, g, xstype, gout, uvw, i_azi, i_pol) & + function nuclide_mg_get_xs_(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) import Nuclide_MG class(Nuclide_MG), intent(in) :: this @@ -125,6 +125,7 @@ module nuclide_header character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle integer, optional, intent(in) :: i_azi ! Azimuthal Index integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs @@ -535,13 +536,14 @@ module nuclide_header ! NUCLIDE_*_GET_XS Returns the requested data type !=============================================================================== - function nuclide_iso_get_xs(this, g, xstype, gout, uvw, i_azi, i_pol) & + function nuclide_iso_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) class(Nuclide_Iso), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle integer, optional, intent(in) :: i_azi ! Azimuthal Index integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs @@ -559,6 +561,11 @@ module nuclide_header xs = this % mult(gout,g) case('nu_fission') xs = this % nu_fission(gout,g) + case('f_mu') + xs = evaluate_legendre(this % scatter(gout,g,:), mu) + case('f_mu/mult') + xs = evaluate_legendre(this % scatter(gout,g,:), mu) / & + this % mult(gout,g) end select else select case(xstype) @@ -580,12 +587,13 @@ module nuclide_header end if end function nuclide_iso_get_xs - function nuclide_angle_get_xs(this, g, xstype, gout, uvw, i_azi, i_pol) & + function nuclide_angle_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) class(Nuclide_Angle), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group + real(8), optional, intent(in) :: mu ! Change in angle real(8), optional, intent(in) :: uvw(3) ! Requested Angle integer, optional, intent(in) :: i_azi ! Azimuthal Index integer, optional, intent(in) :: i_pol ! Polar Index @@ -615,6 +623,11 @@ module nuclide_header xs = this % nu_fission(gout,g,i_azi_,i_pol_) case('chi') xs = this % chi(gout,i_azi_,i_pol_) + case('f_mu') + xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) + case('f_mu/mult') + xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) / & + this % mult(gout,g,i_azi_,i_pol_) end select else select case(xstype) diff --git a/src/tally.F90 b/src/tally.F90 index 3a258c9d3d..ed7165e1cd 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -5,7 +5,7 @@ module tally use error, only: fatal_error use geometry_header use global - use math, only: t_percentile, calc_pn, calc_rn + use math, only: t_percentile, calc_pn, calc_rn, evaluate_legendre use mesh, only: get_mesh_bin, bin_to_mesh_indices, & get_mesh_indices, mesh_indices_to_bin, & mesh_intersects_2d, mesh_intersects_3d @@ -25,17 +25,59 @@ module tally implicit none integer :: position(N_FILTER_TYPES - 3) = 0 ! Tally map positioning array + + procedure(score_general_intfc), pointer :: score_general => null() + procedure(get_scoring_bins_intfc), pointer :: get_scoring_bins => null() + + abstract interface + subroutine score_general_intfc(p, t, start_index, filter_index, i_nuclide, & + atom_density, flux) + import Particle + import TallyObject + type(Particle), intent(in) :: p + type(TallyObject), pointer, intent(inout) :: t + integer, intent(in) :: start_index + integer, intent(in) :: i_nuclide + integer, intent(in) :: filter_index ! for % results + real(8), intent(in) :: flux ! flux estimate + real(8), intent(in) :: atom_density ! atom/b-cm + end subroutine score_general_intfc + + subroutine get_scoring_bins_intfc(p, i_tally, found_bin) + import Particle + type(Particle), intent(in) :: p + integer, intent(in) :: i_tally + logical, intent(out) :: found_bin + end subroutine get_scoring_bins_intfc + + end interface + !$omp threadprivate(position) contains !=============================================================================== -! SCORE_GENERAL adds scores to the tally array for the given filter and nuclide. -! This will work for either analog or tracklength tallies. Note that +! INIT_TALLY_ROUTINES Sets the procedure pointers needed for minimizing code +! with the CE and MG modes. +!=============================================================================== + + subroutine init_tally_routines() + if (run_CE) then + score_general => score_general_ce + get_scoring_bins => get_scoring_bins_ce + else + score_general => score_general_mg + get_scoring_bins => get_scoring_bins_mg + end if + end subroutine init_tally_routines + +!=============================================================================== +! SCORE_GENERAL* adds scores to the tally array for the given filter and +! nuclide. This will work for either analog or tracklength tallies. Note that ! atom_density and flux are not used for analog tallies. !=============================================================================== - subroutine score_general(p, t, start_index, filter_index, i_nuclide, & + subroutine score_general_ce(p, t, start_index, filter_index, i_nuclide, & atom_density, flux) type(Particle), intent(in) :: p type(TallyObject), pointer, intent(inout) :: t @@ -48,8 +90,6 @@ contains integer :: i ! loop index for scoring bins integer :: l ! loop index for nuclides in material integer :: m ! loop index for reactions - integer :: n ! loop index for legendre order - integer :: num_nm ! Number of N,M orders in harmonic integer :: q ! loop index for scoring bins integer :: i_nuc ! index in nuclides array (from material) integer :: i_energy ! index in nuclide energy grid @@ -64,7 +104,6 @@ contains real(8) :: score ! analog tally score real(8) :: macro_total ! material macro total xs real(8) :: macro_scatt ! material macro scatt xs - real(8) :: uvw(3) ! particle direction type(Material), pointer :: mat type(Reaction), pointer :: rxn type(Nuclide_CE), pointer :: nuc @@ -201,43 +240,29 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (run_CE) then - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt - else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity - end if - end if + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - if (i_nuclide > 0) then - score = p % last_wgt * & - nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt else - score = p % last_wgt * & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity end if end if @@ -252,43 +277,29 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (run_CE) then - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt - else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity - end if - end if + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - if (i_nuclide > 0) then - score = p % last_wgt * & - nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt else - score = p % last_wgt * & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity end if end if @@ -303,43 +314,29 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - if (run_CE) then - if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & - (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. - score = p % last_wgt - else - do m = 1, nuclides(p % event_nuclide) % n_reaction - ! Check if this is the desired MT - if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then - ! Found the reaction, set our pointer and move on with life - rxn => nuclides(p % event_nuclide) % reactions(m) - exit - end if - end do - - ! Get multiplicity and apply to score - if (rxn % multiplicity_with_E) then - ! Then the multiplicity was already incorporated in to p % wgt - ! per the scattering routine, - score = p % wgt - else - ! Grab the multiplicity from the rxn - score = p % last_wgt * rxn % multiplicity - end if - end if + if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & + (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then + ! Don't waste time on very common reactions we know have multiplicities + ! of one. + score = p % last_wgt else - if (i_nuclide > 0) then - score = p % last_wgt * & - nuclides_MG(p % event_nuclide) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + do m = 1, nuclides(p % event_nuclide) % n_reaction + ! Check if this is the desired MT + if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then + ! Found the reaction, set our pointer and move on with life + rxn => nuclides(p % event_nuclide) % reactions(m) + exit + end if + end do + + ! Get multiplicity and apply to score + if (rxn % multiplicity_with_E) then + ! Then the multiplicity was already incorporated in to p % wgt + ! per the scattering routine, + score = p % wgt else - score = p % last_wgt * & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % coord(1) % uvw) + ! Grab the multiplicity from the rxn + score = p % last_wgt * rxn % multiplicity end if end if @@ -431,7 +428,7 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout(p, t, score_index) + call score_fission_eout_ce(p, t, score_index) cycle SCORE_LOOP end if end if @@ -776,10 +773,430 @@ contains !######################################################################### ! Expand score if necessary and add to tally results. + call expand_and_score(p, t, score_index, filter_index, score_bin, & + score, i) + + end do SCORE_LOOP + end subroutine score_general_ce + + subroutine score_general_mg(p, t, start_index, filter_index, i_nuclide, & + atom_density, flux) + type(Particle), intent(in) :: p + type(TallyObject), pointer, intent(inout) :: t + integer, intent(in) :: start_index + integer, intent(in) :: i_nuclide + integer, intent(in) :: filter_index ! for % results + real(8), intent(in) :: flux ! flux estimate + real(8), intent(in) :: atom_density ! atom/b-cm + + integer :: i ! loop index for scoring bins + integer :: q ! loop index for scoring bins + integer :: score_bin ! scoring bin, e.g. SCORE_FLUX + integer :: score_index ! scoring bin index + real(8) :: score ! analog tally score + real(8) :: macro_total ! material macro total xs + real(8) :: macro_scatt ! material macro scatt xs + real(8) :: micro_abs ! nuclidic microscopic abs + class(Nuclide_MG), pointer :: nuc + + nuc => nuclides_MG(i_nuclide) % obj + + i = 0 + SCORE_LOOP: do q = 1, t % n_user_score_bins + i = i + 1 + + ! determine what type of score bin + score_bin = t % score_bins(i) + + ! determine scoring bin index + score_index = start_index + i + + !######################################################################### + ! Determine appropirate scoring value. select case(score_bin) + case (SCORE_FLUX, SCORE_FLUX_YN) + if (t % estimator == ESTIMATOR_ANALOG) then + ! All events score to a flux bin. We actually use a collision + ! estimator in place of an analog one since there is no way to count + ! 'events' exactly for the flux + if (survival_biasing) then + ! We need to account for the fact that some weight was already + ! absorbed + score = p % last_wgt + p % absorb_wgt + else + score = p % last_wgt + end if + score = score / material_xs % total + + else + ! For flux, we need no cross section + score = flux + end if + + + case (SCORE_TOTAL, SCORE_TOTAL_YN) + if (t % estimator == ESTIMATOR_ANALOG) then + ! All events will score to the total reaction rate. We can just + ! use the weight of the particle entering the collision as the + ! score + if (survival_biasing) then + ! We need to account for the fact that some weight was already + ! absorbed + score = p % last_wgt + p % absorb_wgt + else + score = p % last_wgt + end if + + else + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'total', UVW=p % coord(i) % uvw) * & + atom_density * flux + else + score = material_xs % total * flux + end if + end if + + + case (SCORE_INVERSE_VELOCITY) + if (t % estimator == ESTIMATOR_ANALOG) then + ! All events score to an inverse velocity bin. We actually use a + ! collision estimator in place of an analog one since there is no way + ! to count 'events' exactly for the inverse velocity + if (survival_biasing) then + ! We need to account for the fact that some weight was already + ! absorbed + score = p % last_wgt + p % absorb_wgt + else + score = p % last_wgt + end if + score = score / material_xs % total & + / (sqrt(TWO * p % E / (MASS_NEUTRON_MEV)) * C_LIGHT) + + else + ! For inverse velocity, we need no cross section + score = flux / (sqrt(TWO * p % E / (MASS_NEUTRON_MEV)) * C_LIGHT) + end if + + + case (SCORE_SCATTER, SCORE_SCATTER_N) + if (t % estimator == ESTIMATOR_ANALOG) then + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP + ! Since only scattering events make it here, again we can use + ! the weight entering the collision as the estimator for the + ! reaction rate + score = p % last_wgt + + else + ! Note SCORE_SCATTER_N not available for tracklength/collision. + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'scatter', UVW=p % coord(i) % uvw) * & + atom_density * flux + else + ! Get the scattering x/s (stored in % elastic) + score = material_xs % elastic * flux + end if + end if + + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & + p % last_uvw, p % mu) + else + score = score / & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % last_uvw) + end if + + + case (SCORE_SCATTER_PN) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) then + i = i + t % moment_order(i) + cycle SCORE_LOOP + end if + ! Since only scattering events make it here, again we can use + ! the weight entering the collision as the estimator for the + ! reaction rate + score = p % last_wgt + + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & + p % last_uvw, p % mu) + else + score = score / & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % last_uvw) + end if + + + case (SCORE_SCATTER_YN) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) then + i = i + (t % moment_order(i) + 1)**2 - 1 + cycle SCORE_LOOP + end if + ! Since only scattering events make it here, again we can use + ! the weight entering the collision as the estimator for the + ! reaction rate + score = p % last_wgt + + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & + p % last_uvw, p % mu) + else + score = score / & + macro_xs(p % material) % obj % get_xs(p % g, 'mult', & + p % last_g, & + p % last_uvw) + end if + + + case (SCORE_NU_SCATTER, SCORE_NU_SCATTER_N) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP + ! For scattering production, we need to use the pre-collision + ! weight times the multiplicity as the estimate for the number of + ! neutrons exiting a reaction with neutrons in the exit channel + score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + p % last_uvw, p % mu) + + + case (SCORE_NU_SCATTER_PN) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) then + i = i + t % moment_order(i) + cycle SCORE_LOOP + end if + ! For scattering production, we need to use the pre-collision + ! weight times the multiplicity as the estimate for the number of + ! neutrons exiting a reaction with neutrons in the exit channel + score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + p % last_uvw, p % mu) + + + case (SCORE_NU_SCATTER_YN) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) then + i = i + (t % moment_order(i) + 1)**2 - 1 + cycle SCORE_LOOP + end if + ! For scattering production, we need to use the pre-collision + ! weight times the multiplicity as the estimate for the number of + ! neutrons exiting a reaction with neutrons in the exit channel + score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + p % last_uvw, p % mu) + + + case (SCORE_TRANSPORT) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP + ! get material macros + macro_total = material_xs % total + macro_scatt = material_xs % elastic + ! Score total rate - p1 scatter rate Note estimator needs to be + ! adjusted since tallying is only occuring when a scatter has + ! happened. Effectively this means multiplying the estimator by + ! total/scatter macro + score = (macro_total - p % mu * macro_scatt) * (ONE / macro_scatt) + + + case (SCORE_N_1N) + ! Only analog estimators are available. + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP + ! Skip any events where weight of particle changed + if (p % wgt /= p % last_wgt) cycle SCORE_LOOP + ! All events that reach this point are (n,1n) reactions + score = p % last_wgt + + + case (SCORE_ABSORPTION) + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing) then + ! No absorption events actually occur if survival biasing is on -- + ! just use weight absorbed in survival biasing + score = p % absorb_wgt + else + ! Skip any event where the particle wasn't absorbed + if (p % event == EVENT_SCATTER) cycle SCORE_LOOP + ! All fission and absorption events will contribute here, so we + ! can just use the particle's weight entering the collision + score = p % last_wgt + end if + + else + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) & + * atom_density * flux + else + score = material_xs % absorption * flux + end if + end if + + + case (SCORE_FISSION) + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! fission + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + if (micro_abs > ZERO) then + score = p % absorb_wgt * & + nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) & + / micro_abs + else + score = ZERO + end if + else + ! Skip any non-absorption events + if (p % event == EVENT_SCATTER) cycle SCORE_LOOP + ! All fission events will contribute, so again we can use + ! particle's weight entering the collision as the estimate for the + ! fission reaction rate + score = p % last_wgt & + * nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) & + / nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + end if + + else + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) * & + atom_density * flux + else + score = material_xs % fission * flux + end if + end if + + + case (SCORE_NU_FISSION) + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing .or. p % fission) then + if (t % find_filter(FILTER_ENERGYOUT) > 0) then + ! Normally, we only need to make contributions to one scoring + ! bin. However, in the case of fission, since multiple fission + ! neutrons were emitted with different energies, multiple + ! outgoing energy bins may have been scored to. The following + ! logic treats this special case and results to multiple bins + call score_fission_eout_mg(p, t, score_index) + cycle SCORE_LOOP + end if + end if + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! nu-fission + if (micro_xs(p % event_nuclide) % absorption > ZERO) then + score = p % absorb_wgt * & + nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) / & + nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + else + score = ZERO + end if + else + ! Skip any non-fission events + if (.not. p % fission) cycle SCORE_LOOP + ! If there is no outgoing energy filter, than we only need to + ! score to one bin. For the score to be 'analog', we need to + ! score the number of particles that were banked in the fission + ! bank. Since this was weighted by 1/keff, we multiply by keff + ! to get the proper score. + score = keff * p % wgt_bank + end if + + else + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(1) % uvw) & + * atom_density * flux + else + score = material_xs % nu_fission * flux + end if + end if + + + case (SCORE_KAPPA_FISSION) + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! fission scale by kappa-fission + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + if (micro_abs > ZERO) then + score = p % absorb_wgt * & + nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / & + micro_abs + else + score = ZERO + end if + else + ! Skip any non-absorption events + if (p % event == EVENT_SCATTER) cycle SCORE_LOOP + ! All fission events will contribute, so again we can use + ! particle's weight entering the collision as the estimate for + ! the fission energy production rate + score = p % last_wgt * & + nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / & + nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + end if + + else + if (i_nuclide > 0) then + score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) & + * atom_density * flux + else + score = material_xs % kappa_fission * flux + end if + end if + + + case (SCORE_EVENTS) + ! Simply count number of scoring events + score = ONE + + end select + + !######################################################################### + ! Expand score if necessary and add to tally results. + call expand_and_score(p, t, score_index, filter_index, score_bin, & + score, i) + + end do SCORE_LOOP + end subroutine score_general_mg + +!=============================================================================== +! EXPAND_AND_SCORE takes a previously determined score value and adjusts it +! if necessary (for functional expansion weighting), and then adds the resultant +! value to the tally results array. +!=============================================================================== + + subroutine expand_and_score(p, t, score_index, filter_index, score_bin, & + score, i) + type(Particle), intent(in) :: p + type(TallyObject), pointer, intent(inout) :: t + integer, intent(inout) :: score_index + integer, intent(in) :: filter_index ! for % results + integer, intent(in) :: score_bin ! score of concern + real(8), intent(inout) :: score ! data to score + integer, intent(inout) :: i ! Working index + + integer :: num_nm ! Number of N,M orders in harmonic + integer :: n ! Moment loop index + real(8) :: uvw(3) + + select case(score_bin) + + case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N) ! Find the scattering order for a singly requested moment, and ! store its moment contribution. @@ -869,8 +1286,8 @@ contains end select - end do SCORE_LOOP - end subroutine score_general + + end subroutine expand_and_score !=============================================================================== ! SCORE_ALL_NUCLIDES tallies individual nuclide reaction rates specifically when @@ -1039,7 +1456,7 @@ contains ! neutrons produced with different energies. !=============================================================================== - subroutine score_fission_eout(p, t, i_score) + subroutine score_fission_eout_ce(p, t, i_score) type(Particle), intent(in) :: p type(TallyObject), pointer :: t @@ -1092,7 +1509,58 @@ contains ! reset outgoing energy bin and score index matching_bins(i) = bin_energyout - end subroutine score_fission_eout + end subroutine score_fission_eout_ce + + subroutine score_fission_eout_mg(p, t, i_score) + + type(Particle), intent(in) :: p + type(TallyObject), pointer :: t + integer, intent(in) :: i_score ! index for score + + integer :: i ! index of outgoing energy filter + integer :: n ! number of energies on filter + integer :: k ! loop index for bank sites + integer :: bin_energyout ! original outgoing energy bin + integer :: i_filter ! index for matching filter bin combination + real(8) :: score ! actual score + integer :: gout ! energy group of fission bank site + + ! save original outgoing energy bin and score index + i = t % find_filter(FILTER_ENERGYOUT) + bin_energyout = matching_bins(i) + + ! Get number of energies on filter + n = size(t % filters(i) % int_bins) + + ! Since the creation of fission sites is weighted such that it is + ! expected to create n_particles sites, we need to multiply the + ! score by keff to get the true nu-fission rate. Otherwise, the sum + ! of all nu-fission rates would be ~1.0. + + ! loop over number of particles banked + do k = 1, p % n_bank + ! determine score based on bank site weight and keff + score = keff * fission_bank(n_bank - p % n_bank + k) % wgt + + ! determine outgoing energy from fission bank + gout = fission_bank(n_bank - p % n_bank + k) % g + + ! change outgoing energy bin + matching_bins(i) = gout + + ! determine scoring index + i_filter = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 + + ! Add score to tally +!$omp atomic + t % results(i_score, i_filter) % value = & + t % results(i_score, i_filter) % value + score + end do + + ! reset outgoing energy bin and score index + matching_bins(i) = bin_energyout + + end subroutine score_fission_eout_mg !=============================================================================== ! SCORE_FISSION_DELAYED_EOUT handles a special case where we need to store @@ -1734,7 +2202,7 @@ contains ! for a tally based on the particle's current attributes. !=============================================================================== - subroutine get_scoring_bins(p, i_tally, found_bin) + subroutine get_scoring_bins_ce(p, i_tally, found_bin) type(Particle), intent(in) :: p integer, intent(in) :: i_tally @@ -1937,7 +2405,192 @@ contains end do FILTER_LOOP - end subroutine get_scoring_bins + end subroutine get_scoring_bins_ce + + subroutine get_scoring_bins_mg(p, i_tally, found_bin) + + type(Particle), intent(in) :: p + integer, intent(in) :: i_tally + logical, intent(out) :: found_bin + + integer :: i ! loop index for filters + integer :: j + integer :: n ! number of bins for single filter + integer :: offset ! offset for distribcell + integer :: g ! particle energy group + real(8) :: theta, phi ! Polar and Azimuthal Angles, respectively + type(TallyObject), pointer :: t + type(RegularMesh), pointer :: m + + found_bin = .true. + t => tallies(i_tally) + matching_bins(1:t%n_filters) = 1 + + FILTER_LOOP: do i = 1, t % n_filters + + select case (t % filters(i) % type) + case (FILTER_MESH) + ! determine mesh bin + m => meshes(t % filters(i) % int_bins(1)) + + ! Determine if we're in the mesh first + call get_mesh_bin(m, p % coord(1) % xyz, matching_bins(i)) + + case (FILTER_UNIVERSE) + ! determine next universe bin + ! TODO: Account for multiple universes when performing this filter + matching_bins(i) = get_next_bin(FILTER_UNIVERSE, & + p % coord(p % n_coord) % universe, i_tally) + + case (FILTER_MATERIAL) + if (p % material == MATERIAL_VOID) then + matching_bins(i) = NO_BIN_FOUND + else + matching_bins(i) = get_next_bin(FILTER_MATERIAL, & + p % material, i_tally) + endif + + case (FILTER_CELL) + ! determine next cell bin + do j = 1, p % n_coord + position(FILTER_CELL) = 0 + matching_bins(i) = get_next_bin(FILTER_CELL, & + p % coord(j) % cell, i_tally) + if (matching_bins(i) /= NO_BIN_FOUND) exit + end do + + case (FILTER_DISTRIBCELL) + ! determine next distribcell bin + matching_bins(i) = NO_BIN_FOUND + offset = 0 + do j = 1, p % n_coord + if (cells(p % coord(j) % cell) % type == CELL_FILL) then + offset = offset + cells(p % coord(j) % cell) % & + offset(t % filters(i) % offset) + elseif(cells(p % coord(j) % cell) % type == CELL_LATTICE) then + if (lattices(p % coord(j + 1) % lattice) % obj & + % are_valid_indices([& + p % coord(j + 1) % lattice_x, & + p % coord(j + 1) % lattice_y, & + p % coord(j + 1) % lattice_z])) then + offset = offset + lattices(p % coord(j + 1) % lattice) % obj % & + offset(t % filters(i) % offset, & + p % coord(j + 1) % lattice_x, & + p % coord(j + 1) % lattice_y, & + p % coord(j + 1) % lattice_z) + end if + end if + if (t % filters(i) % int_bins(1) == p % coord(j) % cell) then + matching_bins(i) = offset + 1 + exit + end if + end do + + case (FILTER_CELLBORN) + ! determine next cellborn bin + matching_bins(i) = get_next_bin(FILTER_CELLBORN, & + p % cell_born, i_tally) + + case (FILTER_SURFACE) + ! determine next surface bin + matching_bins(i) = get_next_bin(FILTER_SURFACE, & + p % surface, i_tally) + + case (FILTER_ENERGYIN) + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + g = p % g + else + g = p % last_g + end if + + ! Since all groups are filters, the filter bin is the group + matching_bins(i) = g + + case (FILTER_ENERGYOUT) + ! Since all groups are filters, the filter bin is the group + matching_bins(i) = p % g + + case (FILTER_DELAYEDGROUP) + + if (survival_biasing .and. t % find_filter(FILTER_ENERGYOUT) <= 0) then + matching_bins(i) = 1 + elseif (active_tracklength_tallies % size() > 0) then + matching_bins(i) = 1 + else + if (p % delayed_group == 0) then + matching_bins = NO_BIN_FOUND + else + matching_bins(i) = p % delayed_group + end if + end if + + case (FILTER_MU) + ! determine mu bin + n = t % filters(i) % n_bins + + ! check if particle is within mu bins + if (p % mu < t % filters(i) % real_bins(1) .or. & + p % mu > t % filters(i) % real_bins(n + 1)) then + matching_bins(i) = NO_BIN_FOUND + else + ! search to find mu bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, & + n + 1, p % mu) + end if + + case (FILTER_POLAR) + ! make sure the correct direction vector is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + theta = acos(p % coord(1) % uvw(3)) + else + theta = acos(p % last_uvw(3)) + end if + + ! determine polar angle bin + n = t % filters(i) % n_bins + + ! check if particle is within polar angle bins + if (theta < t % filters(i) % real_bins(1) .or. & + theta > t % filters(i) % real_bins(n + 1)) then + matching_bins(i) = NO_BIN_FOUND + else + ! search to find polar angle bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, & + n + 1, theta) + end if + + case (FILTER_AZIMUTHAL) + ! make sure the correct direction vector is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + phi = atan2(p % coord(1) % uvw(2), p % coord(1) % uvw(1)) + else + phi = atan2(p % last_uvw(2), p % last_uvw(1)) + end if + ! determine mu bin + n = t % filters(i) % n_bins + + ! check if particle is within azimuthal angle bins + if (phi < t % filters(i) % real_bins(1) .or. & + phi > t % filters(i) % real_bins(n + 1)) then + matching_bins(i) = NO_BIN_FOUND + else + ! search to find azimuthal angle bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, & + n + 1, phi) + end if + + end select + + ! If the current filter didn't match, exit this subroutine + if (matching_bins(i) == NO_BIN_FOUND) then + found_bin = .false. + return + end if + + end do FILTER_LOOP + + end subroutine get_scoring_bins_mg !=============================================================================== ! SCORE_SURFACE_CURRENT tallies surface crossings in a mesh tally by manually diff --git a/src/tracking.F90 b/src/tracking.F90 index c761cd5337..028ec3ee6c 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -91,10 +91,8 @@ contains else ! Since the MGXS can be angle dependent, this needs to be done ! After every collision for the MGXS mode - call calculate_mgxs(macro_xs(p % material) % obj, & - materials(p % material), nuclides_MG, p % g, & - p % coord(p % n_coord) % uvw, material_xs, & - micro_xs) + call calculate_mgxs(macro_xs(p % material) % obj, p % g, & + p % coord(p % n_coord) % uvw, material_xs) end if ! Find the distance to the nearest boundary From d32556fe89ccd79d954a144d4f2ff426a443c9eb Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 5 Nov 2015 04:47:51 -0500 Subject: [PATCH 19/84] Added support of tallying scatter-*n info with histogram based input. --- src/nuclide_header.F90 | 64 +++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 3e320ab273..9d79bbe22d 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -548,6 +548,9 @@ module nuclide_header integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs + integer :: imu + real(8) :: dmu, r, f + xs = ZERO if ((xstype == 'nu_fission' .or. xstype == 'fission' .or. xstype =='chi' & @@ -561,11 +564,31 @@ module nuclide_header xs = this % mult(gout,g) case('nu_fission') xs = this % nu_fission(gout,g) - case('f_mu') - xs = evaluate_legendre(this % scatter(gout,g,:), mu) - case('f_mu/mult') - xs = evaluate_legendre(this % scatter(gout,g,:), mu) / & - this % mult(gout,g) + case('f_mu', 'f_mu/mult') + if (this % scatt_type == ANGLE_LEGENDRE) then + xs = evaluate_legendre(this % scatter(gout,g,:), mu) + else + dmu = TWO / real(this % order) + ! Find mu bin algebraically, knowing that the spacing is equal + f = (mu + ONE) / dmu + ONE + imu = floor(f) + ! But save the amount that mu is past the previous index + ! so we can use interpolation later. + f = f - real(imu) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + + ! Now intepolate to find f(mu) + r = f / dmu + xs = (ONE - r) * this % scatter(gout, g, imu) + & + r * this % scatter(gout, g, imu+1) + end if + if (xstype == 'f_mu/mult') then + xs = xs / this % mult(gout,g) + end if + end select else select case(xstype) @@ -600,6 +623,8 @@ module nuclide_header real(8) :: xs ! Resultant xs integer :: i_azi_, i_pol_ + integer :: imu + real(8) :: dmu, r, f xs = ZERO @@ -623,11 +648,30 @@ module nuclide_header xs = this % nu_fission(gout,g,i_azi_,i_pol_) case('chi') xs = this % chi(gout,i_azi_,i_pol_) - case('f_mu') - xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) - case('f_mu/mult') - xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) / & - this % mult(gout,g,i_azi_,i_pol_) + case('f_mu', 'f_mu/mult') + if (this % scatt_type == ANGLE_LEGENDRE) then + xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) + else + dmu = TWO / real(this % order) + ! Find mu bin algebraically, knowing that the spacing is equal + f = (mu + ONE) / dmu + ONE + imu = floor(f) + ! But save the amount that mu is past the previous index + ! so we can use interpolation later. + f = f - real(imu) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + + ! Now intepolate to find f(mu) + r = f / dmu + xs = (ONE - r) * this % scatter(gout,g,imu,i_azi_,i_pol_) + & + r * this % scatter(gout,g,imu+1,i_azi_,i_pol_) + end if + if (xstype == 'f_mu/mult') then + xs = xs / this % mult(gout,g,i_azi_,i_pol_) + end if end select else select case(xstype) From 60d418adf07371dcc65d3ba2f671cfcd2c169413 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 5 Nov 2015 05:20:39 -0500 Subject: [PATCH 20/84] Added printing of xs data to mg types and fixed some summary bugs --- src/mgxs_data.F90 | 12 +++-- src/nuclide_header.F90 | 99 ++++++++++++++++++++++++++++++++++++++++++ src/output.F90 | 31 +++++++------ src/summary.F90 | 6 ++- src/tally.F90 | 3 +- 5 files changed, 126 insertions(+), 25 deletions(-) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index d51dfd603e..39abff1b23 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -31,7 +31,6 @@ contains character(12) :: alias ! alias of isotope, e.g. U-235.03c integer :: representation ! Data representation type(Material), pointer :: mat - class(Nuclide_MG), pointer :: nuc type(SetChar) :: already_read type(Node), pointer :: doc => null() type(Node), pointer :: node_xsdata @@ -94,9 +93,6 @@ contains name = xs_listings(i_listing) % name alias = xs_listings(i_listing) % alias - ! Keep track of what listing is associated with this nuclide - nuc => nuclides_MG(i_nuclide) % obj - ! Get pointer to xsdata table XML node call get_list_item(node_xsdata_list, i_listing, node_xsdata) @@ -131,6 +127,9 @@ contains energy_groups, get_kfiss, error_code, & error_text) + ! Keep track of what listing is associated with this nuclide + nuclides_MG(i_nuclide) % obj % listing = i_listing + ! Handle any errors if (error_code /= 0) then call fatal_error(trim(error_text)) @@ -154,9 +153,8 @@ contains ! Loop around nuclides in material NUCLIDE_LOOP2: do j = 1, mat % n_nuclides - ! Get nuclide - nuc => nuclides_MG(mat % nuclide(j)) % obj - if (nuc % fissionable) then + ! Is this fissionable? + if (nuclides_MG(mat % nuclide(j)) % obj % fissionable) then mat % fissionable = .true. end if if (mat % fissionable) then diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 9d79bbe22d..910b2ecf39 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -516,11 +516,74 @@ module nuclide_header end subroutine nuclide_ce_print + subroutine nuclide_mg_print(this, unit_) + class(Nuclide_MG), intent(in) :: this + integer, intent(in) :: unit_ + + character(MAX_LINE_LEN) :: temp_str + + ! Basic nuclide information + write(unit_,*) 'Nuclide ' // trim(this % name) + write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + if (this % scatt_type == ANGLE_LEGENDRE) then + temp_str = "Legendre" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + write(unit_,*) ' # of Scatter Moments = ' // & + trim(to_str(this % order - 1)) + else if (this % scatt_type == ANGLE_HISTOGRAM) then + temp_str = "Histogram" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + write(unit_,*) ' # of Scatter Bins = ' // & + trim(to_str(this % order)) + else if (this % scatt_type == ANGLE_TABULAR) then + temp_str = "Tabular" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + write(unit_,*) ' # of Scatter Points = ' // trim(to_str(this % order)) + end if + write(unit_,*) ' Fissionable = ', this % fissionable + + end subroutine nuclide_mg_print + subroutine nuclide_iso_print(this, unit) class(Nuclide_Iso), intent(in) :: this integer, optional, intent(in) :: unit + integer :: unit_ ! unit to write to + integer :: size_total, size_scattmat, size_mgxs + character(MAX_LINE_LEN) :: temp_str + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Write Basic Nuclide Information + call nuclide_mg_print(this, unit_) + + ! Determine size of mgxs and scattering matrices + size_scattmat = (size(this % scatter) + size(this % mult)) * 8 + size_mgxs = size(this % total) + size(this % absorption) + & + size(this % nu_fission) + size(this % k_fission) + & + size(this % fission) + size(this % chi) + size_mgxs = size_mgxs * 8 + + ! Calculate total memory + size_total = size_scattmat + size_mgxs + + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' + write(unit_,*) ' Scattering Matrices = ' // & + trim(to_str(size_scattmat)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' + + ! Blank line at end of nuclide + write(unit_,*) end subroutine nuclide_iso_print @@ -529,6 +592,42 @@ module nuclide_header class(Nuclide_Angle), intent(in) :: this integer, optional, intent(in) :: unit + integer :: unit_ ! unit to write to + integer :: size_total, size_scattmat, size_mgxs + character(MAX_LINE_LEN) :: temp_str + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Write Basic Nuclide Information + call nuclide_mg_print(this, unit_) + write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % Npol)) + write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % Nazi)) + + ! Determine size of mgxs and scattering matrices + size_scattmat = (size(this % scatter) + size(this % mult)) * 8 + size_mgxs = size(this % total) + size(this % absorption) + & + size(this % nu_fission) + size(this % k_fission) + & + size(this % fission) + size(this % chi) + size_mgxs = size_mgxs * 8 + + ! Calculate total memory + size_total = size_scattmat + size_mgxs + + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' + write(unit_,*) ' Scattering Matrices = ' // & + trim(to_str(size_scattmat)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' + + ! Blank line at end of nuclide + write(unit_,*) + end subroutine nuclide_angle_print diff --git a/src/output.F90 b/src/output.F90 index 30039e1181..8076a91dfc 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -332,8 +332,6 @@ contains integer :: i ! loop index integer :: unit_xs ! cross_sections.out file unit character(MAX_FILE_LEN) :: path ! path of summary file - type(Nuclide_CE), pointer :: nuc => null() - type(SAlphaBeta), pointer :: sab => null() ! Create filename for log file path = trim(path_output) // "cross_sections.out" @@ -344,21 +342,22 @@ contains ! Write header call header("CROSS SECTION TABLES", unit=unit_xs) - NUCLIDE_LOOP: do i = 1, n_nuclides_total - ! Get pointer to nuclide - nuc => nuclides(i) + if (run_CE) then + NUCLIDE_LOOP: do i = 1, n_nuclides_total + ! Print information about nuclide + call nuclides(i) % print(unit=unit_xs) + end do NUCLIDE_LOOP - ! Print information about nuclide - call nuc % print(unit=unit_xs) - end do NUCLIDE_LOOP - - SAB_TABLES_LOOP: do i = 1, n_sab_tables - ! Get pointer to S(a,b) table - sab => sab_tables(i) - - ! Print information about S(a,b) table - call sab % print(unit=unit_xs) - end do SAB_TABLES_LOOP + SAB_TABLES_LOOP: do i = 1, n_sab_tables + ! Print information about S(a,b) table + call sab_tables(i) % print(unit=unit_xs) + end do SAB_TABLES_LOOP + else + NUCLIDE_MG_LOOP: do i = 1, n_nuclides_total + ! Print information about nuclide + call nuclides_mg(i) % obj % print(unit=unit_xs) + end do NUCLIDE_MG_LOOP + end if ! Close cross section summary file close(unit_xs) diff --git a/src/summary.F90 b/src/summary.F90 index 1b0797fc9b..078099dbd0 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -454,7 +454,11 @@ contains ! Copy ZAID for each nuclide to temporary array allocate(nucnames(m%n_nuclides)) do j = 1, m%n_nuclides - i_list = nuclides(m%nuclide(j))%listing + if (run_CE) then + i_list = nuclides(m%nuclide(j))%listing + else + i_list = nuclides_MG(m%nuclide(j))%obj%listing + end if nucnames(j) = xs_listings(i_list)%alias end do diff --git a/src/tally.F90 b/src/tally.F90 index ed7165e1cd..7ad701b168 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -799,7 +799,8 @@ contains real(8) :: micro_abs ! nuclidic microscopic abs class(Nuclide_MG), pointer :: nuc - nuc => nuclides_MG(i_nuclide) % obj + if (i_nuclide > 0) & + nuc => nuclides_MG(i_nuclide) % obj i = 0 SCORE_LOOP: do q = 1, t % n_user_score_bins From fdf0f78258f13f15f19e150e79b2868fa83b19e4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 5 Nov 2015 06:49:09 -0500 Subject: [PATCH 21/84] Added in data like zaid and name to the mg nuclide itself --- src/mgxs_data.F90 | 11 ++++++----- src/nuclide_header.F90 | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 39abff1b23..086bc6b95d 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -1,9 +1,8 @@ module mgxs_data use constants - use error, only: fatal_error, warning + use error, only: fatal_error use global - use list_header, only: ListInt use macroxs_header use material_header, only: Material use nuclide_header @@ -208,10 +207,12 @@ contains error_text = '' ! Load the data - if (check_for_node(node_xsdata, "awr")) then - call get_node_value(node_xsdata, "awr", this % awr) + call get_node_value(node_xsdata, "name", this % name) + this % name = to_lower(this % name) + if (check_for_node(node_xsdata, "kT")) then + call get_node_value(node_xsdata, "kT", this % kT) else - this % awr = ONE + this % kT = ZERO end if if (check_for_node(node_xsdata, "zaid")) then call get_node_value(node_xsdata, "zaid", this % zaid) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 910b2ecf39..e8c8eb13f5 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -524,8 +524,10 @@ module nuclide_header ! Basic nuclide information write(unit_,*) 'Nuclide ' // trim(this % name) - write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) - write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + if (this % zaid > 0) then + ! Dont print if data was macroscopic and thus zaid would be nonsense + write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + end if write(unit_,*) ' kT = ' // trim(to_str(this % kT)) if (this % scatt_type == ANGLE_LEGENDRE) then temp_str = "Legendre" From d26546001a50a8a6c05d49e6bf7998fd13be61d5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 6 Nov 2015 05:29:27 -0500 Subject: [PATCH 22/84] Added tabular nuclide data inputting capability, revised legendre_mu_points input format, and added calc_f routine to nuclide_mg types --- src/global.F90 | 5 +- src/input_xml.F90 | 16 +--- src/macroxs_header.F90 | 86 +---------------- src/mgxs_data.F90 | 54 +++++++++-- src/nuclide_header.F90 | 193 ++++++++++++++++++++++++++++----------- src/physics_mg.F90 | 2 +- src/scattdata_header.F90 | 32 +++---- 7 files changed, 204 insertions(+), 184 deletions(-) diff --git a/src/global.F90 b/src/global.F90 index 737aef51f8..700f43ddc0 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -119,14 +119,11 @@ module global ! Energy group structure real(8), allocatable :: energy_bins(:) - real(8), allocatable :: energy_bin_midpoints(:) + real(8), allocatable :: energy_bin_avg(:) ! Maximum Data Order integer :: max_order - ! Scattering Treatment (if Legendre) - integer :: legendre_mu_points - ! ============================================================================ ! TALLY-RELATED VARIABLES diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 65c840ce25..3cf26b49b6 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4377,23 +4377,11 @@ contains call fatal_error("group_structures element must exist!") end if - allocate(energy_bin_midpoints(energy_groups)) + allocate(energy_bin_avg(energy_groups)) do i = 1, energy_groups - energy_bin_midpoints(i) = 0.5_8 * (energy_bins(i) + energy_bins(i + 1)) + energy_bin_avg(i) = 0.5_8 * (energy_bins(i) + energy_bins(i + 1)) end do - if (check_for_node(doc, "legendre_mu_points")) then - ! Get scattering treatment - call get_node_value(doc, "legendre_mu_points", legendre_mu_points) - if (legendre_mu_points <= 0) then - call fatal_error("legendre_mu_points element must be positive and non-zero!") - end if - legendre_mu_points = -1 * legendre_mu_points - else - ! One means 'don't expand scattering moments to a table, sample via legendre' - legendre_mu_points = 1 - end if - ! Get node list of all call get_node_list(doc, "xsdata", node_xsdata_list) n_listings = get_list_size(node_xsdata_list) diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index d33de9241f..602db4a3b6 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -22,7 +22,6 @@ module macroxs_header contains procedure(macroxs_init_), deferred, pass :: init ! initializes object procedure(macroxs_clear_), deferred, pass :: clear ! Deallocates object - procedure(macroxs_size_), deferred, pass :: get_size ! Finds size of object procedure(macroxs_get_xs_), deferred, pass :: get_xs ! Return xs end type MacroXS_Base @@ -66,14 +65,6 @@ module macroxs_header end subroutine macroxs_clear_ - subroutine macroxs_size_(this, size_total, size_scatt, size_fission) - import MacroXS_Base - class(MacroXS_Base), intent(in) :: this - integer, intent(out) :: size_total ! Total Data Size - integer, intent(out) :: size_scatt ! Scattering Data Size - integer, intent(out) :: size_fission ! Fission Data Size - - end subroutine macroxs_size_ end interface type, extends(MacroXS_Base) :: MacroXS_Iso @@ -91,7 +82,6 @@ module macroxs_header contains procedure, pass :: init => macroxs_iso_init ! inits object procedure, pass :: clear => macroxs_iso_clear ! Deallocates object - procedure, pass :: get_size => macroxs_iso_size ! Finds size of object procedure, pass :: get_xs => macroxs_iso_get_xs ! Returns xs end type MacroXS_Iso @@ -112,7 +102,6 @@ module macroxs_header contains procedure, pass :: init => macroxs_angle_init ! inits object procedure, pass :: clear => macroxs_angle_clear ! Deallocates object - procedure, pass :: get_size => macroxs_angle_size ! Finds size of object procedure, pass :: get_xs => macroxs_angle_get_xs ! Returns xs end type MacroXS_Angle @@ -194,7 +183,7 @@ contains ! Allocate stuff for later allocate(scatt_coeffs(order, groups, groups)) scatt_coeffs = ZERO - allocate(ScattData_Histogram :: this % scatter) + allocate(ScattData_Tabular :: this % scatter) else if (scatt_type == ANGLE_LEGENDRE) then ! Otherwise find the maximum scattering order @@ -711,79 +700,6 @@ contains end subroutine macroxs_angle_clear -!=============================================================================== -! MACROXS_*_SIZE Finds the size of the data in MacroXS_Base, MacroXS_Iso, -! or MacroXS_Angle -!=============================================================================== - - subroutine macroxs_iso_size(this, size_total, size_scatt, size_fission) - class(MacroXS_Iso), intent(in) :: this - integer, intent(out) :: size_total ! Total Data Size - integer, intent(out) :: size_scatt ! Scattering Data Size - integer, intent(out) :: size_fission ! Fission Data Size - - integer :: groups - - groups = size(this % total, dim=1) - - ! Size Information On Each Reaction - ! Sum up for total, absorption, nu_scatter, nu_fission, fission - size_total = groups * 8 * (1 + 1 + 1 + 1 + 1) - ! Now do k_fission - ! Check k_fission - if (allocated (this % k_fission)) then - size_total = size_total + groups * 8 - end if - - ! Calculate chi data size - size_fission = 0 - if (allocated(this % chi)) then - size_fission = size_fission + 8 * size(this % chi) - end if - - ! Calculate Scatter Data Size - size_scatt = size(this % scatter % energy) - - ! Calculate Total Memory - size_total = size_total + size_fission + size_scatt - - end subroutine macroxs_iso_size - - subroutine macroxs_angle_size(this, size_total, size_scatt, size_fission) - class(MacroXS_Angle), intent(in) :: this - integer, intent(out) :: size_total ! Total Data Size - integer, intent(out) :: size_scatt ! Scattering Data Size - integer, intent(out) :: size_fission ! Fission Data Size - - integer :: groups - integer :: tot_angle - - groups = size(this % total, dim=2) - tot_angle = size(this % total, dim=1) - - ! Size Information On Each Reaction - ! Sum up for total, absorption, nu_scatter, nu_fission, fission - size_total = groups * 8 * (1 + 1 + 1 + 1 + 1) * tot_angle - ! Now do k_fission - ! Check k_fission - if (allocated (this % k_fission)) then - size_total = size_total + groups * 8 * tot_angle - end if - - ! Calculate chi data size - size_fission = 0 - if (allocated(this % chi)) then - size_fission = size_fission + 8 * size(this % chi) - end if - - ! Calculate Scatter Data Size - size_scatt = 0 - - ! Calculate Total Memory - size_total = size_total + size_fission + size_scatt - - end subroutine macroxs_angle_size - !=============================================================================== ! MACROXS_*_GET_XS returns the requested data type !=============================================================================== diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 086bc6b95d..e3ea314d6c 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -200,7 +200,9 @@ contains integer, intent(inout) :: error_code ! Code signifying error character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + type(Node), pointer :: node_legendre_mu character(MAX_LINE_LEN) :: temp_str + logical :: enable_leg_mu ! Initialize error data error_code = 0 @@ -224,8 +226,10 @@ contains temp_str = trim(to_lower(temp_str)) if (temp_str == 'legendre') then this % scatt_type = ANGLE_LEGENDRE - else if (temp_str == 'tabular') then + else if (temp_str == 'histogram') then this % scatt_type = ANGLE_HISTOGRAM + else if (temp_str == 'tabular') then + this % scatt_type = ANGLE_TABULAR else error_code = 1 error_text = "Invalid Scatt Type Option!" @@ -234,6 +238,7 @@ contains else this % scatt_type = ANGLE_LEGENDRE end if + if (check_for_node(node_xsdata, "order")) then call get_node_value(node_xsdata, "order", this % order) else @@ -241,6 +246,37 @@ contains error_text = "Order Must Be Provided!" return end if + + ! Get scattering treatment + if (check_for_node(node_xsdata, "tabular_legendre")) then + call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) + if (check_for_node(node_legendre_mu, "enable")) then + call get_node_value(node_legendre_mu, "enable", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'true' .or. temp_str == '1') then + enable_leg_mu = .true. + elseif (temp_str == 'false' .or. temp_str == '0') then + enable_leg_mu = .false. + else + call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) + end if + else + enable_leg_mu = .false. + this % legendre_mu_points = 1 + end if + if (enable_leg_mu .and. & + check_for_node(node_legendre_mu, "num_points")) then + call get_node_value(node_legendre_mu, "num_points", & + this % legendre_mu_points) + if (this % legendre_mu_points <= 0) then + call fatal_error("num_points element must be positive and non-zero!") + end if + this % legendre_mu_points = -1 * this % legendre_mu_points + end if + else + this % legendre_mu_points = 1 + end if + if (check_for_node(node_xsdata, "fissionable")) then call get_node_value(node_xsdata, "fissionable", temp_str) temp_str = to_lower(temp_str) @@ -349,6 +385,8 @@ contains order_dim = this % order + 1 else if (this % scatt_type == ANGLE_HISTOGRAM) then order_dim = this % order + else if (this % scatt_type == ANGLE_TABULAR) then + order_dim = this % order end if allocate(this % scatter(groups, groups, order_dim)) @@ -410,6 +448,8 @@ contains order_dim = this % order + 1 else if (this % scatt_type == ANGLE_HISTOGRAM) then order_dim = this % order + else if (this % scatt_type == ANGLE_TABULAR) then + order_dim = this % order end if if (check_for_node(node_xsdata, "num_polar")) then @@ -592,6 +632,7 @@ contains character(MAX_LINE_LEN) :: error_text integer :: representation integer :: scatt_type + integer :: legendre_mu_points ! Find out if we need kappa fission (are there any k_fiss tallies?) get_kfiss = .false. @@ -612,23 +653,18 @@ contains mat => materials(i_mat) ! Check to see how our nuclides are represented - ! For now assume all are the same type + ! Assume all are the same type ! Therefore type(nuclides(1) % obj) dictates type(macroxs) ! At the same time, we will find the scattering type, as that will dictate ! how we allocate the scatter object within macroxs - scatt_type = ANGLE_LEGENDRE + legendre_mu_points = nuclides_MG(1) % obj % legendre_mu_points select type(nuc => nuclides_MG(1) % obj) type is (Nuclide_Iso) representation = ISOTROPIC - if (nuc % scatt_type == ANGLE_HISTOGRAM) then - scatt_type = ANGLE_HISTOGRAM - end if type is (Nuclide_Angle) representation = ANGLE - if (nuc % scatt_type == ANGLE_HISTOGRAM) then - scatt_type = ANGLE_HISTOGRAM - end if end select + scatt_type = nuclides_MG(1) % obj % scatt_type ! Now allocate accordingly select case(representation) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index e8c8eb13f5..ad143facb9 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -107,13 +107,16 @@ module nuclide_header type, abstract, extends(Nuclide_Base) :: Nuclide_MG ! Scattering Order Information - integer :: order ! Order of data (Scattering for Nuclide_Iso, - ! Number of angles for all in Nuclide_Angle) - integer :: scatt_type ! either legendre or tabular. - - ! Type-Bound procedures + integer :: order ! Order of data (Scattering for Nuclide_Iso, + ! Number of angles for all in Nuclide_Angle) + integer :: scatt_type ! either legendre, histogram, or tabular. + integer :: legendre_mu_points ! Number of tabular points to use to represent + ! Legendre distribs, -1 if sample with the + ! Legendres themselves +! Type-Bound procedures contains - procedure(nuclide_mg_get_xs_), deferred, pass :: get_xs ! Get the xs + procedure(nuclide_mg_get_xs_), deferred, pass :: get_xs ! Get the xs + procedure(nuclide_calc_f_), deferred, pass :: calc_f ! Calculates f, given mu end type Nuclide_MG abstract interface @@ -130,6 +133,19 @@ module nuclide_header integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs end function nuclide_mg_get_xs_ + + pure function nuclide_calc_f_(this, gin, gout, mu, uvw, i_azi, i_pol) result(f) + import Nuclide_MG + class(Nuclide_MG), intent(in) :: this + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8), intent(in), optional :: uvw(3) ! Direction vector + integer, intent(in), optional :: i_azi ! Incoming Energy Group + integer, intent(in), optional :: i_pol ! Outgoing Energy Group + real(8) :: f ! Return value of f(mu) + + end function nuclide_calc_f_ end interface !=============================================================================== @@ -151,9 +167,10 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclide_iso_clear ! Deallocates Nuclide - procedure, pass :: print => nuclide_iso_print ! Writes nuclide info - procedure, pass :: get_xs => nuclide_iso_get_xs ! Gets Size of Data w/in Object + procedure, pass :: clear => nuclide_iso_clear ! Deallocates Nuclide + procedure, pass :: print => nuclide_iso_print ! Writes nuclide info + procedure, pass :: get_xs => nuclide_iso_get_xs ! Gets Size of Data w/in Object + procedure, pass :: calc_f => nuclide_mg_iso_calc_f ! Calcs f given mu end type Nuclide_Iso !=============================================================================== @@ -181,9 +198,10 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclide_angle_clear ! Deallocates Nuclide - procedure, pass :: print => nuclide_angle_print ! Gets Size of Data w/in Object - procedure, pass :: get_xs => nuclide_angle_get_xs ! Gets Size of Data w/in Object + procedure, pass :: clear => nuclide_angle_clear ! Deallocates Nuclide + procedure, pass :: print => nuclide_angle_print ! Gets Size of Data w/in Object + procedure, pass :: get_xs => nuclide_angle_get_xs ! Gets Size of Data w/in Object + procedure, pass :: calc_f => nuclide_mg_angle_calc_f ! Calcs f given mu end type Nuclide_Angle !=============================================================================== @@ -533,7 +551,7 @@ module nuclide_header temp_str = "Legendre" write(unit_,*) ' Scattering Type = ' // trim(temp_str) write(unit_,*) ' # of Scatter Moments = ' // & - trim(to_str(this % order - 1)) + trim(to_str(this % order)) else if (this % scatt_type == ANGLE_HISTOGRAM) then temp_str = "Histogram" write(unit_,*) ' Scattering Type = ' // trim(temp_str) @@ -666,30 +684,10 @@ module nuclide_header case('nu_fission') xs = this % nu_fission(gout,g) case('f_mu', 'f_mu/mult') - if (this % scatt_type == ANGLE_LEGENDRE) then - xs = evaluate_legendre(this % scatter(gout,g,:), mu) - else - dmu = TWO / real(this % order) - ! Find mu bin algebraically, knowing that the spacing is equal - f = (mu + ONE) / dmu + ONE - imu = floor(f) - ! But save the amount that mu is past the previous index - ! so we can use interpolation later. - f = f - real(imu) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - - ! Now intepolate to find f(mu) - r = f / dmu - xs = (ONE - r) * this % scatter(gout, g, imu) + & - r * this % scatter(gout, g, imu+1) - end if + xs = this % calc_f(g, gout, mu) if (xstype == 'f_mu/mult') then xs = xs / this % mult(gout,g) end if - end select else select case(xstype) @@ -750,26 +748,7 @@ module nuclide_header case('chi') xs = this % chi(gout,i_azi_,i_pol_) case('f_mu', 'f_mu/mult') - if (this % scatt_type == ANGLE_LEGENDRE) then - xs = evaluate_legendre(this % scatter(gout,g,:,i_azi_,i_pol_), mu) - else - dmu = TWO / real(this % order) - ! Find mu bin algebraically, knowing that the spacing is equal - f = (mu + ONE) / dmu + ONE - imu = floor(f) - ! But save the amount that mu is past the previous index - ! so we can use interpolation later. - f = f - real(imu) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - - ! Now intepolate to find f(mu) - r = f / dmu - xs = (ONE - r) * this % scatter(gout,g,imu,i_azi_,i_pol_) + & - r * this % scatter(gout,g,imu+1,i_azi_,i_pol_) - end if + xs = this % calc_f(g, gout, mu, I_AZI=i_azi_, I_POL=i_pol_) if (xstype == 'f_mu/mult') then xs = xs / this % mult(gout,g,i_azi_,i_pol_) end if @@ -796,10 +775,114 @@ module nuclide_header end function nuclide_angle_get_xs !=============================================================================== +! NUCLIDE_*_CALC_F Finds the value of f(mu), the scattering probability, given mu +!=============================================================================== + + pure function nuclide_mg_iso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & + result(f) + class(Nuclide_Iso), intent(in) :: this + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8), intent(in), optional :: uvw(3) ! Direction vector + integer, intent(in), optional :: i_azi ! Incoming Energy Group + integer, intent(in), optional :: i_pol ! Outgoing Energy Group + real(8) :: f ! Return value of f(mu) + + real(8) :: dmu, r + integer :: imu + + if (this % scatt_type == ANGLE_LEGENDRE) then + f = evaluate_legendre(this % scatter(gout,gin,:), mu) + else if (this % scatt_type == ANGLE_TABULAR) then + dmu = TWO / (real(this % order) - 1) + ! Find mu bin algebraically, knowing that the spacing is equal + f = (mu + ONE) / dmu + ONE + imu = floor(f) + ! But save the amount that mu is past the previous index + ! so we can use interpolation later. + f = f - real(imu) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + + ! Now intepolate to find f(mu) + r = f / dmu + f = (ONE - r) * this % scatter(gout,gin,imu) + & + r * this % scatter(gout,gin,imu+1) + else ! (ANGLE_HISTOGRAM) + dmu = TWO / real(this % order) + ! Find mu bin algebraically, knowing that the spacing is equal + imu = floor((mu + ONE) / dmu + ONE) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + f = this % scatter(gout, gin, imu) + + end if + + end function nuclide_mg_iso_calc_f + + pure function nuclide_mg_angle_calc_f(this, gin, gout, mu, uvw, i_azi, & + i_pol) result(f) + class(Nuclide_Angle), intent(in) :: this + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8), intent(in), optional :: uvw(3) ! Direction vector + integer, intent(in), optional :: i_azi ! Incoming Energy Group + integer, intent(in), optional :: i_pol ! Outgoing Energy Group + real(8) :: f ! Return value of f(mu) + + real(8) :: dmu, r + integer :: imu + integer :: i_azi_, i_pol_ + if (present(i_azi) .and. present(i_pol)) then + i_azi_ = i_azi + i_pol_ = i_pol + else if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, i_azi_, i_pol_) + end if + + if (this % scatt_type == ANGLE_LEGENDRE) then + f = evaluate_legendre(this % scatter(gout,gin,:,i_azi_,i_pol_), mu) + else if (this % scatt_type == ANGLE_TABULAR) then + dmu = TWO / (real(this % order) - 1) + ! Find mu bin algebraically, knowing that the spacing is equal + f = (mu + ONE) / dmu + ONE + imu = floor(f) + ! But save the amount that mu is past the previous index + ! so we can use interpolation later. + f = f - real(imu) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + + ! Now intepolate to find f(mu) + r = f / dmu + f = (ONE - r) * this % scatter(gout,gin,imu,i_azi_,i_pol_) + & + r * this % scatter(gout,gin,imu+1,i_azi_,i_pol_) + else ! (ANGLE_HISTOGRAM) + dmu = TWO / real(this % order) + ! Find mu bin algebraically, knowing that the spacing is equal + imu = floor((mu + ONE) / dmu + ONE) + ! Adjust so interpolation works on the last bin if necessary + if (imu == size(this % scatter, dim=3)) then + imu = imu - 1 + end if + f = this % scatter(gout, gin, imu,i_azi_,i_pol_) + + end if + + end function nuclide_mg_angle_calc_f +!=============================================================================== ! find_angle finds the closest angle on the data grid and returns that index !=============================================================================== - subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) + pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) real(8), intent(in) :: polar(:) ! Polar angles [0,pi] real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] real(8), intent(in) :: uvw(3) ! Direction of motion diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 7d3448aeaa..198dbf2cf5 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -148,7 +148,7 @@ contains p % mu, p % wgt) ! Update energy value for downstream compatability (in tallying) - p % E = energy_bin_midpoints(p % g) + p % E = energy_bin_avg(p % g) p % coord(p % n_coord) % uvw = rotate_angle(p % coord(p % n_coord) % uvw, & p % mu) diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 63a428717b..29ab616e0a 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -188,9 +188,9 @@ contains call scattdata_base_init(this, this_order, energy, mult) allocate(this % mu(this_order)) - this % dmu = TWO / (real(this_order,8) - 1) + this % dmu = TWO / (real(this_order) - 1) do imu = 1, this_order - 1 - this % mu(imu) = -ONE + real(imu - 1, 8) * this % dmu + this % mu(imu) = -ONE + real(imu - 1) * this % dmu end do this % mu(this_order) = ONE @@ -220,7 +220,7 @@ contains ! the negative fix-up introduced un-normalized data norm = ZERO do imu = 2, this_order - norm = norm + 0.5_8 * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) + norm = norm + HALF * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) end do if (norm > ZERO) then this % fmu(:,gout,gin) = this % fmu(:,gout,gin) / norm @@ -230,7 +230,7 @@ contains this % data(1,gout,gin) = ZERO do imu = 2, this_order - 1 this % data(imu,gout,gin) = this % data(imu-1,gout,gin) + & - 0.5_8 * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) + HALF * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) end do this % data(this_order,gout,gin) = ONE end if @@ -295,10 +295,10 @@ contains pure function scattdata_legendre_calc_f(this, gin, gout, mu) result(f) class(ScattData_Legendre), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) ! Plug mu in to the legendre expansion and go from there f = evaluate_legendre(this % data(:, gout, gin), mu) @@ -307,10 +307,10 @@ contains pure function scattdata_histogram_calc_f(this, gin, gout, mu) result(f) class(ScattData_Histogram), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) integer :: imu @@ -328,10 +328,10 @@ contains pure function scattdata_tabular_calc_f(this, gin, gout, mu) result(f) class(ScattData_Tabular), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) integer :: imu real(8) :: r From 7497efb15359a0b225ae8c62c4098853a9425775 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 7 Nov 2015 12:33:10 -0500 Subject: [PATCH 23/84] Removed update to last_E since we dont need that in MG mode --- src/physics_mg.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 198dbf2cf5..1da3619063 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -32,7 +32,6 @@ contains ! Store pre-collision particle properties p % last_wgt = p % wgt - p % last_E = p % E p % last_g = p % g p % last_uvw = p % coord(1) % uvw @@ -150,6 +149,7 @@ contains ! Update energy value for downstream compatability (in tallying) p % E = energy_bin_avg(p % g) + ! Convert change in angle (mu) to new direction p % coord(p % n_coord) % uvw = rotate_angle(p % coord(p % n_coord) % uvw, & p % mu) From 39445f059fa673d53ded657ab8cb83b7e1bddca1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 7 Nov 2015 14:06:38 -0500 Subject: [PATCH 24/84] Fixed p%coord(?) bug where i had the wrong coordinate index, showed up in the c5g7 problems with their lattices and thus n_coord was not 1. Also added c5g7 example problems. --- examples/xml/multigroup/c5g7/2d/cmfd.xml | 20 + examples/xml/multigroup/c5g7/2d/geometry.xml | 118 ++++++ examples/xml/multigroup/c5g7/2d/materials.xml | 1 + examples/xml/multigroup/c5g7/2d/plots.xml | 29 ++ examples/xml/multigroup/c5g7/2d/settings.xml | 50 +++ examples/xml/multigroup/c5g7/2d/tallies.xml | 25 ++ examples/xml/multigroup/c5g7/3d/geometry.xml | 138 +++++++ examples/xml/multigroup/c5g7/3d/materials.xml | 1 + examples/xml/multigroup/c5g7/3d/plots.xml | 42 ++ examples/xml/multigroup/c5g7/3d/settings.xml | 49 +++ examples/xml/multigroup/c5g7/3d/tallies.xml | 33 ++ examples/xml/multigroup/c5g7/data.xml | 383 ++++++++++++++++++ examples/xml/multigroup/c5g7/materials.xml | 54 +++ examples/xml/multigroup/c5g7/pin/geometry.xml | 16 + .../xml/multigroup/c5g7/pin/materials.xml | 1 + examples/xml/multigroup/c5g7/pin/plots.xml | 28 ++ examples/xml/multigroup/c5g7/pin/settings.xml | 46 +++ examples/xml/multigroup/c5g7/pin/tallies.xml | 16 + src/mgxs_data.F90 | 4 +- src/physics_mg.F90 | 6 +- 20 files changed, 1054 insertions(+), 6 deletions(-) create mode 100644 examples/xml/multigroup/c5g7/2d/cmfd.xml create mode 100644 examples/xml/multigroup/c5g7/2d/geometry.xml create mode 120000 examples/xml/multigroup/c5g7/2d/materials.xml create mode 100644 examples/xml/multigroup/c5g7/2d/plots.xml create mode 100644 examples/xml/multigroup/c5g7/2d/settings.xml create mode 100644 examples/xml/multigroup/c5g7/2d/tallies.xml create mode 100644 examples/xml/multigroup/c5g7/3d/geometry.xml create mode 120000 examples/xml/multigroup/c5g7/3d/materials.xml create mode 100644 examples/xml/multigroup/c5g7/3d/plots.xml create mode 100644 examples/xml/multigroup/c5g7/3d/settings.xml create mode 100644 examples/xml/multigroup/c5g7/3d/tallies.xml create mode 100644 examples/xml/multigroup/c5g7/data.xml create mode 100644 examples/xml/multigroup/c5g7/materials.xml create mode 100644 examples/xml/multigroup/c5g7/pin/geometry.xml create mode 120000 examples/xml/multigroup/c5g7/pin/materials.xml create mode 100644 examples/xml/multigroup/c5g7/pin/plots.xml create mode 100644 examples/xml/multigroup/c5g7/pin/settings.xml create mode 100644 examples/xml/multigroup/c5g7/pin/tallies.xml diff --git a/examples/xml/multigroup/c5g7/2d/cmfd.xml b/examples/xml/multigroup/c5g7/2d/cmfd.xml new file mode 100644 index 0000000000..22b1e9042f --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/cmfd.xml @@ -0,0 +1,20 @@ + + + + 1 + true + jfnk + + 0.0 0.0 -100.0 + 64.26 64.26 100.0 + 6 6 1 + + 2 2 2 2 1 1 + 2 2 2 2 1 1 + 2 2 2 2 1 1 + 2 2 2 2 1 1 + 1 1 1 1 1 1 + 1 1 1 1 1 1 + + + diff --git a/examples/xml/multigroup/c5g7/2d/geometry.xml b/examples/xml/multigroup/c5g7/2d/geometry.xml new file mode 100644 index 0000000000..3b43562f37 --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/geometry.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 17 17 + -10.71 -10.71 + 1.26 1.26 + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 + 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 5 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 + 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + + + + + + 0 + 17 17 + -10.71 -10.71 + 1.26 1.26 + + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 + 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 + 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 + 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 + 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 6 4 4 6 4 4 5 4 4 6 4 4 6 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 + 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 + 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 + 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 + 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + + + + + + + + + + + + + + + 0 + 3 3 + 0.0 0.0 + 21.42 21.42 + + 10 11 12 + 11 10 12 + 12 12 12 + + + + + + + diff --git a/examples/xml/multigroup/c5g7/2d/materials.xml b/examples/xml/multigroup/c5g7/2d/materials.xml new file mode 120000 index 0000000000..c3825cffc5 --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/materials.xml @@ -0,0 +1 @@ +/home/nelsonag/cases/c5g7/materials.xml \ No newline at end of file diff --git a/examples/xml/multigroup/c5g7/2d/plots.xml b/examples/xml/multigroup/c5g7/2d/plots.xml new file mode 100644 index 0000000000..a38f73f4e3 --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/plots.xml @@ -0,0 +1,29 @@ + + + + + 1 + mat + material + 32.13 32.13 0 + 64.26 64.26 + slice + 1000 1000 + + + + + 2 + cell + cell + 32.13 32.13 0 + 64.26 64.26 + slice + 1000 1000 + + + diff --git a/examples/xml/multigroup/c5g7/2d/settings.xml b/examples/xml/multigroup/c5g7/2d/settings.xml new file mode 100644 index 0000000000..189adc6c96 --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/settings.xml @@ -0,0 +1,50 @@ + + + multi-group + + + 2500 + 500 + 1000 + + + + 0.0 21.42 -100 + 42.84 64.26 100 + 34 34 1 + + + + + + + 0.0 21.42 -100 + 42.84 64.26 100 + + + + + + + 2000 + true + + + + true + true + true + + + false + + ../data.xml + + diff --git a/examples/xml/multigroup/c5g7/2d/tallies.xml b/examples/xml/multigroup/c5g7/2d/tallies.xml new file mode 100644 index 0000000000..8b21bf524a --- /dev/null +++ b/examples/xml/multigroup/c5g7/2d/tallies.xml @@ -0,0 +1,25 @@ + + + + + + + flux + + + + + fission + + + + 1 + regular + 0.0 0.0 -100.0 + 64.26 64.26 100.0 + 51 51 1 + + + false + + diff --git a/examples/xml/multigroup/c5g7/3d/geometry.xml b/examples/xml/multigroup/c5g7/3d/geometry.xml new file mode 100644 index 0000000000..b7766b32a0 --- /dev/null +++ b/examples/xml/multigroup/c5g7/3d/geometry.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 17 17 + -10.71 -10.71 + 1.26 1.26 + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 + 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 5 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 + 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + + + + + + 0 + 17 17 + -10.71 -10.71 + 1.26 1.26 + + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 + 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 + 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 + 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 + 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 6 4 4 6 4 4 5 4 4 6 4 4 6 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 + 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 + 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 + 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 + 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 + 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + + + + + + + + + + + + + + + + 3 3 + 0.0 0.0 + 21.42 21.42 + + 10 11 12 + 11 10 12 + 12 12 12 + + + + + + + + + + + + 3 3 + 0.0 0.0 + 21.42 21.42 + + 13 13 13 + 13 13 13 + 13 13 13 + + + + + + + + \ No newline at end of file diff --git a/examples/xml/multigroup/c5g7/3d/materials.xml b/examples/xml/multigroup/c5g7/3d/materials.xml new file mode 120000 index 0000000000..c344223b66 --- /dev/null +++ b/examples/xml/multigroup/c5g7/3d/materials.xml @@ -0,0 +1 @@ +../materials.xml \ No newline at end of file diff --git a/examples/xml/multigroup/c5g7/3d/plots.xml b/examples/xml/multigroup/c5g7/3d/plots.xml new file mode 100644 index 0000000000..caab977866 --- /dev/null +++ b/examples/xml/multigroup/c5g7/3d/plots.xml @@ -0,0 +1,42 @@ + + + + + 1 + mat + material + 32.13 32.13 107.1 + 64.26 214.2 + slice + 1000 1000 + + xz + + + + 2 + cell + cell + 32.13 32.13 107.1 + 64.26 214.2 + slice + 1000 1000 + xz + + + + 3 + mat_xy + material + 32.13 32.13 107.1 + 64.26 64.26 + slice + 1000 1000 + xy + + + diff --git a/examples/xml/multigroup/c5g7/3d/settings.xml b/examples/xml/multigroup/c5g7/3d/settings.xml new file mode 100644 index 0000000000..b67b882908 --- /dev/null +++ b/examples/xml/multigroup/c5g7/3d/settings.xml @@ -0,0 +1,49 @@ + + + multi-group + + + 2000 + 500 + 1000 + + + + 0.0 21.42 0.0 + 42.84 64.26 192.78 + 34 34 54 + + + + + + + 0.0 21.42 0.0 + 42.84 64.26 192.78 + + + + + + + 2000 + + + + true + true + true + + + false + + ../data.xml + + diff --git a/examples/xml/multigroup/c5g7/3d/tallies.xml b/examples/xml/multigroup/c5g7/3d/tallies.xml new file mode 100644 index 0000000000..e3826ccb63 --- /dev/null +++ b/examples/xml/multigroup/c5g7/3d/tallies.xml @@ -0,0 +1,33 @@ + + + + + + + flux + + + + + fission + + + + 1 + rectangular + 0.0 0.0 0.0 + 64.26 64.26 214.2 + 51 51 60 + + + + 2 + rectangular + 0.0 21.42 0.0 + 42.84 64.26 192.78 + 34 34 54 + + + false + + diff --git a/examples/xml/multigroup/c5g7/data.xml b/examples/xml/multigroup/c5g7/data.xml new file mode 100644 index 0000000000..ec85d4b593 --- /dev/null +++ b/examples/xml/multigroup/c5g7/data.xml @@ -0,0 +1,383 @@ + + + + 7 + + 1E-11 0.0635E-6 10.0E-6 1.0E-4 1.0E-3 0.5 1.0 20.0 + + + + + + UO2.71c + UO2.71c + 2.53E-8 + 0 + true + + isotropic + + + + 8.0248E-03 3.7174E-03 2.6769E-02 9.6236E-02 3.0020E-02 1.1126E-01 2.8278E-01 + + + + 2.005998E-02 2.027303E-03 1.570599E-02 4.518301E-02 4.334208E-02 2.020901E-01 5.257105E-01 + + + + 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 + + + 7.21206E-03 8.19301E-04 6.45320E-03 1.85648E-02 1.78084E-02 8.30348E-02 2.16004E-01 + + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 0.1275370 0.0423780 0.0000094 0.0000000 0.0000000 0.0000000 0.0000000 + 0.0000000 0.3244560 0.0016314 0.0000000 0.0000000 0.0000000 0.0000000 + 0.0000000 0.0000000 0.4509400 0.0026792 0.0000000 0.0000000 0.0000000 + 0.0000000 0.0000000 0.0000000 0.4525650 0.0055664 0.0000000 0.0000000 + 0.0000000 0.0000000 0.0000000 0.0001253 0.2714010 0.0102550 0.0000000 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0012968 0.2658020 0.0168090 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0085458 0.2730800 + + + + + 0.1779492 0.3298048 0.4803882 0.5543674000000001 0.3118013 0.39516779999999996 0.5644058 + + + + + + + MOX1.71c + MOX1.71c + 2.53E-8 + 0 + true + + + + 8.4339E-03 3.7577E-03 2.7970E-02 1.0421E-01 1.3994E-01 4.0918E-01 4.0935E-01 + + + + 1.27888062E-02 8.95701528E-03 7.37557218E-06 2.55837033E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.49041240E-03 1.04385401E-03 8.59552023E-07 2.98153464E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 9.56411400E-03 6.69850756E-03 5.51582469E-06 1.91327830E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.84928781E-02 2.69596154E-02 2.21996483E-05 7.70040890E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.80629998E-02 1.26509513E-02 1.04173100E-05 3.61346022E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.91930789E-01 2.74500216E-01 2.26034688E-04 7.84048241E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 4.19762096E-01 2.93992687E-01 2.42085585E-04 8.39724109E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 7.62704E-03 8.76898E-04 5.69835E-03 2.28872E-02 1.07635E-02 2.32757E-01 2.48968E-01 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.27537000E-01 4.23780000E-02 9.43740000E-06 5.51630000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.24456000E-01 1.63140000E-03 3.14270000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.50940000E-01 2.67920000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.52565000E-01 5.56640000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.25250000E-04 2.71401000E-01 1.02550000E-02 1.00210000E-08 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.29680000E-03 2.65802000E-01 1.68090000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.54580000E-03 2.73080000E-01 + + + + 0.1783583429163 0.3298451031427 0.4815892 0.5623414 0.421721260021 0.6930878 0.6909757999999999 + + + + + + + MOX2.71c + MOX2.71c + 2.53E-8 + 0 + true + + + + 0.0090657 0.0042967 0.032881 0.12203 0.18298 0.56846 0.58521 + + + + 1.40004593E-02 9.80563205E-03 8.07435789E-06 2.80075866E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.26856185E-03 1.58885378E-03 1.30832709E-06 4.53820413E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.41886199E-02 9.93741584E-03 8.18287404E-06 2.83839974E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 5.54788444E-02 3.88562347E-02 3.19958106E-05 1.10984111E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.69085702E-02 1.88462058E-02 1.55187355E-05 5.38299559E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 5.45687127E-01 3.82187973E-01 3.14709185E-04 1.09163414E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.13307712E-01 4.29548032E-01 3.53707392E-04 1.22690752E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 0.00825446 0.00132565 0.00842156 0.032873 0.0159636 0.323794 0.362803 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.30457000E-01 4.17920000E-02 8.51050000E-06 5.13290000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.28428000E-01 1.64360000E-03 2.20170000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.58371000E-01 2.53310000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.63709000E-01 5.47660000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.76190000E-04 2.82313000E-01 8.72890000E-03 9.00160000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.27600000E-03 2.49751000E-01 1.31140000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.86450000E-03 2.59529000E-01 + + + + 0.1813232156329 0.3343683022017 0.4937851 0.5912156 0.47419809900160004 0.833601 0.8536035 + + + + + + + MOX3.71c + MOX3.71c + 2.53E-8 + 0 + true + + + + 9.48620000E-03 4.65560000E-03 3.62400000E-02 1.32720000E-01 2.08400000E-01 6.58700000E-01 6.90170000E-01 + + + + 1.48071013E-02 1.03705874E-02 8.53956516E-06 2.96212546E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.78640474E-03 1.95154023E-03 1.60697792E-06 5.57413653E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.73304404E-02 1.21378819E-02 9.99482763E-06 3.46691346E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.59928975E-02 4.62200600E-02 3.80594850E-05 1.32017225E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.25131926E-02 2.27715674E-02 1.87510386E-05 6.50418701E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.32002662E-01 4.42641588E-01 3.64489161E-04 1.26430632E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 7.28595687E-01 5.10293344E-01 4.20196380E-04 1.45753838E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 8.67209000E-03 1.62426000E-03 1.02716000E-02 3.90447000E-02 1.92576000E-02 3.74888000E-01 4.30599000E-01 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.31504000E-01 4.20460000E-02 8.69720000E-06 5.19380000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.30403000E-01 1.64630000E-03 2.60060000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.61792000E-01 2.47490000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.68021000E-01 5.43300000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.85970000E-04 2.85771000E-01 8.39730000E-03 8.92800000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.39160000E-03 2.47614000E-01 1.23220000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.96810000E-03 2.56093000E-01 + + + + 1.83044902E-01 3.36704903E-01 5.00506900E-01 6.06174000E-01 5.02754279E-01 9.21027600E-01 9.55231100E-01 + + + + + + + FC.71c + FC.71c + 2.53E-8 + 0 + true + + + + 5.1132E-04 7.5813E-05 3.1643E-04 1.1675E-03 3.3977E-03 9.1886E-03 2.3244E-02 + + + + 1.323401E-08 1.434500E-08 1.128599E-06 1.276299E-05 3.538502E-07 1.740099E-06 5.063302E-06 + + + + 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 + + + + 4.79002E-09 5.82564E-09 4.63719E-07 5.24406E-06 1.45390E-07 7.14972E-07 2.08041E-06 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E00 0.00000000E00 + 0.00000000E00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 + 0.00000000E00 0.00000000E00 1.83425000E-01 9.22880000E-02 6.93650000E-03 1.07900000E-03 2.05430000E-04 + 0.00000000E00 0.00000000E00 0.00000000E00 7.90769000E-02 1.69990000E-01 2.58600000E-02 4.92560000E-03 + 0.00000000E00 0.00000000E00 0.00000000E00 3.73400000E-05 9.97570000E-02 2.06790000E-01 2.44780000E-02 + 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 9.17420000E-04 3.16774000E-01 2.38760000E-01 + 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 4.97930000E-02 1.09910000E00 + + + + 1.26032048E-01 2.93160367E-01 2.84250824E-01 2.81025244E-01 3.34460185E-01 5.65640735E-01 1.17213908E00 + + + + + + + GT.71c + GT.71c + 2.53E-8 + 0 + false + + + + 5.11320000E-04 7.58010000E-05 3.15720000E-04 1.15820000E-03 3.39750000E-03 9.18780000E-03 2.32420000E-02 + + + + + + 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 + 0.00000000E+00 0.00000000E+00 1.83297000E-01 9.23970000E-02 6.94460000E-03 1.08030000E-03 2.05670000E-04 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 7.88511000E-02 1.70140000E-01 2.58810000E-02 4.92970000E-03 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.73330000E-05 9.97372000E-02 2.06790000E-01 2.44780000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 9.17260000E-04 3.16765000E-01 2.38770000E-01 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.97920000E-02 1.09912000E+00 + + + + 1.26032043E-01 2.93160349E-01 2.84240290E-01 2.80960000E-01 3.34440033E-01 5.65640060E-01 1.17215400E+00 + + + + + + LWTR.71c + LWTR.71c + 2.53E-8 + 0 + false + + + + 6.0105E-04 1.5793E-05 3.3716E-04 1.9406E-03 5.7416E-03 1.5001E-02 3.7239E-02 + + + + + + 0.0444777 0.1134000 0.0007235 0.0000037 0.0000001 0.0000000 0.0000000 + 0.0000000 0.2823340 0.1299400 0.0006234 0.0000480 0.0000074 0.0000010 + 0.0000000 0.0000000 0.3452560 0.2245700 0.0169990 0.0026443 0.0005034 + 0.0000000 0.0000000 0.0000000 0.0910284 0.4155100 0.0637320 0.0121390 + 0.0000000 0.0000000 0.0000000 0.0000714 0.1391380 0.5118200 0.0612290 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0022157 0.6999130 0.5373200 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.1324400 2.4807000 + + + + 0.15920605 0.41296959299999997 0.59030986 0.5843499999999999 0.7180000000000001 1.2544497000000001 2.650379 + + + + + + + CR.71c + CR.71c + 2.53E-8 + 0 + false + + + + 1.70490000E-03 8.36224000E-03 8.37901000E-02 3.97797000E-01 6.98763000E-01 9.29508000E-01 1.17836000E+00 + + + + + + 1.70563000E-01 4.44012000E-02 9.83670000E-05 1.27786000E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 4.71050000E-01 6.85480000E-04 3.91395000E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 8.01859000E-01 7.20132000E-04 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 5.70752000E-01 1.46015000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 6.55562000E-05 2.07838000E-01 3.81486000E-03 3.69760000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.02427000E-03 2.02465000E-01 4.75290000E-03 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.53043000E-03 6.58597000E-01 + + + + 2.16767595E-01 4.80097720E-01 8.86369232E-01 9.70009150E-01 9.10481420E-01 1.13775017E+00 1.84048743E+00 + + + diff --git a/examples/xml/multigroup/c5g7/materials.xml b/examples/xml/multigroup/c5g7/materials.xml new file mode 100644 index 0000000000..930fc09085 --- /dev/null +++ b/examples/xml/multigroup/c5g7/materials.xml @@ -0,0 +1,54 @@ + + + + 71c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xml/multigroup/c5g7/pin/geometry.xml b/examples/xml/multigroup/c5g7/pin/geometry.xml new file mode 100644 index 0000000000..94c70cb340 --- /dev/null +++ b/examples/xml/multigroup/c5g7/pin/geometry.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/xml/multigroup/c5g7/pin/materials.xml b/examples/xml/multigroup/c5g7/pin/materials.xml new file mode 120000 index 0000000000..c3825cffc5 --- /dev/null +++ b/examples/xml/multigroup/c5g7/pin/materials.xml @@ -0,0 +1 @@ +/home/nelsonag/cases/c5g7/materials.xml \ No newline at end of file diff --git a/examples/xml/multigroup/c5g7/pin/plots.xml b/examples/xml/multigroup/c5g7/pin/plots.xml new file mode 100644 index 0000000000..cbb8e532c1 --- /dev/null +++ b/examples/xml/multigroup/c5g7/pin/plots.xml @@ -0,0 +1,28 @@ + + + + + 1 + mat + material + 0 0 0 + 1.26 1.26 + slice + 1000 1000 + + + + + + + + 2 + cell + cell + 0 0 0 + 1.26 1.26 + slice + 1000 1000 + + + diff --git a/examples/xml/multigroup/c5g7/pin/settings.xml b/examples/xml/multigroup/c5g7/pin/settings.xml new file mode 100644 index 0000000000..46c0bd2264 --- /dev/null +++ b/examples/xml/multigroup/c5g7/pin/settings.xml @@ -0,0 +1,46 @@ + + + + multi-group + + + + 2000 + 500 + 1000 + + + + + + + -0.63 -0.63 -1E50 + 0.63 0.63 1E50 + + + + + + + 2000 + true + + + + true + true + true + + + false + + ../data.xml + + diff --git a/examples/xml/multigroup/c5g7/pin/tallies.xml b/examples/xml/multigroup/c5g7/pin/tallies.xml new file mode 100644 index 0000000000..727584a627 --- /dev/null +++ b/examples/xml/multigroup/c5g7/pin/tallies.xml @@ -0,0 +1,16 @@ + + + + + + + flux + + + + + + scatter + + + diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index e3ea314d6c..c9830f8d0f 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -261,8 +261,8 @@ contains call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) end if else - enable_leg_mu = .false. - this % legendre_mu_points = 1 + enable_leg_mu = .true. + this % legendre_mu_points = 33 end if if (enable_leg_mu .and. & check_for_node(node_legendre_mu, "num_points")) then diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 1da3619063..6ac2b44464 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -88,7 +88,6 @@ contains call scatter(p) ! Play russian roulette if survival biasing is turned on - if (survival_biasing) then call russian_roulette(p) if (.not. p % alive) return @@ -143,15 +142,14 @@ contains type(Particle), intent(inout) :: p call sample_scatter(macro_xs(p % material) % obj, & - p % coord(p % n_coord) % uvw, p % last_g, p % g, & + p % coord(1) % uvw, p % last_g, p % g, & p % mu, p % wgt) ! Update energy value for downstream compatability (in tallying) p % E = energy_bin_avg(p % g) ! Convert change in angle (mu) to new direction - p % coord(p % n_coord) % uvw = rotate_angle(p % coord(p % n_coord) % uvw, & - p % mu) + p % coord(1) % uvw = rotate_angle(p % coord(1) % uvw, p % mu) ! Set event component p % event = EVENT_SCATTER From c571a4b12629699250f8c19c3a95f6ba2b15c6eb Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 7 Nov 2015 14:23:20 -0500 Subject: [PATCH 25/84] Got cmfd working, not sure about with feedback just yet --- examples/xml/multigroup/c5g7/2d/cmfd.xml | 6 +++--- examples/xml/multigroup/c5g7/2d/settings.xml | 4 ++-- src/tally.F90 | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/examples/xml/multigroup/c5g7/2d/cmfd.xml b/examples/xml/multigroup/c5g7/2d/cmfd.xml index 22b1e9042f..1b1e523b10 100644 --- a/examples/xml/multigroup/c5g7/2d/cmfd.xml +++ b/examples/xml/multigroup/c5g7/2d/cmfd.xml @@ -1,9 +1,9 @@ - 1 - true - jfnk + 2 + false + power 0.0 0.0 -100.0 64.26 64.26 100.0 diff --git a/examples/xml/multigroup/c5g7/2d/settings.xml b/examples/xml/multigroup/c5g7/2d/settings.xml index 189adc6c96..faed7cd7fc 100644 --- a/examples/xml/multigroup/c5g7/2d/settings.xml +++ b/examples/xml/multigroup/c5g7/2d/settings.xml @@ -33,7 +33,7 @@ - 2000 + 2500 true @@ -43,7 +43,7 @@ true - false + true ../data.xml diff --git a/src/tally.F90 b/src/tally.F90 index 7ad701b168..6b3e7a7934 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -966,8 +966,11 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + score = p % wgt + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & p % last_uvw, p % mu) + end if case (SCORE_NU_SCATTER_PN) @@ -980,8 +983,11 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + score = p % wgt + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & p % last_uvw, p % mu) + end if case (SCORE_NU_SCATTER_YN) @@ -994,8 +1000,11 @@ contains ! For scattering production, we need to use the pre-collision ! weight times the multiplicity as the estimate for the number of ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt * nuc % get_xs(p % g, 'f_mu', p % last_g, & + score = p % wgt + if (i_nuclide > 0) then + score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & p % last_uvw, p % mu) + end if case (SCORE_TRANSPORT) From 2262045e633340dff9b05f185b4e66a91d22635a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 8 Nov 2015 14:12:33 -0500 Subject: [PATCH 26/84] Changes to get tallying on better footing, moved C5G7 problem to higher subdir in examples --- .../xml/{multigroup => }/c5g7/2d/cmfd.xml | 5 +- .../xml/{multigroup => }/c5g7/2d/geometry.xml | 0 .../{multigroup => }/c5g7/2d/materials.xml | 0 .../xml/{multigroup => }/c5g7/2d/plots.xml | 0 .../xml/{multigroup => }/c5g7/2d/settings.xml | 12 +- .../xml/{multigroup => }/c5g7/2d/tallies.xml | 0 .../xml/{multigroup => }/c5g7/3d/geometry.xml | 0 .../{multigroup => }/c5g7/3d/materials.xml | 0 .../xml/{multigroup => }/c5g7/3d/plots.xml | 0 .../xml/{multigroup => }/c5g7/3d/settings.xml | 2 - .../xml/{multigroup => }/c5g7/3d/tallies.xml | 0 examples/xml/{multigroup => }/c5g7/data.xml | 0 .../xml/{multigroup => }/c5g7/materials.xml | 0 .../{multigroup => }/c5g7/pin/geometry.xml | 0 .../{multigroup => }/c5g7/pin/materials.xml | 0 .../xml/{multigroup => }/c5g7/pin/plots.xml | 0 .../{multigroup => }/c5g7/pin/settings.xml | 0 .../xml/{multigroup => }/c5g7/pin/tallies.xml | 0 src/cmfd_input.F90 | 19 ++- src/geometry.F90 | 4 +- src/input_xml.F90 | 8 ++ src/particle_header.F90 | 4 +- src/physics_mg.F90 | 1 + src/tally.F90 | 128 +++++++++++------- src/tally_header.F90 | 4 + 25 files changed, 123 insertions(+), 64 deletions(-) rename examples/xml/{multigroup => }/c5g7/2d/cmfd.xml (69%) rename examples/xml/{multigroup => }/c5g7/2d/geometry.xml (100%) rename examples/xml/{multigroup => }/c5g7/2d/materials.xml (100%) rename examples/xml/{multigroup => }/c5g7/2d/plots.xml (100%) rename examples/xml/{multigroup => }/c5g7/2d/settings.xml (76%) rename examples/xml/{multigroup => }/c5g7/2d/tallies.xml (100%) rename examples/xml/{multigroup => }/c5g7/3d/geometry.xml (100%) rename examples/xml/{multigroup => }/c5g7/3d/materials.xml (100%) rename examples/xml/{multigroup => }/c5g7/3d/plots.xml (100%) rename examples/xml/{multigroup => }/c5g7/3d/settings.xml (97%) rename examples/xml/{multigroup => }/c5g7/3d/tallies.xml (100%) rename examples/xml/{multigroup => }/c5g7/data.xml (100%) rename examples/xml/{multigroup => }/c5g7/materials.xml (100%) rename examples/xml/{multigroup => }/c5g7/pin/geometry.xml (100%) rename examples/xml/{multigroup => }/c5g7/pin/materials.xml (100%) rename examples/xml/{multigroup => }/c5g7/pin/plots.xml (100%) rename examples/xml/{multigroup => }/c5g7/pin/settings.xml (100%) rename examples/xml/{multigroup => }/c5g7/pin/tallies.xml (100%) diff --git a/examples/xml/multigroup/c5g7/2d/cmfd.xml b/examples/xml/c5g7/2d/cmfd.xml similarity index 69% rename from examples/xml/multigroup/c5g7/2d/cmfd.xml rename to examples/xml/c5g7/2d/cmfd.xml index 1b1e523b10..aa3deb4b67 100644 --- a/examples/xml/multigroup/c5g7/2d/cmfd.xml +++ b/examples/xml/c5g7/2d/cmfd.xml @@ -2,12 +2,12 @@ 2 - false - power + true 0.0 0.0 -100.0 64.26 64.26 100.0 6 6 1 + 2 2 2 2 1 1 2 2 2 2 1 1 @@ -16,5 +16,6 @@ 1 1 1 1 1 1 1 1 1 1 1 1 + 1 0 0 1 1 1 diff --git a/examples/xml/multigroup/c5g7/2d/geometry.xml b/examples/xml/c5g7/2d/geometry.xml similarity index 100% rename from examples/xml/multigroup/c5g7/2d/geometry.xml rename to examples/xml/c5g7/2d/geometry.xml diff --git a/examples/xml/multigroup/c5g7/2d/materials.xml b/examples/xml/c5g7/2d/materials.xml similarity index 100% rename from examples/xml/multigroup/c5g7/2d/materials.xml rename to examples/xml/c5g7/2d/materials.xml diff --git a/examples/xml/multigroup/c5g7/2d/plots.xml b/examples/xml/c5g7/2d/plots.xml similarity index 100% rename from examples/xml/multigroup/c5g7/2d/plots.xml rename to examples/xml/c5g7/2d/plots.xml diff --git a/examples/xml/multigroup/c5g7/2d/settings.xml b/examples/xml/c5g7/2d/settings.xml similarity index 76% rename from examples/xml/multigroup/c5g7/2d/settings.xml rename to examples/xml/c5g7/2d/settings.xml index faed7cd7fc..2ad738704a 100644 --- a/examples/xml/multigroup/c5g7/2d/settings.xml +++ b/examples/xml/c5g7/2d/settings.xml @@ -6,17 +6,11 @@ in an eigenvalue calculation mode --> - 2500 + 2000 500 - 1000 + 1000 - - 0.0 21.42 -100 - 42.84 64.26 100 - 34 34 1 - - - 2500 + 2000 true diff --git a/examples/xml/multigroup/c5g7/2d/tallies.xml b/examples/xml/c5g7/2d/tallies.xml similarity index 100% rename from examples/xml/multigroup/c5g7/2d/tallies.xml rename to examples/xml/c5g7/2d/tallies.xml diff --git a/examples/xml/multigroup/c5g7/3d/geometry.xml b/examples/xml/c5g7/3d/geometry.xml similarity index 100% rename from examples/xml/multigroup/c5g7/3d/geometry.xml rename to examples/xml/c5g7/3d/geometry.xml diff --git a/examples/xml/multigroup/c5g7/3d/materials.xml b/examples/xml/c5g7/3d/materials.xml similarity index 100% rename from examples/xml/multigroup/c5g7/3d/materials.xml rename to examples/xml/c5g7/3d/materials.xml diff --git a/examples/xml/multigroup/c5g7/3d/plots.xml b/examples/xml/c5g7/3d/plots.xml similarity index 100% rename from examples/xml/multigroup/c5g7/3d/plots.xml rename to examples/xml/c5g7/3d/plots.xml diff --git a/examples/xml/multigroup/c5g7/3d/settings.xml b/examples/xml/c5g7/3d/settings.xml similarity index 97% rename from examples/xml/multigroup/c5g7/3d/settings.xml rename to examples/xml/c5g7/3d/settings.xml index b67b882908..51241492d5 100644 --- a/examples/xml/multigroup/c5g7/3d/settings.xml +++ b/examples/xml/c5g7/3d/settings.xml @@ -42,8 +42,6 @@ true - false - ../data.xml diff --git a/examples/xml/multigroup/c5g7/3d/tallies.xml b/examples/xml/c5g7/3d/tallies.xml similarity index 100% rename from examples/xml/multigroup/c5g7/3d/tallies.xml rename to examples/xml/c5g7/3d/tallies.xml diff --git a/examples/xml/multigroup/c5g7/data.xml b/examples/xml/c5g7/data.xml similarity index 100% rename from examples/xml/multigroup/c5g7/data.xml rename to examples/xml/c5g7/data.xml diff --git a/examples/xml/multigroup/c5g7/materials.xml b/examples/xml/c5g7/materials.xml similarity index 100% rename from examples/xml/multigroup/c5g7/materials.xml rename to examples/xml/c5g7/materials.xml diff --git a/examples/xml/multigroup/c5g7/pin/geometry.xml b/examples/xml/c5g7/pin/geometry.xml similarity index 100% rename from examples/xml/multigroup/c5g7/pin/geometry.xml rename to examples/xml/c5g7/pin/geometry.xml diff --git a/examples/xml/multigroup/c5g7/pin/materials.xml b/examples/xml/c5g7/pin/materials.xml similarity index 100% rename from examples/xml/multigroup/c5g7/pin/materials.xml rename to examples/xml/c5g7/pin/materials.xml diff --git a/examples/xml/multigroup/c5g7/pin/plots.xml b/examples/xml/c5g7/pin/plots.xml similarity index 100% rename from examples/xml/multigroup/c5g7/pin/plots.xml rename to examples/xml/c5g7/pin/plots.xml diff --git a/examples/xml/multigroup/c5g7/pin/settings.xml b/examples/xml/c5g7/pin/settings.xml similarity index 100% rename from examples/xml/multigroup/c5g7/pin/settings.xml rename to examples/xml/c5g7/pin/settings.xml diff --git a/examples/xml/multigroup/c5g7/pin/tallies.xml b/examples/xml/c5g7/pin/tallies.xml similarity index 100% rename from examples/xml/multigroup/c5g7/pin/tallies.xml rename to examples/xml/c5g7/pin/tallies.xml diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index c15c250e64..4588444d05 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -52,7 +52,7 @@ contains use xml_interface use, intrinsic :: ISO_FORTRAN_ENV - integer :: i + integer :: i, g integer :: ng integer :: n_params integer, allocatable :: iarray(:) @@ -102,6 +102,23 @@ contains if(.not.allocated(cmfd%egrid)) allocate(cmfd%egrid(ng)) call get_node_array(node_mesh, "energy", cmfd%egrid) cmfd % indices(4) = ng - 1 ! sets energy group dimension + ! If using MG mode, check to see if these egrid points at least match + ! the MG Data breakpoints + if (.not. run_CE) then + do i = 1, ng + found = .false. + do g = 1, energy_groups + 1 + if (cmfd%egrid(i) == energy_bins(g)) then + found = .true. + exit + end if + end do + if (.not. found) then + call fatal_error("CMFD energy mesh boundaries must align with& + & boundaries of multi-group data!") + end if + end do + end if else if(.not.allocated(cmfd % egrid)) allocate(cmfd % egrid(2)) cmfd % egrid = [ ZERO, 20.0_8 ] diff --git a/src/geometry.F90 b/src/geometry.F90 index 7675c70dc1..a8348d4188 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -199,6 +199,7 @@ contains type(Cell), pointer :: c ! pointer to cell class(Lattice), pointer :: lat ! pointer to lattice type(Universe), pointer :: univ ! universe to search in + real(8) :: new_xyz(3) ! perturbed location used to look for cell do j = p % n_coord + 1, MAX_COORD call p % coord(j) % reset() @@ -285,7 +286,8 @@ contains lat => lattices(c % fill) % obj ! Determine lattice indices - i_xyz = lat % get_indices(p % coord(j) % xyz + TINY_BIT * p % coord(j) % uvw) + new_xyz = p % coord(j) % xyz + TINY_BIT * p % coord(j) % uvw + i_xyz = lat % get_indices(new_xyz) ! Store lower level coordinates p % coord(j + 1) % xyz = lat % get_local_xyz(p % coord(j) % xyz, i_xyz) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 3cf26b49b6..06e1c154e8 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2705,6 +2705,8 @@ contains ! Allocate and store bins allocate(t % filters(j) % real_bins(n_words)) call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + + if (.not. run_CE) t % energy_matches_groups = .false. else if (n_words == -1) then ! Set number of bins t % filters(j) % n_bins = energy_groups @@ -2712,6 +2714,8 @@ contains ! Allocate and store bins allocate(t % filters(j) % real_bins(energy_groups)) t % filters(j) % real_bins = energy_bins + + if (.not. run_CE) t % energy_matches_groups = .true. end if case ('energyout') @@ -2725,6 +2729,8 @@ contains ! Allocate and store bins allocate(t % filters(j) % real_bins(n_words)) call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + + if (.not. run_CE) t % energyout_matches_groups = .false. else if (n_words == -1) then ! Set number of bins t % filters(j) % n_bins = energy_groups @@ -2732,6 +2738,8 @@ contains ! Allocate and store bins allocate(t % filters(j) % real_bins(energy_groups)) t % filters(j) % real_bins = energy_bins + + if (.not. run_CE) t % energyout_matches_groups = .true. end if ! Set to analog estimator diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 9c0ddfde0d..ff6e4d15cc 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -198,8 +198,8 @@ contains this % E = src % E this % last_E = src % E if (.not. run_CE) then - this % g = src % g - this % last_g = src % g + this % g = src % g + this % last_g = src % g end if end subroutine initialize_from_source diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 6ac2b44464..38e144e625 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -241,6 +241,7 @@ contains ! Sample secondary energy distribution for fission reaction and set energy ! in fission bank fission_bank(i) % g = sample_fission_energy(xs, p % g, fission_bank(i) % uvw) + fission_bank(i) % E = energy_bin_avg(fission_bank(i) % g) end do ! increment number of bank sites diff --git a/src/tally.F90 b/src/tally.F90 index 6b3e7a7934..848a6cb7eb 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -799,8 +799,7 @@ contains real(8) :: micro_abs ! nuclidic microscopic abs class(Nuclide_MG), pointer :: nuc - if (i_nuclide > 0) & - nuc => nuclides_MG(i_nuclide) % obj + if (i_nuclide > 0) nuc => nuclides_MG(i_nuclide) % obj i = 0 SCORE_LOOP: do q = 1, t % n_user_score_bins @@ -1047,7 +1046,7 @@ contains else if (i_nuclide > 0) then - score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) & + score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) & * atom_density * flux else score = material_xs % absorption * flux @@ -1061,10 +1060,10 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! fission - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) & + nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) & / micro_abs else score = ZERO @@ -1076,13 +1075,13 @@ contains ! particle's weight entering the collision as the estimate for the ! fission reaction rate score = p % last_wgt & - * nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) & - / nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + * nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) & + / nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) end if else if (i_nuclide > 0) then - score = nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) * & + score = nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) * & atom_density * flux else score = material_xs % fission * flux @@ -1107,10 +1106,11 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! nu-fission - if (micro_xs(p % event_nuclide) % absorption > ZERO) then + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) / & - nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) / & + micro_abs else score = ZERO end if @@ -1127,7 +1127,7 @@ contains else if (i_nuclide > 0) then - score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(1) % uvw) & + score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(i) % uvw) & * atom_density * flux else score = material_xs % nu_fission * flux @@ -1141,10 +1141,10 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! fission scale by kappa-fission - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / & + nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / & micro_abs else score = ZERO @@ -1156,13 +1156,13 @@ contains ! particle's weight entering the collision as the estimate for ! the fission energy production rate score = p % last_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / & - nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) + nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / & + nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) end if else if (i_nuclide > 0) then - score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) & + score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) & * atom_density * flux else score = material_xs % kappa_fission * flux @@ -1534,13 +1534,14 @@ contains integer :: i_filter ! index for matching filter bin combination real(8) :: score ! actual score integer :: gout ! energy group of fission bank site + real(8) :: E_out ! save original outgoing energy bin and score index i = t % find_filter(FILTER_ENERGYOUT) bin_energyout = matching_bins(i) ! Get number of energies on filter - n = size(t % filters(i) % int_bins) + n = size(t % filters(i) % real_bins) ! Since the creation of fission sites is weighted such that it is ! expected to create n_particles sites, we need to multiply the @@ -1552,11 +1553,23 @@ contains ! determine score based on bank site weight and keff score = keff * fission_bank(n_bank - p % n_bank + k) % wgt - ! determine outgoing energy from fission bank - gout = fission_bank(n_bank - p % n_bank + k) % g + if (t % energyout_matches_groups) then + ! determine outgoing energy from fission bank + gout = fission_bank(n_bank - p % n_bank + k) % g - ! change outgoing energy bin - matching_bins(i) = gout + ! change outgoing energy bin + matching_bins(i) = gout + else + ! determine outgoing energy from fission bank + E_out = fission_bank(n_bank - p % n_bank + k) % E + + ! check if outgoing energy is within specified range on filter + if (E_out < t % filters(i) % real_bins(1) .or. & + E_out > t % filters(i) % real_bins(n)) cycle + + ! change outgoing energy bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, n, E_out) + end if ! determine scoring index i_filter = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 @@ -2427,8 +2440,8 @@ contains integer :: j integer :: n ! number of bins for single filter integer :: offset ! offset for distribcell - integer :: g ! particle energy group real(8) :: theta, phi ! Polar and Azimuthal Angles, respectively + real(8) :: E type(TallyObject), pointer :: t type(RegularMesh), pointer :: m @@ -2507,34 +2520,55 @@ contains p % surface, i_tally) case (FILTER_ENERGYIN) - ! make sure the correct energy is used - if (t % estimator == ESTIMATOR_TRACKLENGTH) then - g = p % g - else - g = p % last_g - end if - - ! Since all groups are filters, the filter bin is the group - matching_bins(i) = g - - case (FILTER_ENERGYOUT) - ! Since all groups are filters, the filter bin is the group - matching_bins(i) = p % g - - case (FILTER_DELAYEDGROUP) - - if (survival_biasing .and. t % find_filter(FILTER_ENERGYOUT) <= 0) then - matching_bins(i) = 1 - elseif (active_tracklength_tallies % size() > 0) then - matching_bins(i) = 1 - else - if (p % delayed_group == 0) then - matching_bins = NO_BIN_FOUND + if (t % energy_matches_groups) then + ! make sure the correct energy group is used + ! Since all groups are filters, the filter bin is the group + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + matching_bins(i) = p % g else - matching_bins(i) = p % delayed_group + matching_bins(i) = p % last_g + end if + else + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + E = p % E + else + E = p % last_E + end if + n = t % filters(i) % n_bins + + ! check if energy of the particle is within energy bins + if (E < t % filters(i) % real_bins(1) .or. & + E > t % filters(i) % real_bins(n + 1)) then + matching_bins(i) = NO_BIN_FOUND + else + ! search to find incoming energy bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, & + n + 1, E) end if end if + + case (FILTER_ENERGYOUT) + if (t % energyout_matches_groups) then + ! Since all groups are filters, the filter bin is the group + matching_bins(i) = p % g + else + ! determine outgoing energy bin + n = t % filters(i) % n_bins + + ! check if energy of the particle is within energy bins + if (p % E < t % filters(i) % real_bins(1) .or. & + p % E > t % filters(i) % real_bins(n + 1)) then + matching_bins(i) = NO_BIN_FOUND + else + ! search to find incoming energy bin + matching_bins(i) = binary_search(t % filters(i) % real_bins, & + n + 1, p % E) + end if + end if + + case (FILTER_MU) ! determine mu bin n = t % filters(i) % n_bins diff --git a/src/tally_header.F90 b/src/tally_header.F90 index 01dcd9bdb5..c592f80d70 100644 --- a/src/tally_header.F90 +++ b/src/tally_header.F90 @@ -130,6 +130,10 @@ module tally_header integer :: n_triggers = 0 ! # of triggers type(TriggerObject), allocatable :: triggers(:) ! Array of triggers + ! Multi-Group Specific Information To Enable Rapid Tallying + logical :: energy_matches_groups = .false. + logical :: energyout_matches_groups = .false. + ! Type-Bound procedures contains procedure :: clear => tallyobject_clear ! Deallocates TallyObject From 4561edfac7bfd6ea1a0fc6be5bd06bcbf6e766f5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 8 Nov 2015 20:21:47 -0500 Subject: [PATCH 27/84] Fixed formatting issues --- src/input_xml.F90 | 50 +++++++++++++++++++++--------------------- src/macroxs_header.F90 | 40 ++++++++++++++++----------------- src/mesh.F90 | 10 ++++----- src/mgxs_data.F90 | 12 +++++----- src/nuclide_header.F90 | 4 ++-- src/physics_mg.F90 | 1 + 6 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 06e1c154e8..c75886b475 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1963,8 +1963,8 @@ contains ! Check to ensure material has at least one nuclide if ((.not. check_for_node(node_mat, "nuclide") .and. & - .not. check_for_node(node_mat, "element")) .and. & - (.not. check_for_node(node_mat, "macroscopic"))) then + .not. check_for_node(node_mat, "element")) .and. & + (.not. check_for_node(node_mat, "macroscopic"))) then call fatal_error("No macroscopic data, nuclides or natural elements & &specified on material " // trim(to_str(mat % id))) end if @@ -2001,7 +2001,7 @@ contains ! store full name call get_node_value(node_nuc, "name", temp_str) if (check_for_node(node_nuc, "xs")) & - call get_node_value(node_nuc, "xs", name) + call get_node_value(node_nuc, "xs", name) name = trim(temp_str) // "." // trim(name) name = to_lower(name) @@ -2014,7 +2014,7 @@ contains call list_density % append(ONE) else call fatal_error("Units can only be macro for macroscopic data " & - &// trim(name)) + &// trim(name)) end if else @@ -2045,7 +2045,7 @@ contains ! store full name call get_node_value(node_nuc, "name", temp_str) if (check_for_node(node_nuc, "xs")) & - call get_node_value(node_nuc, "xs", name) + call get_node_value(node_nuc, "xs", name) name = trim(temp_str) // "." // trim(name) name = to_lower(name) @@ -2058,7 +2058,7 @@ contains call list_density % append(ONE) else if (.not.check_for_node(node_nuc, "ao") .and. & - .not.check_for_node(node_nuc, "wo")) then + .not.check_for_node(node_nuc, "wo")) then call fatal_error("No atom or weight percent specified for nuclide " & &// trim(name)) elseif (check_for_node(node_nuc, "ao") .and. & @@ -2572,7 +2572,7 @@ contains ! If in MG mode, fail if user provides bins, as we are only ! allowing for all groups if (.not. run_CE .and. (temp_str == 'energy' .or. & - temp_str == 'energyout')) then + temp_str == 'energyout')) then call fatal_error("No energy or energyout bins needed on tally " & &// trim(to_str(t % id))) else @@ -4360,9 +4360,9 @@ contains ! Check if cross_sections.xml exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find cross_sections.xml file - call fatal_error("Cross sections XML file '" & - &// trim(path_cross_sections) // "' does not exist!") + ! Could not find cross_sections.xml file + call fatal_error("Cross sections XML file '" & + &// trim(path_cross_sections) // "' does not exist!") end if call write_message("Reading cross sections XML file...", 5) @@ -4371,18 +4371,18 @@ contains call open_xmldoc(doc, path_cross_sections) if (check_for_node(doc, "groups")) then - ! Get neutron group count - call get_node_value(doc, "groups", energy_groups) + ! Get neutron group count + call get_node_value(doc, "groups", energy_groups) else - call fatal_error("groups element must exist!") + call fatal_error("groups element must exist!") end if allocate(energy_bins(energy_groups + 1)) if (check_for_node(doc, "group_structure")) then - ! Get neutron group structure - call get_node_array(doc, "group_structure", energy_bins) + ! Get neutron group structure + call get_node_array(doc, "group_structure", energy_bins) else - call fatal_error("group_structures element must exist!") + call fatal_error("group_structures element must exist!") end if allocate(energy_bin_avg(energy_groups)) @@ -4396,10 +4396,10 @@ contains ! Allocate xs_listings array if (n_listings == 0) then - call fatal_error("No XSDATA listings present in cross_sections.xml & - &file!") + call fatal_error("No XSDATA listings present in cross_sections.xml & + &file!") else - allocate(xs_listings(n_listings)) + allocate(xs_listings(n_listings)) end if do i = 1, n_listings @@ -4413,7 +4413,7 @@ contains listing % name = to_lower(listing % name) listing % alias = listing % name if (check_for_node(node_xsdata, "alias")) & - call get_node_value(node_xsdata, "alias", listing % alias) + call get_node_value(node_xsdata, "alias", listing % alias) listing % alias = to_lower(listing % alias) if (check_for_node(node_xsdata, "zaid")) then call get_node_value(node_xsdata, "zaid", listing % zaid) @@ -4421,7 +4421,7 @@ contains listing % zaid = 100 end if if (check_for_node(node_xsdata, "kT")) & - call get_node_value(node_xsdata, "kT", listing % kT) + call get_node_value(node_xsdata, "kT", listing % kT) if (check_for_node(node_xsdata, "awr")) then call get_node_value(node_xsdata, "awr", listing % awr) else @@ -4430,12 +4430,12 @@ contains ! determine type of cross section if (ends_with(listing % name, 'c')) then - listing % type = NEUTRON + listing % type = NEUTRON end if - ! create dictionary entry for both name and alias - call xs_listing_dict % add_key(to_lower(listing % name), i) - call xs_listing_dict % add_key(to_lower(listing % alias), i) + ! create dictionary entry for both name and alias + call xs_listing_dict % add_key(to_lower(listing % name), i) + call xs_listing_dict % add_key(to_lower(listing % alias), i) end do ! Close cross sections XML file diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 602db4a3b6..b2d9a5fde6 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -249,16 +249,16 @@ contains do gin = 1, groups do gout = 1, groups this % chi(gout,gin) = this % chi(gout,gin) + atom_density * & - nuc % chi(gout) * nuc % nu_fission(gin,1) + nuc % chi(gout) * nuc % nu_fission(gin,1) end do end do this % nu_fission = this % nu_fission + atom_density * & - nuc % nu_fission(:,1) + nuc % nu_fission(:,1) else this % chi = this % chi + atom_density * nuc % nu_fission do gin = 1, groups this % nu_fission(gin) = this % nu_fission(gin) + atom_density * & - sum(nuc % nu_fission(:,gin)) + sum(nuc % nu_fission(:,gin)) end do end if this % fission = this % fission + atom_density * nuc % fission @@ -273,33 +273,33 @@ contains if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then ! Transfer matrix temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & - sum(nuc % scatter(gout,gin,:)) + sum(nuc % scatter(gout,gin,:)) ! Determine the angular distribution do imu = 1, order scatt_coeffs(imu, gout, gin) = scatt_coeffs(imu, gout, gin) + & - nuc % scatter(gout,gin,imu) * & - atom_density + nuc % scatter(gout,gin,imu) * & + atom_density end do else if (scatt_type == ANGLE_LEGENDRE) then ! Transfer matrix temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & - nuc % scatter(gout,gin,1) + nuc % scatter(gout,gin,1) ! Determine the angular distribution coefficients so we can later ! expand do the complete distribution do l = 1, min(nuc % order, order) + 1 scatt_coeffs(l, gout, gin) = scatt_coeffs(l, gout, gin) + & - nuc % scatter(gout,gin,l) * & - atom_density + nuc % scatter(gout,gin,l) * & + atom_density end do end if ! Multiplicity matrix temp_mult(gout,gin) = temp_mult(gout,gin) + atom_density * & - nuc % mult(gout,gin) + nuc % mult(gout,gin) end do end do type is (Nuclide_Angle) @@ -530,16 +530,16 @@ contains do gin = 1, groups do gout = 1, groups this % chi(gout,gin,:,:) = this % chi(gout,gin,:,:) + atom_density * & - nuc % chi(gout,:,:) * nuc % nu_fission(gin,1,:,:) + nuc % chi(gout,:,:) * nuc % nu_fission(gin,1,:,:) end do end do this % nu_fission = this % nu_fission + atom_density * & - nuc % nu_fission(:,1,:,:) + nuc % nu_fission(:,1,:,:) else this % chi = this % chi + atom_density * nuc % nu_fission do gin = 1, groups this % nu_fission(gin,:,:) = this % nu_fission(gin,:,:) + atom_density * & - sum(nuc % nu_fission(:,gin,:,:),dim=1) + sum(nuc % nu_fission(:,gin,:,:),dim=1) end do end if this % fission = this % fission + atom_density * nuc % fission @@ -554,31 +554,31 @@ contains if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then ! Transfer matrix temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & - sum(nuc % scatter(gout,gin,:,:,:),dim=1) + sum(nuc % scatter(gout,gin,:,:,:),dim=1) ! Determine the angular distribution do imu = 1, order scatt_coeffs(imu,gout,gin,:,:) = scatt_coeffs(imu,gout,gin,:,:) + & - nuc % scatter(gout,gin,imu,:,:) * & - atom_density + nuc % scatter(gout,gin,imu,:,:) * & + atom_density end do else if (scatt_type == ANGLE_LEGENDRE) then ! Transfer matrix temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & - nuc % scatter(gout,gin,1,:,:) + nuc % scatter(gout,gin,1,:,:) ! Determine the angular distribution coefficients so we can later ! expand do the complete distribution do l = 1, min(nuc % order, order) + 1 scatt_coeffs(l, gout, gin,:,:) = scatt_coeffs(l, gout, gin,:,:) + & - nuc % scatter(gout,gin,l,:,:) * & - atom_density + nuc % scatter(gout,gin,l,:,:) * & + atom_density end do end if ! Multiplicity matrix temp_mult(gout,gin,:,:) = temp_mult(gout,gin,:,:) + atom_density * & - nuc % mult(gout,gin,:,:) + nuc % mult(gout,gin,:,:) end do end do end select diff --git a/src/mesh.F90 b/src/mesh.F90 index 9cb8dc5969..3704b9602c 100644 --- a/src/mesh.F90 +++ b/src/mesh.F90 @@ -163,12 +163,12 @@ contains sites_outside) type(RegularMesh), pointer :: m ! mesh to count sites - type(Bank), intent(in) :: bank_array(:) ! fission or source bank - real(8), intent(out) :: cnt(:,:,:,:) ! weight of sites in each + type(Bank), intent(in) :: bank_array(:) ! fission or source bank + real(8), intent(out) :: cnt(:,:,:,:) ! weight of sites in each ! cell and energy group - real(8), optional :: energies(:) ! energy grid to search - integer(8), optional :: size_bank ! # of bank sites (on each proc) - logical, optional :: sites_outside ! were there sites outside mesh? + real(8), optional :: energies(:) ! energy grid to search + integer(8), optional :: size_bank ! # of bank sites (on each proc) + logical, optional :: sites_outside ! were there sites outside mesh? integer :: i ! loop index for local fission sites integer :: n_sites ! size of bank array diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index c9830f8d0f..b89c73d51a 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -43,9 +43,9 @@ contains ! Check if cross_sections.xml exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find cross_sections.xml file - call fatal_error("Cross sections XML file '" & - &// trim(path_cross_sections) // "' does not exist!") + ! Could not find cross_sections.xml file + call fatal_error("Cross sections XML file '" & + &// trim(path_cross_sections) // "' does not exist!") end if call write_message("Loading Cross Section Data...", 5) @@ -73,7 +73,7 @@ contains end if end do if (get_kfiss) & - exit + exit end do ! ========================================================================== @@ -265,7 +265,7 @@ contains this % legendre_mu_points = 33 end if if (enable_leg_mu .and. & - check_for_node(node_legendre_mu, "num_points")) then + check_for_node(node_legendre_mu, "num_points")) then call get_node_value(node_legendre_mu, "num_points", & this % legendre_mu_points) if (this % legendre_mu_points <= 0) then @@ -644,7 +644,7 @@ contains end if end do if (get_kfiss) & - exit + exit end do allocate(macro_xs(n_materials)) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index ad143facb9..7786537db5 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -374,7 +374,7 @@ module nuclide_header if (allocated(this % k_fission)) then deallocate(this % k_fission) end if - if (allocated(this % chi)) then + if (allocated(this % chi)) then deallocate(this % chi) end if if (allocated(this % mult)) then @@ -400,7 +400,7 @@ module nuclide_header if (allocated(this % k_fission)) then deallocate(this % k_fission) end if - if (allocated(this % chi)) then + if (allocated(this % chi)) then deallocate(this % chi) end if diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 38e144e625..a63b1ce134 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -33,6 +33,7 @@ contains ! Store pre-collision particle properties p % last_wgt = p % wgt p % last_g = p % g + p % last_E = p % E p % last_uvw = p % coord(1) % uvw ! Add to collision counter for particle From 6ca9949a915e9c4b25784b36b6cea55fe8d7f4de Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 10 Nov 2015 04:54:35 -0500 Subject: [PATCH 28/84] Updated docs to reflect MG usage, though I still have to add the MGXS data format somewhere. Corrected ace.F90 typo pointed out by @samuelshaner --- docs/source/index.rst | 7 +- docs/source/usersguide/beginners.rst | 2 +- docs/source/usersguide/input.rst | 112 ++++++++++++++++++++++++--- docs/source/usersguide/install.rst | 26 +++++-- examples/xml/c5g7/2d/cmfd.xml | 11 +-- examples/xml/c5g7/2d/settings.xml | 2 +- src/ace.F90 | 2 +- src/input_xml.F90 | 2 +- 8 files changed, 131 insertions(+), 33 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 8dba920161..54ba825e58 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,9 +4,10 @@ The OpenMC Monte Carlo Code OpenMC is a Monte Carlo particle transport simulation code focused on neutron criticality calculations. It is capable of simulating 3D models based on -constructive solid geometry with second-order surfaces. The particle interaction -data is based on ACE format cross sections, also used in the MCNP and Serpent -Monte Carlo codes. +constructive solid geometry with second-order surfaces. OpenMC supports either +continuous-energy or multi-group transport. The continuous-energy +particle interaction data is based on ACE format cross sections, also used +in the MCNP and Serpent Monte Carlo codes. OpenMC was originally developed by members of the `Computational Reactor Physics Group`_ at the `Massachusetts Institute of Technology`_ starting diff --git a/docs/source/usersguide/beginners.rst b/docs/source/usersguide/beginners.rst index d65ee1f831..9ecffe3f67 100644 --- a/docs/source/usersguide/beginners.rst +++ b/docs/source/usersguide/beginners.rst @@ -12,7 +12,7 @@ In a nutshell, OpenMC simulates neutrons moving around randomly in a `nuclear reactor`_ (or other fissile system). This is what's known as `Monte Carlo`_ simulation. Neutrons are important in nuclear reactors because they are the particles that induce `fission`_ in uranium and other nuclides. Knowing the -behavior of neutrons allows you to figure out how often and where fission +behavior of neutrons allows you to determine how often and where fission occurs. The amount of energy released is then directly proportional to the fission reaction rate since most heat is produced by fission. By simulating many neutrons (millions or billions), it is possible to determine the average diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index d05dcdf71b..3e7a6ec174 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -114,7 +114,8 @@ The ```` element has no attributes and simply indicates the path to an XML cross section listing file (usually named cross_sections.xml). If this element is absent from the settings.xml file, the :envvar:`CROSS_SECTIONS` environment variable will be used to find the path to the XML cross section -listing. +listing when in continuous-energy mode, and the :envvar:`MG_CROSS_SECTIONS` +environment variable will be used in multi-group mode. ```` Element -------------------- @@ -212,8 +213,21 @@ cross section values between. *Default*: logarithm + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + .. _LA-UR-14-24530: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf +.. _energy_mode: + +```` Element +------------------------- + +The ```` element tells OpenMC if the run-mode should be +continuous-energy or multi-group. Options for entry are: ``continuous-energy`` +or ``multi-group``. + + *Default*: continuous-energy + ```` Element --------------------- @@ -264,6 +278,20 @@ based on the recommended value in LA-UR-14-24530_. *Default*: 8000 + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + +```` Element +--------------------------- + +The ```` element allows the user to set a maximum scattering order +to apply to every nuclide/material in the problem. That is, if the data +library has :math:`P_3` data available, but ```` was set to ``1``, +then, OpenMC will only use up to the :math:`P_1` data. + + *Default*: Use the maximum order in the data library + + .. note:: This element is not used in the continuous-energy :ref:`energy_mode`. + .. _natural_elements: ```` Element @@ -343,6 +371,8 @@ or sub-elements and can be set to either "false" or "true". *Default*: true + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + ```` Element ---------------------------------- @@ -402,6 +432,8 @@ attributes or sub-elements: *Defaults*: None (scatterer), ARES (method), 0.01 eV (E_min), 1.0 keV (E_max) + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + ```` Element ---------------------- @@ -514,6 +546,8 @@ attributes/sub-elements: *Default*: 0.988 2.249 + .. note:: The above format should be used even when using the multi-group :ref:`energy_mode`. + :write_initial: An element specifying whether to write out the initial source bank used at the beginning of the first batch. The output file is named @@ -1113,10 +1147,15 @@ Each ``material`` element can have the following attributes or sub-elements: :density: An element with attributes/sub-elements called ``value`` and ``units``. The ``value`` attribute is the numeric value of the density while the ``units`` - can be "g/cm3", "kg/m3", "atom/b-cm", "atom/cm3", or "sum". The "sum" unit - indicates that the density should be calculated as the sum of the atom - fractions for each nuclide in the material. This should not be used in - conjunction with weight percents. + can be "g/cm3", "kg/m3", "atom/b-cm", "atom/cm3", "sum", or "macro". + The "sum" unit indicates that the density should be calculated as the sum + of the atom fractions for each nuclide in the material. This should not be + used in conjunction with weight percents. The "macro" unit is used with + a ``macroscopic`` to indicate that the density is already included in the + library and thus not needed here. However, if a value is provided for the + ``value``, then this is treated as a number density multiplier on the + macroscopic cross sections in the multi-group data. This can be used, + for example, when perturbing the density slightly. *Default*: None @@ -1171,6 +1210,24 @@ Each ``material`` element can have the following attributes or sub-elements: *Default*: None + :macroscopic: + The ``macroscopic`` element is similar to the ``nuclide`` element, but, + recognizes that some multi-group libraries may be providing material + specific macroscopic cross sections instead of always providing nuclide + specific data like in the continuous-energy case. To that end, the + macroscopic element has attributes/sub-elements called ``name``, and ``xs``. + The ``name`` attribute is the name of the cross-section for a + desired nuclide while the ``xs`` attribute is the cross-section + identifier. One example would be as follows: + + .. code-block:: xml + + + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + + *Default*: None + .. _IUPAC Isotopic Compositions of the Elements 2009: http://pac.iupac.org/publications/pac/pdf/2011/pdf/8302x0397.pdf @@ -1257,7 +1314,8 @@ The ```` element accepts the following sub-elements: A list of universes for which the tally should be accumulated. :energy: - A monotonically increasing list of bounding **pre-collision** energies + In continuous-energy mode, this filter should be provided as a + monotonically increasing list of bounding **pre-collision** energies for a number of groups. For example, if this filter is specified as .. code-block:: xml @@ -1267,17 +1325,40 @@ The ```` element accepts the following sub-elements: then two energy bins will be created, one with energies between 0 and 1 MeV and the other with energies between 1 and 20 MeV. + In multi-group mode, however, the bounds of the filter are already + implied as being the same as the group boundaries of the problem. + Therefore no bins would be needed as they are implicitly applied by + the code. For example, the above filter example for continuous-energy + mode would look like the following for multi-group mode, but the + resultant tallies would still be done for every group in the library: + + .. code-block:: xml + + + :energyout: - A monotonically increasing list of bounding **post-collision** - energies for a number of groups. For example, if this filter is - specified as + In continuous-energy mode, this filter should be provided as a + monotonically increasing list of bounding **post-collision** energies + for a number of groups. For example, if this filter is specified as .. code-block:: xml - then two post-collision energy bins will be created, one with energies - between 0 and 1 MeV and the other with energies between 1 and 20 MeV. + then two post-collision energy bins will be created, one with + energies between 0 and 1 MeV and the other with energies between + 1 and 20 MeV. + + In multi-group mode, however, the bounds of the filter are already + implied as being the same as the group boundaries of the problem. + Therefore no bins would be needed as they are implicitly applied by + the code. For example, the above filter example for continuous-energy + mode would look like the following for multi-group mode, but the + resultant tallies would still be done for every group in the library: + + .. code-block:: xml + + :mu: A monotonically increasing list of bounding **post-collision** cosines @@ -1361,6 +1442,8 @@ The ```` element accepts the following sub-elements: + .. note:: This filter type is not used in the multi-group :ref:`energy_mode`. + :nuclides: If specified, the scores listed will be for particular nuclides, not the summation of reactions from all nuclides. The format for nuclides should be @@ -1424,6 +1507,8 @@ The ```` element accepts the following sub-elements: Total production of delayed neutrons due to fission. Units are neutrons produced per source neutron. + .. note:: This score type is not used in the multi-group :ref:`energy_mode`. + :kappa-fission: The recoverable energy production rate due to fission. The recoverable energy is defined as the fission product kinetic energy, prompt and @@ -1494,6 +1579,8 @@ The ```` element accepts the following sub-elements: The ``analog`` estimator is actually identical to the ``collision`` estimator for the inverse-velocity score. + .. note:: This score type is not used in the multi-group :ref:`energy_mode`. + :events: Number of scoring events. Units are events per source particle. @@ -1871,6 +1958,9 @@ attributes/sub-elements: automatically assumes a one energy group calculation over the entire energy range. + .. note:: When running in the multi-group :ref:`energy_mode`, these + energy bins must match the data library's group boundaries. + :albedo: Surface ratio of incoming to outgoing partial currents on global boundary conditions. They are listed in the following order: -x +x -y +y -z +z. diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index dcf990bdad..246e343c1e 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -366,11 +366,17 @@ Cross Section Configuration --------------------------- In order to run a simulation with OpenMC, you will need cross section data for -each nuclide in your problem. Since OpenMC uses ACE format cross sections, you -can use nuclear data that was processed with NJOY_, such as that distributed -with MCNP_ or Serpent_. Several sources provide free processed ACE data as -described below. The TALYS-based evaluated nuclear data library, TENDL_, is also -openly available in ACE format. +each nuclide or material in your problem. OpenMC can be run in +continuous-energy or multi-group mode. + +In continuous-energy mode OpenMC uses ACE format cross sections; in this case +you can use nuclear data that was processed with NJOY_, such as that +distributed with MCNP_ or Serpent_. Several sources provide free processed +ACE data as described below. The TALYS-based evaluated nuclear data library, +TENDL_, is also openly available in ACE format. + +In multi-group mode, OpenMC utilizes an XML-based library format which can be +used to describe nuclidic- or material-specific quantities. Using ENDF/B-VII.1 Cross Sections from NNDC ------------------------------------------- @@ -435,6 +441,16 @@ distribution to the location of the Serpent cross sections. Then, either set the environment variable to the absolute path of the ``cross_sections_serpent.xml`` file. +Using Multi-Group Cross Sections +-------------------------------- + +Multi-group cross section libraries are generally tailored to the specific +calculation to be performed. Therefore, at this point in time, OpenMC is not +distributed with any pre-existing multi-group cross section libraries. +However, if the user has obtained or generated their own library, the user +should set the :envvar:`MG_CROSS_SECTIONS` environment variable +to the absolute path of the file library expected to used most frequently. + .. _NJOY: http://t2.lanl.gov/nis/codes.shtml .. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html .. _NEA: http://www.oecd-nea.org diff --git a/examples/xml/c5g7/2d/cmfd.xml b/examples/xml/c5g7/2d/cmfd.xml index aa3deb4b67..8e8d77490c 100644 --- a/examples/xml/c5g7/2d/cmfd.xml +++ b/examples/xml/c5g7/2d/cmfd.xml @@ -1,21 +1,12 @@ - 2 + 10 true 0.0 0.0 -100.0 64.26 64.26 100.0 6 6 1 - - - 2 2 2 2 1 1 - 2 2 2 2 1 1 - 2 2 2 2 1 1 - 2 2 2 2 1 1 - 1 1 1 1 1 1 - 1 1 1 1 1 1 - 1 0 0 1 1 1 diff --git a/examples/xml/c5g7/2d/settings.xml b/examples/xml/c5g7/2d/settings.xml index 2ad738704a..038c80c303 100644 --- a/examples/xml/c5g7/2d/settings.xml +++ b/examples/xml/c5g7/2d/settings.xml @@ -8,7 +8,7 @@ 2000 500 - 1000 + 10000 - 2000 - 500 + 100 + 10 1000 diff --git a/openmc/__init__.py b/openmc/__init__.py index 397d9f3e27..5bdc3f089a 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -1,11 +1,13 @@ from openmc.element import * from openmc.geometry import * from openmc.nuclide import * +from openmc.macroscopic import * from openmc.material import * from openmc.plots import * from openmc.settings import * from openmc.surface import * from openmc.universe import * +from openmc.mgxs_library import * from openmc.mesh import * from openmc.filter import * from openmc.trigger import * diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index 787052f5d6..303f784078 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -127,7 +127,7 @@ def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): # But first, have we exceeded the max depth? if len(tree) > max_depth: msg = 'Error setting {0}: Found an iterable at {1}, items '\ - 'in that iterable excceed the maximum depth of {2}' \ + 'in that iterable exceed the maximum depth of {2}' \ .format(name, ind_str, max_depth) raise ValueError(msg) diff --git a/openmc/material.py b/openmc/material.py index b8d13eb979..4ccc9485e0 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -325,17 +325,16 @@ class Material(object): """ - # Ensureno nuclides, elements, or sab are added since these would be + # Ensure no nuclides, elements, or sab are added since these would be # incompatible with macroscopics - if (not self._nuclides) and (not self._elements) and (not self._sab): + if ((len(self._nuclides.keys()) != 0) and + (len(self._elements.keys()) != 0) and (len(self._sab) != 0)): msg = 'Unable to add a Macroscopic data set to Material ID="{0}" ' \ 'with a macroscopic value "{1}" as an incompatible data ' \ 'member (i.e., nuclide, element, or S(a,b) table) ' \ 'has already been added'.format(self._id, macroscopic) raise ValueError(msg) - - if not isinstance(macroscopic, (openmc.Macroscopic, str)): msg = 'Unable to add a Macroscopic to Material ID="{0}" with a ' \ 'non-Macroscopic value "{1}"'.format(self._id, macroscopic) @@ -348,7 +347,7 @@ class Material(object): else: macroscopic = openmc.Macroscopic(macroscopic) - if self._macroscopic is not None: + if self._macroscopic is None: self._macroscopic = macroscopic else: msg = 'Unable to add a Macroscopic to Material ID="{0}", ' \ @@ -577,7 +576,7 @@ class Material(object): element.append(subelement) else: # Create macroscopic XML subelements - subelement = self._get_macroscopic_xml(self, self._macroscopic) + subelement = self._get_macroscopic_xml(self._macroscopic) element.append(subelement) else: diff --git a/openmc/mgxs/groups.py b/openmc/mgxs/groups.py index 3436c0e037..e6838b36ba 100644 --- a/openmc/mgxs/groups.py +++ b/openmc/mgxs/groups.py @@ -54,7 +54,7 @@ class EnergyGroups(object): def __eq__(self, other): if not isinstance(other, EnergyGroups): return False - elif self.group_edges != other.group_edges: + elif (self.group_edges != other.group_edges).all(): return False else: return True diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 70023c2c89..282997983b 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -10,7 +10,8 @@ import numpy as np import openmc from openmc.mgxs import EnergyGroups -from openmc.checkvalue import check_type, check_value, check_greater_than +from openmc.checkvalue import check_type, check_value, check_greater_than, \ + check_iterable_type from openmc.clean_xml import * # MGXS Representations supported by OpenMC @@ -114,6 +115,7 @@ class Xsdata(object): self._nu_fission = None self._k_fission = None self._chi = None + self._use_chi = None @property def name(self): @@ -123,6 +125,11 @@ class Xsdata(object): def energy_groups(self): return self._energy_groups + @property + def representation(self): + return self._representation + + @property def alias(self): return self._alias @@ -202,7 +209,9 @@ class Xsdata(object): check_type("energy_groups", energy_groups, EnergyGroups) # Check that there is one or more groups - if (energy_groups.num_energy_groups.num_group is None) or (energy_groups.num_energy_groups.num_group < 1): + if ((energy_groups.num_energy_groups.num_group is None) or + (energy_groups.num_energy_groups.num_group < 1)): + msg = 'energy_groups object incorrectly initialized.' raise ValueError(msg) @@ -262,13 +271,15 @@ class Xsdata(object): num_points = 33 self._tabular_legendre = {'enable': enable, 'num_points': num_points} - @num_polar.setter(self, num_polar): + @num_polar.setter + def num_polar(self, num_polar): # Make sure we have positive ints check_value("num_polar", num_polar, Integral) check_greater_than("num_polar", num_polar, 0) self._num_polar = num_polar - @num_azimuthal.setter(self, num_azimuthal): + @num_azimuthal.setter + def num_azimuthal(self, num_azimuthal): check_value("num_azimuthal", num_azimuthal, Integral) check_greater_than("num_azimuthal", num_azimuthal, 0) self._num_azimuthal = num_azimuthal @@ -276,10 +287,10 @@ class Xsdata(object): @total.setter def total(self, total): if self._representation is 'isotropic': - shape = (self._energy_groups.num_group) + shape = (self._energy_groups.num_groups,) elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) # check we have a numpy list check_type("total", total, np.ndarray, expected_iter_type=Real) if total.shape == shape: @@ -292,10 +303,10 @@ class Xsdata(object): @absorption.setter def absorption(self, absorption): if self._representation is 'isotropic': - shape = (self._energy_groups.num_group) + shape = (self._energy_groups.num_groups,) elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) # check we have a numpy list check_type("absorption", absorption, np.ndarray, expected_iter_type=Real) if absorption.shape == shape: @@ -308,10 +319,10 @@ class Xsdata(object): @fission.setter def fission(self, fission): if self._representation is 'isotropic': - shape = (self._energy_groups.num_group) + shape = (self._energy_groups.num_groups,) elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) # check we have a numpy list check_type("fission", fission, np.ndarray, expected_iter_type=Real) if fission.shape == shape: @@ -326,10 +337,10 @@ class Xsdata(object): @k_fission.setter def k_fission(self, k_fission): if self._representation is 'isotropic': - shape = (self._energy_groups.num_group) + shape = (self._energy_groups.num_groups,) elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) # check we have a numpy list check_type("k_fission", k_fission, np.ndarray, expected_iter_type=Real) if k_fission.shape == shape: @@ -343,14 +354,14 @@ class Xsdata(object): @chi.setter def chi(self, chi): - if self._use_chi is not None: + if not self._use_chi: msg = 'Providing chi when nu_fission already provided as matrix!' raise ValueError(msg) if self._representation is 'isotropic': - shape = (self._energy_groups.num_group) + shape = (self._energy_groups.num_groups,) elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) # check we have a numpy list check_type("chi", chi, np.ndarray, expected_iter_type=Real) if chi.shape == shape: @@ -365,14 +376,17 @@ class Xsdata(object): @scatter.setter def scatter(self, scatter): if self._representation is 'isotropic': - shape = (self.num_orders, self._energy_groups.num_group, - self._energy_groups.num_group) + shape = (self.num_orders, self._energy_groups.num_groups, + self._energy_groups.num_groups) + max_depth = 3 elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, self.num_orders, - self._energy_groups.num_group, - self._energy_groups.num_group) + self._energy_groups.num_groups, + self._energy_groups.num_groups) + max_depth = 5 # check we have a numpy list - check_type("scatter", scatter, np.ndarray, expected_iter_type=Real) + check_iterable_type("scatter", scatter, expected_type=Real, + max_depth=max_depth) if scatter.shape == shape: self._scatter = np.copy(scatter) else: @@ -384,14 +398,16 @@ class Xsdata(object): def multiplicity(self, multiplicity): if self._representation is 'isotropic': shape = (self._energy_groups.num_group, - self._energy_groups.num_group) + self._energy_groups.num_groups) + max_depth = 2 elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, self._energy_groups.num_group, - self._energy_groups.num_group) + self._energy_groups.num_groups) + max_depth = 4 # check we have a numpy list - check_type("multiplicity", multiplicity, np.ndarray, - expected_iter_type=Real) + check_iterable_type("multiplicity", multiplicity, expected_type=Real, + max_depth=max_depth) if multiplicity.shape == shape: self._multiplicity = np.copy(multiplicity) else: @@ -411,15 +427,15 @@ class Xsdata(object): # First lets set our dimensions here since they get used repeatedly # throughout this code. if self._representation is 'isotropic': - shape_vec = (self._energy_groups.num_group) - shape_mat = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + shape_vec = (self._energy_groups.num_groups,) + shape_mat = (self._energy_groups.num_groups, + self._energy_groups.num_groups) elif self._representation is 'angle': shape_vec = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group) + self._energy_groups.num_groups) shape_mat = (self._num_polar, self._num_azimuthal, self._energy_groups.num_group, - self._energy_groups.num_group) + self._energy_groups.num_groups) # Begin by checking the case when chi has already been given and thus # the rules for filling in nu_fission are set. @@ -428,7 +444,7 @@ class Xsdata(object): shape = shape_vec else: shape = shape_mat - if nu_fission.shape /= shape: + if nu_fission.shape != shape: msg = "Invalid Shape of Nu_fission!" raise ValueError(msg) else: @@ -436,7 +452,7 @@ class Xsdata(object): if nu_fission.shape == shape_vec: self._use_chi = True shape = shape_vec - elif nu_fission.shape = shape_mat: + elif nu_fission.shape == shape_mat: self._use_chi = False shape = shape_mat else: @@ -449,77 +465,77 @@ class Xsdata(object): def _get_xsdata_xml(self): element = ET.Element("xsdata") - element.set("name", xsdata._name) + element.set("name", self._name) - if xsdata._alias is not None: + if self._alias is not None: subelement = ET.SubElement(element, 'alias') - subelement.text(xsdata.alias) + subelement.text = self.alias - if xsdata._kT is not None: + if self._kT is not None: subelement = ET.SubElement(element, 'kT') - subelement.text(str(self._kT)) + subelement.text = str(self._kT) - if xsdata._fissionable is not None: + if self._fissionable is not None: subelement = ET.SubElement(element, 'fissionable') - subelement.text(str(self._fissionable)) + subelement.text = str(self._fissionable) - if xsdata._representation is not None: + if self._representation is not None: subelement = ET.SubElement(element, 'representation') - subelement.text(self._representation) + subelement.text = self._representation - if xsdata._representation == 'angle': - if xsdata._num_azimuthal is not None: + if self._representation == 'angle': + if self._num_azimuthal is not None: subelement = ET.SubElement(element, 'num_azimuthal') - subelement.text(str(self._num_azimuthal)) - if xsdata._num_polar is not None: + subelement.text = str(self._num_azimuthal) + if self._num_polar is not None: subelement = ET.SubElement(element, 'num_polar') - subelement.text(str(self._num_polar)) + subelement.text = str(self._num_polar) - if xsdata._scatt_type is not None: + if self._scatt_type is not None: subelement = ET.SubElement(element, 'scatt_type') - subelement.text(self._scatt_type) + subelement.text = self._scatt_type - if xsdata._order is not None: + if self._order is not None: subelement = ET.SubElement(element, 'order') - subelement.text(str(self._order)) + subelement.text = str(self._order) - if xsdata._tabular_legendre is not None: + if self._tabular_legendre is not None: subelement = ET.SubElement(element, 'tabular_legendre') - subelement.set('enable', str(xsdata._tabular_legendre['enable'])) - subelement.set('num_points', str(xsdata._tabular_legendre['num_points'])) + subelement.set('enable', str(self._tabular_legendre['enable'])) + subelement.set('num_points', str(self._tabular_legendre['num_points'])) if self._total is not None: subelement = ET.SubElement(element, 'total') - subelement.text(ndarray_to_string(self._total)) + subelement.text = ndarray_to_string(self._total) if self._absorption is not None: subelement = ET.SubElement(element, 'absorption') - subelement.text(ndarray_to_string(self._absorption)) + subelement.text = ndarray_to_string(self._absorption) if self._scatter is not None: subelement = ET.SubElement(element, 'scatter') - subelement.text(ndarray_to_string(self._scatter)) + subelement.text = ndarray_to_string(self._scatter) if self._multiplicity is not None: subelement = ET.SubElement(element, 'multiplicity') - subelement.text(ndarray_to_string(self._multiplicity)) + subelement.text = ndarray_to_string(self._multiplicity) if self._fissionable: if self._fission is not None: subelement = ET.SubElement(element, 'fission') - subelement.text(ndarray_to_string(self._fission)) + subelement.text = ndarray_to_string(self._fission) if self._k_fission is not None: subelement = ET.SubElement(element, 'k_fission') - subelement.text(ndarray_to_string(self._k_fission)) + subelement.text = ndarray_to_string(self._k_fission) if self._nu_fission is not None: subelement = ET.SubElement(element, 'nu_fission') - subelement.text(ndarray_to_string(self._nu_fission)) + subelement.text = ndarray_to_string(self._nu_fission) if self._chi is not None: subelement = ET.SubElement(element, 'chi') - subelement.text(ndarray_to_string(self._chi)) + subelement.text = ndarray_to_string(self._chi) return element @@ -581,7 +597,7 @@ class MGXSLibraryFile(object): raise ValueError(msg) # Make sure energy groups match. - if xsdata.energy_groups /= self._energy_groups: + if xsdata.energy_groups != self._energy_groups: msg = 'Energy groups of Xsdata do not match that of MGXSLibraryFile!' raise ValueError(msg) @@ -625,7 +641,7 @@ class MGXSLibraryFile(object): def _create_groups_subelement(self): if self._energy_groups is not None: element = ET.SubElement(self._cross_sections_file, "groups") - element.text = str(self._energy_groups.num_group) + element.text = str(self._energy_groups.num_groups) def _create_group_structure_subelement(self): if self._energy_groups is not None: @@ -641,7 +657,7 @@ class MGXSLibraryFile(object): def _create_xsdata_subelements(self): for xsdata in self._xsdatas: - xml_element = xsdata.get_xsdata_xml() + xml_element = xsdata._get_xsdata_xml() self._cross_sections_file.append(xml_element) From 5e788cdffb7f5ba836da4a9c5c114c19d0c3b8f6 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 16 Nov 2015 05:31:40 -0500 Subject: [PATCH 39/84] Whoops, forgot to add --- .../python/pincell_multigroup/build-xml.py | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 examples/python/pincell_multigroup/build-xml.py diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py new file mode 100644 index 0000000000..300f36ce01 --- /dev/null +++ b/examples/python/pincell_multigroup/build-xml.py @@ -0,0 +1,185 @@ +import openmc +import openmc.mgxs +import numpy as np + +############################################################################### +# Simulation Input File Parameters +############################################################################### + +# OpenMC simulation parameters +batches = 100 +inactive = 10 +particles = 1000 + +############################################################################### +# Exporting to OpenMC mg_cross_sections.xml File +############################################################################### + +# Instantiate the energy group data +groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, + 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) + +# Instantiate the 7-group (C5G7) cross section data +uo2_xsdata = openmc.Xsdata('UO2.300k', groups) +uo2_xsdata.order = 0 +uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, + 0.3118013, 0.3951678, 0.5644058]) +uo2_xsdata.absorption = np.array([8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, + 3.0020E-02, 1.1126E-01, 2.8278E-01]) +scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]] +uo2_xsdata.scatter = np.array(scatter[:][:]) +uo2_xsdata.fission = np.array([7.21206E-03, 8.19301E-04, 6.45320E-03, + 1.85648E-02, 1.78084E-02, 8.30348E-02, + 2.16004E-01]) +uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, + 4.518301E-02, 4.334208E-02, 2.020901E-01, + 5.257105E-01]) +uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, + 0.0000E+00, 0.0000E+00, 0.0000E+00]) + +h2o_xsdata = openmc.Xsdata('LWTR.300k', groups) +h2o_xsdata.order = 0 +h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, + 0.718, 1.2544497, 2.650379]) +h2o_xsdata.absorption = np.array([6.0105E-04, 1.5793E-05, 3.3716E-04, + 1.9406E-03, 5.7416E-03, 1.5001E-02, + 3.7239E-02]) +scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], + [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], + [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], + [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], + [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]] +h2o_xsdata.scatter = np.array(scatter[:][:]) + +mg_cross_sections_file = openmc.MGXSLibraryFile(groups) +mg_cross_sections_file.add_xsdatas([uo2_xsdata,h2o_xsdata]) +mg_cross_sections_file.export_to_xml() + + +############################################################################### +# Exporting to OpenMC materials.xml File +############################################################################### + +# Instantiate some Macroscopic Data +uo2_data = openmc.Macroscopic('UO2', '300k') +h2o_data = openmc.Macroscopic('LWTR', '300k') + +# Instantiate some Materials and register the appropriate Nuclides +uo2 = openmc.Material(material_id=1, name='UO2 fuel') +uo2.set_density('macro', 1.0) +uo2.add_macroscopic(uo2_data) + +water = openmc.Material(material_id=2, name='Water') +water.set_density('macro', 1.0) +water.add_macroscopic(h2o_data) + +# Instantiate a MaterialsFile, register all Materials, and export to XML +materials_file = openmc.MaterialsFile() +materials_file.default_xs = '300k' +materials_file.add_materials([uo2, water]) +materials_file.export_to_xml() + + +############################################################################### +# Exporting to OpenMC geometry.xml File +############################################################################### + +# Instantiate ZCylinder surfaces +fuel_or = openmc.ZCylinder(surface_id=1, x0=0, y0=0, R=0.54, name='Fuel OR') +left = openmc.XPlane(surface_id=4, x0=-0.63, name='left') +right = openmc.XPlane(surface_id=5, x0=0.63, name='right') +bottom = openmc.YPlane(surface_id=6, y0=-0.63, name='bottom') +top = openmc.YPlane(surface_id=7, y0=0.63, name='top') + +left.boundary_type = 'reflective' +right.boundary_type = 'reflective' +top.boundary_type = 'reflective' +bottom.boundary_type = 'reflective' + +# Instantiate Cells +fuel = openmc.Cell(cell_id=1, name='cell 1') +moderator = openmc.Cell(cell_id=2, name='cell 2') + +# Use surface half-spaces to define regions +fuel.region = -fuel_or +moderator.region = +fuel_or & +left & -right & +bottom & -top + +# Register Materials with Cells +fuel.fill = uo2 +moderator.fill = water + +# Instantiate Universe +root = openmc.Universe(universe_id=0, name='root universe') + +# Register Cells with Universe +root.add_cells([fuel, moderator]) + +# Instantiate a Geometry and register the root Universe +geometry = openmc.Geometry() +geometry.root_universe = root + +# Instantiate a GeometryFile, register Geometry, and export to XML +geometry_file = openmc.GeometryFile() +geometry_file.geometry = geometry +geometry_file.export_to_xml() + + +############################################################################### +# Exporting to OpenMC settings.xml File +############################################################################### + +# Instantiate a SettingsFile, set all runtime parameters, and export to XML +settings_file = openmc.SettingsFile() +settings_file.energy_mode = "multi-group" +settings_file.cross_sections = "./mg_cross_sections.xml" +settings_file.batches = batches +settings_file.inactive = inactive +settings_file.particles = particles +settings_file.set_source_space('box', [-0.63, -0.63, -1, \ + 0.63, 0.63, 1]) +settings_file.entropy_lower_left = [-0.54, -0.54, -1.e50] +settings_file.entropy_upper_right = [0.54, 0.54, 1.e50] +settings_file.entropy_dimension = [10, 10, 1] +settings_file.export_to_xml() + + +############################################################################### +# Exporting to OpenMC tallies.xml File +############################################################################### + +# Instantiate a tally mesh +mesh = openmc.Mesh(mesh_id=1) +mesh.type = 'regular' +mesh.dimension = [100, 100, 1] +mesh.lower_left = [-0.63, -0.63, -1.e50] +mesh.upper_right = [0.63, 0.63, 1.e50] + +# Instantiate some tally Filters +# energy_filter = openmc.Filter(type='energy', +# bins=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, +# 0.5, 1.0, 20.0]) +energy_filter = openmc.Filter(type='energy') +mesh_filter = openmc.Filter() +mesh_filter.mesh = mesh + +# Instantiate the Tally +tally = openmc.Tally(tally_id=1, name='tally 1') +tally.add_filter(energy_filter) +tally.add_filter(mesh_filter) +tally.add_score('flux') +tally.add_score('fission') +tally.add_score('nu-fission') + +# Instantiate a TalliesFile, register all Tallies, and export to XML +tallies_file = openmc.TalliesFile() +tallies_file.add_mesh(mesh) +tallies_file.add_tally(tally) +tallies_file.export_to_xml() From 5965e92e46e6b12f0212220c8bcb105e7ac1344c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 16 Nov 2015 20:33:42 -0500 Subject: [PATCH 40/84] fixed formatting of python api created mgxs library, added example pincell_multigroup to xml folder, and removed c5g7 as that will be pushed to benchmarks instead once this is complete. --- examples/xml/c5g7/2d/cmfd.xml | 12 -- examples/xml/c5g7/2d/geometry.xml | 118 --------------- examples/xml/c5g7/2d/materials.xml | 1 - examples/xml/c5g7/2d/plots.xml | 29 ---- examples/xml/c5g7/2d/settings.xml | 44 ------ examples/xml/c5g7/2d/tallies.xml | 25 ---- examples/xml/c5g7/3d/geometry.xml | 138 ------------------ examples/xml/c5g7/3d/materials.xml | 1 - examples/xml/c5g7/3d/plots.xml | 42 ------ examples/xml/c5g7/3d/settings.xml | 47 ------ examples/xml/c5g7/3d/tallies.xml | 33 ----- examples/xml/c5g7/pin/materials.xml | 1 - examples/xml/c5g7/pin/tallies.xml | 16 -- .../pin => pincell_multigroup}/geometry.xml | 0 .../materials.xml | 0 .../mg_cross_sections.xml} | 0 .../pin => pincell_multigroup}/plots.xml | 0 .../pin => pincell_multigroup}/settings.xml | 2 +- examples/xml/pincell_multigroup/tallies.xml | 13 ++ openmc/mgxs_library.py | 54 ++++--- 20 files changed, 47 insertions(+), 529 deletions(-) delete mode 100644 examples/xml/c5g7/2d/cmfd.xml delete mode 100644 examples/xml/c5g7/2d/geometry.xml delete mode 120000 examples/xml/c5g7/2d/materials.xml delete mode 100644 examples/xml/c5g7/2d/plots.xml delete mode 100644 examples/xml/c5g7/2d/settings.xml delete mode 100644 examples/xml/c5g7/2d/tallies.xml delete mode 100644 examples/xml/c5g7/3d/geometry.xml delete mode 120000 examples/xml/c5g7/3d/materials.xml delete mode 100644 examples/xml/c5g7/3d/plots.xml delete mode 100644 examples/xml/c5g7/3d/settings.xml delete mode 100644 examples/xml/c5g7/3d/tallies.xml delete mode 120000 examples/xml/c5g7/pin/materials.xml delete mode 100644 examples/xml/c5g7/pin/tallies.xml rename examples/xml/{c5g7/pin => pincell_multigroup}/geometry.xml (100%) rename examples/xml/{c5g7 => pincell_multigroup}/materials.xml (100%) rename examples/xml/{c5g7/data.xml => pincell_multigroup/mg_cross_sections.xml} (100%) rename examples/xml/{c5g7/pin => pincell_multigroup}/plots.xml (100%) rename examples/xml/{c5g7/pin => pincell_multigroup}/settings.xml (94%) create mode 100644 examples/xml/pincell_multigroup/tallies.xml diff --git a/examples/xml/c5g7/2d/cmfd.xml b/examples/xml/c5g7/2d/cmfd.xml deleted file mode 100644 index 8e8d77490c..0000000000 --- a/examples/xml/c5g7/2d/cmfd.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - 10 - true - - 0.0 0.0 -100.0 - 64.26 64.26 100.0 - 6 6 1 - 1 0 0 1 1 1 - - diff --git a/examples/xml/c5g7/2d/geometry.xml b/examples/xml/c5g7/2d/geometry.xml deleted file mode 100644 index 3b43562f37..0000000000 --- a/examples/xml/c5g7/2d/geometry.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - 17 17 - -10.71 -10.71 - 1.26 1.26 - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 - 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 5 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 - 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - - - - - - 0 - 17 17 - -10.71 -10.71 - 1.26 1.26 - - 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 - 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 - 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 - 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 - 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 6 4 4 6 4 4 5 4 4 6 4 4 6 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 - 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 - 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 - 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 - 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 - 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - - - - - - - - - - - - - - - 0 - 3 3 - 0.0 0.0 - 21.42 21.42 - - 10 11 12 - 11 10 12 - 12 12 12 - - - - - - - diff --git a/examples/xml/c5g7/2d/materials.xml b/examples/xml/c5g7/2d/materials.xml deleted file mode 120000 index c3825cffc5..0000000000 --- a/examples/xml/c5g7/2d/materials.xml +++ /dev/null @@ -1 +0,0 @@ -/home/nelsonag/cases/c5g7/materials.xml \ No newline at end of file diff --git a/examples/xml/c5g7/2d/plots.xml b/examples/xml/c5g7/2d/plots.xml deleted file mode 100644 index a38f73f4e3..0000000000 --- a/examples/xml/c5g7/2d/plots.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - 1 - mat - material - 32.13 32.13 0 - 64.26 64.26 - slice - 1000 1000 - - - - - 2 - cell - cell - 32.13 32.13 0 - 64.26 64.26 - slice - 1000 1000 - - - diff --git a/examples/xml/c5g7/2d/settings.xml b/examples/xml/c5g7/2d/settings.xml deleted file mode 100644 index 038c80c303..0000000000 --- a/examples/xml/c5g7/2d/settings.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - multi-group - - - 2000 - 500 - 10000 - - - - - - - 0.0 21.42 -100 - 42.84 64.26 100 - - - - - - - 2000 - true - - - - true - true - true - - - true - - ../data.xml - - diff --git a/examples/xml/c5g7/2d/tallies.xml b/examples/xml/c5g7/2d/tallies.xml deleted file mode 100644 index 8b21bf524a..0000000000 --- a/examples/xml/c5g7/2d/tallies.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - flux - - - - - fission - - - - 1 - regular - 0.0 0.0 -100.0 - 64.26 64.26 100.0 - 51 51 1 - - - false - - diff --git a/examples/xml/c5g7/3d/geometry.xml b/examples/xml/c5g7/3d/geometry.xml deleted file mode 100644 index b7766b32a0..0000000000 --- a/examples/xml/c5g7/3d/geometry.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - 17 17 - -10.71 -10.71 - 1.26 1.26 - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 - 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 5 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 6 1 1 6 1 1 6 1 1 6 1 1 6 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 6 1 1 1 1 1 1 1 1 1 6 1 1 1 - 1 1 1 1 1 6 1 1 6 1 1 6 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - - - - - - 0 - 17 17 - -10.71 -10.71 - 1.26 1.26 - - 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 - 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 - 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 - 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 - 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 6 4 4 6 4 4 5 4 4 6 4 4 6 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 3 4 4 4 4 4 4 4 4 4 4 4 3 3 2 - 2 3 6 4 4 6 4 4 6 4 4 6 4 4 6 3 2 - 2 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 2 - 2 3 3 6 3 4 4 4 4 4 4 4 3 6 3 3 2 - 2 3 3 3 3 6 3 3 6 3 3 6 3 3 3 3 2 - 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 - 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - - - - - - - - - - - - - - - - 3 3 - 0.0 0.0 - 21.42 21.42 - - 10 11 12 - 11 10 12 - 12 12 12 - - - - - - - - - - - - 3 3 - 0.0 0.0 - 21.42 21.42 - - 13 13 13 - 13 13 13 - 13 13 13 - - - - - - - - \ No newline at end of file diff --git a/examples/xml/c5g7/3d/materials.xml b/examples/xml/c5g7/3d/materials.xml deleted file mode 120000 index c344223b66..0000000000 --- a/examples/xml/c5g7/3d/materials.xml +++ /dev/null @@ -1 +0,0 @@ -../materials.xml \ No newline at end of file diff --git a/examples/xml/c5g7/3d/plots.xml b/examples/xml/c5g7/3d/plots.xml deleted file mode 100644 index caab977866..0000000000 --- a/examples/xml/c5g7/3d/plots.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - 1 - mat - material - 32.13 32.13 107.1 - 64.26 214.2 - slice - 1000 1000 - - xz - - - - 2 - cell - cell - 32.13 32.13 107.1 - 64.26 214.2 - slice - 1000 1000 - xz - - - - 3 - mat_xy - material - 32.13 32.13 107.1 - 64.26 64.26 - slice - 1000 1000 - xy - - - diff --git a/examples/xml/c5g7/3d/settings.xml b/examples/xml/c5g7/3d/settings.xml deleted file mode 100644 index 51241492d5..0000000000 --- a/examples/xml/c5g7/3d/settings.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - multi-group - - - 2000 - 500 - 1000 - - - - 0.0 21.42 0.0 - 42.84 64.26 192.78 - 34 34 54 - - - - - - - 0.0 21.42 0.0 - 42.84 64.26 192.78 - - - - - - - 2000 - - - - true - true - true - - - ../data.xml - - diff --git a/examples/xml/c5g7/3d/tallies.xml b/examples/xml/c5g7/3d/tallies.xml deleted file mode 100644 index e3826ccb63..0000000000 --- a/examples/xml/c5g7/3d/tallies.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - flux - - - - - fission - - - - 1 - rectangular - 0.0 0.0 0.0 - 64.26 64.26 214.2 - 51 51 60 - - - - 2 - rectangular - 0.0 21.42 0.0 - 42.84 64.26 192.78 - 34 34 54 - - - false - - diff --git a/examples/xml/c5g7/pin/materials.xml b/examples/xml/c5g7/pin/materials.xml deleted file mode 120000 index c3825cffc5..0000000000 --- a/examples/xml/c5g7/pin/materials.xml +++ /dev/null @@ -1 +0,0 @@ -/home/nelsonag/cases/c5g7/materials.xml \ No newline at end of file diff --git a/examples/xml/c5g7/pin/tallies.xml b/examples/xml/c5g7/pin/tallies.xml deleted file mode 100644 index 727584a627..0000000000 --- a/examples/xml/c5g7/pin/tallies.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - flux - - - - - - scatter - - - diff --git a/examples/xml/c5g7/pin/geometry.xml b/examples/xml/pincell_multigroup/geometry.xml similarity index 100% rename from examples/xml/c5g7/pin/geometry.xml rename to examples/xml/pincell_multigroup/geometry.xml diff --git a/examples/xml/c5g7/materials.xml b/examples/xml/pincell_multigroup/materials.xml similarity index 100% rename from examples/xml/c5g7/materials.xml rename to examples/xml/pincell_multigroup/materials.xml diff --git a/examples/xml/c5g7/data.xml b/examples/xml/pincell_multigroup/mg_cross_sections.xml similarity index 100% rename from examples/xml/c5g7/data.xml rename to examples/xml/pincell_multigroup/mg_cross_sections.xml diff --git a/examples/xml/c5g7/pin/plots.xml b/examples/xml/pincell_multigroup/plots.xml similarity index 100% rename from examples/xml/c5g7/pin/plots.xml rename to examples/xml/pincell_multigroup/plots.xml diff --git a/examples/xml/c5g7/pin/settings.xml b/examples/xml/pincell_multigroup/settings.xml similarity index 94% rename from examples/xml/c5g7/pin/settings.xml rename to examples/xml/pincell_multigroup/settings.xml index b11c328e5a..6bd27df3dd 100644 --- a/examples/xml/c5g7/pin/settings.xml +++ b/examples/xml/pincell_multigroup/settings.xml @@ -41,6 +41,6 @@ false - ../data.xml + ./mg_cross_sections.xml diff --git a/examples/xml/pincell_multigroup/tallies.xml b/examples/xml/pincell_multigroup/tallies.xml new file mode 100644 index 0000000000..ed9763be52 --- /dev/null +++ b/examples/xml/pincell_multigroup/tallies.xml @@ -0,0 +1,13 @@ + + + + 100 100 1 + -0.63 -0.63 -1e+50 + 0.63 0.63 1e+50 + + + + + flux fission nu-fission + + diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 282997983b..d1c1f4e05f 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -24,37 +24,49 @@ def ndarray_to_string(arr): shape = arr.shape ndim = arr.ndim - text = '' + tab = ' ' + indent = '\n' + tab + tab + text = indent if ndim == 1: - text += ' '.join(map(str, arr[:])) + text += tab + for i in range(shape[0]): + text += '{:.7E} '.format(arr[i]) + text += indent elif ndim == 2: - for i in xrange(shape[0]): - text += ' '.join(map(str, arr[i,:])) - text += '\n' + for i in range(shape[0]): + text += tab + for j in range(shape[1]): + text += '{:.7E} '.format(arr[i,j]) + text += indent elif ndim == 3: - for i in xrange(shape[0]): - for j in xrange(shape[1]): - text += ' '.join(map(str, arr[i,j,:])) - text += '\n' + for i in range(shape[0]): + for j in range(shape[1]): + text += tab + for k in range(shape[2]): + text += '{:.7E} '.format(arr[i,j,k]) + text += indent elif ndim == 4: - for i in xrange(shape[0]): - for j in xrange(shape[1]): - for k in xrange(shape[2]): - text += ' '.join(map(str, arr[i,j,k,:])) - text += '\n' + for i in range(shape[0]): + for j in range(shape[1]): + for k in range(shape[2]): + text += tab + for l in range(shape[3]): + text += '{:.7E} '.format(arr[i,j,k,l]) + text += indent elif ndim == 5: - for i in xrange(shape[0]): - for j in xrange(shape[1]): - for k in xrange(shape[2]): - for l in xrange(shape[3]): - text += ' '.join(map(str, arr[i,j,k,l,:])) - text += '\n' + for i in range(shape[0]): + for j in range(shape[1]): + for k in range(shape[2]): + for l in range(shape[3]): + text += tab + for m in range(shape[4]): + text += '{:.7E} '.format(arr[i,j,k,l,m]) + text += indent return text - class Xsdata(object): """A multi-group cross section data set (xsdata) providing all the multi-group data necessary for a multi-group OpenMC calculation. From 640409c412ad7cd1aa05bce4a7a942775bf58439 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 16 Nov 2015 20:56:07 -0500 Subject: [PATCH 41/84] Added back in requirement that user must input energy and energyout bins in MG mode --- docs/source/usersguide/input.rst | 24 +----- .../python/pincell_multigroup/build-xml.py | 7 +- examples/xml/pincell_multigroup/tallies.xml | 2 +- src/input_xml.F90 | 71 ++++++------------ src/relaxng/tallies.rnc | 2 +- src/relaxng/tallies.rng | 74 +++++++++---------- 6 files changed, 68 insertions(+), 112 deletions(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 0244b75fc3..069d483e36 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -1347,16 +1347,8 @@ The ```` element accepts the following sub-elements: then two energy bins will be created, one with energies between 0 and 1 MeV and the other with energies between 1 and 20 MeV. - In multi-group mode, however, the bounds of the filter are already - implied as being the same as the group boundaries of the problem. - Therefore no bins would be needed as they are implicitly applied by - the code. For example, the above filter example for continuous-energy - mode would look like the following for multi-group mode, but the - resultant tallies would still be done for every group in the library: - - .. code-block:: xml - - + In multi-group mode the bins provided must match group edges + defined in the multi-group library. :energyout: In continuous-energy mode, this filter should be provided as a @@ -1371,16 +1363,8 @@ The ```` element accepts the following sub-elements: energies between 0 and 1 MeV and the other with energies between 1 and 20 MeV. - In multi-group mode, however, the bounds of the filter are already - implied as being the same as the group boundaries of the problem. - Therefore no bins would be needed as they are implicitly applied by - the code. For example, the above filter example for continuous-energy - mode would look like the following for multi-group mode, but the - resultant tallies would still be done for every group in the library: - - .. code-block:: xml - - + In multi-group mode the bins provided must match group edges + defined in the multi-group library. :mu: A monotonically increasing list of bounding **post-collision** cosines diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 300f36ce01..bb4c2db14f 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -163,10 +163,9 @@ mesh.lower_left = [-0.63, -0.63, -1.e50] mesh.upper_right = [0.63, 0.63, 1.e50] # Instantiate some tally Filters -# energy_filter = openmc.Filter(type='energy', -# bins=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, -# 0.5, 1.0, 20.0]) -energy_filter = openmc.Filter(type='energy') +energy_filter = openmc.Filter(type='energy', + bins=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, + 0.5, 1.0, 20.0]) mesh_filter = openmc.Filter() mesh_filter.mesh = mesh diff --git a/examples/xml/pincell_multigroup/tallies.xml b/examples/xml/pincell_multigroup/tallies.xml index ed9763be52..df65b461db 100644 --- a/examples/xml/pincell_multigroup/tallies.xml +++ b/examples/xml/pincell_multigroup/tallies.xml @@ -6,7 +6,7 @@ 0.63 0.63 1e+50 - + flux fission nu-fission diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 2cc829454d..8e3e8d8e9c 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2623,25 +2623,10 @@ contains if (temp_str == 'energy' .or. temp_str == 'energyout' .or. & temp_str == 'mu' .or. temp_str == 'polar' .or. & temp_str == 'azimuthal') then - ! If in MG mode, fail if user provides bins, as we are only - ! allowing for all groups - if (.not. run_CE .and. (temp_str == 'energy' .or. & - temp_str == 'energyout')) then - call fatal_error("No energy or energyout bins needed on tally " & - &// trim(to_str(t % id))) - else - n_words = get_arraysize_double(node_filt, "bins") - end if + n_words = get_arraysize_double(node_filt, "bins") else n_words = get_arraysize_integer(node_filt, "bins") end if - else if (.not. run_CE .and. (temp_str == 'energy' .or. & - temp_str == 'energyout')) then - ! For MG calculations, dont require the user to put in all the - ! group boundaries, as there could be many. Assume that if no & - ! bins are entered that that means they want group-wise results. - n_words = -1 - else call fatal_error("Bins not set in filter on tally " & &// trim(to_str(t % id))) @@ -2752,48 +2737,38 @@ contains ! Set type of filter t % filters(j) % type = FILTER_ENERGYIN - if (n_words > 0) then - ! Set number of bins - t % filters(j) % n_bins = n_words - 1 + ! Set number of bins + t % filters(j) % n_bins = n_words - 1 - ! Allocate and store bins - allocate(t % filters(j) % real_bins(n_words)) - call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! Allocate and store bins + allocate(t % filters(j) % real_bins(n_words)) + call get_node_array(node_filt, "bins", t % filters(j) % real_bins) - if (.not. run_CE) t % energy_matches_groups = .false. - else if (n_words == -1) then - ! Set number of bins - t % filters(j) % n_bins = energy_groups - - ! Allocate and store bins - allocate(t % filters(j) % real_bins(energy_groups)) - t % filters(j) % real_bins = energy_bins - - if (.not. run_CE) t % energy_matches_groups = .true. + if (.not. run_CE) then + if (n_words /= energy_groups + 1) then + t % energy_matches_groups = .false. + else if (all(t % filters(j) % real_bins == energy_bins)) then + t % energy_matches_groups = .false. + end if end if case ('energyout') ! Set type of filter t % filters(j) % type = FILTER_ENERGYOUT - if (n_words > 0) then - ! Set number of bins - t % filters(j) % n_bins = n_words - 1 + ! Set number of bins + t % filters(j) % n_bins = n_words - 1 - ! Allocate and store bins - allocate(t % filters(j) % real_bins(n_words)) - call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! Allocate and store bins + allocate(t % filters(j) % real_bins(n_words)) + call get_node_array(node_filt, "bins", t % filters(j) % real_bins) - if (.not. run_CE) t % energyout_matches_groups = .false. - else if (n_words == -1) then - ! Set number of bins - t % filters(j) % n_bins = energy_groups - - ! Allocate and store bins - allocate(t % filters(j) % real_bins(energy_groups)) - t % filters(j) % real_bins = energy_bins - - if (.not. run_CE) t % energyout_matches_groups = .true. + if (.not. run_CE) then + if (n_words /= energy_groups + 1) then + t % energy_matches_groups = .false. + else if (all(t % filters(j) % real_bins == energy_bins)) then + t % energy_matches_groups = .false. + end if end if ! Set to analog estimator diff --git a/src/relaxng/tallies.rnc b/src/relaxng/tallies.rnc index 9efb6c4e2b..75afb0f231 100644 --- a/src/relaxng/tallies.rnc +++ b/src/relaxng/tallies.rnc @@ -27,7 +27,7 @@ element tallies { "polar" | "azimuthal" | "delayedgroup") } | attribute type { ( "cell" | "cellborn" | "material" | "universe" | "surface" | "distribcell" | "mesh" | "energy" | "energyout" | "mu" | - "polar" | "azimuthal" | "delayedgroup") })? & + "polar" | "azimuthal" | "delayedgroup") }) & (element bins { list { xsd:double+ } } | attribute bins { list { xsd:double+ } }) }* & diff --git a/src/relaxng/tallies.rng b/src/relaxng/tallies.rng index 8798efca33..ef55d21e4e 100644 --- a/src/relaxng/tallies.rng +++ b/src/relaxng/tallies.rng @@ -133,44 +133,42 @@ - - - - - cell - cellborn - material - universe - surface - distribcell - mesh - energy - energyout - mu - polar - azimuthal - delayedgroup - - - - - cell - cellborn - material - universe - surface - distribcell - mesh - energy - energyout - mu - polar - azimuthal - delayedgroup - - - - + + + + cell + cellborn + material + universe + surface + distribcell + mesh + energy + energyout + mu + polar + azimuthal + delayedgroup + + + + + cell + cellborn + material + universe + surface + distribcell + mesh + energy + energyout + mu + polar + azimuthal + delayedgroup + + + From 9141e2a00fbaf7afb7a87bfa4c74903d7414e560 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 17 Nov 2015 20:30:16 -0500 Subject: [PATCH 42/84] Updated testing harness and input_set for MG tests and added first MG test: test_mg_basic --- tests/c5g7_mgxs.xml | 383 +++++++++++++++++++++++++++ tests/input_set.py | 162 +++++++++++ tests/test_mg_basic/inputs_true.dat | 1 + tests/test_mg_basic/results_true.dat | 2 + tests/test_mg_basic/test_mg_basic.py | 17 ++ tests/testing_harness.py | 9 +- 6 files changed, 571 insertions(+), 3 deletions(-) create mode 100644 tests/c5g7_mgxs.xml create mode 100644 tests/test_mg_basic/inputs_true.dat create mode 100644 tests/test_mg_basic/results_true.dat create mode 100644 tests/test_mg_basic/test_mg_basic.py diff --git a/tests/c5g7_mgxs.xml b/tests/c5g7_mgxs.xml new file mode 100644 index 0000000000..ec85d4b593 --- /dev/null +++ b/tests/c5g7_mgxs.xml @@ -0,0 +1,383 @@ + + + + 7 + + 1E-11 0.0635E-6 10.0E-6 1.0E-4 1.0E-3 0.5 1.0 20.0 + + + + + + UO2.71c + UO2.71c + 2.53E-8 + 0 + true + + isotropic + + + + 8.0248E-03 3.7174E-03 2.6769E-02 9.6236E-02 3.0020E-02 1.1126E-01 2.8278E-01 + + + + 2.005998E-02 2.027303E-03 1.570599E-02 4.518301E-02 4.334208E-02 2.020901E-01 5.257105E-01 + + + + 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 + + + 7.21206E-03 8.19301E-04 6.45320E-03 1.85648E-02 1.78084E-02 8.30348E-02 2.16004E-01 + + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 0.1275370 0.0423780 0.0000094 0.0000000 0.0000000 0.0000000 0.0000000 + 0.0000000 0.3244560 0.0016314 0.0000000 0.0000000 0.0000000 0.0000000 + 0.0000000 0.0000000 0.4509400 0.0026792 0.0000000 0.0000000 0.0000000 + 0.0000000 0.0000000 0.0000000 0.4525650 0.0055664 0.0000000 0.0000000 + 0.0000000 0.0000000 0.0000000 0.0001253 0.2714010 0.0102550 0.0000000 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0012968 0.2658020 0.0168090 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0085458 0.2730800 + + + + + 0.1779492 0.3298048 0.4803882 0.5543674000000001 0.3118013 0.39516779999999996 0.5644058 + + + + + + + MOX1.71c + MOX1.71c + 2.53E-8 + 0 + true + + + + 8.4339E-03 3.7577E-03 2.7970E-02 1.0421E-01 1.3994E-01 4.0918E-01 4.0935E-01 + + + + 1.27888062E-02 8.95701528E-03 7.37557218E-06 2.55837033E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.49041240E-03 1.04385401E-03 8.59552023E-07 2.98153464E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 9.56411400E-03 6.69850756E-03 5.51582469E-06 1.91327830E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.84928781E-02 2.69596154E-02 2.21996483E-05 7.70040890E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.80629998E-02 1.26509513E-02 1.04173100E-05 3.61346022E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.91930789E-01 2.74500216E-01 2.26034688E-04 7.84048241E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 4.19762096E-01 2.93992687E-01 2.42085585E-04 8.39724109E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 7.62704E-03 8.76898E-04 5.69835E-03 2.28872E-02 1.07635E-02 2.32757E-01 2.48968E-01 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.27537000E-01 4.23780000E-02 9.43740000E-06 5.51630000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.24456000E-01 1.63140000E-03 3.14270000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.50940000E-01 2.67920000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.52565000E-01 5.56640000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.25250000E-04 2.71401000E-01 1.02550000E-02 1.00210000E-08 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.29680000E-03 2.65802000E-01 1.68090000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.54580000E-03 2.73080000E-01 + + + + 0.1783583429163 0.3298451031427 0.4815892 0.5623414 0.421721260021 0.6930878 0.6909757999999999 + + + + + + + MOX2.71c + MOX2.71c + 2.53E-8 + 0 + true + + + + 0.0090657 0.0042967 0.032881 0.12203 0.18298 0.56846 0.58521 + + + + 1.40004593E-02 9.80563205E-03 8.07435789E-06 2.80075866E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.26856185E-03 1.58885378E-03 1.30832709E-06 4.53820413E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.41886199E-02 9.93741584E-03 8.18287404E-06 2.83839974E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 5.54788444E-02 3.88562347E-02 3.19958106E-05 1.10984111E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.69085702E-02 1.88462058E-02 1.55187355E-05 5.38299559E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 5.45687127E-01 3.82187973E-01 3.14709185E-04 1.09163414E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.13307712E-01 4.29548032E-01 3.53707392E-04 1.22690752E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 0.00825446 0.00132565 0.00842156 0.032873 0.0159636 0.323794 0.362803 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.30457000E-01 4.17920000E-02 8.51050000E-06 5.13290000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.28428000E-01 1.64360000E-03 2.20170000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.58371000E-01 2.53310000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.63709000E-01 5.47660000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.76190000E-04 2.82313000E-01 8.72890000E-03 9.00160000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.27600000E-03 2.49751000E-01 1.31140000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.86450000E-03 2.59529000E-01 + + + + 0.1813232156329 0.3343683022017 0.4937851 0.5912156 0.47419809900160004 0.833601 0.8536035 + + + + + + + MOX3.71c + MOX3.71c + 2.53E-8 + 0 + true + + + + 9.48620000E-03 4.65560000E-03 3.62400000E-02 1.32720000E-01 2.08400000E-01 6.58700000E-01 6.90170000E-01 + + + + 1.48071013E-02 1.03705874E-02 8.53956516E-06 2.96212546E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 2.78640474E-03 1.95154023E-03 1.60697792E-06 5.57413653E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 1.73304404E-02 1.21378819E-02 9.99482763E-06 3.46691346E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.59928975E-02 4.62200600E-02 3.80594850E-05 1.32017225E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.25131926E-02 2.27715674E-02 1.87510386E-05 6.50418701E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 6.32002662E-01 4.42641588E-01 3.64489161E-04 1.26430632E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 7.28595687E-01 5.10293344E-01 4.20196380E-04 1.45753838E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + + + + 8.67209000E-03 1.62426000E-03 1.02716000E-02 3.90447000E-02 1.92576000E-02 3.74888000E-01 4.30599000E-01 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 1.31504000E-01 4.20460000E-02 8.69720000E-06 5.19380000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 3.30403000E-01 1.64630000E-03 2.60060000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 4.61792000E-01 2.47490000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.68021000E-01 5.43300000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.85970000E-04 2.85771000E-01 8.39730000E-03 8.92800000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.39160000E-03 2.47614000E-01 1.23220000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.96810000E-03 2.56093000E-01 + + + + 1.83044902E-01 3.36704903E-01 5.00506900E-01 6.06174000E-01 5.02754279E-01 9.21027600E-01 9.55231100E-01 + + + + + + + FC.71c + FC.71c + 2.53E-8 + 0 + true + + + + 5.1132E-04 7.5813E-05 3.1643E-04 1.1675E-03 3.3977E-03 9.1886E-03 2.3244E-02 + + + + 1.323401E-08 1.434500E-08 1.128599E-06 1.276299E-05 3.538502E-07 1.740099E-06 5.063302E-06 + + + + 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 + + + + 4.79002E-09 5.82564E-09 4.63719E-07 5.24406E-06 1.45390E-07 7.14972E-07 2.08041E-06 + + + + + 1.0 1.0 1.0 1.0 1.0 1.0 1.0 + + + + + + 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E00 0.00000000E00 + 0.00000000E00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 + 0.00000000E00 0.00000000E00 1.83425000E-01 9.22880000E-02 6.93650000E-03 1.07900000E-03 2.05430000E-04 + 0.00000000E00 0.00000000E00 0.00000000E00 7.90769000E-02 1.69990000E-01 2.58600000E-02 4.92560000E-03 + 0.00000000E00 0.00000000E00 0.00000000E00 3.73400000E-05 9.97570000E-02 2.06790000E-01 2.44780000E-02 + 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 9.17420000E-04 3.16774000E-01 2.38760000E-01 + 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 4.97930000E-02 1.09910000E00 + + + + 1.26032048E-01 2.93160367E-01 2.84250824E-01 2.81025244E-01 3.34460185E-01 5.65640735E-01 1.17213908E00 + + + + + + + GT.71c + GT.71c + 2.53E-8 + 0 + false + + + + 5.11320000E-04 7.58010000E-05 3.15720000E-04 1.15820000E-03 3.39750000E-03 9.18780000E-03 2.32420000E-02 + + + + + + 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 + 0.00000000E+00 0.00000000E+00 1.83297000E-01 9.23970000E-02 6.94460000E-03 1.08030000E-03 2.05670000E-04 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 7.88511000E-02 1.70140000E-01 2.58810000E-02 4.92970000E-03 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.73330000E-05 9.97372000E-02 2.06790000E-01 2.44780000E-02 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 9.17260000E-04 3.16765000E-01 2.38770000E-01 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.97920000E-02 1.09912000E+00 + + + + 1.26032043E-01 2.93160349E-01 2.84240290E-01 2.80960000E-01 3.34440033E-01 5.65640060E-01 1.17215400E+00 + + + + + + LWTR.71c + LWTR.71c + 2.53E-8 + 0 + false + + + + 6.0105E-04 1.5793E-05 3.3716E-04 1.9406E-03 5.7416E-03 1.5001E-02 3.7239E-02 + + + + + + 0.0444777 0.1134000 0.0007235 0.0000037 0.0000001 0.0000000 0.0000000 + 0.0000000 0.2823340 0.1299400 0.0006234 0.0000480 0.0000074 0.0000010 + 0.0000000 0.0000000 0.3452560 0.2245700 0.0169990 0.0026443 0.0005034 + 0.0000000 0.0000000 0.0000000 0.0910284 0.4155100 0.0637320 0.0121390 + 0.0000000 0.0000000 0.0000000 0.0000714 0.1391380 0.5118200 0.0612290 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0022157 0.6999130 0.5373200 + 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.1324400 2.4807000 + + + + 0.15920605 0.41296959299999997 0.59030986 0.5843499999999999 0.7180000000000001 1.2544497000000001 2.650379 + + + + + + + CR.71c + CR.71c + 2.53E-8 + 0 + false + + + + 1.70490000E-03 8.36224000E-03 8.37901000E-02 3.97797000E-01 6.98763000E-01 9.29508000E-01 1.17836000E+00 + + + + + + 1.70563000E-01 4.44012000E-02 9.83670000E-05 1.27786000E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 4.71050000E-01 6.85480000E-04 3.91395000E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 8.01859000E-01 7.20132000E-04 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 5.70752000E-01 1.46015000E-03 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 6.55562000E-05 2.07838000E-01 3.81486000E-03 3.69760000E-09 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.02427000E-03 2.02465000E-01 4.75290000E-03 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.53043000E-03 6.58597000E-01 + + + + 2.16767595E-01 4.80097720E-01 8.86369232E-01 9.70009150E-01 9.10481420E-01 1.13775017E+00 1.84048743E+00 + + + diff --git a/tests/input_set.py b/tests/input_set.py index 87b857f4a9..4e8974680e 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -569,3 +569,165 @@ class InputSet(object): plot.color = 'mat' self.plots.add_plot(plot) + +class MGInputSet(InputSet): + def build_default_materials_and_geometry(self): + # Define materials needed for C5G7 2-D UO2 Assembly + uo2_data = openmc.Macroscopic('UO2', '71c') + uo2 = openmc.Material(name='UO2', material_id=1) + uo2.set_density('macro', 1.0) + uo2.add_macroscopic(uo2_data) + + fiss_cham_data = openmc.Macroscopic('FC', '71c') + fiss_cham = openmc.Material(name='FC', material_id=2) + fiss_cham.set_density('macro', 1.0) + fiss_cham.add_macroscopic(fiss_cham_data) + + guide_tube_data = openmc.Macroscopic('GT', '71c') + guide_tube = openmc.Material(name='GT', material_id=3) + guide_tube.set_density('macro', 1.0) + guide_tube.add_macroscopic(guide_tube_data) + + water_data = openmc.Macroscopic('LWTR', '71c') + water = openmc.Material(name='LWTR', material_id=4) + water.set_density('macro', 1.0) + water.add_macroscopic(water_data) + + # Define the materials file. + self.materials.default_xs = '71c' + self.materials.add_materials((uo2, fiss_cham, guide_tube, water)) + + # Define surfaces. + + # Pin cell + s1 = openmc.ZCylinder(R=0.54, surface_id=1) + # Assembly/Problem Boundary + left = openmc.XPlane(x0=0.0, surface_id=20, + boundary_type='reflective') + right = openmc.XPlane(x0=21.42, surface_id=21, + boundary_type='reflective') + bottom = openmc.YPlane(y0=0.0, surface_id=22, + boundary_type='reflective') + top = openmc.YPlane(y0=21.42, surface_id=23, + boundary_type='reflective') + down = openmc.ZPlane(z0=0.0, surface_id=24, + boundary_type='reflective') + up = openmc.ZPlane(z0=21.42, surface_id=25, + boundary_type='reflective') + + # Define pin cells + # uo2 pin + c10 = openmc.Cell(cell_id=10) + c10.region = -s1 + c10.fill = uo2 + c11 = openmc.Cell(cell_id=11) + c11.region = +s1 + c11.fill = water + fuel_pin = openmc.Universe(name='Fuel pin', universe_id=1) + fuel_pin.add_cells((c10, c11)) + + # Fission chamber pin + c20 = openmc.Cell(cell_id=20) + c20.region = -s1 + c20.fill = fiss_cham + c21 = openmc.Cell(cell_id=21) + c21.region = +s1 + c21.fill = water + fiss_chamber_pin = openmc.Universe(name='Fission Chamber', universe_id=2) + fiss_chamber_pin.add_cells((c20, c21)) + + # Guide Tube pin + c30 = openmc.Cell(cell_id=30) + c30.region = -s1 + c30.fill = guide_tube + c31 = openmc.Cell(cell_id=31) + c31.region = +s1 + c31.fill = water + gt_pin = openmc.Universe(name='Guide Tube', universe_id=3) + gt_pin.add_cells((c30, c31)) + + # Define fuel lattice + l100 = openmc.RectLattice(name='UO2 assembly', lattice_id=100) + l100.dimension = (17, 17) + l100.lower_left = (-10.71, -10.71) + l100.pitch = (1.26, 1.26) + l100.universes = [ + [fuel_pin]*17, + [fuel_pin]*17, + [fuel_pin]*5 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*5, + [fuel_pin]*3 + [gt_pin] + [fuel_pin]*9 + [gt_pin] + + [fuel_pin]*3, + [fuel_pin]*17, + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, + [fuel_pin]*17, + [fuel_pin]*17, + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [fiss_chamber_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, + [fuel_pin]*17, + [fuel_pin]*17, + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, + [fuel_pin]*17, + [fuel_pin]*3 + [gt_pin] + [fuel_pin]*9 + [gt_pin] + + [fuel_pin]*3, + [fuel_pin]*5 + [gt_pin] + [fuel_pin]*2 + [gt_pin] + + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*5, + [fuel_pin]*17, + [fuel_pin]*17 ] + + # Define assemblies. + fa = openmc.Universe(name='Fuel assembly', universe_id=10) + c100 = openmc.Cell(cell_id=110) + c100.region = +down & -up + c100.fill = l100 + fa.add_cells((c100, )) + + # Define core lattices + l200 = openmc.RectLattice(name='Core lattice', lattice_id=200) + l200.dimension = (1, 1) + l200.lower_left = (0.0, 0.0) + l200.pitch = (21.42, 21.42) + l200.universes = [[fa]] + + # Define root universe. + root = openmc.Universe(universe_id=0, name='root universe') + c1 = openmc.Cell(cell_id=1) + c1.region = +left & -right & +bottom & -top & +down & -up + c1.fill = l200 + + root.add_cells((c1,)) + + # Define the geometry file. + geometry = openmc.Geometry() + geometry.root_universe = root + + self.geometry.geometry = geometry + + + def build_default_settings(self): + self.settings.batches = 10 + self.settings.inactive = 5 + self.settings.particles = 100 + self.settings.set_source_space('box', (0.0, 0.0, 0.0, 21.42, 21.42, 100.0)) + self.settings.energy_mode = "multi-group" + self.settings.cross_sections = "../c5g7_mgxs.xml" + + def build_defualt_plots(self): + plot = openmc.Plot() + plot.filename = 'mat' + plot.origin = (10.71, 10.71, 50.0) + plot.width = (21.42, 21.42) + plot.pixels = (3000, 3000) + plot.color = 'mat' + + self.plots.add_plot(plot) + + + + + diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat new file mode 100644 index 0000000000..d576cd402a --- /dev/null +++ b/tests/test_mg_basic/inputs_true.dat @@ -0,0 +1 @@ +b41c9621e2f068dab8f44b4fbf29aa5f075c04e463543550b7d1324b75b4709db810808e64474d2400c8c36465814bcca095650b0e19d640860dd4a860bb40a3 \ No newline at end of file diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat new file mode 100644 index 0000000000..93683d28bb --- /dev/null +++ b/tests/test_mg_basic/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +1.359283E+00 7.465863E-02 diff --git a/tests/test_mg_basic/test_mg_basic.py b/tests/test_mg_basic/test_mg_basic.py new file mode 100644 index 0000000000..1a49ee8a82 --- /dev/null +++ b/tests/test_mg_basic/test_mg_basic.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import TestHarness, PyAPITestHarness +import openmc + + +class MGBasicTestHarness(PyAPITestHarness): + def _build_inputs(self): + super(MGBasicTestHarness, self)._build_inputs() + + +if __name__ == '__main__': + harness = MGBasicTestHarness('statepoint.10.*', False, mg=True) + harness.main() diff --git a/tests/testing_harness.py b/tests/testing_harness.py index ed89f76946..90f35078a6 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -12,7 +12,7 @@ import sys import numpy as np sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from input_set import InputSet +from input_set import InputSet, MGInputSet from openmc.statepoint import StatePoint from openmc.executor import Executor import openmc.particle_restart as pr @@ -273,9 +273,12 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): - def __init__(self, statepoint_name, tallies_present=False): + def __init__(self, statepoint_name, tallies_present=False, mg=False): TestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = InputSet() + if mg: + self._input_set = MGInputSet() + else: + self._input_set = InputSet() def execute_test(self): """Build input XMLs, run OpenMC, and verify correct results.""" From da76c2c8ff34d1fef5a2e71da91153f2560dc845 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 17 Nov 2015 20:49:22 -0500 Subject: [PATCH 43/84] Added test for MG tallying --- tests/test_mg_tallies/inputs_true.dat | 1 + tests/test_mg_tallies/results_true.dat | 3482 ++++++++++++++++++++++ tests/test_mg_tallies/test_mg_tallies.py | 61 + 3 files changed, 3544 insertions(+) create mode 100644 tests/test_mg_tallies/inputs_true.dat create mode 100644 tests/test_mg_tallies/results_true.dat create mode 100644 tests/test_mg_tallies/test_mg_tallies.py diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat new file mode 100644 index 0000000000..44099dbd82 --- /dev/null +++ b/tests/test_mg_tallies/inputs_true.dat @@ -0,0 +1 @@ +87d5adff4c8d53f020baa25db59d9ad6eada791ef010577e3586c543a9ee6cee6022d99e7a27911a94560acddba3602570c0748a0b4cba48f630b726221f14dc \ No newline at end of file diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat new file mode 100644 index 0000000000..920f5f3e36 --- /dev/null +++ b/tests/test_mg_tallies/results_true.dat @@ -0,0 +1,3482 @@ +k-combined: +1.359283E+00 7.465863E-02 +tally 1: +2.847813E-01 +2.025790E-02 +1.172423E-02 +4.616814E-05 +6.871019E-01 +1.096320E-01 +5.348095E-03 +1.062108E-05 +1.340369E-02 +6.465987E-05 +1.682119E-01 +7.397131E-03 +9.038916E-03 +2.581353E-05 +4.138462E-01 +3.732581E-02 +4.267302E-03 +6.286845E-06 +1.058944E-02 +3.804411E-05 +3.633299E-01 +3.976542E-02 +2.487014E-02 +2.126766E-04 +6.982763E-01 +1.317345E-01 +1.257758E-02 +6.051328E-05 +3.075036E-02 +3.600723E-04 +2.492313E-01 +1.682228E-02 +1.380182E-02 +6.570494E-05 +5.765551E-01 +9.181006E-02 +7.743475E-03 +2.727482E-05 +1.902781E-02 +1.627120E-04 +2.191122E-01 +1.298025E-02 +1.148883E-02 +4.334141E-05 +5.203670E-01 +7.022054E-02 +5.000169E-03 +7.803760E-06 +1.236816E-02 +4.736991E-05 +2.269064E-01 +2.056966E-02 +1.410446E-02 +1.199602E-04 +4.515464E-01 +7.417552E-02 +7.887256E-03 +4.708793E-05 +1.932915E-02 +2.805214E-04 +2.364191E-01 +1.654063E-02 +1.415339E-02 +1.415624E-04 +4.940050E-01 +6.265173E-02 +6.299407E-03 +3.280872E-05 +1.540495E-02 +1.953911E-04 +3.192689E-01 +2.306298E-02 +1.230781E-02 +6.401926E-05 +6.470467E-01 +9.154956E-02 +5.234535E-03 +1.578586E-05 +1.286806E-02 +9.375617E-05 +2.540069E-01 +1.409067E-02 +7.206254E-03 +1.691929E-05 +6.264964E-01 +8.583680E-02 +1.958907E-03 +1.137122E-06 +4.944068E-03 +7.184508E-06 +3.299226E-01 +2.361991E-02 +1.153904E-02 +3.398774E-05 +7.350880E-01 +1.172602E-01 +4.976946E-03 +7.515943E-06 +1.226957E-02 +4.522435E-05 +2.734191E-01 +1.823188E-02 +1.314351E-02 +4.883110E-05 +5.162639E-01 +5.997683E-02 +5.567315E-03 +1.116578E-05 +1.355695E-02 +6.620192E-05 +1.971066E-01 +8.872106E-03 +7.289937E-03 +1.482506E-05 +3.624107E-01 +2.788172E-02 +3.946019E-03 +4.911976E-06 +9.796252E-03 +2.939620E-05 +2.435676E-01 +1.550957E-02 +1.471975E-02 +6.447073E-05 +3.711107E-01 +3.097190E-02 +8.485525E-03 +2.418503E-05 +2.074995E-02 +1.440717E-04 +2.427633E-01 +1.927418E-02 +1.659082E-02 +9.533795E-05 +3.947070E-01 +4.039320E-02 +8.721245E-03 +3.472785E-05 +2.129433E-02 +2.058398E-04 +2.930833E-01 +3.717078E-02 +1.961320E-02 +2.361042E-04 +5.029290E-01 +7.452592E-02 +1.162396E-02 +9.544883E-05 +2.835116E-02 +5.654990E-04 +3.612968E-01 +3.626192E-02 +2.275737E-02 +2.915981E-04 +6.836531E-01 +1.007739E-01 +1.386251E-02 +1.308722E-04 +3.381273E-02 +7.755475E-04 +3.379726E-01 +3.059811E-02 +1.034847E-02 +2.508685E-05 +7.876015E-01 +1.626433E-01 +4.304432E-03 +4.836158E-06 +1.080846E-02 +3.049489E-05 +2.207527E-01 +1.480236E-02 +9.133299E-03 +4.378685E-05 +5.306469E-01 +6.883187E-02 +3.832635E-03 +7.385540E-06 +9.542013E-03 +4.429238E-05 +1.746455E-01 +7.365091E-03 +6.210077E-03 +1.980262E-05 +4.018765E-01 +3.788658E-02 +3.022816E-03 +4.602873E-06 +7.491747E-03 +2.745170E-05 +2.568492E-01 +1.811320E-02 +1.821423E-02 +2.069737E-04 +4.656788E-01 +5.401259E-02 +1.232525E-02 +1.058384E-04 +3.013811E-02 +6.273405E-04 +2.225493E-01 +1.562018E-02 +1.010014E-02 +5.040357E-05 +4.589131E-01 +6.663804E-02 +5.258730E-03 +1.491454E-05 +1.298284E-02 +9.047317E-05 +2.447664E-01 +1.706786E-02 +1.478729E-02 +6.497711E-05 +5.983362E-01 +1.049331E-01 +6.596398E-03 +1.524559E-05 +1.633146E-02 +9.299953E-05 +2.413969E-01 +2.116589E-02 +2.021668E-02 +2.024522E-04 +3.619973E-01 +4.122998E-02 +1.346912E-02 +9.583517E-05 +3.286803E-02 +5.685240E-04 +2.049752E-01 +8.601175E-03 +1.025940E-02 +2.514980E-05 +4.043912E-01 +3.463281E-02 +4.452720E-03 +6.434910E-06 +1.096850E-02 +3.904161E-05 +3.102820E-01 +2.045820E-02 +1.459368E-02 +5.241789E-05 +6.773052E-01 +9.567203E-02 +7.341203E-03 +1.649958E-05 +1.800485E-02 +9.887491E-05 +2.550379E-01 +1.497142E-02 +1.091961E-02 +3.974930E-05 +5.647093E-01 +7.433920E-02 +5.249459E-03 +1.177345E-05 +1.284826E-02 +7.017030E-05 +3.556052E-01 +2.703280E-02 +2.735992E-02 +1.564623E-04 +6.683707E-01 +1.040515E-01 +1.590490E-02 +6.014424E-05 +3.877604E-02 +3.576128E-04 +2.497863E-01 +1.507086E-02 +1.494719E-02 +1.025755E-04 +4.762993E-01 +5.549879E-02 +8.527272E-03 +4.579896E-05 +2.085262E-02 +2.725955E-04 +1.839365E-01 +8.369442E-03 +1.237838E-02 +7.164219E-05 +3.775826E-01 +3.190193E-02 +7.884508E-03 +3.507069E-05 +1.929540E-02 +2.080904E-04 +1.708555E-01 +9.399504E-03 +7.715238E-03 +2.292805E-05 +3.732199E-01 +4.315843E-02 +3.978302E-03 +6.440288E-06 +9.770196E-03 +3.826434E-05 +3.241297E-01 +2.680732E-02 +2.827721E-02 +2.383010E-04 +5.925440E-01 +7.572445E-02 +1.805046E-02 +9.773692E-05 +4.409968E-02 +5.812383E-04 +2.602482E-01 +1.672576E-02 +7.932620E-03 +1.561951E-05 +5.580855E-01 +6.844216E-02 +2.088329E-03 +9.313432E-07 +5.186486E-03 +5.737715E-06 +2.890696E-01 +2.384728E-02 +1.015490E-02 +3.717081E-05 +6.111526E-01 +8.518321E-02 +4.213456E-03 +7.925859E-06 +1.037122E-02 +4.719897E-05 +3.855713E-01 +3.814941E-02 +1.595567E-02 +1.026684E-04 +8.322980E-01 +1.786719E-01 +6.646130E-03 +1.662975E-05 +1.674159E-02 +1.022582E-04 +1.897658E-01 +1.150551E-02 +8.071193E-03 +3.172610E-05 +4.219179E-01 +4.854116E-02 +3.808837E-03 +8.709924E-06 +9.434346E-03 +5.203901E-05 +2.195178E-01 +1.516218E-02 +7.926578E-03 +2.639446E-05 +5.306593E-01 +7.568838E-02 +2.106381E-03 +1.749456E-06 +5.313752E-03 +1.093384E-05 +3.256867E-01 +4.534052E-02 +2.131147E-02 +2.570637E-04 +5.297378E-01 +1.136688E-01 +1.158918E-02 +7.267385E-05 +2.831750E-02 +4.331969E-04 +1.414992E-01 +5.003890E-03 +4.258013E-03 +7.891903E-06 +3.615210E-01 +3.145749E-02 +1.093412E-03 +3.546225E-07 +2.758486E-03 +2.166206E-06 +1.514116E-01 +6.201312E-03 +4.857451E-03 +6.866877E-06 +3.984685E-01 +3.930815E-02 +2.038032E-03 +1.261346E-06 +5.152722E-03 +7.792008E-06 +3.159334E-01 +3.379738E-02 +2.905400E-03 +4.164258E-06 +5.469766E-01 +9.022824E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.132668E-01 +1.056200E-02 +9.631005E-03 +2.427206E-05 +4.566464E-01 +5.683176E-02 +4.166599E-03 +5.882400E-06 +1.031031E-02 +3.580708E-05 +2.912415E-01 +2.272338E-02 +1.775965E-02 +1.443229E-04 +4.943869E-01 +5.913494E-02 +1.104606E-02 +6.433295E-05 +2.697987E-02 +3.816975E-04 +2.570902E-01 +1.798689E-02 +2.361267E-03 +2.378626E-06 +4.065439E-01 +4.281600E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.949017E-01 +2.326343E-02 +1.187639E-02 +4.961037E-05 +6.020356E-01 +9.395273E-02 +6.276821E-03 +1.931834E-05 +1.538205E-02 +1.153434E-04 +2.558511E-01 +1.698459E-02 +1.575580E-02 +8.651862E-05 +5.875503E-01 +8.849521E-02 +7.883870E-03 +3.015633E-05 +1.949261E-02 +1.802377E-04 +1.839277E-01 +8.799415E-03 +9.390667E-04 +4.683772E-07 +4.384277E-01 +4.401825E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.609130E-01 +1.523879E-02 +1.198704E-02 +4.620730E-05 +6.275273E-01 +8.589709E-02 +6.342769E-03 +1.539049E-05 +1.563218E-02 +9.287339E-05 +2.481956E-01 +1.445135E-02 +7.512217E-03 +2.578216E-05 +5.254869E-01 +6.462207E-02 +4.109411E-03 +1.008346E-05 +1.011567E-02 +5.994042E-05 +2.029184E-01 +9.361823E-03 +5.088961E-03 +6.279329E-06 +4.979684E-01 +5.589905E-02 +1.833935E-03 +7.843470E-07 +4.590978E-03 +4.909945E-06 +2.259899E-01 +1.904652E-02 +1.437025E-02 +1.402125E-04 +5.175625E-01 +7.750371E-02 +8.659314E-03 +5.998348E-05 +2.125004E-02 +3.556838E-04 +2.491821E-01 +1.416884E-02 +1.505865E-02 +1.184227E-04 +6.046546E-01 +7.493539E-02 +9.648000E-03 +5.809858E-05 +2.378233E-02 +3.456642E-04 +2.380529E-01 +1.543764E-02 +1.826271E-02 +8.884450E-05 +4.803110E-01 +5.846859E-02 +8.805950E-03 +2.475992E-05 +2.159062E-02 +1.489502E-04 +2.026084E-01 +1.110441E-02 +8.160845E-03 +1.785658E-05 +4.437692E-01 +5.639028E-02 +3.565175E-03 +3.302071E-06 +8.864014E-03 +2.024481E-05 +2.224558E-01 +1.680211E-02 +1.555273E-02 +1.869799E-04 +4.173737E-01 +6.228541E-02 +9.135566E-03 +7.133316E-05 +2.241062E-02 +4.286070E-04 +2.004042E-01 +1.095639E-02 +1.437370E-03 +8.849524E-07 +4.174469E-01 +4.395281E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.755714E-01 +6.756269E-03 +8.983808E-03 +1.906916E-05 +4.261288E-01 +3.852168E-02 +3.247612E-03 +3.858076E-06 +8.028951E-03 +2.337512E-05 +2.223071E-01 +1.353146E-02 +1.705765E-02 +1.245386E-04 +5.197542E-01 +6.518812E-02 +9.805805E-03 +4.604085E-05 +2.405033E-02 +2.748160E-04 +1.948532E-01 +9.221640E-03 +1.164060E-02 +3.726891E-05 +4.394449E-01 +4.772119E-02 +5.615780E-03 +1.145305E-05 +1.379554E-02 +6.876959E-05 +1.729605E-01 +7.269018E-03 +7.081459E-03 +1.086510E-05 +3.596419E-01 +3.677088E-02 +2.576810E-03 +2.237622E-06 +6.357471E-03 +1.343160E-05 +2.686943E-01 +2.027464E-02 +1.549158E-02 +1.119369E-04 +4.683049E-01 +6.133136E-02 +8.958022E-03 +4.362320E-05 +2.185541E-02 +2.586495E-04 +2.805365E-01 +1.741332E-02 +1.350305E-02 +4.115261E-05 +6.438641E-01 +9.350345E-02 +5.285236E-03 +6.082302E-06 +1.295017E-02 +3.639939E-05 +2.572894E-01 +1.557396E-02 +9.152971E-03 +2.187378E-05 +5.397672E-01 +6.947168E-02 +3.989601E-03 +5.329696E-06 +9.816007E-03 +3.199508E-05 +1.844650E-01 +6.889035E-03 +9.054549E-03 +2.388416E-05 +4.959347E-01 +5.022290E-02 +6.016437E-03 +1.166505E-05 +1.483958E-02 +6.985694E-05 +2.448423E-01 +1.383982E-02 +1.979087E-02 +1.017532E-04 +5.292703E-01 +7.138674E-02 +1.203905E-02 +3.777525E-05 +2.948865E-02 +2.261060E-04 +3.678431E-01 +4.444197E-02 +3.828158E-03 +8.237670E-06 +5.902793E-01 +7.688814E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.935423E-01 +7.592536E-03 +6.894656E-03 +1.790118E-05 +4.320616E-01 +3.963147E-02 +2.212586E-03 +1.758405E-06 +5.535114E-03 +1.077459E-05 +2.000222E-01 +8.790536E-03 +6.130353E-03 +1.084913E-05 +5.241401E-01 +6.739015E-02 +2.660110E-03 +2.912115E-06 +6.629933E-03 +1.756202E-05 +2.006222E-01 +1.191794E-02 +3.681584E-03 +4.563880E-06 +4.694831E-01 +5.256578E-02 +1.424456E-03 +6.817103E-07 +3.630744E-03 +4.291288E-06 +1.427746E-01 +5.192636E-03 +1.037189E-02 +4.055885E-05 +3.029633E-01 +2.157045E-02 +4.326032E-03 +8.614945E-06 +1.057731E-02 +5.155246E-05 +1.646414E-01 +6.623537E-03 +5.439480E-03 +7.768447E-06 +4.145907E-01 +4.057023E-02 +1.461466E-03 +5.282344E-07 +3.707510E-03 +3.392769E-06 +1.648802E-01 +7.366519E-03 +1.070584E-02 +7.721854E-05 +3.742934E-01 +3.508076E-02 +6.499009E-03 +3.696865E-05 +1.592990E-02 +2.222355E-04 +2.180319E-01 +9.923859E-03 +7.969510E-03 +1.700099E-05 +5.221346E-01 +5.681643E-02 +3.896242E-03 +5.553555E-06 +9.611215E-03 +3.391405E-05 +2.292243E-01 +1.349466E-02 +1.175536E-02 +6.134192E-05 +5.588849E-01 +7.531263E-02 +5.067123E-03 +1.484964E-05 +1.251725E-02 +8.896195E-05 +3.324146E-01 +2.547046E-02 +2.018340E-02 +1.567704E-04 +7.652357E-01 +1.207356E-01 +1.178472E-02 +6.216943E-05 +2.903536E-02 +3.717118E-04 +2.285590E-01 +1.197525E-02 +6.912934E-03 +1.203784E-05 +4.578967E-01 +5.011634E-02 +2.559431E-03 +2.572737E-06 +6.387641E-03 +1.570623E-05 +1.930700E-01 +1.057009E-02 +6.872837E-03 +2.126589E-05 +3.910460E-01 +4.649162E-02 +3.546523E-03 +6.380991E-06 +8.655793E-03 +3.783828E-05 +3.934470E-01 +3.734695E-02 +2.227825E-02 +1.453115E-04 +6.775238E-01 +1.033120E-01 +1.338820E-02 +5.501040E-05 +3.274687E-02 +3.279809E-04 +3.088799E-01 +2.873704E-02 +1.749960E-02 +1.305258E-04 +5.601385E-01 +8.645103E-02 +1.038254E-02 +5.085454E-05 +2.542701E-02 +3.023135E-04 +3.700473E-01 +3.161307E-02 +2.646517E-02 +1.740940E-04 +6.414793E-01 +8.696363E-02 +1.500269E-02 +5.967096E-05 +3.661756E-02 +3.551291E-04 +3.565351E-01 +2.588617E-02 +2.829818E-02 +2.379254E-04 +6.754679E-01 +9.310347E-02 +1.785149E-02 +1.083839E-04 +4.359723E-02 +6.452495E-04 +2.956875E-01 +2.095277E-02 +1.344873E-02 +5.606169E-05 +5.669819E-01 +6.817515E-02 +7.251551E-03 +1.703252E-05 +1.777118E-02 +1.016817E-04 +2.506887E-01 +1.299858E-02 +1.588362E-02 +7.727995E-05 +4.753313E-01 +5.001149E-02 +1.000924E-02 +3.700899E-05 +2.445351E-02 +2.204775E-04 +2.126121E-01 +1.123409E-02 +1.190127E-02 +3.832263E-05 +3.707959E-01 +3.067361E-02 +5.030198E-03 +9.080178E-06 +1.230610E-02 +5.408354E-05 +2.764143E-01 +1.563717E-02 +1.790747E-02 +9.078882E-05 +5.678500E-01 +6.620735E-02 +1.046412E-02 +3.855578E-05 +2.561249E-02 +2.296019E-04 +2.902769E-01 +2.046134E-02 +1.234799E-02 +6.085833E-05 +6.155753E-01 +8.929554E-02 +6.140705E-03 +2.104623E-05 +1.517340E-02 +1.267427E-04 +2.178843E-01 +1.129871E-02 +6.208339E-03 +9.542966E-06 +5.034079E-01 +6.194116E-02 +2.128719E-03 +1.227568E-06 +5.264120E-03 +7.484188E-06 +2.125960E-01 +9.351344E-03 +6.822592E-03 +1.025641E-05 +4.869649E-01 +4.997451E-02 +2.293340E-03 +1.145791E-06 +5.665763E-03 +6.954001E-06 +2.709614E-01 +1.628033E-02 +1.293964E-03 +6.917833E-07 +6.177875E-01 +8.137663E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.314443E-01 +2.391247E-02 +1.873938E-02 +1.577380E-04 +6.121093E-01 +8.135846E-02 +1.073229E-02 +7.334175E-05 +2.617620E-02 +4.348152E-04 +3.166995E-01 +2.320865E-02 +2.036524E-02 +1.279210E-04 +6.658781E-01 +9.649554E-02 +9.461128E-03 +3.244725E-05 +2.313190E-02 +1.926149E-04 +3.297678E-01 +2.820763E-02 +1.923411E-03 +1.900405E-06 +8.093044E-01 +1.549168E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.456076E-01 +1.494726E-02 +1.107664E-02 +5.262577E-05 +4.808813E-01 +5.271759E-02 +5.560675E-03 +1.646259E-05 +1.363247E-02 +9.798701E-05 +2.427021E-01 +1.432013E-02 +1.238222E-02 +4.787991E-05 +4.944297E-01 +5.130649E-02 +6.815175E-03 +1.474275E-05 +1.672131E-02 +8.786745E-05 +3.752437E-01 +4.854811E-02 +3.614564E-03 +7.655432E-06 +6.782217E-01 +1.182298E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.647096E-01 +3.545521E-02 +1.786012E-02 +1.465595E-04 +6.852491E-01 +1.194618E-01 +8.922910E-03 +5.271906E-05 +2.195699E-02 +3.131230E-04 +3.739088E-01 +3.265037E-02 +2.215242E-02 +1.812199E-04 +7.104581E-01 +1.100949E-01 +1.112087E-02 +4.919605E-05 +2.716623E-02 +2.917209E-04 +3.646148E-01 +3.098153E-02 +3.468938E-03 +3.673617E-06 +6.439522E-01 +8.790186E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.988792E-01 +3.585276E-02 +1.769735E-02 +7.190181E-05 +7.203928E-01 +1.136161E-01 +8.994571E-03 +1.910703E-05 +2.195114E-02 +1.134487E-04 +2.180681E-01 +1.069385E-02 +1.207089E-02 +3.821459E-05 +4.543812E-01 +4.676007E-02 +5.078523E-03 +7.405974E-06 +1.242019E-02 +4.429054E-05 +3.387204E-01 +3.973516E-02 +3.338763E-03 +5.743416E-06 +6.143123E-01 +9.874284E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.573709E-01 +1.674382E-02 +1.789150E-02 +8.268291E-05 +4.926442E-01 +5.444271E-02 +1.080063E-02 +3.171383E-05 +2.644879E-02 +1.900877E-04 +3.675868E-01 +3.260765E-02 +3.091945E-02 +3.382288E-04 +6.630012E-01 +9.843066E-02 +1.886091E-02 +1.405418E-04 +4.605866E-02 +8.347384E-04 +2.393729E-01 +1.348727E-02 +9.089783E-03 +2.427644E-05 +5.291297E-01 +7.168179E-02 +4.297079E-03 +6.989668E-06 +1.057952E-02 +4.186885E-05 +3.231612E-01 +2.306799E-02 +1.049737E-02 +2.683860E-05 +6.962022E-01 +1.052928E-01 +3.906472E-03 +4.558902E-06 +9.688302E-03 +2.762523E-05 +3.081575E-01 +2.418407E-02 +1.147679E-02 +3.854959E-05 +6.947453E-01 +1.227514E-01 +5.492866E-03 +1.250383E-05 +1.366407E-02 +7.575691E-05 +3.601378E-01 +3.119766E-02 +1.856683E-02 +1.137752E-04 +6.790405E-01 +1.110025E-01 +1.005459E-02 +3.495544E-05 +2.461545E-02 +2.087020E-04 +3.505867E-01 +3.343394E-02 +1.851972E-02 +1.598653E-04 +6.695596E-01 +9.510495E-02 +1.018052E-02 +5.221675E-05 +2.496525E-02 +3.096426E-04 +3.832686E-01 +3.148793E-02 +1.999211E-02 +1.215996E-04 +7.990637E-01 +1.345049E-01 +1.016673E-02 +4.022763E-05 +2.487451E-02 +2.398045E-04 +3.238454E-01 +2.516992E-02 +1.603342E-02 +7.138171E-05 +6.930200E-01 +1.094620E-01 +9.610453E-03 +2.882518E-05 +2.367498E-02 +1.737604E-04 +2.433247E-01 +1.382228E-02 +1.026348E-02 +3.722424E-05 +6.058218E-01 +8.021503E-02 +5.222456E-03 +1.425419E-05 +1.293486E-02 +8.486641E-05 +3.405008E-01 +2.926643E-02 +1.702379E-02 +9.214884E-05 +6.732747E-01 +1.123595E-01 +7.705730E-03 +2.518557E-05 +1.891328E-02 +1.517838E-04 +2.619123E-01 +1.659685E-02 +6.964887E-03 +1.698405E-05 +5.916662E-01 +8.408950E-02 +2.958893E-03 +5.202669E-06 +7.307355E-03 +3.175251E-05 +5.917279E-01 +8.427634E-02 +3.884610E-02 +4.129413E-04 +1.054440E+00 +2.468893E-01 +2.320189E-02 +1.593770E-04 +5.690805E-02 +9.561233E-04 +4.377758E-01 +4.319166E-02 +2.986805E-02 +2.393363E-04 +8.248635E-01 +1.512547E-01 +1.372568E-02 +4.799401E-05 +3.349029E-02 +2.857467E-04 +3.421089E-01 +2.979789E-02 +2.249013E-02 +1.559001E-04 +6.850890E-01 +1.290414E-01 +1.160224E-02 +4.302043E-05 +2.846348E-02 +2.591994E-04 +3.722540E-01 +2.904052E-02 +2.335195E-02 +1.699377E-04 +6.863934E-01 +1.046451E-01 +1.439649E-02 +7.569328E-05 +3.524469E-02 +4.513332E-04 +3.015492E-01 +2.688128E-02 +2.018127E-02 +2.032826E-04 +6.714661E-01 +1.187385E-01 +1.212713E-02 +8.198620E-05 +2.973564E-02 +4.888576E-04 +2.528792E-01 +1.477470E-02 +1.121978E-02 +3.087195E-05 +6.406078E-01 +9.017936E-02 +5.885821E-03 +9.181268E-06 +1.457639E-02 +5.584147E-05 +2.038650E-01 +9.623965E-03 +1.310712E-02 +5.593573E-05 +4.908799E-01 +5.902527E-02 +6.946389E-03 +2.251232E-05 +1.702889E-02 +1.340271E-04 +1.139788E-01 +4.277809E-03 +4.614286E-03 +1.120138E-05 +2.704042E-01 +2.220192E-02 +1.076409E-03 +5.608463E-07 +2.705241E-03 +3.490247E-06 +2.370973E-01 +1.305565E-02 +7.409820E-03 +1.519920E-05 +5.419723E-01 +6.833854E-02 +3.405550E-03 +3.330468E-06 +8.520273E-03 +2.078583E-05 +2.382071E-01 +1.383356E-02 +9.254640E-03 +2.398783E-05 +6.083591E-01 +8.592760E-02 +4.554881E-03 +6.539019E-06 +1.130393E-02 +3.971676E-05 +2.799334E-01 +1.704488E-02 +1.745706E-02 +7.748191E-05 +5.327410E-01 +6.309686E-02 +8.374890E-03 +2.219332E-05 +2.046374E-02 +1.322507E-04 +3.299989E-01 +2.500153E-02 +1.662220E-02 +9.214247E-05 +5.777125E-01 +7.504937E-02 +9.185426E-03 +3.401334E-05 +2.245932E-02 +2.018294E-04 +2.480945E-01 +1.409562E-02 +1.027283E-02 +2.736596E-05 +5.305733E-01 +7.019314E-02 +4.898185E-03 +5.923984E-06 +1.209377E-02 +3.598246E-05 +2.435916E-01 +1.296299E-02 +1.168450E-02 +5.994065E-05 +5.303919E-01 +5.892047E-02 +6.394644E-03 +2.573114E-05 +1.573948E-02 +1.534027E-04 +3.382910E-01 +3.158552E-02 +1.585392E-02 +1.113895E-04 +6.399010E-01 +1.083590E-01 +6.841954E-03 +2.411006E-05 +1.678550E-02 +1.439749E-04 +3.981095E-01 +3.726016E-02 +2.142413E-02 +1.284486E-04 +7.603821E-01 +1.209106E-01 +1.046497E-02 +4.179315E-05 +2.573004E-02 +2.505335E-04 +3.874363E-01 +3.575389E-02 +2.107756E-02 +1.052519E-04 +8.211656E-01 +1.924162E-01 +1.256245E-02 +3.945660E-05 +3.082654E-02 +2.380887E-04 +4.456573E-01 +4.237155E-02 +2.596764E-02 +1.687922E-04 +8.729138E-01 +1.545134E-01 +1.510275E-02 +6.265801E-05 +3.696609E-02 +3.740070E-04 +3.992793E-01 +3.296068E-02 +2.048068E-02 +9.504244E-05 +8.331278E-01 +1.470933E-01 +1.127453E-02 +3.432997E-05 +2.760806E-02 +2.054207E-04 +3.886517E-01 +3.801441E-02 +2.253407E-02 +1.768474E-04 +7.039271E-01 +1.249249E-01 +1.248570E-02 +6.126807E-05 +3.052526E-02 +3.644213E-04 +3.138763E-01 +2.242983E-02 +2.691593E-02 +3.776077E-04 +6.449202E-01 +8.943446E-02 +1.834857E-02 +2.003405E-04 +4.483992E-02 +1.189482E-03 +3.304662E-01 +2.601947E-02 +1.705125E-02 +1.093125E-04 +7.576247E-01 +1.316185E-01 +8.728845E-03 +2.691230E-05 +2.149655E-02 +1.614671E-04 +3.542477E-01 +2.702674E-02 +2.469817E-02 +1.455831E-04 +7.115078E-01 +1.026190E-01 +1.552045E-02 +5.994661E-05 +3.791483E-02 +3.569299E-04 +2.614009E-01 +1.471316E-02 +9.277502E-03 +2.274093E-05 +5.564657E-01 +6.496526E-02 +3.380006E-03 +2.763922E-06 +8.448047E-03 +1.692336E-05 +4.068252E-01 +3.446693E-02 +2.245360E-02 +1.722882E-04 +7.532457E-01 +1.251856E-01 +1.415713E-02 +8.327501E-05 +3.483023E-02 +4.989609E-04 +3.836239E-01 +3.481679E-02 +2.946278E-02 +2.273732E-04 +6.795627E-01 +1.096060E-01 +1.842353E-02 +9.338437E-05 +4.498328E-02 +5.557198E-04 +2.678688E-01 +1.982541E-02 +1.936290E-03 +1.603437E-06 +5.664033E-01 +7.235502E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.540894E-01 +2.828987E-02 +1.435174E-02 +5.674926E-05 +6.973646E-01 +1.020010E-01 +6.832777E-03 +1.519381E-05 +1.682126E-02 +9.113421E-05 +3.455532E-01 +2.525192E-02 +2.020162E-02 +9.765516E-05 +7.040136E-01 +1.093402E-01 +1.088099E-02 +3.831955E-05 +2.661063E-02 +2.277881E-04 +2.776016E-01 +1.920243E-02 +2.052713E-03 +1.376197E-06 +6.585464E-01 +9.903277E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.091116E-01 +2.801257E-02 +2.024177E-02 +1.487498E-04 +6.138896E-01 +9.760701E-02 +1.262011E-02 +5.893128E-05 +3.079776E-02 +3.500582E-04 +4.487706E-01 +4.623185E-02 +4.373194E-02 +6.227096E-04 +8.118881E-01 +1.430088E-01 +2.909097E-02 +2.931199E-04 +7.090335E-02 +1.741024E-03 +4.974461E-01 +7.638705E-02 +5.262803E-03 +9.305275E-06 +8.298919E-01 +1.867351E-01 +4.223383E-07 +5.157240E-14 +1.028071E-06 +3.055838E-13 +3.906825E-01 +3.395073E-02 +2.733734E-02 +2.244620E-04 +7.121951E-01 +1.102604E-01 +1.681025E-02 +9.894122E-05 +4.107934E-02 +5.893557E-04 +2.885297E-01 +1.780804E-02 +1.916292E-02 +1.071634E-04 +6.439592E-01 +8.863510E-02 +1.116822E-02 +3.755311E-05 +2.741619E-02 +2.250014E-04 +3.733478E-01 +2.968457E-02 +2.417235E-03 +1.601471E-06 +8.160636E-01 +1.392543E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.807050E-01 +3.567435E-02 +1.639520E-02 +8.976183E-05 +8.352591E-01 +1.618917E-01 +7.549384E-03 +2.052873E-05 +1.868571E-02 +1.237926E-04 +4.113785E-01 +4.105596E-02 +2.760797E-02 +3.224706E-04 +8.312520E-01 +1.593787E-01 +1.755904E-02 +1.501020E-04 +4.309969E-02 +8.945939E-04 +4.264452E-01 +3.725052E-02 +2.761193E-03 +2.435650E-06 +9.907602E-01 +1.997766E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.190564E-01 +2.211691E-02 +2.297586E-02 +1.527095E-04 +6.146814E-01 +8.438195E-02 +1.406876E-02 +6.039729E-05 +3.440408E-02 +3.599638E-04 +3.441464E-01 +2.721527E-02 +2.208497E-02 +2.084304E-04 +6.754061E-01 +9.588273E-02 +1.249467E-02 +7.294249E-05 +3.053834E-02 +4.341021E-04 +4.902348E-01 +5.753291E-02 +4.141899E-02 +4.944456E-04 +8.677723E-01 +1.834890E-01 +2.563835E-02 +1.920950E-04 +6.257208E-02 +1.139519E-03 +3.219458E-01 +2.681583E-02 +1.509759E-02 +7.089200E-05 +7.411535E-01 +1.399501E-01 +7.267619E-03 +2.195119E-05 +1.781703E-02 +1.304167E-04 +3.460861E-01 +3.062496E-02 +2.305587E-02 +1.686535E-04 +7.279411E-01 +1.156782E-01 +1.567573E-02 +7.910023E-05 +3.843848E-02 +4.721498E-04 +3.706413E-01 +4.607848E-02 +2.101789E-02 +2.205947E-04 +6.385961E-01 +1.004148E-01 +1.096358E-02 +6.216344E-05 +2.682421E-02 +3.692258E-04 +4.326697E-01 +4.048321E-02 +2.321371E-02 +1.359451E-04 +8.057041E-01 +1.359077E-01 +1.178456E-02 +4.532462E-05 +2.882484E-02 +2.702988E-04 +3.700813E-01 +3.145900E-02 +1.629352E-02 +7.752174E-05 +7.168661E-01 +1.142671E-01 +8.563032E-03 +2.424964E-05 +2.094203E-02 +1.448273E-04 +4.171696E-01 +4.090198E-02 +1.942144E-02 +1.387048E-04 +7.827435E-01 +1.320064E-01 +1.123721E-02 +5.225505E-05 +2.747262E-02 +3.113824E-04 +3.936452E-01 +3.863175E-02 +1.864453E-02 +1.426388E-04 +7.621977E-01 +1.259923E-01 +1.114507E-02 +5.649068E-05 +2.735223E-02 +3.374133E-04 +4.146463E-01 +4.565600E-02 +2.051099E-02 +1.708674E-04 +8.092070E-01 +1.483485E-01 +1.068128E-02 +5.635889E-05 +2.623860E-02 +3.368690E-04 +3.502918E-01 +2.962552E-02 +2.245539E-02 +1.353853E-04 +6.798743E-01 +1.244576E-01 +1.299645E-02 +5.263601E-05 +3.188515E-02 +3.178466E-04 +3.664319E-01 +3.762644E-02 +1.543591E-02 +6.786902E-05 +7.257390E-01 +1.308037E-01 +7.920735E-03 +2.010753E-05 +1.954092E-02 +1.209187E-04 +2.881558E-01 +2.091566E-02 +1.253893E-02 +4.874752E-05 +6.867849E-01 +1.142347E-01 +6.304481E-03 +1.195351E-05 +1.563357E-02 +7.346975E-05 +4.226989E-01 +3.731519E-02 +1.464919E-02 +5.381568E-05 +9.709527E-01 +1.979486E-01 +5.624028E-03 +7.623772E-06 +1.400491E-02 +4.711591E-05 +4.177322E-01 +4.315006E-02 +1.820553E-02 +1.147713E-04 +8.897521E-01 +1.764672E-01 +8.738022E-03 +3.234864E-05 +2.155239E-02 +1.941292E-04 +4.092607E-01 +3.530369E-02 +2.094863E-02 +1.698700E-04 +9.371798E-01 +1.782535E-01 +1.252469E-02 +6.937532E-05 +3.076548E-02 +4.148830E-04 +3.694768E-01 +3.810772E-02 +1.842214E-02 +1.102654E-04 +7.440566E-01 +1.378317E-01 +1.077497E-02 +3.938422E-05 +2.649591E-02 +2.371539E-04 +3.561758E-01 +3.892218E-02 +1.971769E-02 +1.829864E-04 +7.613019E-01 +1.474240E-01 +1.192622E-02 +7.156692E-05 +2.936758E-02 +4.300051E-04 +2.527416E-01 +1.830741E-02 +1.645432E-02 +1.267160E-04 +5.925996E-01 +9.467855E-02 +8.871453E-03 +5.348101E-05 +2.184328E-02 +3.189633E-04 +3.300644E-01 +2.928166E-02 +1.882410E-02 +1.436109E-04 +7.237383E-01 +1.333008E-01 +9.519880E-03 +4.704072E-05 +2.342545E-02 +2.806433E-04 +3.764914E-01 +3.641557E-02 +1.821370E-02 +1.541319E-04 +7.651976E-01 +1.295027E-01 +1.036579E-02 +6.438503E-05 +2.552774E-02 +3.859463E-04 +2.999858E-01 +2.596841E-02 +2.166579E-02 +2.610355E-04 +6.375460E-01 +1.048518E-01 +1.456288E-02 +1.290713E-04 +3.563700E-02 +7.694303E-04 +4.842591E-01 +6.171881E-02 +2.321959E-02 +1.668178E-04 +8.833362E-01 +1.695389E-01 +1.327201E-02 +5.801276E-05 +3.246066E-02 +3.448393E-04 +5.214507E-01 +7.645410E-02 +2.106712E-02 +1.794528E-04 +8.149268E-01 +1.497643E-01 +1.099539E-02 +6.388195E-05 +2.693654E-02 +3.799114E-04 +4.660026E-01 +5.353148E-02 +2.651479E-02 +2.310878E-04 +8.389665E-01 +1.518968E-01 +1.651906E-02 +9.356467E-05 +4.039371E-02 +5.572969E-04 +5.848474E-01 +9.288276E-02 +4.985330E-02 +1.127634E-03 +1.055201E+00 +2.709678E-01 +3.348026E-02 +5.556505E-04 +8.197497E-02 +3.315235E-03 +4.139721E-01 +3.782370E-02 +1.933292E-02 +1.125655E-04 +9.059089E-01 +1.795184E-01 +9.265770E-03 +3.682450E-05 +2.278990E-02 +2.207751E-04 +3.882528E-01 +4.110026E-02 +1.561145E-02 +6.509900E-05 +6.762051E-01 +9.661914E-02 +7.561172E-03 +1.586464E-05 +1.861326E-02 +9.601481E-05 +3.055549E-01 +2.290439E-02 +1.869038E-02 +1.012810E-04 +6.519604E-01 +9.557502E-02 +1.045342E-02 +3.401674E-05 +2.561909E-02 +2.031141E-04 +3.784039E-01 +3.540818E-02 +1.144663E-02 +3.747954E-05 +7.982030E-01 +1.492246E-01 +3.743861E-03 +3.826041E-06 +9.336060E-03 +2.375886E-05 +3.893167E-01 +3.224146E-02 +1.465378E-02 +5.640030E-05 +8.519576E-01 +1.546319E-01 +7.851346E-03 +2.140423E-05 +1.941671E-02 +1.297116E-04 +4.628352E-01 +4.648532E-02 +3.104209E-02 +2.927221E-04 +9.424350E-01 +1.848692E-01 +1.805340E-02 +1.259139E-04 +4.411679E-02 +7.489332E-04 +5.036437E-01 +6.329907E-02 +3.701287E-02 +4.293191E-04 +9.845647E-01 +2.302864E-01 +2.189511E-02 +1.860705E-04 +5.357155E-02 +1.113432E-03 +3.651286E-01 +3.372208E-02 +1.898638E-02 +1.788233E-04 +7.283966E-01 +1.166080E-01 +1.159586E-02 +7.325796E-05 +2.849437E-02 +4.369152E-04 +3.712514E-01 +3.312825E-02 +2.124449E-02 +1.626400E-04 +7.116233E-01 +1.089685E-01 +1.329424E-02 +6.857983E-05 +3.257383E-02 +4.067854E-04 +2.729718E-01 +2.308771E-02 +5.130628E-03 +8.219165E-06 +7.257857E-01 +1.711422E-01 +1.662698E-03 +9.477833E-07 +4.314077E-03 +6.608852E-06 +2.780491E-01 +2.511642E-02 +1.327468E-02 +1.125406E-04 +5.815634E-01 +9.937798E-02 +6.802535E-03 +3.433855E-05 +1.678587E-02 +2.048151E-04 +4.836173E-01 +6.301714E-02 +5.126877E-03 +7.676969E-06 +7.235761E-01 +1.309488E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.031875E-01 +4.115015E-02 +2.401570E-02 +1.884922E-04 +7.226240E-01 +1.246862E-01 +1.365997E-02 +6.483039E-05 +3.348484E-02 +3.878250E-04 +3.969397E-01 +3.388912E-02 +1.954568E-02 +1.484093E-04 +8.502161E-01 +1.499123E-01 +1.000927E-02 +5.813943E-05 +2.452378E-02 +3.457355E-04 +5.393064E-01 +7.598949E-02 +4.596848E-03 +8.271188E-06 +9.233647E-01 +1.837028E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.305005E-01 +3.980527E-02 +3.622333E-02 +2.714888E-04 +7.562019E-01 +1.251870E-01 +2.210501E-02 +1.044787E-04 +5.402135E-02 +6.242016E-04 +4.150253E-01 +4.310022E-02 +3.055341E-02 +3.204376E-04 +8.383810E-01 +1.598344E-01 +1.799260E-02 +1.186722E-04 +4.421143E-02 +7.098098E-04 +5.053663E-01 +6.741744E-02 +4.302548E-03 +5.486457E-06 +1.001508E+00 +2.499069E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +5.305404E-01 +9.168988E-02 +4.204388E-02 +6.233654E-04 +1.019287E+00 +2.883833E-01 +2.692540E-02 +2.702944E-04 +6.578499E-02 +1.604933E-03 +2.979429E-01 +2.557053E-02 +1.270971E-02 +6.086980E-05 +6.133144E-01 +9.302940E-02 +6.554631E-03 +2.408980E-05 +1.614693E-02 +1.437968E-04 +2.985643E-01 +2.168009E-02 +1.675518E-03 +6.853400E-07 +6.603013E-01 +1.039248E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.978111E-01 +3.476147E-02 +2.583972E-02 +1.494411E-04 +8.471730E-01 +1.545734E-01 +1.585722E-02 +6.154411E-05 +3.885738E-02 +3.693284E-04 +5.202672E-01 +6.063991E-02 +2.696218E-02 +2.266432E-04 +1.106648E+00 +2.681959E-01 +1.522211E-02 +8.625903E-05 +3.740299E-02 +5.175445E-04 +4.764994E-01 +7.395612E-02 +4.506348E-03 +1.035606E-05 +9.157662E-01 +2.118046E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.132742E-01 +4.146437E-02 +3.375089E-02 +4.225536E-04 +7.921867E-01 +1.381808E-01 +2.045881E-02 +1.753311E-04 +5.005367E-02 +1.042462E-03 +2.661077E-01 +1.751445E-02 +1.121639E-02 +3.636881E-05 +5.712386E-01 +7.771405E-02 +6.533439E-03 +1.250013E-05 +1.610362E-02 +7.471829E-05 +3.425750E-01 +3.408776E-02 +1.156146E-02 +5.411528E-05 +8.276841E-01 +1.940431E-01 +6.001009E-03 +2.103242E-05 +1.484593E-02 +1.276999E-04 +3.790958E-01 +5.528325E-02 +2.035138E-02 +2.087186E-04 +7.464973E-01 +1.698540E-01 +1.056382E-02 +7.655648E-05 +2.594266E-02 +4.578317E-04 +4.673249E-01 +5.113730E-02 +2.751426E-02 +1.816642E-04 +8.149126E-01 +1.677855E-01 +1.476997E-02 +5.736790E-05 +3.624040E-02 +3.439634E-04 +4.969678E-01 +6.703663E-02 +3.324010E-02 +4.839680E-04 +7.957816E-01 +1.402618E-01 +1.787791E-02 +1.889011E-04 +4.366390E-02 +1.122265E-03 +3.987041E-01 +3.319083E-02 +1.717610E-02 +7.614560E-05 +8.405362E-01 +1.455051E-01 +9.116726E-03 +2.731734E-05 +2.243998E-02 +1.635133E-04 +3.557016E-01 +2.733014E-02 +1.946614E-02 +9.722258E-05 +8.042289E-01 +1.325000E-01 +1.081675E-02 +3.317997E-05 +2.660183E-02 +1.988697E-04 +4.238750E-01 +5.071137E-02 +3.860553E-02 +4.907754E-04 +6.818241E-01 +1.059015E-01 +2.594551E-02 +2.253483E-04 +6.329673E-02 +1.337276E-03 +4.845466E-01 +4.739927E-02 +3.781105E-02 +3.188017E-04 +8.754691E-01 +1.592141E-01 +2.256002E-02 +1.269857E-04 +5.521664E-02 +7.580381E-04 +4.762135E-01 +5.411538E-02 +2.732678E-02 +2.310254E-04 +7.810833E-01 +1.311139E-01 +1.597068E-02 +8.360266E-05 +3.898613E-02 +4.967345E-04 +4.626499E-01 +6.385872E-02 +2.294200E-02 +1.768315E-04 +9.372052E-01 +2.270799E-01 +1.299342E-02 +6.187834E-05 +3.189449E-02 +3.716202E-04 +3.261518E-01 +3.233233E-02 +1.344996E-02 +7.296974E-05 +6.438319E-01 +1.139836E-01 +6.902941E-03 +2.347639E-05 +1.691710E-02 +1.400440E-04 +4.352336E-01 +5.775668E-02 +2.123686E-02 +1.661853E-04 +8.342632E-01 +1.707879E-01 +1.088157E-02 +4.787467E-05 +2.666381E-02 +2.851629E-04 +4.309663E-01 +3.819583E-02 +2.280285E-02 +1.438300E-04 +8.522076E-01 +1.478770E-01 +1.272222E-02 +4.969054E-05 +3.123456E-02 +2.971660E-04 +3.545417E-01 +3.176670E-02 +2.104462E-02 +1.973843E-04 +6.924468E-01 +1.084661E-01 +1.359515E-02 +9.318781E-05 +3.323698E-02 +5.537381E-04 +2.601793E-01 +1.854037E-02 +7.292982E-03 +2.119725E-05 +5.911869E-01 +8.786472E-02 +3.411247E-03 +4.494329E-06 +8.395279E-03 +2.694816E-05 +2.856586E-01 +1.974948E-02 +1.054334E-02 +2.769649E-05 +6.966115E-01 +1.097272E-01 +4.020408E-03 +5.909802E-06 +1.002274E-02 +3.621226E-05 +2.990262E-01 +2.895771E-02 +1.524669E-02 +1.075200E-04 +5.511247E-01 +7.221915E-02 +7.850283E-03 +4.154474E-05 +1.921607E-02 +2.483852E-04 +2.734313E-01 +2.247782E-02 +1.398383E-02 +1.162049E-04 +6.576619E-01 +1.210529E-01 +8.907424E-03 +5.814670E-05 +2.190592E-02 +3.497392E-04 +2.815363E-01 +1.901069E-02 +1.186929E-02 +3.364035E-05 +6.515902E-01 +9.851410E-02 +6.886950E-03 +1.323736E-05 +1.695569E-02 +7.940407E-05 +3.484143E-01 +2.809808E-02 +2.158706E-02 +1.746308E-04 +6.459834E-01 +9.326184E-02 +1.339059E-02 +7.862843E-05 +3.279132E-02 +4.674908E-04 +4.872293E-01 +6.299198E-02 +4.535678E-03 +8.886458E-06 +7.995378E-01 +1.391013E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.517270E-01 +4.298933E-02 +2.983900E-02 +2.534533E-04 +9.003348E-01 +1.639649E-01 +1.797753E-02 +1.058508E-04 +4.408492E-02 +6.323324E-04 +3.840449E-01 +3.048942E-02 +2.304747E-02 +1.451405E-04 +7.696800E-01 +1.200152E-01 +1.291566E-02 +4.856104E-05 +3.169233E-02 +2.900548E-04 +3.899986E-01 +4.842017E-02 +3.398750E-02 +5.012913E-04 +7.289300E-01 +1.213432E-01 +2.225136E-02 +2.225919E-04 +5.443442E-02 +1.322013E-03 +5.598647E-01 +7.209791E-02 +3.636258E-02 +2.972603E-04 +9.425990E-01 +1.980189E-01 +2.180409E-02 +1.030147E-04 +5.325326E-02 +6.135525E-04 +5.137462E-01 +5.449795E-02 +2.968013E-02 +2.213205E-04 +1.089121E+00 +2.416550E-01 +1.633665E-02 +8.162297E-05 +4.019388E-02 +4.875490E-04 +4.289801E-01 +4.093477E-02 +2.010221E-02 +9.125869E-05 +8.441503E-01 +1.577640E-01 +1.121134E-02 +3.076206E-05 +2.749358E-02 +1.837347E-04 +4.669049E-01 +4.985409E-02 +3.155885E-02 +2.843354E-04 +8.541836E-01 +1.586915E-01 +1.971407E-02 +1.199500E-04 +4.819514E-02 +7.142000E-04 +5.476118E-01 +7.964842E-02 +3.671613E-02 +5.048684E-04 +9.819505E-01 +2.224104E-01 +2.057791E-02 +1.723983E-04 +5.020646E-02 +1.023284E-03 +3.570430E-01 +3.236156E-02 +2.642812E-02 +2.499237E-04 +6.566192E-01 +1.028336E-01 +1.658528E-02 +1.090997E-04 +4.052667E-02 +6.501756E-04 +3.157944E-01 +2.754029E-02 +2.510614E-03 +2.597981E-06 +6.619048E-01 +1.052488E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.796550E-01 +1.863344E-02 +1.041219E-02 +5.191551E-05 +6.609168E-01 +1.042598E-01 +6.108228E-03 +2.425637E-05 +1.502705E-02 +1.442032E-04 +2.179231E-01 +1.148681E-02 +1.158771E-02 +5.115165E-05 +5.338009E-01 +6.387573E-02 +6.955519E-03 +2.069739E-05 +1.714723E-02 +1.242632E-04 +2.723379E-01 +1.612703E-02 +1.661668E-02 +8.393477E-05 +6.115831E-01 +7.762931E-02 +8.158618E-03 +2.912656E-05 +2.012066E-02 +1.734434E-04 +4.177079E-01 +5.021689E-02 +1.465133E-02 +8.170592E-05 +8.821701E-01 +2.073297E-01 +5.279873E-03 +1.131685E-05 +1.297780E-02 +6.813348E-05 +4.389866E-01 +5.718767E-02 +2.509233E-02 +2.986289E-04 +8.525743E-01 +1.748816E-01 +1.369565E-02 +1.018308E-04 +3.355369E-02 +6.079070E-04 +4.137349E-01 +4.314157E-02 +2.371796E-02 +2.559421E-04 +7.149288E-01 +1.144426E-01 +1.335685E-02 +1.050731E-04 +3.269465E-02 +6.277716E-04 +6.493181E-01 +8.850590E-02 +4.003436E-02 +4.029382E-04 +1.240508E+00 +3.254748E-01 +2.412272E-02 +1.510168E-04 +5.916870E-02 +9.052554E-04 +4.999253E-01 +5.822974E-02 +2.648913E-02 +2.036552E-04 +8.603421E-01 +1.542102E-01 +1.503446E-02 +7.780397E-05 +3.680872E-02 +4.627887E-04 +2.140322E-01 +1.009989E-02 +9.821979E-04 +2.888126E-07 +5.412641E-01 +6.614023E-02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.473664E-01 +1.445695E-02 +1.115793E-02 +4.639483E-05 +6.402572E-01 +1.087519E-01 +6.977317E-03 +2.012165E-05 +1.726283E-02 +1.209389E-04 +4.106842E-01 +4.252374E-02 +2.865498E-02 +2.625513E-04 +6.937372E-01 +1.072413E-01 +1.818386E-02 +1.104345E-04 +4.446846E-02 +6.595035E-04 +4.211497E-01 +4.077958E-02 +2.971575E-03 +2.487030E-06 +8.520797E-01 +1.481605E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +5.226188E-01 +5.944362E-02 +2.960968E-02 +2.245340E-04 +9.222348E-01 +1.736139E-01 +1.631529E-02 +7.908945E-05 +3.982616E-02 +4.708490E-04 +4.418421E-01 +4.437957E-02 +2.517739E-02 +1.907600E-04 +7.787605E-01 +1.249305E-01 +1.536054E-02 +7.917968E-05 +3.755245E-02 +4.723672E-04 +4.343976E-01 +4.457981E-02 +3.388911E-03 +3.822692E-06 +8.737430E-01 +1.764940E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.598455E-01 +2.729560E-02 +2.418740E-02 +2.378985E-04 +7.302175E-01 +1.135251E-01 +1.616906E-02 +1.246680E-04 +3.949063E-02 +7.402107E-04 +2.619461E-01 +1.513254E-02 +8.926754E-03 +1.978809E-05 +6.435721E-01 +9.157538E-02 +4.651147E-03 +7.139204E-06 +1.149560E-02 +4.303315E-05 +3.477772E-01 +3.056585E-02 +1.223437E-02 +5.499474E-05 +7.995504E-01 +1.386715E-01 +6.975627E-03 +1.888125E-05 +1.734787E-02 +1.146221E-04 +3.619349E-01 +3.702197E-02 +1.807440E-02 +1.270513E-04 +7.778669E-01 +1.474144E-01 +1.099124E-02 +4.917455E-05 +2.701829E-02 +2.940738E-04 +3.162191E-01 +2.268893E-02 +1.158071E-02 +3.480324E-05 +7.692808E-01 +1.327980E-01 +4.095665E-03 +5.158750E-06 +1.022758E-02 +3.212100E-05 +5.342532E-01 +8.478330E-02 +2.903573E-02 +3.357498E-04 +1.120085E+00 +3.408745E-01 +1.690122E-02 +1.279478E-04 +4.141172E-02 +7.637947E-04 +4.496065E-01 +6.505133E-02 +2.635557E-02 +3.323123E-04 +9.612470E-01 +2.510212E-01 +1.538003E-02 +1.327695E-04 +3.782149E-02 +7.945656E-04 +4.847046E-01 +5.967696E-02 +2.535687E-02 +2.173087E-04 +1.077043E+00 +2.811943E-01 +1.097101E-02 +3.799483E-05 +2.709062E-02 +2.304602E-04 +5.175767E-01 +5.719466E-02 +1.973241E-02 +8.575798E-05 +9.679612E-01 +2.056860E-01 +8.303999E-03 +1.805765E-05 +2.040361E-02 +1.089188E-04 +5.517001E-01 +6.994072E-02 +2.497158E-02 +1.771114E-04 +1.098639E+00 +2.726418E-01 +1.399598E-02 +6.099098E-05 +3.430186E-02 +3.665835E-04 +2.863207E-01 +1.857525E-02 +8.336069E-03 +1.649811E-05 +6.476326E-01 +9.010693E-02 +3.429198E-03 +3.106979E-06 +8.565244E-03 +1.898164E-05 +2.620263E-01 +1.413830E-02 +1.486260E-02 +6.016669E-05 +5.979318E-01 +7.637631E-02 +7.005392E-03 +1.590920E-05 +1.730862E-02 +9.593066E-05 +3.655323E-01 +3.067786E-02 +2.564543E-02 +2.165772E-04 +7.572344E-01 +1.217887E-01 +1.473507E-02 +8.140802E-05 +3.619562E-02 +4.852029E-04 +3.419278E-01 +2.642670E-02 +2.272345E-02 +1.520173E-04 +6.406916E-01 +8.632502E-02 +1.398347E-02 +6.589014E-05 +3.414144E-02 +3.923320E-04 +4.462443E-01 +4.882939E-02 +3.221856E-02 +4.381937E-04 +7.714529E-01 +1.298248E-01 +2.030822E-02 +2.050592E-04 +4.959466E-02 +1.221874E-03 +4.241623E-01 +4.238067E-02 +3.017189E-02 +3.192439E-04 +8.184443E-01 +1.472953E-01 +1.653484E-02 +9.828819E-05 +4.040308E-02 +5.837728E-04 +5.468649E-01 +6.932849E-02 +3.506986E-02 +3.414126E-04 +9.081801E-01 +1.955422E-01 +2.067323E-02 +1.252268E-04 +5.051840E-02 +7.466097E-04 +4.049238E-01 +3.619626E-02 +1.820878E-02 +8.370629E-05 +7.947251E-01 +1.471574E-01 +6.827689E-03 +1.877378E-05 +1.682488E-02 +1.119968E-04 +3.181706E-01 +2.312073E-02 +1.853503E-02 +9.670338E-05 +7.307830E-01 +1.165409E-01 +1.133833E-02 +4.507577E-05 +2.784164E-02 +2.700020E-04 +4.535053E-01 +4.781822E-02 +2.298094E-02 +1.379435E-04 +9.393810E-01 +1.913101E-01 +1.088324E-02 +3.746573E-05 +2.670626E-02 +2.245210E-04 +3.711608E-01 +3.011209E-02 +2.135571E-02 +1.326869E-04 +7.941852E-01 +1.316708E-01 +1.330360E-02 +5.321889E-05 +3.253974E-02 +3.167152E-04 +4.121174E-01 +3.478939E-02 +1.586472E-02 +6.068678E-05 +1.040216E+00 +2.214218E-01 +5.758712E-03 +1.002333E-05 +1.426440E-02 +6.037119E-05 +4.435090E-01 +4.161468E-02 +1.602560E-02 +5.789996E-05 +1.002899E+00 +2.058070E-01 +7.221739E-03 +1.233021E-05 +1.798457E-02 +7.523251E-05 +4.605997E-01 +5.734630E-02 +1.933007E-02 +1.409861E-04 +1.082221E+00 +2.959635E-01 +9.105646E-03 +3.669942E-05 +2.256185E-02 +2.209209E-04 +4.760643E-01 +5.548670E-02 +2.305845E-02 +1.988737E-04 +1.108307E+00 +2.819143E-01 +1.141829E-02 +5.438996E-05 +2.821950E-02 +3.289724E-04 +2.990870E-01 +2.614044E-02 +1.379131E-02 +6.530395E-05 +6.526311E-01 +1.174214E-01 +6.340014E-03 +1.465241E-05 +1.577489E-02 +8.917934E-05 +4.539651E-01 +5.989053E-02 +3.706059E-02 +7.451853E-04 +9.479066E-01 +2.087790E-01 +2.371011E-02 +3.624597E-04 +5.802863E-02 +2.153033E-03 +3.550875E-01 +3.154848E-02 +1.517370E-02 +6.019907E-05 +8.233200E-01 +1.604220E-01 +7.096967E-03 +1.239328E-05 +1.749843E-02 +7.496910E-05 +2.669672E-01 +1.655119E-02 +9.921355E-03 +2.850701E-05 +6.229281E-01 +9.065592E-02 +3.525996E-03 +3.622432E-06 +8.763114E-03 +2.217997E-05 +3.117641E-01 +2.706928E-02 +1.301318E-02 +6.380468E-05 +7.069278E-01 +1.223940E-01 +5.520667E-03 +1.450549E-05 +1.364327E-02 +8.705049E-05 +4.253175E-01 +4.226465E-02 +3.130303E-02 +2.892976E-04 +8.847586E-01 +1.831350E-01 +1.869718E-02 +1.080033E-04 +4.581100E-02 +6.437392E-04 +4.373877E-01 +4.563513E-02 +2.171789E-02 +1.852469E-04 +8.427752E-01 +1.639163E-01 +1.193320E-02 +6.904423E-05 +2.934222E-02 +4.124494E-04 +3.309335E-01 +2.360277E-02 +1.782689E-02 +7.495262E-05 +7.435456E-01 +1.161667E-01 +9.806683E-03 +2.456418E-05 +2.407241E-02 +1.471923E-04 +3.295651E-01 +2.892136E-02 +9.136199E-03 +2.751683E-05 +7.402491E-01 +1.444989E-01 +4.232396E-03 +6.593472E-06 +1.064377E-02 +4.140318E-05 +2.646177E-01 +1.820511E-02 +6.560072E-03 +1.355487E-05 +6.853657E-01 +1.299412E-01 +2.501821E-03 +2.093278E-06 +6.398968E-03 +1.362528E-05 +5.276217E-01 +6.992447E-02 +4.094462E-02 +5.970189E-04 +1.098251E+00 +3.357754E-01 +2.710360E-02 +2.943539E-04 +6.624993E-02 +1.748479E-03 +4.706582E-01 +4.760382E-02 +1.885346E-02 +7.652927E-05 +9.303306E-01 +1.833640E-01 +9.384721E-03 +2.029091E-05 +2.290445E-02 +1.208163E-04 +5.382357E-01 +6.759212E-02 +2.981285E-02 +2.571507E-04 +1.218516E+00 +3.361214E-01 +1.807366E-02 +9.486632E-05 +4.459288E-02 +5.717156E-04 +5.926040E-01 +7.178398E-02 +4.360128E-02 +5.324114E-04 +1.307820E+00 +3.690548E-01 +2.600218E-02 +2.365448E-04 +6.382907E-02 +1.415541E-03 +tally 2: +2.410000E+00 +1.233100E+00 +2.410000E+00 +1.233100E+00 +8.400000E-01 +1.434000E-01 +8.400000E-01 +1.434000E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.262000E+01 +3.207480E+01 +1.262000E+01 +3.207480E+01 +6.000000E-02 +1.800000E-03 +6.000000E-02 +1.800000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.220000E+00 +1.365100E+01 +8.220000E+00 +1.365100E+01 +9.000000E-02 +2.300000E-03 +9.000000E-02 +2.300000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.430000E+00 +2.409500E+00 +3.430000E+00 +2.409500E+00 +4.000000E-02 +4.000000E-04 +4.000000E-02 +4.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.450000E+00 +4.253000E-01 +1.450000E+00 +4.253000E-01 +7.000000E-02 +1.900000E-03 +7.000000E-02 +1.900000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +1.570000E+00 +5.095000E-01 +1.570000E+00 +5.095000E-01 +9.000000E-02 +2.300000E-03 +9.000000E-02 +2.300000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +9.000000E-02 +1.900000E-03 +9.000000E-02 +1.900000E-03 +2.010000E+00 +8.355000E-01 +2.010000E+00 +8.355000E-01 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +2.000000E-02 +2.000000E-04 +2.000000E-02 +2.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.000000E-02 +6.000000E-04 +4.000000E-02 +6.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.000000E-02 +4.000000E-04 +4.000000E-02 +4.000000E-04 +5.000000E-02 +5.000000E-04 +5.000000E-02 +5.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +7.000000E-02 +2.100000E-03 +7.000000E-02 +2.100000E-03 +1.000000E-01 +2.600000E-03 +1.000000E-01 +2.600000E-03 +8.000000E-02 +1.600000E-03 +8.000000E-02 +1.600000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.600000E-01 +1.528000E-01 +8.600000E-01 +1.528000E-01 +1.800000E-01 +8.000000E-03 +1.800000E-01 +8.000000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.600000E-01 +1.420000E-02 +2.600000E-01 +1.420000E-02 +1.600000E-01 +6.200000E-03 +1.600000E-01 +6.200000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +5.000000E-02 +9.000000E-04 +5.000000E-02 +9.000000E-04 +1.200000E-01 +3.800000E-03 +1.200000E-01 +3.800000E-03 +2.000000E-02 +2.000000E-04 +2.000000E-02 +2.000000E-04 +1.000000E-02 +1.000000E-04 +1.000000E-02 +1.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +9.000000E-02 +2.300000E-03 +9.000000E-02 +2.300000E-03 +1.500000E-01 +7.300000E-03 +1.500000E-01 +7.300000E-03 +3.000000E-02 +5.000000E-04 +3.000000E-02 +5.000000E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.400000E-01 +4.000000E-03 +1.400000E-01 +4.000000E-03 +1.000000E-01 +2.400000E-03 +1.000000E-01 +2.400000E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.000000E-02 +6.000000E-04 +4.000000E-02 +6.000000E-04 +1.140000E+00 +2.858000E-01 +1.140000E+00 +2.858000E-01 diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py new file mode 100644 index 0000000000..a9b1860c59 --- /dev/null +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import TestHarness, PyAPITestHarness +import openmc + + +class MGTalliesTestHarness(PyAPITestHarness): + def _build_inputs(self): + # Instantiate a tally mesh + mesh = openmc.Mesh(mesh_id=1) + mesh.type = 'regular' + mesh.dimension = [17, 17, 1] + mesh.lower_left = [0.0, 0.0, 0.0] + mesh.upper_right = [21.42, 21.42, 100.0] + + # Instantiate some tally filters + energy_filter = openmc.Filter(type='energy', + bins=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, + 1.0E-3, 0.5, 1.0, 20.0]) + energyout_filter = openmc.Filter(type='energyout', + bins=[1E-11, 0.0635E-6, 10.0E-6, + 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) + mesh_filter = openmc.Filter() + mesh_filter.mesh = mesh + + mat_filter = openmc.Filter(type='material', bins=[1,2,3]) + + tally1 = openmc.Tally(tally_id=1) + tally1.add_filter(mesh_filter) + tally1.add_score('total') + tally1.add_score('absorption') + tally1.add_score('flux') + tally1.add_score('fission') + tally1.add_score('nu-fission') + + tally2 = openmc.Tally(tally_id=2) + tally2.add_filter(mat_filter) + tally2.add_filter(energy_filter) + tally2.add_filter(energyout_filter) + tally2.add_score('scatter') + tally2.add_score('nu-scatter') + + self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies.add_mesh(mesh) + self._input_set.tallies.add_tally(tally1) + self._input_set.tallies.add_tally(tally2) + + super(MGTalliesTestHarness, self)._build_inputs() + + def _cleanup(self): + super(MGTalliesTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): os.remove(f) + + +if __name__ == '__main__': + harness = MGTalliesTestHarness('statepoint.10.*', True, mg=True) + harness.main() From a093d6fde8e4db4615f780356e9a9f4ea245b44b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 17 Nov 2015 21:28:57 -0500 Subject: [PATCH 44/84] Added option tp print logfile for failing tests --- tests/run_tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run_tests.py b/tests/run_tests.py index 338732c142..e62629401a 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -470,6 +470,7 @@ for key in iter(tests): logfilename = os.path.splitext(logfilename)[0] logfilename = logfilename + '_{0}.log'.format(test.name) shutil.copy(logfile[0], logfilename) + with open(logfilename) as fh: print(fh.read()) # Clear build directory and remove binary and hdf5 files shutil.rmtree('build', ignore_errors=True) From bd39cbe59ec51ce66dd87e27d3bb14178e40002a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 18 Nov 2015 04:52:38 -0500 Subject: [PATCH 45/84] Fixed failing MPI case - didnt update MPI_BANK type for addition of group - and cleaned up travis log dump change --- src/initialize.F90 | 18 ++++++++++-------- tests/run_tests.py | 1 - 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index 128759e429..7aa351b498 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -202,17 +202,17 @@ contains subroutine initialize_mpi() - integer :: bank_blocks(5) ! Count for each datatype + integer :: bank_blocks(6) ! Count for each datatype #ifdef MPIF08 - type(MPI_Datatype) :: bank_types(5) + type(MPI_Datatype) :: bank_types(6) type(MPI_Datatype) :: result_types(1) type(MPI_Datatype) :: temp_type #else - integer :: bank_types(5) ! Datatypes + integer :: bank_types(6) ! Datatypes integer :: result_types(1) ! Datatypes integer :: temp_type ! temporary derived type #endif - integer(MPI_ADDRESS_KIND) :: bank_disp(5) ! Displacements + integer(MPI_ADDRESS_KIND) :: bank_disp(6) ! Displacements integer :: result_blocks(1) ! Count for each datatype integer(MPI_ADDRESS_KIND) :: result_disp(1) ! Displacements integer(MPI_ADDRESS_KIND) :: result_base_disp ! Base displacement @@ -246,15 +246,17 @@ contains call MPI_GET_ADDRESS(b % xyz, bank_disp(2), mpi_err) call MPI_GET_ADDRESS(b % uvw, bank_disp(3), mpi_err) call MPI_GET_ADDRESS(b % E, bank_disp(4), mpi_err) - call MPI_GET_ADDRESS(b % delayed_group, bank_disp(5), mpi_err) + call MPI_GET_ADDRESS(b % g, bank_disp(5), mpi_err) + call MPI_GET_ADDRESS(b % delayed_group, bank_disp(6), mpi_err) ! Adjust displacements bank_disp = bank_disp - bank_disp(1) ! Define MPI_BANK for fission sites - bank_blocks = (/ 1, 3, 3, 1, 1 /) - bank_types = (/ MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_INTEGER /) - call MPI_TYPE_CREATE_STRUCT(5, bank_blocks, bank_disp, & + bank_blocks = (/ 1, 3, 3, 1, 1, 1 /) + bank_types = (/ MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_REAL8, & + MPI_INTEGER, MPI_INTEGER /) + call MPI_TYPE_CREATE_STRUCT(6, bank_blocks, bank_disp, & bank_types, MPI_BANK, mpi_err) call MPI_TYPE_COMMIT(MPI_BANK, mpi_err) diff --git a/tests/run_tests.py b/tests/run_tests.py index e62629401a..338732c142 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -470,7 +470,6 @@ for key in iter(tests): logfilename = os.path.splitext(logfilename)[0] logfilename = logfilename + '_{0}.log'.format(test.name) shutil.copy(logfile[0], logfilename) - with open(logfilename) as fh: print(fh.read()) # Clear build directory and remove binary and hdf5 files shutil.rmtree('build', ignore_errors=True) From d6f71ff6034af1e75f05cc613cb43934b19cbe52 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 18 Nov 2015 20:47:54 -0500 Subject: [PATCH 46/84] Revised existing MG tests to use my 1d problem since I had angular xs and tabular scattering kernels already generated; added tests for max_order and nuclidic data instead of macroscopic mgxs data. Fixed a bug related to doing the nuclidic data. --- src/input_xml.F90 | 7 + src/mgxs_data.F90 | 10 +- src/nuclide_header.F90 | 3 +- tests/1d_mgxs.xml | 9859 ++++++++++++++++++ tests/c5g7_mgxs.xml | 383 - tests/input_set.py | 144 +- tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/inputs_true.dat | 1 + tests/test_mg_max_order/results_true.dat | 2 + tests/test_mg_max_order/test_mg_max_order.py | 85 + tests/test_mg_nuclide/inputs_true.dat | 1 + tests/test_mg_nuclide/results_true.dat | 2 + tests/test_mg_nuclide/test_mg_nuclide.py | 84 + tests/test_mg_tallies/inputs_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 6382 ++++++------ tests/test_mg_tallies/test_mg_tallies.py | 6 +- 17 files changed, 12991 insertions(+), 3984 deletions(-) create mode 100644 tests/1d_mgxs.xml delete mode 100644 tests/c5g7_mgxs.xml create mode 100644 tests/test_mg_max_order/inputs_true.dat create mode 100644 tests/test_mg_max_order/results_true.dat create mode 100644 tests/test_mg_max_order/test_mg_max_order.py create mode 100644 tests/test_mg_nuclide/inputs_true.dat create mode 100644 tests/test_mg_nuclide/results_true.dat create mode 100644 tests/test_mg_nuclide/test_mg_nuclide.py diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8e3e8d8e9c..b3d85e4688 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4463,6 +4463,13 @@ contains else listing % zaid = -1 end if + if (check_for_node(node_xsdata, "awr")) then + call get_node_value(node_xsdata, "awr", listing % awr) + else + ! Set to a default of 1; this allows a macroscopic library to still + ! be used with materials with atom/b-cm units for testing purposes + listing % awr = ONE + end if if (check_for_node(node_xsdata, "kT")) then call get_node_value(node_xsdata, "kT", listing % kT) else diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index b89c73d51a..10f66882fe 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -653,18 +653,18 @@ contains mat => materials(i_mat) ! Check to see how our nuclides are represented - ! Assume all are the same type - ! Therefore type(nuclides(1) % obj) dictates type(macroxs) + ! Force all to be the same type + ! Therefore type(nuclides(mat % nuclide(1)) % obj) dictates type(macroxs) ! At the same time, we will find the scattering type, as that will dictate ! how we allocate the scatter object within macroxs - legendre_mu_points = nuclides_MG(1) % obj % legendre_mu_points - select type(nuc => nuclides_MG(1) % obj) + legendre_mu_points = nuclides_MG(mat % nuclide(1)) % obj % legendre_mu_points + select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) type is (Nuclide_Iso) representation = ISOTROPIC type is (Nuclide_Angle) representation = ANGLE end select - scatt_type = nuclides_MG(1) % obj % scatt_type + scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type ! Now allocate accordingly select case(representation) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 7786537db5..5102528d05 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -543,8 +543,9 @@ module nuclide_header ! Basic nuclide information write(unit_,*) 'Nuclide ' // trim(this % name) if (this % zaid > 0) then - ! Dont print if data was macroscopic and thus zaid would be nonsense + ! Dont print if data was macroscopic and thus zaid & AWR would be nonsense write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) end if write(unit_,*) ' kT = ' // trim(to_str(this % kT)) if (this % scatt_type == ANGLE_LEGENDRE) then diff --git a/tests/1d_mgxs.xml b/tests/1d_mgxs.xml new file mode 100644 index 0000000000..33b20464b6 --- /dev/null +++ b/tests/1d_mgxs.xml @@ -0,0 +1,9859 @@ + + + 1 + 0.0000000E+00 2.0000000E+01 + + + uo2_iso.71c + uo2_iso.71c + 2.5300000E-08 + 5 + true + isotropic + + 4.1022364E-01 + + + 3.4687432E-02 + + + 4.9631431E-02 + + + 1.0000000E+00 + + + 2.0019027E-02 + + + 3.7564339E-01 + + 4.4983802E-02 + + 2.2781624E-02 + + 1.1639469E-02 + + 7.1975833E-03 + + 3.5887673E-03 + + + 1.0002764E+00 + + + + + clad_iso.71c + clad_iso.71c + 2.5300000E-08 + 5 + false + isotropic + + 3.0736836E-01 + + + 1.7027907E-03 + + + 3.0566993E-01 + + 4.1625057E-02 + + 2.2287832E-02 + + 3.9580806E-03 + + 3.3420849E-03 + + 1.3963828E-03 + + + 1.0000372E+00 + + + + + lwtr_iso.71c + lwtr_iso.71c + 2.5300000E-08 + 5 + false + isotropic + + 9.6904862E-01 + + + 1.0230968E-02 + + + 9.5881780E-01 + + 3.9202760E-01 + + 1.2865356E-01 + + 9.5231115E-03 + + -1.9647208E-02 + + 5.9291968E-04 + + + 1.0000000E+00 + + + + + uo2_iso_mu.71c + uo2_iso_mu.71c + 2.5300000E-08 + 32 + true + isotropic + histogram + + 4.1022364E-01 + + + 3.4687432E-02 + + + 4.9631431E-02 + + + 1.0000000E+00 + + + 2.0019027E-02 + + + 9.7621928E-03 + + 9.6669975E-03 + + 9.6217012E-03 + + 9.6029285E-03 + + 9.6155223E-03 + + 9.6417022E-03 + + 9.6845888E-03 + + 9.7355785E-03 + + 9.7971852E-03 + + 9.8708684E-03 + + 9.9451996E-03 + + 1.0026273E-02 + + 1.0121536E-02 + + 1.0227606E-02 + + 1.0340467E-02 + + 1.0461281E-02 + + 1.0600371E-02 + + 1.0742182E-02 + + 1.0892295E-02 + + 1.1062409E-02 + + 1.1236639E-02 + + 1.1440302E-02 + + 1.1662283E-02 + + 1.1931512E-02 + + 1.2259589E-02 + + 1.2696194E-02 + + 1.3272953E-02 + + 1.4078939E-02 + + 1.5238289E-02 + + 1.6956791E-02 + + 1.9602217E-02 + + 2.3848802E-02 + + + 1.0002764E+00 + + + + + clad_iso_mu.71c + clad_iso_mu.71c + 2.5300000E-08 + 32 + false + isotropic + histogram + + 3.0736836E-01 + + + 1.7027907E-03 + + + 8.7275040E-03 + + 8.3252599E-03 + + 8.0120655E-03 + + 7.7711039E-03 + + 7.5947251E-03 + + 7.4705350E-03 + + 7.3804037E-03 + + 7.3241515E-03 + + 7.3010244E-03 + + 7.3107188E-03 + + 7.3487081E-03 + + 7.4144814E-03 + + 7.5104992E-03 + + 7.6438156E-03 + + 7.7974114E-03 + + 7.9812213E-03 + + 8.1816102E-03 + + 8.4284406E-03 + + 8.6892059E-03 + + 8.9675370E-03 + + 9.2626673E-03 + + 9.6121293E-03 + + 9.9669464E-03 + + 1.0354054E-02 + + 1.0794903E-02 + + 1.1296566E-02 + + 1.1883978E-02 + + 1.2592532E-02 + + 1.3494682E-02 + + 1.4666635E-02 + + 1.6229823E-02 + + 1.8334594E-02 + + + 1.0000372E+00 + + + + + lwtr_iso_mu.71c + lwtr_iso_mu.71c + 2.5300000E-08 + 32 + false + isotropic + histogram + + 9.6904862E-01 + + + 1.0230968E-02 + + + 5.8755233E-03 + + 1.0934725E-02 + + 1.1142414E-02 + + 1.0437139E-02 + + 1.0756915E-02 + + 1.0623054E-02 + + 1.1295335E-02 + + 1.1326212E-02 + + 1.1795885E-02 + + 1.2179916E-02 + + 1.2528003E-02 + + 1.3121696E-02 + + 1.3563685E-02 + + 1.4242846E-02 + + 1.4567732E-02 + + 1.5913317E-02 + + 1.6851680E-02 + + 2.0792196E-02 + + 2.4129531E-02 + + 2.8258248E-02 + + 3.2040957E-02 + + 3.6266761E-02 + + 4.0455247E-02 + + 4.4731350E-02 + + 4.8820583E-02 + + 5.3746086E-02 + + 5.7743648E-02 + + 6.3513540E-02 + + 6.7353451E-02 + + 7.2430683E-02 + + 8.0723820E-02 + + 8.0655621E-02 + + + 1.0000000E+00 + + + + + uo2_ang.71c + uo2_ang.71c + 2.5300000E-08 + 5 + true + 32 + 1 + angle + + 4.0734790E-01 + + 4.0709470E-01 + + 4.0665280E-01 + + 4.0605122E-01 + + 4.0509226E-01 + + 4.0399893E-01 + + 4.0264927E-01 + + 4.0112684E-01 + + 3.9937450E-01 + + 3.9743081E-01 + + 3.9533879E-01 + + 3.9307550E-01 + + 3.9084961E-01 + + 3.8878017E-01 + + 3.8751931E-01 + + 3.8693825E-01 + + 3.9039929E-01 + + 4.0037023E-01 + + 4.1057791E-01 + + 4.1924835E-01 + + 4.2629128E-01 + + 4.3202621E-01 + + 4.3673213E-01 + + 4.4062993E-01 + + 4.4385222E-01 + + 4.4647166E-01 + + 4.4861335E-01 + + 4.5026817E-01 + + 4.5165329E-01 + + 4.5255720E-01 + + 4.5310208E-01 + + 4.5337269E-01 + + + 3.1599020E-02 + + 3.1371085E-02 + + 3.1023091E-02 + + 3.0539250E-02 + + 2.9839460E-02 + + 2.9013479E-02 + + 2.8058288E-02 + + 2.7047229E-02 + + 2.5977776E-02 + + 2.4952391E-02 + + 2.4009896E-02 + + 2.3244570E-02 + + 2.2725200E-02 + + 2.2489873E-02 + + 2.2624168E-02 + + 2.3059735E-02 + + 2.4782557E-02 + + 2.8553081E-02 + + 3.3194318E-02 + + 3.8038660E-02 + + 4.2666012E-02 + + 4.6923885E-02 + + 5.0708283E-02 + + 5.3996846E-02 + + 5.6845491E-02 + + 5.9213445E-02 + + 6.1182604E-02 + + 6.2742563E-02 + + 6.3985293E-02 + + 6.4852148E-02 + + 6.5364227E-02 + + 6.5703785E-02 + + + 4.5146530E-02 + + 4.4766687E-02 + + 4.4155441E-02 + + 4.3323960E-02 + + 4.2141314E-02 + + 4.0739637E-02 + + 3.9143652E-02 + + 3.7465300E-02 + + 3.5735871E-02 + + 3.4113931E-02 + + 3.2678644E-02 + + 3.1591060E-02 + + 3.0966537E-02 + + 3.0821062E-02 + + 3.1238242E-02 + + 3.2075654E-02 + + 3.4603728E-02 + + 3.9898114E-02 + + 4.6725370E-02 + + 5.4142159E-02 + + 6.1436273E-02 + + 6.8238302E-02 + + 7.4365771E-02 + + 7.9727018E-02 + + 8.4398863E-02 + + 8.8315890E-02 + + 9.1574736E-02 + + 9.4183896E-02 + + 9.6266615E-02 + + 9.7706019E-02 + + 9.8564505E-02 + + 9.9171965E-02 + + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + + 1.8183034E-02 + + 1.8028751E-02 + + 1.7777081E-02 + + 1.7434939E-02 + + 1.6947918E-02 + + 1.6371445E-02 + + 1.5714505E-02 + + 1.5023310E-02 + + 1.4310527E-02 + + 1.3640363E-02 + + 1.3045308E-02 + + 1.2590537E-02 + + 1.2323486E-02 + + 1.2250235E-02 + + 1.2408325E-02 + + 1.2741816E-02 + + 1.3791905E-02 + + 1.6011218E-02 + + 1.8846275E-02 + + 2.1907807E-02 + + 2.4909120E-02 + + 2.7704245E-02 + + 3.0220623E-02 + + 3.2422114E-02 + + 3.4339614E-02 + + 3.5947934E-02 + + 3.7286018E-02 + + 3.8357139E-02 + + 3.9212858E-02 + + 3.9804080E-02 + + 4.0156625E-02 + + 4.0404918E-02 + + + 3.7585902E-01 + + 4.4872720E-02 + + 2.2814276E-02 + + 1.1556342E-02 + + 7.2018303E-03 + + 3.6175403E-03 + + + + 3.7582315E-01 + + 4.4995749E-02 + + 2.2725116E-02 + + 1.1466478E-02 + + 7.0875483E-03 + + 3.5308164E-03 + + + + 3.7572011E-01 + + 4.4992452E-02 + + 2.2759820E-02 + + 1.1516099E-02 + + 7.0323440E-03 + + 3.5020003E-03 + + + + 3.7562995E-01 + + 4.5132914E-02 + + 2.2777514E-02 + + 1.1548988E-02 + + 7.0831467E-03 + + 3.5299129E-03 + + + + 3.7536612E-01 + + 4.5293164E-02 + + 2.2890080E-02 + + 1.1675089E-02 + + 7.1438522E-03 + + 3.5771809E-03 + + + + 3.7510372E-01 + + 4.5594244E-02 + + 2.2986083E-02 + + 1.1616892E-02 + + 7.1593645E-03 + + 3.5827527E-03 + + + + 3.7471139E-01 + + 4.5893399E-02 + + 2.3129097E-02 + + 1.1710573E-02 + + 7.2294990E-03 + + 3.6035030E-03 + + + + 3.7417853E-01 + + 4.6212271E-02 + + 2.3407493E-02 + + 1.1803607E-02 + + 7.2768873E-03 + + 3.6185275E-03 + + + + 3.7350485E-01 + + 4.6653124E-02 + + 2.3603271E-02 + + 1.1928427E-02 + + 7.3368483E-03 + + 3.6311780E-03 + + + + 3.7257204E-01 + + 4.7127424E-02 + + 2.3927026E-02 + + 1.2138279E-02 + + 7.4376541E-03 + + 3.6855451E-03 + + + + 3.7144563E-01 + + 4.7675499E-02 + + 2.4252831E-02 + + 1.2320100E-02 + + 7.5749097E-03 + + 3.7669728E-03 + + + + 3.6996977E-01 + + 4.8300830E-02 + + 2.4647138E-02 + + 1.2560662E-02 + + 7.7886594E-03 + + 3.8654464E-03 + + + + 3.6821602E-01 + + 4.8824396E-02 + + 2.5017750E-02 + + 1.2840163E-02 + + 7.9274823E-03 + + 3.9779025E-03 + + + + 3.6638016E-01 + + 4.9306135E-02 + + 2.5474307E-02 + + 1.3192593E-02 + + 8.2112330E-03 + + 4.1160831E-03 + + + + 3.6503713E-01 + + 4.9560796E-02 + + 2.5756337E-02 + + 1.3455138E-02 + + 8.3858370E-03 + + 4.2114689E-03 + + + + 3.6400368E-01 + + 4.9633132E-02 + + 2.5987536E-02 + + 1.3659891E-02 + + 8.5714354E-03 + + 4.3181256E-03 + + + + 3.6576117E-01 + + 4.8863049E-02 + + 2.5525363E-02 + + 1.3370670E-02 + + 8.3567729E-03 + + 4.1905625E-03 + + + + 3.7192172E-01 + + 4.6844936E-02 + + 2.3959446E-02 + + 1.2270393E-02 + + 7.5751281E-03 + + 3.7309644E-03 + + + + 3.7748124E-01 + + 4.4748629E-02 + + 2.2514789E-02 + + 1.1348962E-02 + + 6.9297472E-03 + + 3.4104693E-03 + + + + 3.8128097E-01 + + 4.3075850E-02 + + 2.1398961E-02 + + 1.0675116E-02 + + 6.5306660E-03 + + 3.2210938E-03 + + + + 3.8373406E-01 + + 4.1672472E-02 + + 2.0547117E-02 + + 1.0330913E-02 + + 6.3048028E-03 + + 3.1386749E-03 + + + + 3.8520439E-01 + + 4.0681902E-02 + + 2.0057126E-02 + + 1.0056063E-02 + + 6.1829817E-03 + + 3.0802737E-03 + + + + 3.8614505E-01 + + 3.9879282E-02 + + 1.9626439E-02 + + 9.9375963E-03 + + 6.1229946E-03 + + 3.0426688E-03 + + + + 3.8675390E-01 + + 3.9278504E-02 + + 1.9339777E-02 + + 9.8184985E-03 + + 6.0956157E-03 + + 3.0580002E-03 + + + + 3.8705360E-01 + + 3.8883125E-02 + + 1.9159064E-02 + + 9.7301477E-03 + + 6.0595588E-03 + + 3.0225068E-03 + + + + 3.8731880E-01 + + 3.8576519E-02 + + 1.9045072E-02 + + 9.7127863E-03 + + 6.0463869E-03 + + 3.0519472E-03 + + + + 3.8756725E-01 + + 3.8382695E-02 + + 1.8916082E-02 + + 9.6925622E-03 + + 6.0590015E-03 + + 2.9913798E-03 + + + + 3.8761982E-01 + + 3.8249486E-02 + + 1.8841512E-02 + + 9.6699646E-03 + + 6.0488356E-03 + + 3.0212480E-03 + + + + 3.8779017E-01 + + 3.8052198E-02 + + 1.8815974E-02 + + 9.5833623E-03 + + 5.9965640E-03 + + 2.9751261E-03 + + + + 3.8780028E-01 + + 3.7931450E-02 + + 1.8735581E-02 + + 9.6072395E-03 + + 5.9416328E-03 + + 3.0080955E-03 + + + + 3.8782277E-01 + + 3.7963999E-02 + + 1.8776116E-02 + + 9.6491264E-03 + + 5.9087373E-03 + + 3.0066367E-03 + + + + 3.8767898E-01 + + 3.7876954E-02 + + 1.8837344E-02 + + 9.7088929E-03 + + 5.9136976E-03 + + 3.0171235E-03 + + + 1.0002763E+00 + + + 1.0002760E+00 + + + 1.0002658E+00 + + + 1.0002710E+00 + + + 1.0002776E+00 + + + 1.0002767E+00 + + + 1.0002833E+00 + + + 1.0002791E+00 + + + 1.0002788E+00 + + + 1.0002858E+00 + + + 1.0002884E+00 + + + 1.0002916E+00 + + + 1.0003039E+00 + + + 1.0003181E+00 + + + 1.0003365E+00 + + + 1.0003544E+00 + + + 1.0003372E+00 + + + 1.0002764E+00 + + + 1.0002508E+00 + + + 1.0002343E+00 + + + 1.0002360E+00 + + + 1.0002375E+00 + + + 1.0002331E+00 + + + 1.0002344E+00 + + + 1.0002385E+00 + + + 1.0002316E+00 + + + 1.0002360E+00 + + + 1.0002360E+00 + + + 1.0002354E+00 + + + 1.0002349E+00 + + + 1.0002325E+00 + + + 1.0002268E+00 + + + + + clad_ang.71c + clad_ang.71c + 2.5300000E-08 + 5 + false + 32 + 1 + angle + + 3.1005638E-01 + + 3.0999067E-01 + + 3.0994879E-01 + + 3.0987779E-01 + + 3.0961631E-01 + + 3.0948272E-01 + + 3.0913340E-01 + + 3.0868239E-01 + + 3.0799925E-01 + + 3.0712597E-01 + + 3.0590948E-01 + + 3.0432728E-01 + + 3.0235012E-01 + + 2.9996873E-01 + + 2.9743091E-01 + + 2.9739624E-01 + + 3.0835788E-01 + + 3.1305337E-01 + + 3.1379599E-01 + + 3.1314506E-01 + + 3.1216249E-01 + + 3.1129786E-01 + + 3.1059203E-01 + + 3.1009561E-01 + + 3.0977837E-01 + + 3.0951041E-01 + + 3.0930940E-01 + + 3.0929712E-01 + + 3.0925741E-01 + + 3.0917641E-01 + + 3.0919741E-01 + + 3.0912502E-01 + + + 1.3490691E-03 + + 1.3463259E-03 + + 1.3498512E-03 + + 1.3366347E-03 + + 1.3288899E-03 + + 1.3176269E-03 + + 1.3059971E-03 + + 1.2891508E-03 + + 1.2713136E-03 + + 1.2555332E-03 + + 1.2394055E-03 + + 1.2170158E-03 + + 1.1969201E-03 + + 1.1849620E-03 + + 1.1899173E-03 + + 1.2761137E-03 + + 1.6244505E-03 + + 1.9090551E-03 + + 2.0837409E-03 + + 2.1976011E-03 + + 2.2746911E-03 + + 2.3308251E-03 + + 2.3700744E-03 + + 2.3981231E-03 + + 2.4248079E-03 + + 2.4441792E-03 + + 2.4510541E-03 + + 2.4640212E-03 + + 2.4741885E-03 + + 2.4697219E-03 + + 2.4721421E-03 + + 2.4729172E-03 + + + 3.0860746E-01 + + 5.0621457E-02 + + 2.7347709E-02 + + 4.7204795E-03 + + 4.0838896E-03 + + 1.6974585E-03 + + + + 3.0865194E-01 + + 5.0806752E-02 + + 2.6916586E-02 + + 4.8439138E-03 + + 4.1728626E-03 + + 1.7130886E-03 + + + + 3.0861586E-01 + + 5.0757624E-02 + + 2.7196188E-02 + + 4.8679553E-03 + + 4.0626181E-03 + + 1.7815988E-03 + + + + 3.0850283E-01 + + 5.0925397E-02 + + 2.7204505E-02 + + 4.8109149E-03 + + 4.1177685E-03 + + 1.7500469E-03 + + + + 3.0831737E-01 + + 5.1138142E-02 + + 2.7308021E-02 + + 4.8683307E-03 + + 4.0620680E-03 + + 1.6728150E-03 + + + + 3.0815133E-01 + + 5.1220538E-02 + + 2.7286345E-02 + + 4.8715905E-03 + + 4.0963982E-03 + + 1.6783881E-03 + + + + 3.0777979E-01 + + 5.1536936E-02 + + 2.7522750E-02 + + 4.9751865E-03 + + 4.1461347E-03 + + 1.7481718E-03 + + + + 3.0740186E-01 + + 5.1745014E-02 + + 2.7548398E-02 + + 4.9705992E-03 + + 4.2128374E-03 + + 1.7852471E-03 + + + + 3.0674467E-01 + + 5.2102012E-02 + + 2.7721735E-02 + + 4.9326171E-03 + + 4.2065723E-03 + + 1.7520577E-03 + + + + 3.0588587E-01 + + 5.2410298E-02 + + 2.7935183E-02 + + 5.1068594E-03 + + 4.2771962E-03 + + 1.7875734E-03 + + + + 3.0465659E-01 + + 5.2543078E-02 + + 2.7962434E-02 + + 5.0839680E-03 + + 4.3050048E-03 + + 1.8499733E-03 + + + + 3.0312229E-01 + + 5.2483292E-02 + + 2.8137041E-02 + + 5.2734764E-03 + + 4.4574974E-03 + + 1.8578935E-03 + + + + 3.0117092E-01 + + 5.2332000E-02 + + 2.8003257E-02 + + 5.2432554E-03 + + 4.5485878E-03 + + 1.8980534E-03 + + + + 2.9880209E-01 + + 5.1679340E-02 + + 2.7750518E-02 + + 5.3056401E-03 + + 4.5878997E-03 + + 1.9401945E-03 + + + + 2.9627667E-01 + + 5.0169523E-02 + + 2.7059202E-02 + + 5.2026216E-03 + + 4.5921641E-03 + + 1.8856744E-03 + + + + 2.9609986E-01 + + 4.6032461E-02 + + 2.4630572E-02 + + 4.5841577E-03 + + 3.9297754E-03 + + 1.6420383E-03 + + + + 3.0675667E-01 + + 3.7400062E-02 + + 1.9426565E-02 + + 2.7294131E-03 + + 2.0654845E-03 + + 6.7157182E-04 + + + + 3.1112942E-01 + + 3.2514340E-02 + + 1.7042298E-02 + + 2.2975512E-03 + + 1.7171252E-03 + + 6.1586296E-04 + + + + 3.1168284E-01 + + 2.9994361E-02 + + 1.5982971E-02 + + 2.2082409E-03 + + 1.7621544E-03 + + 6.7848731E-04 + + + + 3.1094402E-01 + + 2.9043011E-02 + + 1.5559822E-02 + + 2.3867453E-03 + + 1.8805422E-03 + + 8.0257257E-04 + + + + 3.0988917E-01 + + 2.8642621E-02 + + 1.5527633E-02 + + 2.5363175E-03 + + 2.0667848E-03 + + 8.9512793E-04 + + + + 3.0900783E-01 + + 2.8683967E-02 + + 1.5531635E-02 + + 2.6907133E-03 + + 2.2374989E-03 + + 9.9838820E-04 + + + + 3.0823110E-01 + + 2.8772506E-02 + + 1.5617343E-02 + + 2.7855260E-03 + + 2.3324886E-03 + + 1.0334317E-03 + + + + 3.0768619E-01 + + 2.9118421E-02 + + 1.5860568E-02 + + 2.8469804E-03 + + 2.4600144E-03 + + 1.0754851E-03 + + + + 3.0729355E-01 + + 2.9429106E-02 + + 1.6138063E-02 + + 2.9901807E-03 + + 2.5154903E-03 + + 1.1139796E-03 + + + + 3.0707342E-01 + + 2.9773340E-02 + + 1.6110013E-02 + + 2.9606704E-03 + + 2.6433692E-03 + + 1.1310602E-03 + + + + 3.0685025E-01 + + 3.0055483E-02 + + 1.6246774E-02 + + 3.1035410E-03 + + 2.6316501E-03 + + 1.1158252E-03 + + + + 3.0681469E-01 + + 3.0238686E-02 + + 1.6524723E-02 + + 3.0402635E-03 + + 2.6108287E-03 + + 1.1691486E-03 + + + + 3.0690606E-01 + + 3.0618190E-02 + + 1.6493402E-02 + + 3.0268029E-03 + + 2.5956288E-03 + + 1.0751657E-03 + + + + 3.0676357E-01 + + 3.0613175E-02 + + 1.6679358E-02 + + 2.8764512E-03 + + 2.5398735E-03 + + 1.0482210E-03 + + + + 3.0676223E-01 + + 3.0798581E-02 + + 1.6764686E-02 + + 3.1471928E-03 + + 2.7160881E-03 + + 1.2265875E-03 + + + + 3.0687178E-01 + + 3.0702117E-02 + + 1.6628813E-02 + + 2.8692462E-03 + + 2.4997850E-03 + + 9.3974161E-04 + + + 1.0000416E+00 + + + 1.0000513E+00 + + + 1.0000397E+00 + + + 1.0000409E+00 + + + 1.0000455E+00 + + + 1.0000417E+00 + + + 1.0000452E+00 + + + 1.0000431E+00 + + + 1.0000455E+00 + + + 1.0000451E+00 + + + 1.0000445E+00 + + + 1.0000482E+00 + + + 1.0000507E+00 + + + 1.0000542E+00 + + + 1.0000545E+00 + + + 1.0000461E+00 + + + 1.0000114E+00 + + + 1.0000112E+00 + + + 1.0000195E+00 + + + 1.0000216E+00 + + + 1.0000279E+00 + + + 1.0000307E+00 + + + 1.0000302E+00 + + + 1.0000313E+00 + + + 1.0000334E+00 + + + 1.0000309E+00 + + + 1.0000325E+00 + + + 1.0000318E+00 + + + 1.0000346E+00 + + + 1.0000335E+00 + + + 1.0000285E+00 + + + 1.0000358E+00 + + + + + lwtr_ang.71c + lwtr_ang.71c + 2.5300000E-08 + 5 + false + 32 + 1 + angle + + 8.3129229E-01 + + 8.3203829E-01 + + 8.3332424E-01 + + 8.3539719E-01 + + 8.3799288E-01 + + 8.4156597E-01 + + 8.4594074E-01 + + 8.5122773E-01 + + 8.5788274E-01 + + 8.6633387E-01 + + 8.7719846E-01 + + 8.9195077E-01 + + 9.1326621E-01 + + 9.4469159E-01 + + 9.9368716E-01 + + 1.0616854E+00 + + 1.0982938E+00 + + 1.0997200E+00 + + 1.0855410E+00 + + 1.0676695E+00 + + 1.0508172E+00 + + 1.0369337E+00 + + 1.0255762E+00 + + 1.0162841E+00 + + 1.0086633E+00 + + 1.0025783E+00 + + 9.9737297E-01 + + 9.9326768E-01 + + 9.9030852E-01 + + 9.8792719E-01 + + 9.8610453E-01 + + 9.8540665E-01 + + + 7.7368065E-03 + + 7.7519393E-03 + + 7.7819449E-03 + + 7.8285240E-03 + + 7.8881877E-03 + + 7.9652685E-03 + + 8.0588251E-03 + + 8.1724303E-03 + + 8.3079937E-03 + + 8.4749946E-03 + + 8.6811506E-03 + + 8.9456784E-03 + + 9.3049336E-03 + + 9.8025199E-03 + + 1.0529992E-02 + + 1.1498571E-02 + + 1.2065971E-02 + + 1.2168395E-02 + + 1.2053690E-02 + + 1.1870414E-02 + + 1.1678759E-02 + + 1.1516371E-02 + + 1.1377145E-02 + + 1.1262809E-02 + + 1.1166687E-02 + + 1.1090107E-02 + + 1.1022668E-02 + + 1.0968772E-02 + + 1.0931381E-02 + + 1.0898236E-02 + + 1.0872094E-02 + + 1.0866295E-02 + + + 8.2371185E-01 + + 3.5234207E-01 + + 1.1927931E-01 + + 7.4555729E-03 + + -1.8093822E-02 + + 4.7584668E-04 + + + + 8.2420033E-01 + + 3.5255993E-01 + + 1.1937026E-01 + + 7.2853742E-03 + + -1.8313481E-02 + + 4.3042936E-04 + + + + 8.2554395E-01 + + 3.5269171E-01 + + 1.1923224E-01 + + 7.3701368E-03 + + -1.8272340E-02 + + 4.4800957E-04 + + + + 8.2759297E-01 + + 3.5316566E-01 + + 1.1927088E-01 + + 7.3660347E-03 + + -1.8328170E-02 + + 4.1130682E-04 + + + + 8.3010220E-01 + + 3.5369971E-01 + + 1.1938537E-01 + + 7.4104975E-03 + + -1.8303317E-02 + + 4.1953876E-04 + + + + 8.3343687E-01 + + 3.5441436E-01 + + 1.1949872E-01 + + 7.5322327E-03 + + -1.8306753E-02 + + 4.5747101E-04 + + + + 8.3787092E-01 + + 3.5551997E-01 + + 1.1969232E-01 + + 7.5811660E-03 + + -1.8329166E-02 + + 4.7852748E-04 + + + + 8.4310387E-01 + + 3.5672367E-01 + + 1.1987885E-01 + + 7.6564988E-03 + + -1.8365527E-02 + + 4.5067238E-04 + + + + 8.4958953E-01 + + 3.5843887E-01 + + 1.2018528E-01 + + 7.7892315E-03 + + -1.8386164E-02 + + 4.8596316E-04 + + + + 8.5783406E-01 + + 3.6063097E-01 + + 1.2066889E-01 + + 7.9351893E-03 + + -1.8471175E-02 + + 4.7399741E-04 + + + + 8.6863002E-01 + + 3.6377631E-01 + + 1.2139807E-01 + + 8.1733217E-03 + + -1.8540490E-02 + + 5.0406643E-04 + + + + 8.8306988E-01 + + 3.6819641E-01 + + 1.2250274E-01 + + 8.4479144E-03 + + -1.8664160E-02 + + 5.3786229E-04 + + + + 9.0387733E-01 + + 3.7488040E-01 + + 1.2420959E-01 + + 8.7500816E-03 + + -1.8976448E-02 + + 4.9664889E-04 + + + + 9.3478951E-01 + + 3.8530100E-01 + + 1.2704555E-01 + + 9.1818403E-03 + + -1.9402464E-02 + + 5.3777400E-04 + + + + 9.8306151E-01 + + 4.0212328E-01 + + 1.3182489E-01 + + 9.8420986E-03 + + -2.0147587E-02 + + 5.9236718E-04 + + + + 1.0501953E+00 + + 4.2587762E-01 + + 1.3867637E-01 + + 1.0689470E-02 + + -2.1155894E-02 + + 6.5005469E-04 + + + + 1.0862685E+00 + + 4.3797788E-01 + + 1.4197736E-01 + + 1.1172759E-02 + + -2.1737067E-02 + + 6.5599084E-04 + + + + 1.0874414E+00 + + 4.3717092E-01 + + 1.4142760E-01 + + 1.1235986E-02 + + -2.1646253E-02 + + 6.5585383E-04 + + + + 1.0736455E+00 + + 4.3084349E-01 + + 1.3933736E-01 + + 1.1186759E-02 + + -2.1309779E-02 + + 6.3989000E-04 + + + + 1.0558960E+00 + + 4.2321090E-01 + + 1.3684390E-01 + + 1.1034633E-02 + + -2.0842589E-02 + + 6.8339604E-04 + + + + 1.0391120E+00 + + 4.1635648E-01 + + 1.3463939E-01 + + 1.0869743E-02 + + -2.0503958E-02 + + 6.5877305E-04 + + + + 1.0254663E+00 + + 4.1079355E-01 + + 1.3288830E-01 + + 1.0692002E-02 + + -2.0222325E-02 + + 7.2411022E-04 + + + + 1.0142449E+00 + + 4.0621344E-01 + + 1.3145072E-01 + + 1.0526222E-02 + + -1.9995334E-02 + + 6.8891812E-04 + + + + 1.0049846E+00 + + 4.0236090E-01 + + 1.3022093E-01 + + 1.0429641E-02 + + -1.9811424E-02 + + 7.3287561E-04 + + + + 9.9758865E-01 + + 3.9933064E-01 + + 1.2934518E-01 + + 1.0285856E-02 + + -1.9735216E-02 + + 6.4095239E-04 + + + + 9.9137092E-01 + + 3.9669204E-01 + + 1.2850897E-01 + + 1.0180247E-02 + + -1.9595919E-02 + + 7.4239863E-04 + + + + 9.8633885E-01 + + 3.9464706E-01 + + 1.2782783E-01 + + 1.0115679E-02 + + -1.9489063E-02 + + 6.7732699E-04 + + + + 9.8241480E-01 + + 3.9293162E-01 + + 1.2725328E-01 + + 1.0076113E-02 + + -1.9411729E-02 + + 6.7080378E-04 + + + + 9.7912906E-01 + + 3.9164180E-01 + + 1.2687293E-01 + + 9.9947816E-03 + + -1.9390105E-02 + + 6.8484948E-04 + + + + 9.7702901E-01 + + 3.9079267E-01 + + 1.2678305E-01 + + 1.0006132E-02 + + -1.9296574E-02 + + 7.3827259E-04 + + + + 9.7553202E-01 + + 3.9010913E-01 + + 1.2644932E-01 + + 9.9292219E-03 + + -1.9314591E-02 + + 7.3482134E-04 + + + + 9.7483429E-01 + + 3.8985598E-01 + + 1.2640804E-01 + + 9.9206549E-03 + + -1.9266376E-02 + + 7.6472379E-04 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + + + uo2_ang_mu.71c + uo2_ang_mu.71c + 2.5300000E-08 + 32 + true + 32 + 1 + angle + histogram + + 4.0734790E-01 + + 4.0709470E-01 + + 4.0665280E-01 + + 4.0605122E-01 + + 4.0509226E-01 + + 4.0399893E-01 + + 4.0264927E-01 + + 4.0112684E-01 + + 3.9937450E-01 + + 3.9743081E-01 + + 3.9533879E-01 + + 3.9307550E-01 + + 3.9084961E-01 + + 3.8878017E-01 + + 3.8751931E-01 + + 3.8693825E-01 + + 3.9039929E-01 + + 4.0037023E-01 + + 4.1057791E-01 + + 4.1924835E-01 + + 4.2629128E-01 + + 4.3202621E-01 + + 4.3673213E-01 + + 4.4062993E-01 + + 4.4385222E-01 + + 4.4647166E-01 + + 4.4861335E-01 + + 4.5026817E-01 + + 4.5165329E-01 + + 4.5255720E-01 + + 4.5310208E-01 + + 4.5337269E-01 + + + 3.1599020E-02 + + 3.1371085E-02 + + 3.1023091E-02 + + 3.0539250E-02 + + 2.9839460E-02 + + 2.9013479E-02 + + 2.8058288E-02 + + 2.7047229E-02 + + 2.5977776E-02 + + 2.4952391E-02 + + 2.4009896E-02 + + 2.3244570E-02 + + 2.2725200E-02 + + 2.2489873E-02 + + 2.2624168E-02 + + 2.3059735E-02 + + 2.4782557E-02 + + 2.8553081E-02 + + 3.3194318E-02 + + 3.8038660E-02 + + 4.2666012E-02 + + 4.6923885E-02 + + 5.0708283E-02 + + 5.3996846E-02 + + 5.6845491E-02 + + 5.9213445E-02 + + 6.1182604E-02 + + 6.2742563E-02 + + 6.3985293E-02 + + 6.4852148E-02 + + 6.5364227E-02 + + 6.5703785E-02 + + + 4.5146530E-02 + + 4.4766687E-02 + + 4.4155441E-02 + + 4.3323960E-02 + + 4.2141314E-02 + + 4.0739637E-02 + + 3.9143652E-02 + + 3.7465300E-02 + + 3.5735871E-02 + + 3.4113931E-02 + + 3.2678644E-02 + + 3.1591060E-02 + + 3.0966537E-02 + + 3.0821062E-02 + + 3.1238242E-02 + + 3.2075654E-02 + + 3.4603728E-02 + + 3.9898114E-02 + + 4.6725370E-02 + + 5.4142159E-02 + + 6.1436273E-02 + + 6.8238302E-02 + + 7.4365771E-02 + + 7.9727018E-02 + + 8.4398863E-02 + + 8.8315890E-02 + + 9.1574736E-02 + + 9.4183896E-02 + + 9.6266615E-02 + + 9.7706019E-02 + + 9.8564505E-02 + + 9.9171965E-02 + + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + 1.0000000E+00 + + + 1.8183034E-02 + + 1.8028751E-02 + + 1.7777081E-02 + + 1.7434939E-02 + + 1.6947918E-02 + + 1.6371445E-02 + + 1.5714505E-02 + + 1.5023310E-02 + + 1.4310527E-02 + + 1.3640363E-02 + + 1.3045308E-02 + + 1.2590537E-02 + + 1.2323486E-02 + + 1.2250235E-02 + + 1.2408325E-02 + + 1.2741816E-02 + + 1.3791905E-02 + + 1.6011218E-02 + + 1.8846275E-02 + + 2.1907807E-02 + + 2.4909120E-02 + + 2.7704245E-02 + + 3.0220623E-02 + + 3.2422114E-02 + + 3.4339614E-02 + + 3.5947934E-02 + + 3.7286018E-02 + + 3.8357139E-02 + + 3.9212858E-02 + + 3.9804080E-02 + + 4.0156625E-02 + + 4.0404918E-02 + + + 9.8066123E-03 + + 9.6646401E-03 + + 9.6663597E-03 + + 9.6289590E-03 + + 9.6096138E-03 + + 9.6458323E-03 + + 9.7060173E-03 + + 9.7686742E-03 + + 9.7497590E-03 + + 9.8863575E-03 + + 9.9653503E-03 + + 1.0024461E-02 + + 1.0143433E-02 + + 1.0224038E-02 + + 1.0343441E-02 + + 1.0433289E-02 + + 1.0526146E-02 + + 1.0783759E-02 + + 1.0949268E-02 + + 1.1096291E-02 + + 1.1232675E-02 + + 1.1455467E-02 + + 1.1650746E-02 + + 1.1903201E-02 + + 1.2297735E-02 + + 1.2748370E-02 + + 1.3264457E-02 + + 1.4048689E-02 + + 1.5280440E-02 + + 1.6908123E-02 + + 1.9601832E-02 + + 2.3844984E-02 + + + + 9.7708240E-03 + + 9.6914019E-03 + + 9.6149267E-03 + + 9.5973173E-03 + + 9.6433893E-03 + + 9.6506128E-03 + + 9.7039801E-03 + + 9.6956785E-03 + + 9.7873194E-03 + + 9.8654118E-03 + + 9.9413480E-03 + + 1.0063248E-02 + + 1.0102923E-02 + + 1.0232802E-02 + + 1.0308882E-02 + + 1.0501651E-02 + + 1.0589986E-02 + + 1.0719182E-02 + + 1.0893048E-02 + + 1.1057750E-02 + + 1.1303383E-02 + + 1.1462120E-02 + + 1.1668725E-02 + + 1.1965138E-02 + + 1.2270967E-02 + + 1.2704483E-02 + + 1.3318045E-02 + + 1.4113776E-02 + + 1.5284443E-02 + + 1.6903540E-02 + + 1.9623766E-02 + + 2.3773086E-02 + + + + 9.7573912E-03 + + 9.6754767E-03 + + 9.6414920E-03 + + 9.5888776E-03 + + 9.6229707E-03 + + 9.6517720E-03 + + 9.7047117E-03 + + 9.7260741E-03 + + 9.8017859E-03 + + 9.8536413E-03 + + 9.9389825E-03 + + 1.0024606E-02 + + 1.0138509E-02 + + 1.0234629E-02 + + 1.0324330E-02 + + 1.0453936E-02 + + 1.0578467E-02 + + 1.0739823E-02 + + 1.0879319E-02 + + 1.1046986E-02 + + 1.1241981E-02 + + 1.1441204E-02 + + 1.1664457E-02 + + 1.1957610E-02 + + 1.2276940E-02 + + 1.2759947E-02 + + 1.3279607E-02 + + 1.4124886E-02 + + 1.5267698E-02 + + 1.6982394E-02 + + 1.9550155E-02 + + 2.3789453E-02 + + + + 9.7595941E-03 + + 9.6406785E-03 + + 9.6091241E-03 + + 9.6094212E-03 + + 9.6096714E-03 + + 9.6231813E-03 + + 9.6784094E-03 + + 9.7493834E-03 + + 9.7951671E-03 + + 9.8514115E-03 + + 9.9241369E-03 + + 1.0012170E-02 + + 1.0117529E-02 + + 1.0213412E-02 + + 1.0335767E-02 + + 1.0447944E-02 + + 1.0584231E-02 + + 1.0753231E-02 + + 1.0883138E-02 + + 1.1065663E-02 + + 1.1250080E-02 + + 1.1439297E-02 + + 1.1646700E-02 + + 1.1958053E-02 + + 1.2287514E-02 + + 1.2721568E-02 + + 1.3290189E-02 + + 1.4110041E-02 + + 1.5281715E-02 + + 1.6979118E-02 + + 1.9608566E-02 + + 2.3793845E-02 + + + + 9.7316881E-03 + + 9.6194631E-03 + + 9.6065192E-03 + + 9.5773341E-03 + + 9.6080573E-03 + + 9.6136679E-03 + + 9.6707217E-03 + + 9.7207622E-03 + + 9.7745677E-03 + + 9.8542855E-03 + + 9.9290325E-03 + + 1.0013807E-02 + + 1.0087705E-02 + + 1.0212493E-02 + + 1.0318553E-02 + + 1.0440413E-02 + + 1.0586043E-02 + + 1.0693482E-02 + + 1.0881032E-02 + + 1.1028668E-02 + + 1.1236016E-02 + + 1.1448039E-02 + + 1.1645248E-02 + + 1.1940864E-02 + + 1.2280554E-02 + + 1.2704859E-02 + + 1.3284908E-02 + + 1.4087561E-02 + + 1.5269781E-02 + + 1.6974160E-02 + + 1.9647654E-02 + + 2.3878185E-02 + + + + 9.7161201E-03 + + 9.6202380E-03 + + 9.5797790E-03 + + 9.5545189E-03 + + 9.5785124E-03 + + 9.5970413E-03 + + 9.6077970E-03 + + 9.7078158E-03 + + 9.7457417E-03 + + 9.8241572E-03 + + 9.9053715E-03 + + 9.9664533E-03 + + 1.0069700E-02 + + 1.0182303E-02 + + 1.0310258E-02 + + 1.0426742E-02 + + 1.0561490E-02 + + 1.0707708E-02 + + 1.0863937E-02 + + 1.1051125E-02 + + 1.1221704E-02 + + 1.1442069E-02 + + 1.1658848E-02 + + 1.1941489E-02 + + 1.2275743E-02 + + 1.2702110E-02 + + 1.3323051E-02 + + 1.4108176E-02 + + 1.5289516E-02 + + 1.6993392E-02 + + 1.9675117E-02 + + 2.3895695E-02 + + + + 9.6862964E-03 + + 9.6118860E-03 + + 9.5204994E-03 + + 9.5427943E-03 + + 9.5461966E-03 + + 9.5657839E-03 + + 9.5949449E-03 + + 9.6654696E-03 + + 9.7413833E-03 + + 9.7999604E-03 + + 9.8652718E-03 + + 9.9395415E-03 + + 1.0066252E-02 + + 1.0162957E-02 + + 1.0288525E-02 + + 1.0410136E-02 + + 1.0544012E-02 + + 1.0683294E-02 + + 1.0857487E-02 + + 1.1034643E-02 + + 1.1202400E-02 + + 1.1413244E-02 + + 1.1649707E-02 + + 1.1927823E-02 + + 1.2268032E-02 + + 1.2711207E-02 + + 1.3301163E-02 + + 1.4107114E-02 + + 1.5299888E-02 + + 1.7035047E-02 + + 1.9688248E-02 + + 2.3980184E-02 + + + + 9.6789320E-03 + + 9.5794368E-03 + + 9.5136834E-03 + + 9.4987637E-03 + + 9.5122403E-03 + + 9.5462846E-03 + + 9.5893599E-03 + + 9.6291844E-03 + + 9.6755880E-03 + + 9.7758823E-03 + + 9.8512097E-03 + + 9.9153183E-03 + + 1.0010492E-02 + + 1.0132751E-02 + + 1.0249082E-02 + + 1.0374304E-02 + + 1.0525789E-02 + + 1.0647590E-02 + + 1.0816183E-02 + + 1.1002705E-02 + + 1.1172733E-02 + + 1.1391942E-02 + + 1.1634015E-02 + + 1.1896152E-02 + + 1.2250313E-02 + + 1.2701494E-02 + + 1.3297953E-02 + + 1.4128277E-02 + + 1.5304878E-02 + + 1.7057822E-02 + + 1.9759949E-02 + + 2.4058227E-02 + + + + 9.6295658E-03 + + 9.5389047E-03 + + 9.4742925E-03 + + 9.4575039E-03 + + 9.4670086E-03 + + 9.5016333E-03 + + 9.5287576E-03 + + 9.5962610E-03 + + 9.6450345E-03 + + 9.7355000E-03 + + 9.8168240E-03 + + 9.8832939E-03 + + 9.9783337E-03 + + 1.0096077E-02 + + 1.0226691E-02 + + 1.0343925E-02 + + 1.0478576E-02 + + 1.0624400E-02 + + 1.0795052E-02 + + 1.0971506E-02 + + 1.1155210E-02 + + 1.1359948E-02 + + 1.1600072E-02 + + 1.1891155E-02 + + 1.2217464E-02 + + 1.2687949E-02 + + 1.3279851E-02 + + 1.4139232E-02 + + 1.5331088E-02 + + 1.7109049E-02 + + 1.9804341E-02 + + 2.4140346E-02 + + + + 9.5761863E-03 + + 9.4820918E-03 + + 9.4335419E-03 + + 9.4124923E-03 + + 9.4238881E-03 + + 9.4447526E-03 + + 9.4999957E-03 + + 9.5315541E-03 + + 9.6078277E-03 + + 9.7003335E-03 + + 9.7574525E-03 + + 9.8379436E-03 + + 9.9462733E-03 + + 1.0053971E-02 + + 1.0174903E-02 + + 1.0296178E-02 + + 1.0416178E-02 + + 1.0598338E-02 + + 1.0736969E-02 + + 1.0921999E-02 + + 1.1103049E-02 + + 1.1337535E-02 + + 1.1560952E-02 + + 1.1844754E-02 + + 1.2186109E-02 + + 1.2650980E-02 + + 1.3288356E-02 + + 1.4113781E-02 + + 1.5336174E-02 + + 1.7136757E-02 + + 1.9885917E-02 + + 2.4274812E-02 + + + + 9.5122168E-03 + + 9.4370370E-03 + + 9.3789842E-03 + + 9.3641793E-03 + + 9.3461446E-03 + + 9.3736151E-03 + + 9.4378621E-03 + + 9.4888307E-03 + + 9.5578870E-03 + + 9.6287585E-03 + + 9.7018579E-03 + + 9.7842398E-03 + + 9.8853931E-03 + + 9.9928939E-03 + + 1.0118830E-02 + + 1.0234335E-02 + + 1.0390558E-02 + + 1.0549529E-02 + + 1.0695492E-02 + + 1.0871300E-02 + + 1.1074656E-02 + + 1.1276285E-02 + + 1.1528116E-02 + + 1.1795259E-02 + + 1.2170410E-02 + + 1.2620687E-02 + + 1.3248447E-02 + + 1.4113310E-02 + + 1.5330992E-02 + + 1.7146317E-02 + + 1.9971083E-02 + + 2.4420125E-02 + + + + 9.4655965E-03 + + 9.3472543E-03 + + 9.3135845E-03 + + 9.2723897E-03 + + 9.2802062E-03 + + 9.3207904E-03 + + 9.3438769E-03 + + 9.4089282E-03 + + 9.4772470E-03 + + 9.5593066E-03 + + 9.6350349E-03 + + 9.7156422E-03 + + 9.8254749E-03 + + 9.9256153E-03 + + 1.0046422E-02 + + 1.0170127E-02 + + 1.0324109E-02 + + 1.0494779E-02 + + 1.0643991E-02 + + 1.0830850E-02 + + 1.1006031E-02 + + 1.1226896E-02 + + 1.1461160E-02 + + 1.1751421E-02 + + 1.2117075E-02 + + 1.2580807E-02 + + 1.3191655E-02 + + 1.4078045E-02 + + 1.5308284E-02 + + 1.7194422E-02 + + 2.0045307E-02 + + 2.4607445E-02 + + + + 9.3803794E-03 + + 9.2679518E-03 + + 9.2244314E-03 + + 9.2113545E-03 + + 9.2138570E-03 + + 9.2462589E-03 + + 9.2883856E-03 + + 9.3378797E-03 + + 9.4087558E-03 + + 9.4791189E-03 + + 9.5459849E-03 + + 9.6532937E-03 + + 9.7407231E-03 + + 9.8542750E-03 + + 9.9718785E-03 + + 1.0102253E-02 + + 1.0257191E-02 + + 1.0422947E-02 + + 1.0576154E-02 + + 1.0751370E-02 + + 1.0937694E-02 + + 1.1150504E-02 + + 1.1403363E-02 + + 1.1690271E-02 + + 1.2041631E-02 + + 1.2515941E-02 + + 1.3148002E-02 + + 1.4030663E-02 + + 1.5293666E-02 + + 1.7182409E-02 + + 2.0111404E-02 + + 2.4776028E-02 + + + + 9.3172617E-03 + + 9.2089569E-03 + + 9.1486659E-03 + + 9.1277777E-03 + + 9.1461098E-03 + + 9.1678665E-03 + + 9.2093270E-03 + + 9.2630599E-03 + + 9.3084731E-03 + + 9.4133582E-03 + + 9.4836368E-03 + + 9.5792942E-03 + + 9.6772510E-03 + + 9.7775420E-03 + + 9.9042034E-03 + + 1.0042269E-02 + + 1.0180349E-02 + + 1.0339342E-02 + + 1.0499500E-02 + + 1.0689206E-02 + + 1.0856780E-02 + + 1.1064872E-02 + + 1.1313606E-02 + + 1.1607748E-02 + + 1.1964604E-02 + + 1.2435691E-02 + + 1.3060461E-02 + + 1.3974178E-02 + + 1.5269813E-02 + + 1.7174181E-02 + + 2.0168154E-02 + + 2.5006625E-02 + + + + 9.2675186E-03 + + 9.1560947E-03 + + 9.1099682E-03 + + 9.0686023E-03 + + 9.0949282E-03 + + 9.1189359E-03 + + 9.1587135E-03 + + 9.2079644E-03 + + 9.2872523E-03 + + 9.3678425E-03 + + 9.4331971E-03 + + 9.5255074E-03 + + 9.6234797E-03 + + 9.7408756E-03 + + 9.8464228E-03 + + 9.9839770E-03 + + 1.0134229E-02 + + 1.0296950E-02 + + 1.0437157E-02 + + 1.0621205E-02 + + 1.0805038E-02 + + 1.1016214E-02 + + 1.1261528E-02 + + 1.1539985E-02 + + 1.1895722E-02 + + 1.2371092E-02 + + 1.3001136E-02 + + 1.3913205E-02 + + 1.5214879E-02 + + 1.7172526E-02 + + 2.0220324E-02 + + 2.5144658E-02 + + + + 9.2487420E-03 + + 9.1281258E-03 + + 9.0754703E-03 + + 9.0528962E-03 + + 9.0607826E-03 + + 9.0836186E-03 + + 9.1336267E-03 + + 9.1791302E-03 + + 9.2456080E-03 + + 9.3262261E-03 + + 9.3970635E-03 + + 9.4814471E-03 + + 9.5988170E-03 + + 9.7082444E-03 + + 9.8223867E-03 + + 9.9431245E-03 + + 1.0105918E-02 + + 1.0235908E-02 + + 1.0399441E-02 + + 1.0585520E-02 + + 1.0757015E-02 + + 1.0981562E-02 + + 1.1194196E-02 + + 1.1486474E-02 + + 1.1845432E-02 + + 1.2322129E-02 + + 1.2940763E-02 + + 1.3835543E-02 + + 1.5166292E-02 + + 1.7159569E-02 + + 2.0241404E-02 + + 2.5261208E-02 + + + + 9.3326963E-03 + + 9.2136145E-03 + + 9.1672115E-03 + + 9.1448034E-03 + + 9.1509378E-03 + + 9.1710414E-03 + + 9.2163629E-03 + + 9.2665486E-03 + + 9.3325121E-03 + + 9.4016396E-03 + + 9.5034088E-03 + + 9.5773816E-03 + + 9.6674816E-03 + + 9.7850853E-03 + + 9.9014422E-03 + + 1.0023693E-02 + + 1.0166562E-02 + + 1.0315995E-02 + + 1.0472398E-02 + + 1.0641203E-02 + + 1.0830711E-02 + + 1.1048828E-02 + + 1.1263336E-02 + + 1.1551095E-02 + + 1.1894787E-02 + + 1.2358496E-02 + + 1.2983340E-02 + + 1.3874895E-02 + + 1.5186930E-02 + + 1.7144384E-02 + + 2.0133533E-02 + + 2.5038814E-02 + + + + 9.5906528E-03 + + 9.4714149E-03 + + 9.4373276E-03 + + 9.4092245E-03 + + 9.4080878E-03 + + 9.4464166E-03 + + 9.4856267E-03 + + 9.5436808E-03 + + 9.6059463E-03 + + 9.6771305E-03 + + 9.7582049E-03 + + 9.8361595E-03 + + 9.9382461E-03 + + 1.0051079E-02 + + 1.0152805E-02 + + 1.0287101E-02 + + 1.0441087E-02 + + 1.0565078E-02 + + 1.0711502E-02 + + 1.0891178E-02 + + 1.1071184E-02 + + 1.1292859E-02 + + 1.1522246E-02 + + 1.1788324E-02 + + 1.2135266E-02 + + 1.2615017E-02 + + 1.3201487E-02 + + 1.4060330E-02 + + 1.5281894E-02 + + 1.7084038E-02 + + 1.9845860E-02 + + 2.4315267E-02 + + + + 9.8248104E-03 + + 9.7323237E-03 + + 9.6774360E-03 + + 9.6780777E-03 + + 9.6806071E-03 + + 9.7078157E-03 + + 9.7458638E-03 + + 9.8100671E-03 + + 9.8562275E-03 + + 9.9244575E-03 + + 1.0022233E-02 + + 1.0083426E-02 + + 1.0184960E-02 + + 1.0286955E-02 + + 1.0393298E-02 + + 1.0523934E-02 + + 1.0674383E-02 + + 1.0799950E-02 + + 1.0950769E-02 + + 1.1117330E-02 + + 1.1304368E-02 + + 1.1511486E-02 + + 1.1731876E-02 + + 1.2009368E-02 + + 1.2343059E-02 + + 1.2776813E-02 + + 1.3375541E-02 + + 1.4170942E-02 + + 1.5323633E-02 + + 1.7010159E-02 + + 1.9570530E-02 + + 2.3678539E-02 + + + + 1.0003922E-02 + + 9.9126090E-03 + + 9.8710015E-03 + + 9.8670066E-03 + + 9.8659781E-03 + + 9.8893674E-03 + + 9.9377144E-03 + + 9.9843851E-03 + + 1.0043716E-02 + + 1.0114248E-02 + + 1.0187530E-02 + + 1.0267347E-02 + + 1.0358552E-02 + + 1.0462167E-02 + + 1.0591882E-02 + + 1.0702606E-02 + + 1.0831901E-02 + + 1.0977238E-02 + + 1.1108339E-02 + + 1.1308120E-02 + + 1.1462407E-02 + + 1.1644185E-02 + + 1.1896695E-02 + + 1.2152261E-02 + + 1.2470909E-02 + + 1.2904242E-02 + + 1.3463705E-02 + + 1.4217800E-02 + + 1.5306830E-02 + + 1.6913123E-02 + + 1.9352840E-02 + + 2.3210338E-02 + + + + 1.0110150E-02 + + 1.0038689E-02 + + 1.0006487E-02 + + 9.9882512E-03 + + 1.0012465E-02 + + 1.0038003E-02 + + 1.0080385E-02 + + 1.0133099E-02 + + 1.0195776E-02 + + 1.0230495E-02 + + 1.0337794E-02 + + 1.0414378E-02 + + 1.0494026E-02 + + 1.0600307E-02 + + 1.0712290E-02 + + 1.0823942E-02 + + 1.0947285E-02 + + 1.1079870E-02 + + 1.1237336E-02 + + 1.1392659E-02 + + 1.1573008E-02 + + 1.1782567E-02 + + 1.1965944E-02 + + 1.2231191E-02 + + 1.2530296E-02 + + 1.2940908E-02 + + 1.3487030E-02 + + 1.4206747E-02 + + 1.5258559E-02 + + 1.6813287E-02 + + 1.9165344E-02 + + 2.2905494E-02 + + + + 1.0214736E-02 + + 1.0132229E-02 + + 1.0105238E-02 + + 1.0076016E-02 + + 1.0102342E-02 + + 1.0126079E-02 + + 1.0166649E-02 + + 1.0211271E-02 + + 1.0274414E-02 + + 1.0328594E-02 + + 1.0415141E-02 + + 1.0493084E-02 + + 1.0583179E-02 + + 1.0679080E-02 + + 1.0785554E-02 + + 1.0896861E-02 + + 1.1025180E-02 + + 1.1151734E-02 + + 1.1308616E-02 + + 1.1460250E-02 + + 1.1631030E-02 + + 1.1818829E-02 + + 1.2020589E-02 + + 1.2270878E-02 + + 1.2564608E-02 + + 1.2974969E-02 + + 1.3498179E-02 + + 1.4207601E-02 + + 1.5228538E-02 + + 1.6730509E-02 + + 1.9011440E-02 + + 2.2710972E-02 + + + + 1.0268267E-02 + + 1.0196885E-02 + + 1.0157361E-02 + + 1.0140649E-02 + + 1.0169437E-02 + + 1.0183304E-02 + + 1.0243979E-02 + + 1.0276945E-02 + + 1.0343732E-02 + + 1.0412311E-02 + + 1.0476453E-02 + + 1.0547309E-02 + + 1.0646659E-02 + + 1.0745962E-02 + + 1.0848409E-02 + + 1.0960759E-02 + + 1.1082990E-02 + + 1.1214082E-02 + + 1.1358598E-02 + + 1.1499661E-02 + + 1.1661477E-02 + + 1.1836025E-02 + + 1.2058652E-02 + + 1.2293116E-02 + + 1.2566338E-02 + + 1.2977505E-02 + + 1.3480636E-02 + + 1.4176526E-02 + + 1.5190195E-02 + + 1.6660100E-02 + + 1.8910243E-02 + + 2.2560488E-02 + + + + 1.0317792E-02 + + 1.0247350E-02 + + 1.0209518E-02 + + 1.0176974E-02 + + 1.0202003E-02 + + 1.0234569E-02 + + 1.0290041E-02 + + 1.0329819E-02 + + 1.0401460E-02 + + 1.0453530E-02 + + 1.0512745E-02 + + 1.0606160E-02 + + 1.0688319E-02 + + 1.0769020E-02 + + 1.0865579E-02 + + 1.0991642E-02 + + 1.1131957E-02 + + 1.1257621E-02 + + 1.1387433E-02 + + 1.1532542E-02 + + 1.1687029E-02 + + 1.1880598E-02 + + 1.2082924E-02 + + 1.2307513E-02 + + 1.2595319E-02 + + 1.2957554E-02 + + 1.3464867E-02 + + 1.4143088E-02 + + 1.5132042E-02 + + 1.6579665E-02 + + 1.8862731E-02 + + 2.2454495E-02 + + + + 1.0353436E-02 + + 1.0273106E-02 + + 1.0227967E-02 + + 1.0220784E-02 + + 1.0226684E-02 + + 1.0260876E-02 + + 1.0312588E-02 + + 1.0358157E-02 + + 1.0401938E-02 + + 1.0498406E-02 + + 1.0534029E-02 + + 1.0633113E-02 + + 1.0711786E-02 + + 1.0806930E-02 + + 1.0902341E-02 + + 1.1005862E-02 + + 1.1140903E-02 + + 1.1256190E-02 + + 1.1418216E-02 + + 1.1551704E-02 + + 1.1699315E-02 + + 1.1876316E-02 + + 1.2095791E-02 + + 1.2321059E-02 + + 1.2598778E-02 + + 1.2945785E-02 + + 1.3441410E-02 + + 1.4150310E-02 + + 1.5110707E-02 + + 1.6555004E-02 + + 1.8801362E-02 + + 2.2362745E-02 + + + + 1.0368488E-02 + + 1.0298130E-02 + + 1.0243651E-02 + + 1.0237480E-02 + + 1.0271825E-02 + + 1.0283702E-02 + + 1.0344999E-02 + + 1.0388950E-02 + + 1.0443402E-02 + + 1.0499057E-02 + + 1.0554275E-02 + + 1.0647638E-02 + + 1.0712690E-02 + + 1.0827382E-02 + + 1.0931601E-02 + + 1.1018556E-02 + + 1.1152881E-02 + + 1.1290059E-02 + + 1.1420028E-02 + + 1.1563732E-02 + + 1.1705467E-02 + + 1.1895794E-02 + + 1.2092710E-02 + + 1.2310135E-02 + + 1.2594991E-02 + + 1.2963713E-02 + + 1.3446042E-02 + + 1.4105472E-02 + + 1.5078624E-02 + + 1.6548015E-02 + + 1.8734322E-02 + + 2.2344993E-02 + + + + 1.0381081E-02 + + 1.0306858E-02 + + 1.0277150E-02 + + 1.0252664E-02 + + 1.0290401E-02 + + 1.0294657E-02 + + 1.0329546E-02 + + 1.0392619E-02 + + 1.0438626E-02 + + 1.0515024E-02 + + 1.0591864E-02 + + 1.0665572E-02 + + 1.0764627E-02 + + 1.0867664E-02 + + 1.0949159E-02 + + 1.1055591E-02 + + 1.1176115E-02 + + 1.1296618E-02 + + 1.1417920E-02 + + 1.1572450E-02 + + 1.1714864E-02 + + 1.1894815E-02 + + 1.2080388E-02 + + 1.2311306E-02 + + 1.2600200E-02 + + 1.2956245E-02 + + 1.3438289E-02 + + 1.4113577E-02 + + 1.5087407E-02 + + 1.6503410E-02 + + 1.8740374E-02 + + 2.2290166E-02 + + + + 1.0379499E-02 + + 1.0316828E-02 + + 1.0280998E-02 + + 1.0282758E-02 + + 1.0275605E-02 + + 1.0306117E-02 + + 1.0348208E-02 + + 1.0378745E-02 + + 1.0464787E-02 + + 1.0530463E-02 + + 1.0608232E-02 + + 1.0674147E-02 + + 1.0763998E-02 + + 1.0837280E-02 + + 1.0949195E-02 + + 1.1058508E-02 + + 1.1190589E-02 + + 1.1322242E-02 + + 1.1432422E-02 + + 1.1582770E-02 + + 1.1718207E-02 + + 1.1912632E-02 + + 1.2075287E-02 + + 1.2309263E-02 + + 1.2598203E-02 + + 1.2947275E-02 + + 1.3422204E-02 + + 1.4101792E-02 + + 1.5074531E-02 + + 1.6493963E-02 + + 1.8703917E-02 + + 2.2279156E-02 + + + + 1.0425160E-02 + + 1.0318223E-02 + + 1.0301788E-02 + + 1.0294047E-02 + + 1.0284686E-02 + + 1.0349566E-02 + + 1.0366017E-02 + + 1.0397170E-02 + + 1.0476721E-02 + + 1.0527169E-02 + + 1.0602826E-02 + + 1.0679945E-02 + + 1.0766188E-02 + + 1.0868516E-02 + + 1.0967919E-02 + + 1.1069388E-02 + + 1.1166089E-02 + + 1.1293657E-02 + + 1.1442396E-02 + + 1.1579055E-02 + + 1.1756181E-02 + + 1.1901153E-02 + + 1.2075228E-02 + + 1.2329489E-02 + + 1.2582177E-02 + + 1.2965246E-02 + + 1.3451596E-02 + + 1.4114325E-02 + + 1.5048259E-02 + + 1.6478843E-02 + + 1.8702139E-02 + + 2.2209013E-02 + + + + 1.0403120E-02 + + 1.0338330E-02 + + 1.0290627E-02 + + 1.0277361E-02 + + 1.0322671E-02 + + 1.0363565E-02 + + 1.0362094E-02 + + 1.0440786E-02 + + 1.0485173E-02 + + 1.0557958E-02 + + 1.0608779E-02 + + 1.0701287E-02 + + 1.0735526E-02 + + 1.0841760E-02 + + 1.0953485E-02 + + 1.1083460E-02 + + 1.1193252E-02 + + 1.1297597E-02 + + 1.1457508E-02 + + 1.1572681E-02 + + 1.1742409E-02 + + 1.1907920E-02 + + 1.2078022E-02 + + 1.2328222E-02 + + 1.2585186E-02 + + 1.2967887E-02 + + 1.3432333E-02 + + 1.4108413E-02 + + 1.5033330E-02 + + 1.6472418E-02 + + 1.8651936E-02 + + 2.2205180E-02 + + + + 1.0383972E-02 + + 1.0327340E-02 + + 1.0320447E-02 + + 1.0278943E-02 + + 1.0322805E-02 + + 1.0366993E-02 + + 1.0395218E-02 + + 1.0418111E-02 + + 1.0463460E-02 + + 1.0564171E-02 + + 1.0601357E-02 + + 1.0671268E-02 + + 1.0756633E-02 + + 1.0863620E-02 + + 1.0982943E-02 + + 1.1088262E-02 + + 1.1182298E-02 + + 1.1297412E-02 + + 1.1404871E-02 + + 1.1585288E-02 + + 1.1730768E-02 + + 1.1878353E-02 + + 1.2074551E-02 + + 1.2333404E-02 + + 1.2612428E-02 + + 1.2970577E-02 + + 1.3454326E-02 + + 1.4077858E-02 + + 1.5040384E-02 + + 1.6507810E-02 + + 1.8671362E-02 + + 2.2195534E-02 + + + + 1.0393621E-02 + + 1.0343827E-02 + + 1.0278122E-02 + + 1.0307024E-02 + + 1.0321853E-02 + + 1.0374136E-02 + + 1.0395136E-02 + + 1.0457919E-02 + + 1.0485306E-02 + + 1.0588898E-02 + + 1.0597124E-02 + + 1.0623537E-02 + + 1.0731134E-02 + + 1.0828231E-02 + + 1.0959209E-02 + + 1.1072327E-02 + + 1.1248877E-02 + + 1.1263490E-02 + + 1.1402046E-02 + + 1.1566689E-02 + + 1.1767919E-02 + + 1.1861445E-02 + + 1.2076314E-02 + + 1.2322575E-02 + + 1.2537228E-02 + + 1.2963070E-02 + + 1.3353083E-02 + + 1.4108968E-02 + + 1.5044977E-02 + + 1.6501651E-02 + + 1.8769742E-02 + + 2.2133504E-02 + + + 1.0002763E+00 + + + 1.0002760E+00 + + + 1.0002658E+00 + + + 1.0002710E+00 + + + 1.0002776E+00 + + + 1.0002767E+00 + + + 1.0002833E+00 + + + 1.0002791E+00 + + + 1.0002788E+00 + + + 1.0002858E+00 + + + 1.0002884E+00 + + + 1.0002916E+00 + + + 1.0003039E+00 + + + 1.0003181E+00 + + + 1.0003365E+00 + + + 1.0003544E+00 + + + 1.0003372E+00 + + + 1.0002764E+00 + + + 1.0002508E+00 + + + 1.0002343E+00 + + + 1.0002360E+00 + + + 1.0002375E+00 + + + 1.0002331E+00 + + + 1.0002344E+00 + + + 1.0002385E+00 + + + 1.0002316E+00 + + + 1.0002360E+00 + + + 1.0002360E+00 + + + 1.0002354E+00 + + + 1.0002349E+00 + + + 1.0002325E+00 + + + 1.0002268E+00 + + + + + clad_ang_mu.71c + clad_ang_mu.71c + 2.5300000E-08 + 32 + false + 32 + 1 + angle + histogram + + 3.1005638E-01 + + 3.0999067E-01 + + 3.0994879E-01 + + 3.0987779E-01 + + 3.0961631E-01 + + 3.0948272E-01 + + 3.0913340E-01 + + 3.0868239E-01 + + 3.0799925E-01 + + 3.0712597E-01 + + 3.0590948E-01 + + 3.0432728E-01 + + 3.0235012E-01 + + 2.9996873E-01 + + 2.9743091E-01 + + 2.9739624E-01 + + 3.0835788E-01 + + 3.1305337E-01 + + 3.1379599E-01 + + 3.1314506E-01 + + 3.1216249E-01 + + 3.1129786E-01 + + 3.1059203E-01 + + 3.1009561E-01 + + 3.0977837E-01 + + 3.0951041E-01 + + 3.0930940E-01 + + 3.0929712E-01 + + 3.0925741E-01 + + 3.0917641E-01 + + 3.0919741E-01 + + 3.0912502E-01 + + + 1.3490691E-03 + + 1.3463259E-03 + + 1.3498512E-03 + + 1.3366347E-03 + + 1.3288899E-03 + + 1.3176269E-03 + + 1.3059971E-03 + + 1.2891508E-03 + + 1.2713136E-03 + + 1.2555332E-03 + + 1.2394055E-03 + + 1.2170158E-03 + + 1.1969201E-03 + + 1.1849620E-03 + + 1.1899173E-03 + + 1.2761137E-03 + + 1.6244505E-03 + + 1.9090551E-03 + + 2.0837409E-03 + + 2.1976011E-03 + + 2.2746911E-03 + + 2.3308251E-03 + + 2.3700744E-03 + + 2.3981231E-03 + + 2.4248079E-03 + + 2.4441792E-03 + + 2.4510541E-03 + + 2.4640212E-03 + + 2.4741885E-03 + + 2.4697219E-03 + + 2.4721421E-03 + + 2.4729172E-03 + + + 8.6638893E-03 + + 8.2719674E-03 + + 7.8055649E-03 + + 7.4105610E-03 + + 7.2544086E-03 + + 7.0854147E-03 + + 6.9965517E-03 + + 7.0314805E-03 + + 6.8552954E-03 + + 6.9138525E-03 + + 6.9528906E-03 + + 7.0689776E-03 + + 7.0720596E-03 + + 7.2523539E-03 + + 7.5405167E-03 + + 7.7624175E-03 + + 7.9838046E-03 + + 8.1702629E-03 + + 8.4784584E-03 + + 8.8970906E-03 + + 9.3105862E-03 + + 9.7826390E-03 + + 1.0253151E-02 + + 1.0659455E-02 + + 1.1134076E-02 + + 1.1649276E-02 + + 1.2603655E-02 + + 1.3342297E-02 + + 1.4372697E-02 + + 1.5779610E-02 + + 1.7933383E-02 + + 2.0318816E-02 + + + + 8.6137649E-03 + + 8.0815773E-03 + + 7.7778880E-03 + + 7.4879636E-03 + + 7.2446680E-03 + + 7.0652074E-03 + + 6.9244607E-03 + + 6.9131046E-03 + + 6.9017486E-03 + + 6.9408066E-03 + + 6.9814132E-03 + + 7.0440438E-03 + + 7.1589812E-03 + + 7.3353447E-03 + + 7.5896522E-03 + + 7.7529390E-03 + + 8.0199791E-03 + + 8.3484454E-03 + + 8.5960425E-03 + + 8.9554799E-03 + + 9.2763754E-03 + + 9.7440398E-03 + + 1.0084034E-02 + + 1.0634976E-02 + + 1.1176800E-02 + + 1.1768004E-02 + + 1.2488944E-02 + + 1.3414293E-02 + + 1.4307639E-02 + + 1.5845012E-02 + + 1.7838866E-02 + + 2.0339442E-02 + + + + 8.6069286E-03 + + 8.1600584E-03 + + 7.7753343E-03 + + 7.5082514E-03 + + 7.2541589E-03 + + 7.1052368E-03 + + 7.0049508E-03 + + 6.9087178E-03 + + 6.8877253E-03 + + 6.9276318E-03 + + 6.9580813E-03 + + 7.0116019E-03 + + 7.1577180E-03 + + 7.3369857E-03 + + 7.5182280E-03 + + 7.7277374E-03 + + 7.9440018E-03 + + 8.2744779E-03 + + 8.6378977E-03 + + 8.8881451E-03 + + 9.2653867E-03 + + 9.6492794E-03 + + 1.0205685E-02 + + 1.0657959E-02 + + 1.1210208E-02 + + 1.1713716E-02 + + 1.2497402E-02 + + 1.3347079E-02 + + 1.4469243E-02 + + 1.5835834E-02 + + 1.7754882E-02 + + 2.0415319E-02 + + + + 8.6357058E-03 + + 8.1456937E-03 + + 7.7155413E-03 + + 7.4818571E-03 + + 7.2524325E-03 + + 7.0736756E-03 + + 7.0115740E-03 + + 6.8735456E-03 + + 6.8726489E-03 + + 6.9218219E-03 + + 6.9136015E-03 + + 7.0770385E-03 + + 7.1125358E-03 + + 7.2947303E-03 + + 7.5540473E-03 + + 7.7247333E-03 + + 7.9593143E-03 + + 8.2175104E-03 + + 8.5783123E-03 + + 8.9662416E-03 + + 9.2850446E-03 + + 9.7500218E-03 + + 1.0192206E-02 + + 1.0589252E-02 + + 1.1196518E-02 + + 1.1754610E-02 + + 1.2477858E-02 + + 1.3364244E-02 + + 1.4489097E-02 + + 1.5799582E-02 + + 1.7806262E-02 + + 2.0415575E-02 + + + + 8.6187094E-03 + + 8.1028888E-03 + + 7.7502930E-03 + + 7.4368288E-03 + + 7.2053294E-03 + + 7.0754195E-03 + + 6.9609624E-03 + + 6.9199506E-03 + + 6.8721819E-03 + + 6.9170716E-03 + + 6.9278240E-03 + + 7.0082024E-03 + + 7.1469258E-03 + + 7.2928174E-03 + + 7.4578635E-03 + + 7.7005853E-03 + + 7.9397817E-03 + + 8.2897923E-03 + + 8.5642424E-03 + + 8.9336425E-03 + + 9.2822429E-03 + + 9.6866617E-03 + + 1.0169638E-02 + + 1.0601319E-02 + + 1.1134062E-02 + + 1.1797713E-02 + + 1.2521413E-02 + + 1.3398584E-02 + + 1.4465948E-02 + + 1.5920693E-02 + + 1.7831503E-02 + + 2.0386280E-02 + + + + 8.5957828E-03 + + 8.0917421E-03 + + 7.7483058E-03 + + 7.4335661E-03 + + 7.2051598E-03 + + 7.0542832E-03 + + 6.9482999E-03 + + 6.8660522E-03 + + 6.8566650E-03 + + 6.8895446E-03 + + 6.9769966E-03 + + 7.0151292E-03 + + 7.1289919E-03 + + 7.2728159E-03 + + 7.4843447E-03 + + 7.6904746E-03 + + 7.9728210E-03 + + 8.2376090E-03 + + 8.5714149E-03 + + 8.9027889E-03 + + 9.2973443E-03 + + 9.6952072E-03 + + 1.0177798E-02 + + 1.0619290E-02 + + 1.1136220E-02 + + 1.1749356E-02 + + 1.2532485E-02 + + 1.3371645E-02 + + 1.4476030E-02 + + 1.5936887E-02 + + 1.7814576E-02 + + 2.0401706E-02 + + + + 8.5762717E-03 + + 8.0787798E-03 + + 7.6957274E-03 + + 7.4218081E-03 + + 7.1969403E-03 + + 7.0456914E-03 + + 6.9243998E-03 + + 6.8670339E-03 + + 6.8410876E-03 + + 6.8440959E-03 + + 6.9114894E-03 + + 6.9709444E-03 + + 7.1246584E-03 + + 7.2467020E-03 + + 7.4540634E-03 + + 7.6790984E-03 + + 7.9072251E-03 + + 8.2202101E-03 + + 8.5598098E-03 + + 8.9093117E-03 + + 9.2775317E-03 + + 9.6625479E-03 + + 1.0156279E-02 + + 1.0632045E-02 + + 1.1116292E-02 + + 1.1767916E-02 + + 1.2489983E-02 + + 1.3349302E-02 + + 1.4524155E-02 + + 1.5953415E-02 + + 1.7870641E-02 + + 2.0504336E-02 + + + + 8.5580155E-03 + + 8.0552826E-03 + + 7.6847006E-03 + + 7.3901486E-03 + + 7.1714794E-03 + + 6.9956094E-03 + + 6.8966894E-03 + + 6.8584904E-03 + + 6.8074847E-03 + + 6.8182305E-03 + + 6.8700458E-03 + + 6.9598760E-03 + + 7.0775275E-03 + + 7.2721659E-03 + + 7.4256244E-03 + + 7.6626570E-03 + + 7.8956048E-03 + + 8.2476025E-03 + + 8.5876768E-03 + + 8.8916497E-03 + + 9.2599869E-03 + + 9.6607086E-03 + + 1.0104818E-02 + + 1.0621057E-02 + + 1.1139577E-02 + + 1.1789513E-02 + + 1.2505652E-02 + + 1.3335138E-02 + + 1.4480446E-02 + + 1.5926378E-02 + + 1.7926012E-02 + + 2.0526011E-02 + + + + 8.5161659E-03 + + 8.0446298E-03 + + 7.6545410E-03 + + 7.3722009E-03 + + 7.1148071E-03 + + 6.9727284E-03 + + 6.8574133E-03 + + 6.7687628E-03 + + 6.7671107E-03 + + 6.8028617E-03 + + 6.8012426E-03 + + 6.9205557E-03 + + 7.0398688E-03 + + 7.2416867E-03 + + 7.3960899E-03 + + 7.6495518E-03 + + 7.9006016E-03 + + 8.1906074E-03 + + 8.4993478E-03 + + 8.8863636E-03 + + 9.2483009E-03 + + 9.6547452E-03 + + 1.0109959E-02 + + 1.0588004E-02 + + 1.1123575E-02 + + 1.1768480E-02 + + 1.2510924E-02 + + 1.3377043E-02 + + 1.4514862E-02 + + 1.5985046E-02 + + 1.7920853E-02 + + 2.0545741E-02 + + + + 8.4881904E-03 + + 8.0008968E-03 + + 7.5800933E-03 + + 7.3219921E-03 + + 7.0930406E-03 + + 6.9243759E-03 + + 6.8395166E-03 + + 6.7595356E-03 + + 6.7209304E-03 + + 6.7524289E-03 + + 6.7924495E-03 + + 6.8886916E-03 + + 7.0061035E-03 + + 7.1949742E-03 + + 7.3557793E-03 + + 7.6015942E-03 + + 7.8273839E-03 + + 8.1635087E-03 + + 8.4872268E-03 + + 8.8563257E-03 + + 9.1982925E-03 + + 9.6315629E-03 + + 1.0058991E-02 + + 1.0542942E-02 + + 1.1120245E-02 + + 1.1716127E-02 + + 1.2496242E-02 + + 1.3357995E-02 + + 1.4520670E-02 + + 1.5968277E-02 + + 1.7999571E-02 + + 2.0619911E-02 + + + + 8.4547550E-03 + + 7.9415583E-03 + + 7.5504996E-03 + + 7.2492760E-03 + + 7.0388623E-03 + + 6.9114334E-03 + + 6.7880701E-03 + + 6.7298137E-03 + + 6.6707776E-03 + + 6.6865113E-03 + + 6.7469676E-03 + + 6.8440431E-03 + + 6.9530093E-03 + + 7.1334872E-03 + + 7.3320937E-03 + + 7.5447909E-03 + + 7.7926035E-03 + + 8.1024597E-03 + + 8.4776176E-03 + + 8.7989469E-03 + + 9.1860513E-03 + + 9.6106103E-03 + + 1.0035921E-02 + + 1.0516926E-02 + + 1.1111883E-02 + + 1.1693054E-02 + + 1.2421315E-02 + + 1.3359879E-02 + + 1.4448956E-02 + + 1.5939312E-02 + + 1.7946680E-02 + + 2.0638422E-02 + + + + 8.4199682E-03 + + 7.9132357E-03 + + 7.5289024E-03 + + 7.2000914E-03 + + 6.9952420E-03 + + 6.8508371E-03 + + 6.7532303E-03 + + 6.6833325E-03 + + 6.6177839E-03 + + 6.6622382E-03 + + 6.7105208E-03 + + 6.7909136E-03 + + 6.9136513E-03 + + 7.0763901E-03 + + 7.2891302E-03 + + 7.5133811E-03 + + 7.7798727E-03 + + 8.0728234E-03 + + 8.3719982E-03 + + 8.7418259E-03 + + 9.0827206E-03 + + 9.5593221E-03 + + 9.9725625E-03 + + 1.0449294E-02 + + 1.0985324E-02 + + 1.1627712E-02 + + 1.2345830E-02 + + 1.3279892E-02 + + 1.4416720E-02 + + 1.5897541E-02 + + 1.7949472E-02 + + 2.0670535E-02 + + + + 8.3808798E-03 + + 7.8549469E-03 + + 7.4548947E-03 + + 7.1338816E-03 + + 6.9441484E-03 + + 6.7971643E-03 + + 6.6772004E-03 + + 6.6034372E-03 + + 6.5689962E-03 + + 6.6291014E-03 + + 6.6629260E-03 + + 6.7229080E-03 + + 6.8650107E-03 + + 7.0400011E-03 + + 7.2281319E-03 + + 7.4627838E-03 + + 7.7395439E-03 + + 8.0343750E-03 + + 8.3395359E-03 + + 8.6563579E-03 + + 9.0736921E-03 + + 9.4975103E-03 + + 9.9294641E-03 + + 1.0370071E-02 + + 1.0916688E-02 + + 1.1554450E-02 + + 1.2270239E-02 + + 1.3181629E-02 + + 1.4291357E-02 + + 1.5819158E-02 + + 1.7859062E-02 + + 2.0611377E-02 + + + + 8.3161285E-03 + + 7.8077760E-03 + + 7.3959293E-03 + + 7.1090603E-03 + + 6.8980291E-03 + + 6.7587447E-03 + + 6.6504860E-03 + + 6.5749792E-03 + + 6.5613818E-03 + + 6.5416597E-03 + + 6.6015118E-03 + + 6.7070747E-03 + + 6.8290963E-03 + + 7.0031900E-03 + + 7.1846853E-03 + + 7.4125063E-03 + + 7.6750420E-03 + + 7.9813021E-03 + + 8.2806571E-03 + + 8.6141119E-03 + + 8.9704813E-03 + + 9.3882871E-03 + + 9.8368112E-03 + + 1.0298412E-02 + + 1.0822136E-02 + + 1.1413491E-02 + + 1.2145337E-02 + + 1.3048321E-02 + + 1.4114237E-02 + + 1.5706737E-02 + + 1.7654188E-02 + + 2.0500295E-02 + + + + 8.3192873E-03 + + 7.7697531E-03 + + 7.3819594E-03 + + 7.0971817E-03 + + 6.8836908E-03 + + 6.7313952E-03 + + 6.6234836E-03 + + 6.5684539E-03 + + 6.5572540E-03 + + 6.5781759E-03 + + 6.6163018E-03 + + 6.6999200E-03 + + 6.8297696E-03 + + 6.9564324E-03 + + 7.1572917E-03 + + 7.4359960E-03 + + 7.6444528E-03 + + 7.9171531E-03 + + 8.2232683E-03 + + 8.5632604E-03 + + 8.9017284E-03 + + 9.3233527E-03 + + 9.7185361E-03 + + 1.0167756E-02 + + 1.0690318E-02 + + 1.1287654E-02 + + 1.1955699E-02 + + 1.2797701E-02 + + 1.3915636E-02 + + 1.5417831E-02 + + 1.7413631E-02 + + 2.0132344E-02 + + + + 8.3402366E-03 + + 7.8783074E-03 + + 7.5306252E-03 + + 7.2763123E-03 + + 7.0815582E-03 + + 6.9389151E-03 + + 6.8574149E-03 + + 6.7982581E-03 + + 6.7740232E-03 + + 6.7825822E-03 + + 6.8155653E-03 + + 6.8794036E-03 + + 7.0109342E-03 + + 7.1732489E-03 + + 7.3504593E-03 + + 7.5193707E-03 + + 7.7780813E-03 + + 8.0399365E-03 + + 8.3133536E-03 + + 8.6051891E-03 + + 8.9148994E-03 + + 9.3197524E-03 + + 9.7034206E-03 + + 1.0115863E-02 + + 1.0600845E-02 + + 1.1142903E-02 + + 1.1780624E-02 + + 1.2556047E-02 + + 1.3579729E-02 + + 1.4891180E-02 + + 1.6672103E-02 + + 1.9078712E-02 + + + + 8.8088395E-03 + + 8.4507679E-03 + + 8.1708811E-03 + + 7.9801672E-03 + + 7.8027326E-03 + + 7.7405325E-03 + + 7.6178992E-03 + + 7.5796349E-03 + + 7.5729815E-03 + + 7.5709385E-03 + + 7.6313441E-03 + + 7.6551420E-03 + + 7.7197992E-03 + + 7.8770525E-03 + + 7.9879526E-03 + + 8.1371998E-03 + + 8.3342910E-03 + + 8.5247565E-03 + + 8.7962504E-03 + + 9.0806648E-03 + + 9.3313150E-03 + + 9.6858805E-03 + + 1.0017311E-02 + + 1.0396502E-02 + + 1.0810783E-02 + + 1.1308495E-02 + + 1.1873348E-02 + + 1.2517849E-02 + + 1.3292300E-02 + + 1.4204872E-02 + + 1.5413040E-02 + + 1.6865149E-02 + + + + 9.0402122E-03 + + 8.7656934E-03 + + 8.5418137E-03 + + 8.3375574E-03 + + 8.2205328E-03 + + 8.0954859E-03 + + 8.0140696E-03 + + 7.9720195E-03 + + 7.9707073E-03 + + 7.9496524E-03 + + 7.9729738E-03 + + 8.0286530E-03 + + 8.0949490E-03 + + 8.2040408E-03 + + 8.3348436E-03 + + 8.4638271E-03 + + 8.5967473E-03 + + 8.8120082E-03 + + 9.0406595E-03 + + 9.2571730E-03 + + 9.4741636E-03 + + 9.7864082E-03 + + 1.0105154E-02 + + 1.0426882E-02 + + 1.0815324E-02 + + 1.1263114E-02 + + 1.1718090E-02 + + 1.2294266E-02 + + 1.2954841E-02 + + 1.3732023E-02 + + 1.4787929E-02 + + 1.6057604E-02 + + + + 9.1615425E-03 + + 8.8847745E-03 + + 8.6630839E-03 + + 8.4765570E-03 + + 8.3309009E-03 + + 8.2383585E-03 + + 8.1836800E-03 + + 8.1120640E-03 + + 8.1261785E-03 + + 8.0708249E-03 + + 8.1480561E-03 + + 8.1784637E-03 + + 8.2346151E-03 + + 8.3274337E-03 + + 8.4147598E-03 + + 8.5448285E-03 + + 8.7091710E-03 + + 8.8843142E-03 + + 9.0949279E-03 + + 9.2936363E-03 + + 9.5389840E-03 + + 9.7958383E-03 + + 1.0086138E-02 + + 1.0400309E-02 + + 1.0727798E-02 + + 1.1115580E-02 + + 1.1556966E-02 + + 1.2062390E-02 + + 1.2723933E-02 + + 1.3461879E-02 + + 1.4407800E-02 + + 1.5727050E-02 + + + + 9.1377654E-03 + + 8.8751018E-03 + + 8.6821226E-03 + + 8.4858221E-03 + + 8.3554460E-03 + + 8.2804350E-03 + + 8.2266991E-03 + + 8.1758459E-03 + + 8.1472390E-03 + + 8.1455783E-03 + + 8.1349878E-03 + + 8.1925776E-03 + + 8.2538648E-03 + + 8.3264317E-03 + + 8.4644531E-03 + + 8.6009391E-03 + + 8.7147401E-03 + + 8.9206598E-03 + + 9.1064325E-03 + + 9.2780740E-03 + + 9.4991589E-03 + + 9.7677443E-03 + + 1.0040842E-02 + + 1.0310399E-02 + + 1.0637483E-02 + + 1.1002699E-02 + + 1.1454957E-02 + + 1.1928711E-02 + + 1.2543618E-02 + + 1.3315003E-02 + + 1.4311921E-02 + + 1.5626273E-02 + + + + 9.1477964E-03 + + 8.8569131E-03 + + 8.6480911E-03 + + 8.4806682E-03 + + 8.3743826E-03 + + 8.2509863E-03 + + 8.2112855E-03 + + 8.1583830E-03 + + 8.1332616E-03 + + 8.1132990E-03 + + 8.1560439E-03 + + 8.1779291E-03 + + 8.2488074E-03 + + 8.3305803E-03 + + 8.4259072E-03 + + 8.5822114E-03 + + 8.7017305E-03 + + 8.8788944E-03 + + 9.0655429E-03 + + 9.2582475E-03 + + 9.4805275E-03 + + 9.7278007E-03 + + 9.9553998E-03 + + 1.0269546E-02 + + 1.0586672E-02 + + 1.0921006E-02 + + 1.1328973E-02 + + 1.1802691E-02 + + 1.2450626E-02 + + 1.3255698E-02 + + 1.4251456E-02 + + 1.5657809E-02 + + + + 9.0883340E-03 + + 8.8433984E-03 + + 8.6289182E-03 + + 8.4439323E-03 + + 8.3093188E-03 + + 8.2332632E-03 + + 8.1799745E-03 + + 8.1280446E-03 + + 8.0845653E-03 + + 8.1128997E-03 + + 8.1014997E-03 + + 8.1603558E-03 + + 8.2532133E-03 + + 8.3021938E-03 + + 8.4337253E-03 + + 8.5567067E-03 + + 8.6772027E-03 + + 8.8890649E-03 + + 9.0381936E-03 + + 9.2474046E-03 + + 9.4507499E-03 + + 9.7047326E-03 + + 9.9402566E-03 + + 1.0205441E-02 + + 1.0504990E-02 + + 1.0882385E-02 + + 1.1274627E-02 + + 1.1783289E-02 + + 1.2386232E-02 + + 1.3164784E-02 + + 1.4270026E-02 + + 1.5728107E-02 + + + + 9.0807708E-03 + + 8.8015024E-03 + + 8.5814276E-03 + + 8.4248165E-03 + + 8.2946254E-03 + + 8.2126919E-03 + + 8.1370075E-03 + + 8.0715301E-03 + + 8.0815288E-03 + + 8.0835771E-03 + + 8.1054492E-03 + + 8.1477700E-03 + + 8.2076231E-03 + + 8.2545960E-03 + + 8.4024583E-03 + + 8.5599026E-03 + + 8.6575633E-03 + + 8.8233051E-03 + + 9.0064404E-03 + + 9.2354725E-03 + + 9.4557209E-03 + + 9.6788857E-03 + + 9.8947250E-03 + + 1.0174410E-02 + + 1.0498117E-02 + + 1.0823664E-02 + + 1.1218924E-02 + + 1.1737640E-02 + + 1.2318916E-02 + + 1.3224386E-02 + + 1.4293237E-02 + + 1.5742419E-02 + + + + 9.0662532E-03 + + 8.7875937E-03 + + 8.5608939E-03 + + 8.3990606E-03 + + 8.2689578E-03 + + 8.1502455E-03 + + 8.0945876E-03 + + 8.0499873E-03 + + 8.0046473E-03 + + 8.0312744E-03 + + 8.0845285E-03 + + 8.0864516E-03 + + 8.1794243E-03 + + 8.2886692E-03 + + 8.3753921E-03 + + 8.5095259E-03 + + 8.6235784E-03 + + 8.8149234E-03 + + 9.0064533E-03 + + 9.1933604E-03 + + 9.4366281E-03 + + 9.6340012E-03 + + 9.8577424E-03 + + 1.0162178E-02 + + 1.0489950E-02 + + 1.0830480E-02 + + 1.1216758E-02 + + 1.1718234E-02 + + 1.2372964E-02 + + 1.3217004E-02 + + 1.4300060E-02 + + 1.5874384E-02 + + + + 9.0385593E-03 + + 8.7911739E-03 + + 8.5398942E-03 + + 8.3506015E-03 + + 8.2438909E-03 + + 8.1613890E-03 + + 8.0460870E-03 + + 8.0305903E-03 + + 8.0028889E-03 + + 8.0232434E-03 + + 8.0276194E-03 + + 8.1064278E-03 + + 8.1288298E-03 + + 8.2312446E-03 + + 8.3452218E-03 + + 8.4759402E-03 + + 8.6203085E-03 + + 8.7737100E-03 + + 8.9852040E-03 + + 9.1640184E-03 + + 9.3706145E-03 + + 9.6371098E-03 + + 9.8385671E-03 + + 1.0187163E-02 + + 1.0453859E-02 + + 1.0791575E-02 + + 1.1239213E-02 + + 1.1704998E-02 + + 1.2413952E-02 + + 1.3197580E-02 + + 1.4388298E-02 + + 1.5983777E-02 + + + + 9.0381972E-03 + + 8.7249421E-03 + + 8.5299403E-03 + + 8.3296610E-03 + + 8.1906552E-03 + + 8.0856852E-03 + + 8.0084895E-03 + + 7.9976213E-03 + + 7.9681027E-03 + + 7.9954298E-03 + + 8.0300023E-03 + + 8.0899341E-03 + + 8.1518784E-03 + + 8.2341280E-03 + + 8.3101161E-03 + + 8.4644180E-03 + + 8.6281121E-03 + + 8.7991411E-03 + + 8.9588100E-03 + + 9.1981791E-03 + + 9.3869641E-03 + + 9.6145258E-03 + + 9.9132005E-03 + + 1.0156461E-02 + + 1.0475933E-02 + + 1.0810611E-02 + + 1.1229999E-02 + + 1.1691965E-02 + + 1.2394061E-02 + + 1.3229214E-02 + + 1.4413895E-02 + + 1.6023151E-02 + + + + 8.9900779E-03 + + 8.7242101E-03 + + 8.4738461E-03 + + 8.3135886E-03 + + 8.1704723E-03 + + 8.0916227E-03 + + 8.0054050E-03 + + 7.9890825E-03 + + 7.9822260E-03 + + 7.9494275E-03 + + 8.0343148E-03 + + 8.0498187E-03 + + 8.1090198E-03 + + 8.2328458E-03 + + 8.3082672E-03 + + 8.4585469E-03 + + 8.6087756E-03 + + 8.8041342E-03 + + 8.9504229E-03 + + 9.1682953E-03 + + 9.3389911E-03 + + 9.6352014E-03 + + 9.8666333E-03 + + 1.0149489E-02 + + 1.0464017E-02 + + 1.0804437E-02 + + 1.1200629E-02 + + 1.1730829E-02 + + 1.2396625E-02 + + 1.3311556E-02 + + 1.4467897E-02 + + 1.6069551E-02 + + + + 9.0103050E-03 + + 8.7325667E-03 + + 8.5095225E-03 + + 8.3198922E-03 + + 8.1828827E-03 + + 8.0755069E-03 + + 7.9981914E-03 + + 7.9413633E-03 + + 7.9823990E-03 + + 7.9246563E-03 + + 7.9815454E-03 + + 8.0345931E-03 + + 8.0725191E-03 + + 8.2341012E-03 + + 8.3041608E-03 + + 8.3831836E-03 + + 8.6106789E-03 + + 8.7518346E-03 + + 8.9641474E-03 + + 9.0978032E-03 + + 9.3592003E-03 + + 9.5996223E-03 + + 9.9237621E-03 + + 1.0175830E-02 + + 1.0455459E-02 + + 1.0836548E-02 + + 1.1244650E-02 + + 1.1760188E-02 + + 1.2384627E-02 + + 1.3346254E-02 + + 1.4480133E-02 + + 1.6136563E-02 + + + + 9.0228604E-03 + + 8.6804828E-03 + + 8.4614534E-03 + + 8.2426545E-03 + + 8.1392111E-03 + + 8.0814949E-03 + + 7.9912702E-03 + + 7.9974952E-03 + + 7.9421615E-03 + + 7.9138029E-03 + + 7.9451587E-03 + + 8.0340001E-03 + + 8.0954821E-03 + + 8.1764077E-03 + + 8.3095930E-03 + + 8.4157262E-03 + + 8.6168490E-03 + + 8.7576427E-03 + + 8.9333274E-03 + + 9.1895534E-03 + + 9.3857577E-03 + + 9.6418300E-03 + + 9.8564788E-03 + + 1.0150132E-02 + + 1.0487898E-02 + + 1.0870470E-02 + + 1.1271947E-02 + + 1.1778020E-02 + + 1.2502739E-02 + + 1.3339816E-02 + + 1.4543555E-02 + + 1.6130789E-02 + + + + 9.0622003E-03 + + 8.7178702E-03 + + 8.4596226E-03 + + 8.2747360E-03 + + 8.1644825E-03 + + 8.0165944E-03 + + 7.9932716E-03 + + 7.9360246E-03 + + 7.9425974E-03 + + 7.9418553E-03 + + 7.9541528E-03 + + 8.0182907E-03 + + 8.0812624E-03 + + 8.0915456E-03 + + 8.2908500E-03 + + 8.4101146E-03 + + 8.5246086E-03 + + 8.7454336E-03 + + 8.9623361E-03 + + 9.1273983E-03 + + 9.3738784E-03 + + 9.6552369E-03 + + 9.8941901E-03 + + 1.0161555E-02 + + 1.0501008E-02 + + 1.0866011E-02 + + 1.1314128E-02 + + 1.1790338E-02 + + 1.2447300E-02 + + 1.3396964E-02 + + 1.4531939E-02 + + 1.6115773E-02 + + + + 8.9679455E-03 + + 8.7523346E-03 + + 8.4194831E-03 + + 8.2562897E-03 + + 8.2501744E-03 + + 8.0453964E-03 + + 7.9636250E-03 + + 7.9278064E-03 + + 7.9395130E-03 + + 7.8808053E-03 + + 7.8942591E-03 + + 7.9779525E-03 + + 8.1203535E-03 + + 8.1780129E-03 + + 8.2976996E-03 + + 8.3927501E-03 + + 8.5693973E-03 + + 8.7760972E-03 + + 8.9639268E-03 + + 9.1777904E-03 + + 9.3233365E-03 + + 9.6757573E-03 + + 9.8043550E-03 + + 1.0142972E-02 + + 1.0460099E-02 + + 1.0900581E-02 + + 1.1166513E-02 + + 1.1798843E-02 + + 1.2569032E-02 + + 1.3335377E-02 + + 1.4567713E-02 + + 1.6266042E-02 + + + + 9.0235493E-03 + + 8.7359753E-03 + + 8.4400355E-03 + + 8.2314136E-03 + + 8.1409585E-03 + + 8.0562549E-03 + + 8.0165174E-03 + + 7.9631855E-03 + + 7.9527283E-03 + + 7.9590026E-03 + + 7.9558654E-03 + + 7.9982172E-03 + + 7.9903743E-03 + + 8.1472328E-03 + + 8.3527175E-03 + + 8.3019999E-03 + + 8.5775481E-03 + + 8.8353190E-03 + + 8.9853803E-03 + + 9.0836784E-03 + + 9.4481131E-03 + + 9.5401367E-03 + + 9.8920227E-03 + + 1.0186917E-02 + + 1.0500634E-02 + + 1.0833697E-02 + + 1.1379042E-02 + + 1.1793671E-02 + + 1.2553389E-02 + + 1.3369577E-02 + + 1.4595165E-02 + + 1.6031466E-02 + + + 1.0000416E+00 + + + 1.0000513E+00 + + + 1.0000397E+00 + + + 1.0000409E+00 + + + 1.0000455E+00 + + + 1.0000417E+00 + + + 1.0000452E+00 + + + 1.0000431E+00 + + + 1.0000455E+00 + + + 1.0000451E+00 + + + 1.0000445E+00 + + + 1.0000482E+00 + + + 1.0000507E+00 + + + 1.0000542E+00 + + + 1.0000545E+00 + + + 1.0000461E+00 + + + 1.0000114E+00 + + + 1.0000112E+00 + + + 1.0000195E+00 + + + 1.0000216E+00 + + + 1.0000279E+00 + + + 1.0000307E+00 + + + 1.0000302E+00 + + + 1.0000313E+00 + + + 1.0000334E+00 + + + 1.0000309E+00 + + + 1.0000325E+00 + + + 1.0000318E+00 + + + 1.0000346E+00 + + + 1.0000335E+00 + + + 1.0000285E+00 + + + 1.0000358E+00 + + + + + lwtr_ang_mu.71c + lwtr_ang_mu.71c + 2.5300000E-08 + 32 + false + 32 + 1 + angle + histogram + + 8.3129229E-01 + + 8.3203829E-01 + + 8.3332424E-01 + + 8.3539719E-01 + + 8.3799288E-01 + + 8.4156597E-01 + + 8.4594074E-01 + + 8.5122773E-01 + + 8.5788274E-01 + + 8.6633387E-01 + + 8.7719846E-01 + + 8.9195077E-01 + + 9.1326621E-01 + + 9.4469159E-01 + + 9.9368716E-01 + + 1.0616854E+00 + + 1.0982938E+00 + + 1.0997200E+00 + + 1.0855410E+00 + + 1.0676695E+00 + + 1.0508172E+00 + + 1.0369337E+00 + + 1.0255762E+00 + + 1.0162841E+00 + + 1.0086633E+00 + + 1.0025783E+00 + + 9.9737297E-01 + + 9.9326768E-01 + + 9.9030852E-01 + + 9.8792719E-01 + + 9.8610453E-01 + + 9.8540665E-01 + + + 7.7368065E-03 + + 7.7519393E-03 + + 7.7819449E-03 + + 7.8285240E-03 + + 7.8881877E-03 + + 7.9652685E-03 + + 8.0588251E-03 + + 8.1724303E-03 + + 8.3079937E-03 + + 8.4749946E-03 + + 8.6811506E-03 + + 8.9456784E-03 + + 9.3049336E-03 + + 9.8025199E-03 + + 1.0529992E-02 + + 1.1498571E-02 + + 1.2065971E-02 + + 1.2168395E-02 + + 1.2053690E-02 + + 1.1870414E-02 + + 1.1678759E-02 + + 1.1516371E-02 + + 1.1377145E-02 + + 1.1262809E-02 + + 1.1166687E-02 + + 1.1090107E-02 + + 1.1022668E-02 + + 1.0968772E-02 + + 1.0931381E-02 + + 1.0898236E-02 + + 1.0872094E-02 + + 1.0866295E-02 + + + 5.0690953E-03 + + 8.8284325E-03 + + 9.0078067E-03 + + 8.3473577E-03 + + 8.6118779E-03 + + 8.5008333E-03 + + 9.0278160E-03 + + 9.0320024E-03 + + 9.3778370E-03 + + 9.6052477E-03 + + 9.9703821E-03 + + 1.0342612E-02 + + 1.0646441E-02 + + 1.1197549E-02 + + 1.1382812E-02 + + 1.2469275E-02 + + 1.3368771E-02 + + 1.7162734E-02 + + 2.0335842E-02 + + 2.4108518E-02 + + 2.7585384E-02 + + 3.1409361E-02 + + 3.5211839E-02 + + 3.9132244E-02 + + 4.2882641E-02 + + 4.7206070E-02 + + 5.1012876E-02 + + 5.6053305E-02 + + 5.9624825E-02 + + 6.4222850E-02 + + 7.1113785E-02 + + 7.1863425E-02 + + + + 5.0668773E-03 + + 8.8623444E-03 + + 8.9736897E-03 + + 8.4193826E-03 + + 8.6200366E-03 + + 8.5331711E-03 + + 9.0253536E-03 + + 9.0024868E-03 + + 9.3587966E-03 + + 9.6337679E-03 + + 9.9001048E-03 + + 1.0351369E-02 + + 1.0700823E-02 + + 1.1172796E-02 + + 1.1445656E-02 + + 1.2427412E-02 + + 1.3375674E-02 + + 1.7104580E-02 + + 2.0306601E-02 + + 2.4056263E-02 + + 2.7577305E-02 + + 3.1469932E-02 + + 3.5286392E-02 + + 3.9182103E-02 + + 4.2943152E-02 + + 4.7360483E-02 + + 5.1005109E-02 + + 5.6171187E-02 + + 5.9667108E-02 + + 6.4232789E-02 + + 7.1121280E-02 + + 7.1846306E-02 + + + + 5.0585819E-03 + + 8.8480548E-03 + + 9.0578095E-03 + + 8.4267843E-03 + + 8.6269032E-03 + + 8.5421136E-03 + + 9.0526837E-03 + + 9.0736449E-03 + + 9.4245294E-03 + + 9.6888060E-03 + + 9.9567766E-03 + + 1.0375670E-02 + + 1.0725481E-02 + + 1.1243110E-02 + + 1.1484936E-02 + + 1.2521826E-02 + + 1.3438046E-02 + + 1.7151864E-02 + + 2.0343472E-02 + + 2.4110251E-02 + + 2.7659343E-02 + + 3.1511614E-02 + + 3.5309076E-02 + + 3.9196826E-02 + + 4.3043312E-02 + + 4.7345488E-02 + + 5.1124137E-02 + + 5.6080519E-02 + + 5.9764341E-02 + + 6.4292466E-02 + + 7.1165161E-02 + + 7.1900319E-02 + + + + 5.0739533E-03 + + 8.8878014E-03 + + 9.0739746E-03 + + 8.4571184E-03 + + 8.6763187E-03 + + 8.5845734E-03 + + 9.0893274E-03 + + 9.1072493E-03 + + 9.4607350E-03 + + 9.7370233E-03 + + 1.0006337E-02 + + 1.0437546E-02 + + 1.0767301E-02 + + 1.1309766E-02 + + 1.1552543E-02 + + 1.2572863E-02 + + 1.3499221E-02 + + 1.7217227E-02 + + 2.0383163E-02 + + 2.4178222E-02 + + 2.7731888E-02 + + 3.1561770E-02 + + 3.5431417E-02 + + 3.9298803E-02 + + 4.3075219E-02 + + 4.7440921E-02 + + 5.1196928E-02 + + 5.6281715E-02 + + 5.9863517E-02 + + 6.4363763E-02 + + 7.1290039E-02 + + 7.1984722E-02 + + + + 5.0933569E-03 + + 8.9571748E-03 + + 9.1350789E-03 + + 8.5026806E-03 + + 8.7154122E-03 + + 8.6182850E-03 + + 9.1387403E-03 + + 9.1503576E-03 + + 9.5054271E-03 + + 9.8046510E-03 + + 1.0063015E-02 + + 1.0512898E-02 + + 1.0850976E-02 + + 1.1369711E-02 + + 1.1602210E-02 + + 1.2644534E-02 + + 1.3573331E-02 + + 1.7276147E-02 + + 2.0485160E-02 + + 2.4267827E-02 + + 2.7795345E-02 + + 3.1650606E-02 + + 3.5516413E-02 + + 3.9384282E-02 + + 4.3193261E-02 + + 4.7565933E-02 + + 5.1283045E-02 + + 5.6364736E-02 + + 5.9999740E-02 + + 6.4499325E-02 + + 7.1460960E-02 + + 7.2121578E-02 + + + + 5.1073627E-03 + + 9.0205393E-03 + + 9.1796662E-03 + + 8.5645656E-03 + + 8.7990379E-03 + + 8.7021912E-03 + + 9.2162069E-03 + + 9.2138958E-03 + + 9.5751521E-03 + + 9.8799162E-03 + + 1.0149817E-02 + + 1.0595940E-02 + + 1.0925157E-02 + + 1.1451227E-02 + + 1.1697295E-02 + + 1.2747125E-02 + + 1.3679064E-02 + + 1.7388258E-02 + + 2.0589616E-02 + + 2.4369432E-02 + + 2.7920510E-02 + + 3.1792267E-02 + + 3.5621878E-02 + + 3.9491661E-02 + + 4.3278532E-02 + + 4.7679951E-02 + + 5.1436615E-02 + + 5.6547886E-02 + + 6.0145268E-02 + + 6.4662138E-02 + + 7.1681806E-02 + + 7.2326892E-02 + + + + 5.1442091E-03 + + 9.0852521E-03 + + 9.2735609E-03 + + 8.6388628E-03 + + 8.8708740E-03 + + 8.7690933E-03 + + 9.2934119E-03 + + 9.3186161E-03 + + 9.6592707E-03 + + 9.9678700E-03 + + 1.0236163E-02 + + 1.0694734E-02 + + 1.1025890E-02 + + 1.1566030E-02 + + 1.1820104E-02 + + 1.2881706E-02 + + 1.3817409E-02 + + 1.7525018E-02 + + 2.0707299E-02 + + 2.4504049E-02 + + 2.8056398E-02 + + 3.1942086E-02 + + 3.5781215E-02 + + 3.9676732E-02 + + 4.3508487E-02 + + 4.7899374E-02 + + 5.1653601E-02 + + 5.6724194E-02 + + 6.0363176E-02 + + 6.4884496E-02 + + 7.1995314E-02 + + 7.2586420E-02 + + + + 5.1859947E-03 + + 9.1884111E-03 + + 9.3553722E-03 + + 8.7326674E-03 + + 8.9615831E-03 + + 8.8682756E-03 + + 9.3981872E-03 + + 9.4022342E-03 + + 9.7833217E-03 + + 1.0082626E-02 + + 1.0346345E-02 + + 1.0823172E-02 + + 1.1169852E-02 + + 1.1713674E-02 + + 1.1957780E-02 + + 1.3030310E-02 + + 1.3974055E-02 + + 1.7679518E-02 + + 2.0873339E-02 + + 2.4674002E-02 + + 2.8233633E-02 + + 3.2098518E-02 + + 3.5967409E-02 + + 3.9901149E-02 + + 4.3708564E-02 + + 4.8163155E-02 + + 5.1864987E-02 + + 5.6965609E-02 + + 6.0598955E-02 + + 6.5237827E-02 + + 7.2317026E-02 + + 7.2846315E-02 + + + + 5.2179276E-03 + + 9.2840460E-03 + + 9.4689692E-03 + + 8.8426310E-03 + + 9.0784020E-03 + + 8.9710561E-03 + + 9.5058449E-03 + + 9.5242525E-03 + + 9.8985438E-03 + + 1.0230104E-02 + + 1.0489612E-02 + + 1.0966586E-02 + + 1.1313882E-02 + + 1.1867051E-02 + + 1.2127596E-02 + + 1.3217267E-02 + + 1.4158489E-02 + + 1.7874095E-02 + + 2.1071639E-02 + + 2.4904630E-02 + + 2.8444961E-02 + + 3.2350782E-02 + + 3.6218293E-02 + + 4.0127228E-02 + + 4.3958446E-02 + + 4.8412743E-02 + + 5.2176893E-02 + + 5.7339635E-02 + + 6.0969984E-02 + + 6.5571180E-02 + + 7.2752295E-02 + + 7.3254466E-02 + + + + 5.2716442E-03 + + 9.4281164E-03 + + 9.6132026E-03 + + 8.9742401E-03 + + 9.2100433E-03 + + 9.1094424E-03 + + 9.6671272E-03 + + 9.6893875E-03 + + 1.0054424E-02 + + 1.0384782E-02 + + 1.0663088E-02 + + 1.1145331E-02 + + 1.1502660E-02 + + 1.2069220E-02 + + 1.2330654E-02 + + 1.3451168E-02 + + 1.4376732E-02 + + 1.8119744E-02 + + 2.1312268E-02 + + 2.5156150E-02 + + 2.8702855E-02 + + 3.2612605E-02 + + 3.6519082E-02 + + 4.0492357E-02 + + 4.4282144E-02 + + 4.8807320E-02 + + 5.2599863E-02 + + 5.7759050E-02 + + 6.1395630E-02 + + 6.6046712E-02 + + 7.3333461E-02 + + 7.3753560E-02 + + + + 5.3238344E-03 + + 9.5970913E-03 + + 9.7854600E-03 + + 9.1224140E-03 + + 9.3984166E-03 + + 9.2843910E-03 + + 9.8479041E-03 + + 9.8775712E-03 + + 1.0248815E-02 + + 1.0588076E-02 + + 1.0866467E-02 + + 1.1377201E-02 + + 1.1745016E-02 + + 1.2324752E-02 + + 1.2591933E-02 + + 1.3738942E-02 + + 1.4661945E-02 + + 1.8420789E-02 + + 2.1616210E-02 + + 2.5483933E-02 + + 2.9053296E-02 + + 3.3018657E-02 + + 3.6902567E-02 + + 4.0918920E-02 + + 4.4768920E-02 + + 4.9324206E-02 + + 5.3104469E-02 + + 5.8346792E-02 + + 6.2007342E-02 + + 6.6700912E-02 + + 7.4111114E-02 + + 7.4471661E-02 + + + + 5.4122500E-03 + + 9.8114809E-03 + + 9.9988824E-03 + + 9.3373137E-03 + + 9.6193550E-03 + + 9.5022652E-03 + + 1.0091629E-02 + + 1.0102292E-02 + + 1.0507181E-02 + + 1.0845994E-02 + + 1.1145961E-02 + + 1.1663724E-02 + + 1.2054675E-02 + + 1.2641320E-02 + + 1.2925378E-02 + + 1.4109631E-02 + + 1.5019788E-02 + + 1.8801255E-02 + + 2.2007215E-02 + + 2.5928762E-02 + + 2.9530128E-02 + + 3.3525210E-02 + + 3.7488914E-02 + + 4.1518826E-02 + + 4.5409731E-02 + + 5.0007891E-02 + + 5.3821041E-02 + + 5.9155539E-02 + + 6.2863258E-02 + + 6.7589912E-02 + + 7.5149452E-02 + + 7.5483624E-02 + + + + 5.5291381E-03 + + 1.0106920E-02 + + 1.0289680E-02 + + 9.6380580E-03 + + 9.9265277E-03 + + 9.8058620E-03 + + 1.0411771E-02 + + 1.0436031E-02 + + 1.0855919E-02 + + 1.1210324E-02 + + 1.1523264E-02 + + 1.2064653E-02 + + 1.2477020E-02 + + 1.3073068E-02 + + 1.3372106E-02 + + 1.4596687E-02 + + 1.5522669E-02 + + 1.9346144E-02 + + 2.2590235E-02 + + 2.6577078E-02 + + 3.0198519E-02 + + 3.4263702E-02 + + 3.8312940E-02 + + 4.2417033E-02 + + 4.6331184E-02 + + 5.1039786E-02 + + 5.4923952E-02 + + 6.0373272E-02 + + 6.4126997E-02 + + 6.8933518E-02 + + 7.6721947E-02 + + 7.6881324E-02 + + + + 5.7051926E-03 + + 1.0534340E-02 + + 1.0734999E-02 + + 1.0047973E-02 + + 1.0355258E-02 + + 1.0218464E-02 + + 1.0877782E-02 + + 1.0922582E-02 + + 1.1349348E-02 + + 1.1717445E-02 + + 1.2048634E-02 + + 1.2622834E-02 + + 1.3044209E-02 + + 1.3697572E-02 + + 1.4007429E-02 + + 1.5297796E-02 + + 1.6229092E-02 + + 2.0130646E-02 + + 2.3419720E-02 + + 2.7507372E-02 + + 3.1241243E-02 + + 3.5411821E-02 + + 3.9541855E-02 + + 4.3748213E-02 + + 4.7789294E-02 + + 5.2605069E-02 + + 5.6580575E-02 + + 6.2218120E-02 + + 6.6002923E-02 + + 7.0996802E-02 + + 7.9059610E-02 + + 7.9125302E-02 + + + + 5.9798621E-03 + + 1.1178770E-02 + + 1.1398960E-02 + + 1.0686315E-02 + + 1.1015007E-02 + + 1.0888426E-02 + + 1.1578312E-02 + + 1.1599595E-02 + + 1.2096215E-02 + + 1.2485774E-02 + + 1.2847301E-02 + + 1.3454293E-02 + + 1.3910042E-02 + + 1.4624946E-02 + + 1.4951480E-02 + + 1.6345303E-02 + + 1.7294576E-02 + + 2.1305917E-02 + + 2.4724135E-02 + + 2.8975117E-02 + + 3.2851405E-02 + + 3.7179235E-02 + + 4.1473071E-02 + + 4.5870569E-02 + + 5.0061541E-02 + + 5.5118747E-02 + + 5.9217709E-02 + + 6.5121185E-02 + + 6.9056004E-02 + + 7.4268036E-02 + + 8.2796332E-02 + + 8.2707329E-02 + + + + 6.3814382E-03 + + 1.2092503E-02 + + 1.2307256E-02 + + 1.1538828E-02 + + 1.1908080E-02 + + 1.1757836E-02 + + 1.2534374E-02 + + 1.2563508E-02 + + 1.3099926E-02 + + 1.3526120E-02 + + 1.3927022E-02 + + 1.4604411E-02 + + 1.5096848E-02 + + 1.5885767E-02 + + 1.6230507E-02 + + 1.7756050E-02 + + 1.8747181E-02 + + 2.2956423E-02 + + 2.6549953E-02 + + 3.1007445E-02 + + 3.5079178E-02 + + 3.9663485E-02 + + 4.4205438E-02 + + 4.8827182E-02 + + 5.3252335E-02 + + 5.8585422E-02 + + 6.2916830E-02 + + 6.9202743E-02 + + 7.3345048E-02 + + 7.8865458E-02 + + 8.8060504E-02 + + 8.7720181E-02 + + + + 6.5814203E-03 + + 1.2589556E-02 + + 1.2831098E-02 + + 1.2021990E-02 + + 1.2420962E-02 + + 1.2274328E-02 + + 1.3072229E-02 + + 1.3125790E-02 + + 1.3684984E-02 + + 1.4120320E-02 + + 1.4541810E-02 + + 1.5241834E-02 + + 1.5792664E-02 + + 1.6581300E-02 + + 1.6973815E-02 + + 1.8580511E-02 + + 1.9572617E-02 + + 2.3865583E-02 + + 2.7520381E-02 + + 3.2101383E-02 + + 3.6273771E-02 + + 4.0991031E-02 + + 4.5628107E-02 + + 5.0375712E-02 + + 5.4927552E-02 + + 6.0463390E-02 + + 6.4846891E-02 + + 7.1361573E-02 + + 7.5574981E-02 + + 8.1252683E-02 + + 9.0772914E-02 + + 9.0305344E-02 + + + + 6.5954047E-03 + + 1.2649872E-02 + + 1.2894758E-02 + + 1.2088299E-02 + + 1.2500706E-02 + + 1.2323868E-02 + + 1.3135140E-02 + + 1.3183877E-02 + + 1.3757540E-02 + + 1.4215358E-02 + + 1.4630076E-02 + + 1.5341576E-02 + + 1.5875377E-02 + + 1.6697400E-02 + + 1.7075964E-02 + + 1.8685615E-02 + + 1.9688554E-02 + + 2.3959638E-02 + + 2.7582865E-02 + + 3.2154359E-02 + + 3.6319478E-02 + + 4.0991674E-02 + + 4.5627244E-02 + + 5.0390376E-02 + + 5.4901681E-02 + + 6.0435636E-02 + + 6.4805706E-02 + + 7.1338882E-02 + + 7.5494665E-02 + + 8.1186566E-02 + + 9.0719563E-02 + + 9.0193680E-02 + + + + 6.5336047E-03 + + 1.2512090E-02 + + 1.2764479E-02 + + 1.1984145E-02 + + 1.2375802E-02 + + 1.2210337E-02 + + 1.3005945E-02 + + 1.3053548E-02 + + 1.3626485E-02 + + 1.4068961E-02 + + 1.4494598E-02 + + 1.5200428E-02 + + 1.5722617E-02 + + 1.6508783E-02 + + 1.6910525E-02 + + 1.8489314E-02 + + 1.9473998E-02 + + 2.3688731E-02 + + 2.7256893E-02 + + 3.1731269E-02 + + 3.5822276E-02 + + 4.0457390E-02 + + 4.5020879E-02 + + 4.9721896E-02 + + 5.4161674E-02 + + 5.9588663E-02 + + 6.3895979E-02 + + 7.0351683E-02 + + 7.4478980E-02 + + 8.0093110E-02 + + 8.9495166E-02 + + 8.8945256E-02 + + + + 6.4468824E-03 + + 1.2344191E-02 + + 1.2577769E-02 + + 1.1799198E-02 + + 1.2185250E-02 + + 1.2024671E-02 + + 1.2823561E-02 + + 1.2867050E-02 + + 1.3414223E-02 + + 1.3868383E-02 + + 1.4274902E-02 + + 1.4957665E-02 + + 1.5477639E-02 + + 1.6280478E-02 + + 1.6660201E-02 + + 1.8210099E-02 + + 1.9176459E-02 + + 2.3317865E-02 + + 2.6814611E-02 + + 3.1226187E-02 + + 3.5261695E-02 + + 3.9778054E-02 + + 4.4282066E-02 + + 4.8849080E-02 + + 5.3188035E-02 + + 5.8562223E-02 + + 6.2824222E-02 + + 6.9127893E-02 + + 7.3188187E-02 + + 7.8690046E-02 + + 8.7933862E-02 + + 8.7463314E-02 + + + + 6.3504172E-03 + + 1.2150642E-02 + + 1.2387727E-02 + + 1.1620660E-02 + + 1.2007755E-02 + + 1.1841239E-02 + + 1.2616226E-02 + + 1.2659354E-02 + + 1.3210608E-02 + + 1.3647237E-02 + + 1.4056090E-02 + + 1.4738601E-02 + + 1.5248667E-02 + + 1.6022604E-02 + + 1.6399027E-02 + + 1.7924821E-02 + + 1.8865800E-02 + + 2.2962104E-02 + + 2.6396869E-02 + + 3.0722714E-02 + + 3.4680261E-02 + + 3.9148700E-02 + + 4.3549586E-02 + + 4.8057389E-02 + + 5.2369847E-02 + + 5.7634643E-02 + + 6.1797568E-02 + + 6.8018235E-02 + + 7.1991375E-02 + + 7.7432633E-02 + + 8.6562066E-02 + + 8.6040544E-02 + + + + 6.2807225E-03 + + 1.2005102E-02 + + 1.2236833E-02 + + 1.1484849E-02 + + 1.1844265E-02 + + 1.1694745E-02 + + 1.2469442E-02 + + 1.2503258E-02 + + 1.3035750E-02 + + 1.3456731E-02 + + 1.3869786E-02 + + 1.4538788E-02 + + 1.5043345E-02 + + 1.5804904E-02 + + 1.6173155E-02 + + 1.7678967E-02 + + 1.8617817E-02 + + 2.2640680E-02 + + 2.6043512E-02 + + 3.0350793E-02 + + 3.4235767E-02 + + 3.8635112E-02 + + 4.3006209E-02 + + 4.7438737E-02 + + 5.1680206E-02 + + 5.6869882E-02 + + 6.0948428E-02 + + 6.7112720E-02 + + 7.1046470E-02 + + 7.6389984E-02 + + 8.5416908E-02 + + 8.4912400E-02 + + + + 6.2384011E-03 + + 1.1883626E-02 + + 1.2102819E-02 + + 1.1362792E-02 + + 1.1727085E-02 + + 1.1577991E-02 + + 1.2321572E-02 + + 1.2368887E-02 + + 1.2886627E-02 + + 1.3323476E-02 + + 1.3712662E-02 + + 1.4368905E-02 + + 1.4867001E-02 + + 1.5621404E-02 + + 1.6001770E-02 + + 1.7495457E-02 + + 1.8410484E-02 + + 2.2403739E-02 + + 2.5792442E-02 + + 3.0003874E-02 + + 3.3860219E-02 + + 3.8194472E-02 + + 4.2513447E-02 + + 4.6944801E-02 + + 5.1102508E-02 + + 5.6230364E-02 + + 6.0282905E-02 + + 6.6396185E-02 + + 7.0267237E-02 + + 7.5567209E-02 + + 8.4430462E-02 + + 8.3984117E-02 + + + + 6.1845926E-03 + + 1.1774745E-02 + + 1.2008907E-02 + + 1.1282463E-02 + + 1.1630642E-02 + + 1.1486008E-02 + + 1.2212483E-02 + + 1.2255192E-02 + + 1.2777462E-02 + + 1.3204562E-02 + + 1.3600398E-02 + + 1.4255316E-02 + + 1.4736561E-02 + + 1.5470029E-02 + + 1.5845176E-02 + + 1.7313807E-02 + + 1.8247178E-02 + + 2.2230316E-02 + + 2.5531152E-02 + + 2.9731972E-02 + + 3.3558284E-02 + + 3.7872884E-02 + + 4.2109048E-02 + + 4.6517240E-02 + + 5.0645413E-02 + + 5.5683251E-02 + + 5.9750465E-02 + + 6.5766931E-02 + + 6.9579667E-02 + + 7.4872290E-02 + + 8.3643239E-02 + + 8.3206968E-02 + + + + 6.1719734E-03 + + 1.1719545E-02 + + 1.1917909E-02 + + 1.1189341E-02 + + 1.1548606E-02 + + 1.1416064E-02 + + 1.2129643E-02 + + 1.2168083E-02 + + 1.2694983E-02 + + 1.3100793E-02 + + 1.3481593E-02 + + 1.4146417E-02 + + 1.4630389E-02 + + 1.5367839E-02 + + 1.5730917E-02 + + 1.7184516E-02 + + 1.8089440E-02 + + 2.2023196E-02 + + 2.5336832E-02 + + 2.9501303E-02 + + 3.3286048E-02 + + 3.7579302E-02 + + 4.1818920E-02 + + 4.6160226E-02 + + 5.0276169E-02 + + 5.5322377E-02 + + 5.9292479E-02 + + 6.5292838E-02 + + 6.9134443E-02 + + 7.4296625E-02 + + 8.3006295E-02 + + 8.2573545E-02 + + + + 6.1382782E-03 + + 1.1652027E-02 + + 1.1858603E-02 + + 1.1149474E-02 + + 1.1500153E-02 + + 1.1352538E-02 + + 1.2052433E-02 + + 1.2104328E-02 + + 1.2615826E-02 + + 1.3028027E-02 + + 1.3393814E-02 + + 1.4056119E-02 + + 1.4520800E-02 + + 1.5244525E-02 + + 1.5619872E-02 + + 1.7065448E-02 + + 1.7976677E-02 + + 2.1928655E-02 + + 2.5188600E-02 + + 2.9345474E-02 + + 3.3098490E-02 + + 3.7352890E-02 + + 4.1577882E-02 + + 4.5851588E-02 + + 4.9907550E-02 + + 5.5007580E-02 + + 5.8924848E-02 + + 6.4866195E-02 + + 6.8653679E-02 + + 7.3799695E-02 + + 8.2491620E-02 + + 8.2047228E-02 + + + + 6.1241006E-03 + + 1.1590726E-02 + + 1.1801215E-02 + + 1.1080585E-02 + + 1.1434054E-02 + + 1.1286311E-02 + + 1.2000496E-02 + + 1.2020032E-02 + + 1.2555074E-02 + + 1.2968561E-02 + + 1.3345040E-02 + + 1.3984260E-02 + + 1.4471501E-02 + + 1.5187071E-02 + + 1.5527587E-02 + + 1.6969733E-02 + + 1.7880430E-02 + + 2.1827072E-02 + + 2.5070882E-02 + + 2.9204178E-02 + + 3.2920367E-02 + + 3.7138445E-02 + + 4.1355200E-02 + + 4.5651496E-02 + + 4.9686415E-02 + + 5.4664866E-02 + + 5.8632525E-02 + + 6.4518086E-02 + + 6.8341097E-02 + + 7.3449748E-02 + + 8.2031901E-02 + + 8.1619798E-02 + + + + 6.1062727E-03 + + 1.1540200E-02 + + 1.1761046E-02 + + 1.1040109E-02 + + 1.1412932E-02 + + 1.1240736E-02 + + 1.1950046E-02 + + 1.1997678E-02 + + 1.2505989E-02 + + 1.2930265E-02 + + 1.3303213E-02 + + 1.3935054E-02 + + 1.4397122E-02 + + 1.5128867E-02 + + 1.5487202E-02 + + 1.6938379E-02 + + 1.7810772E-02 + + 2.1723430E-02 + + 2.4973244E-02 + + 2.9068452E-02 + + 3.2834028E-02 + + 3.7010997E-02 + + 4.1148015E-02 + + 4.5454526E-02 + + 4.9470264E-02 + + 5.4447102E-02 + + 5.8392796E-02 + + 6.4249338E-02 + + 6.8034422E-02 + + 7.3189468E-02 + + 8.1672467E-02 + + 8.1260364E-02 + + + + 6.0833777E-03 + + 1.1517436E-02 + + 1.1712978E-02 + + 1.1032819E-02 + + 1.1358893E-02 + + 1.1208870E-02 + + 1.1912352E-02 + + 1.1958737E-02 + + 1.2469851E-02 + + 1.2881147E-02 + + 1.3237414E-02 + + 1.3873203E-02 + + 1.4346868E-02 + + 1.5065060E-02 + + 1.5417558E-02 + + 1.6865782E-02 + + 1.7748238E-02 + + 2.1647065E-02 + + 2.4885779E-02 + + 2.8999390E-02 + + 3.2709869E-02 + + 3.6878634E-02 + + 4.1028900E-02 + + 4.5288735E-02 + + 4.9351482E-02 + + 5.4263443E-02 + + 5.8208019E-02 + + 6.4026596E-02 + + 6.7817431E-02 + + 7.2944166E-02 + + 8.1408951E-02 + + 8.0980011E-02 + + + + 6.0960595E-03 + + 1.1509277E-02 + + 1.1717750E-02 + + 1.1016084E-02 + + 1.1324287E-02 + + 1.1181299E-02 + + 1.1926512E-02 + + 1.1924795E-02 + + 1.2430825E-02 + + 1.2836520E-02 + + 1.3191644E-02 + + 1.3847845E-02 + + 1.4306693E-02 + + 1.5047376E-02 + + 1.5361189E-02 + + 1.6797970E-02 + + 1.7681035E-02 + + 2.1572902E-02 + + 2.4843981E-02 + + 2.8950004E-02 + + 3.2646669E-02 + + 3.6798605E-02 + + 4.0927881E-02 + + 4.5165770E-02 + + 4.9225435E-02 + + 5.4165928E-02 + + 5.8066998E-02 + + 6.3897046E-02 + + 6.7667188E-02 + + 7.2785603E-02 + + 8.1253392E-02 + + 8.0864443E-02 + + + + 6.0706294E-03 + + 1.1507691E-02 + + 1.1695334E-02 + + 1.0977998E-02 + + 1.1320263E-02 + + 1.1167309E-02 + + 1.1887145E-02 + + 1.1908635E-02 + + 1.2405259E-02 + + 1.2838152E-02 + + 1.3210507E-02 + + 1.3849960E-02 + + 1.4283591E-02 + + 1.5028182E-02 + + 1.5329706E-02 + + 1.6759635E-02 + + 1.7685388E-02 + + 2.1572849E-02 + + 2.4772494E-02 + + 2.8864133E-02 + + 3.2582677E-02 + + 3.6784719E-02 + + 4.0900801E-02 + + 4.5137865E-02 + + 4.9135372E-02 + + 5.4093178E-02 + + 5.8034149E-02 + + 6.3786244E-02 + + 6.7502120E-02 + + 7.2584553E-02 + + 8.1167082E-02 + + 8.0688398E-02 + + + + 6.0461907E-03 + + 1.1481547E-02 + + 1.1737058E-02 + + 1.0999643E-02 + + 1.1361089E-02 + + 1.1125441E-02 + + 1.1866202E-02 + + 1.1842566E-02 + + 1.2424994E-02 + + 1.2799184E-02 + + 1.3219862E-02 + + 1.3773742E-02 + + 1.4257782E-02 + + 1.4972557E-02 + + 1.5426839E-02 + + 1.6740630E-02 + + 1.7654390E-02 + + 2.1573482E-02 + + 2.4801577E-02 + + 2.8800263E-02 + + 3.2583876E-02 + + 3.6801622E-02 + + 4.0806074E-02 + + 4.5107401E-02 + + 4.9075545E-02 + + 5.3960225E-02 + + 5.7982974E-02 + + 6.3859228E-02 + + 6.7502946E-02 + + 7.2470281E-02 + + 8.1149466E-02 + + 8.0629616E-02 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + 1.0000000E+00 + + + + + \ No newline at end of file diff --git a/tests/c5g7_mgxs.xml b/tests/c5g7_mgxs.xml deleted file mode 100644 index ec85d4b593..0000000000 --- a/tests/c5g7_mgxs.xml +++ /dev/null @@ -1,383 +0,0 @@ - - - - 7 - - 1E-11 0.0635E-6 10.0E-6 1.0E-4 1.0E-3 0.5 1.0 20.0 - - - - - - UO2.71c - UO2.71c - 2.53E-8 - 0 - true - - isotropic - - - - 8.0248E-03 3.7174E-03 2.6769E-02 9.6236E-02 3.0020E-02 1.1126E-01 2.8278E-01 - - - - 2.005998E-02 2.027303E-03 1.570599E-02 4.518301E-02 4.334208E-02 2.020901E-01 5.257105E-01 - - - - 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 - - - 7.21206E-03 8.19301E-04 6.45320E-03 1.85648E-02 1.78084E-02 8.30348E-02 2.16004E-01 - - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 0.1275370 0.0423780 0.0000094 0.0000000 0.0000000 0.0000000 0.0000000 - 0.0000000 0.3244560 0.0016314 0.0000000 0.0000000 0.0000000 0.0000000 - 0.0000000 0.0000000 0.4509400 0.0026792 0.0000000 0.0000000 0.0000000 - 0.0000000 0.0000000 0.0000000 0.4525650 0.0055664 0.0000000 0.0000000 - 0.0000000 0.0000000 0.0000000 0.0001253 0.2714010 0.0102550 0.0000000 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0012968 0.2658020 0.0168090 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0085458 0.2730800 - - - - - 0.1779492 0.3298048 0.4803882 0.5543674000000001 0.3118013 0.39516779999999996 0.5644058 - - - - - - - MOX1.71c - MOX1.71c - 2.53E-8 - 0 - true - - - - 8.4339E-03 3.7577E-03 2.7970E-02 1.0421E-01 1.3994E-01 4.0918E-01 4.0935E-01 - - - - 1.27888062E-02 8.95701528E-03 7.37557218E-06 2.55837033E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.49041240E-03 1.04385401E-03 8.59552023E-07 2.98153464E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 9.56411400E-03 6.69850756E-03 5.51582469E-06 1.91327830E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.84928781E-02 2.69596154E-02 2.21996483E-05 7.70040890E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.80629998E-02 1.26509513E-02 1.04173100E-05 3.61346022E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.91930789E-01 2.74500216E-01 2.26034688E-04 7.84048241E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 4.19762096E-01 2.93992687E-01 2.42085585E-04 8.39724109E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 7.62704E-03 8.76898E-04 5.69835E-03 2.28872E-02 1.07635E-02 2.32757E-01 2.48968E-01 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.27537000E-01 4.23780000E-02 9.43740000E-06 5.51630000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.24456000E-01 1.63140000E-03 3.14270000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.50940000E-01 2.67920000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.52565000E-01 5.56640000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.25250000E-04 2.71401000E-01 1.02550000E-02 1.00210000E-08 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.29680000E-03 2.65802000E-01 1.68090000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.54580000E-03 2.73080000E-01 - - - - 0.1783583429163 0.3298451031427 0.4815892 0.5623414 0.421721260021 0.6930878 0.6909757999999999 - - - - - - - MOX2.71c - MOX2.71c - 2.53E-8 - 0 - true - - - - 0.0090657 0.0042967 0.032881 0.12203 0.18298 0.56846 0.58521 - - - - 1.40004593E-02 9.80563205E-03 8.07435789E-06 2.80075866E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.26856185E-03 1.58885378E-03 1.30832709E-06 4.53820413E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.41886199E-02 9.93741584E-03 8.18287404E-06 2.83839974E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 5.54788444E-02 3.88562347E-02 3.19958106E-05 1.10984111E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.69085702E-02 1.88462058E-02 1.55187355E-05 5.38299559E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 5.45687127E-01 3.82187973E-01 3.14709185E-04 1.09163414E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.13307712E-01 4.29548032E-01 3.53707392E-04 1.22690752E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 0.00825446 0.00132565 0.00842156 0.032873 0.0159636 0.323794 0.362803 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.30457000E-01 4.17920000E-02 8.51050000E-06 5.13290000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.28428000E-01 1.64360000E-03 2.20170000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.58371000E-01 2.53310000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.63709000E-01 5.47660000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.76190000E-04 2.82313000E-01 8.72890000E-03 9.00160000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.27600000E-03 2.49751000E-01 1.31140000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.86450000E-03 2.59529000E-01 - - - - 0.1813232156329 0.3343683022017 0.4937851 0.5912156 0.47419809900160004 0.833601 0.8536035 - - - - - - - MOX3.71c - MOX3.71c - 2.53E-8 - 0 - true - - - - 9.48620000E-03 4.65560000E-03 3.62400000E-02 1.32720000E-01 2.08400000E-01 6.58700000E-01 6.90170000E-01 - - - - 1.48071013E-02 1.03705874E-02 8.53956516E-06 2.96212546E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.78640474E-03 1.95154023E-03 1.60697792E-06 5.57413653E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.73304404E-02 1.21378819E-02 9.99482763E-06 3.46691346E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.59928975E-02 4.62200600E-02 3.80594850E-05 1.32017225E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.25131926E-02 2.27715674E-02 1.87510386E-05 6.50418701E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.32002662E-01 4.42641588E-01 3.64489161E-04 1.26430632E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 7.28595687E-01 5.10293344E-01 4.20196380E-04 1.45753838E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 8.67209000E-03 1.62426000E-03 1.02716000E-02 3.90447000E-02 1.92576000E-02 3.74888000E-01 4.30599000E-01 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.31504000E-01 4.20460000E-02 8.69720000E-06 5.19380000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.30403000E-01 1.64630000E-03 2.60060000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.61792000E-01 2.47490000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.68021000E-01 5.43300000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.85970000E-04 2.85771000E-01 8.39730000E-03 8.92800000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.39160000E-03 2.47614000E-01 1.23220000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.96810000E-03 2.56093000E-01 - - - - 1.83044902E-01 3.36704903E-01 5.00506900E-01 6.06174000E-01 5.02754279E-01 9.21027600E-01 9.55231100E-01 - - - - - - - FC.71c - FC.71c - 2.53E-8 - 0 - true - - - - 5.1132E-04 7.5813E-05 3.1643E-04 1.1675E-03 3.3977E-03 9.1886E-03 2.3244E-02 - - - - 1.323401E-08 1.434500E-08 1.128599E-06 1.276299E-05 3.538502E-07 1.740099E-06 5.063302E-06 - - - - 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 - - - - 4.79002E-09 5.82564E-09 4.63719E-07 5.24406E-06 1.45390E-07 7.14972E-07 2.08041E-06 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E00 0.00000000E00 - 0.00000000E00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 - 0.00000000E00 0.00000000E00 1.83425000E-01 9.22880000E-02 6.93650000E-03 1.07900000E-03 2.05430000E-04 - 0.00000000E00 0.00000000E00 0.00000000E00 7.90769000E-02 1.69990000E-01 2.58600000E-02 4.92560000E-03 - 0.00000000E00 0.00000000E00 0.00000000E00 3.73400000E-05 9.97570000E-02 2.06790000E-01 2.44780000E-02 - 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 9.17420000E-04 3.16774000E-01 2.38760000E-01 - 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 4.97930000E-02 1.09910000E00 - - - - 1.26032048E-01 2.93160367E-01 2.84250824E-01 2.81025244E-01 3.34460185E-01 5.65640735E-01 1.17213908E00 - - - - - - - GT.71c - GT.71c - 2.53E-8 - 0 - false - - - - 5.11320000E-04 7.58010000E-05 3.15720000E-04 1.15820000E-03 3.39750000E-03 9.18780000E-03 2.32420000E-02 - - - - - - 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 - 0.00000000E+00 0.00000000E+00 1.83297000E-01 9.23970000E-02 6.94460000E-03 1.08030000E-03 2.05670000E-04 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 7.88511000E-02 1.70140000E-01 2.58810000E-02 4.92970000E-03 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.73330000E-05 9.97372000E-02 2.06790000E-01 2.44780000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 9.17260000E-04 3.16765000E-01 2.38770000E-01 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.97920000E-02 1.09912000E+00 - - - - 1.26032043E-01 2.93160349E-01 2.84240290E-01 2.80960000E-01 3.34440033E-01 5.65640060E-01 1.17215400E+00 - - - - - - LWTR.71c - LWTR.71c - 2.53E-8 - 0 - false - - - - 6.0105E-04 1.5793E-05 3.3716E-04 1.9406E-03 5.7416E-03 1.5001E-02 3.7239E-02 - - - - - - 0.0444777 0.1134000 0.0007235 0.0000037 0.0000001 0.0000000 0.0000000 - 0.0000000 0.2823340 0.1299400 0.0006234 0.0000480 0.0000074 0.0000010 - 0.0000000 0.0000000 0.3452560 0.2245700 0.0169990 0.0026443 0.0005034 - 0.0000000 0.0000000 0.0000000 0.0910284 0.4155100 0.0637320 0.0121390 - 0.0000000 0.0000000 0.0000000 0.0000714 0.1391380 0.5118200 0.0612290 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0022157 0.6999130 0.5373200 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.1324400 2.4807000 - - - - 0.15920605 0.41296959299999997 0.59030986 0.5843499999999999 0.7180000000000001 1.2544497000000001 2.650379 - - - - - - - CR.71c - CR.71c - 2.53E-8 - 0 - false - - - - 1.70490000E-03 8.36224000E-03 8.37901000E-02 3.97797000E-01 6.98763000E-01 9.29508000E-01 1.17836000E+00 - - - - - - 1.70563000E-01 4.44012000E-02 9.83670000E-05 1.27786000E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 4.71050000E-01 6.85480000E-04 3.91395000E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 8.01859000E-01 7.20132000E-04 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 5.70752000E-01 1.46015000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 6.55562000E-05 2.07838000E-01 3.81486000E-03 3.69760000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.02427000E-03 2.02465000E-01 4.75290000E-03 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.53043000E-03 6.58597000E-01 - - - - 2.16767595E-01 4.80097720E-01 8.86369232E-01 9.70009150E-01 9.10481420E-01 1.13775017E+00 1.84048743E+00 - - - diff --git a/tests/input_set.py b/tests/input_set.py index 4e8974680e..c0bf2b0951 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -572,135 +572,60 @@ class InputSet(object): class MGInputSet(InputSet): def build_default_materials_and_geometry(self): - # Define materials needed for C5G7 2-D UO2 Assembly - uo2_data = openmc.Macroscopic('UO2', '71c') + # Define materials needed for 1D/1G slab problem + uo2_data = openmc.Macroscopic('uo2_iso', '71c') uo2 = openmc.Material(name='UO2', material_id=1) uo2.set_density('macro', 1.0) uo2.add_macroscopic(uo2_data) - fiss_cham_data = openmc.Macroscopic('FC', '71c') - fiss_cham = openmc.Material(name='FC', material_id=2) - fiss_cham.set_density('macro', 1.0) - fiss_cham.add_macroscopic(fiss_cham_data) + clad_data = openmc.Macroscopic('clad_ang_mu', '71c') + clad = openmc.Material(name='Clad', material_id=2) + clad.set_density('macro', 1.0) + clad.add_macroscopic(clad_data) - guide_tube_data = openmc.Macroscopic('GT', '71c') - guide_tube = openmc.Material(name='GT', material_id=3) - guide_tube.set_density('macro', 1.0) - guide_tube.add_macroscopic(guide_tube_data) - - water_data = openmc.Macroscopic('LWTR', '71c') - water = openmc.Material(name='LWTR', material_id=4) + water_data = openmc.Macroscopic('lwtr_iso_mu', '71c') + water = openmc.Material(name='LWTR', material_id=3) water.set_density('macro', 1.0) water.add_macroscopic(water_data) # Define the materials file. self.materials.default_xs = '71c' - self.materials.add_materials((uo2, fiss_cham, guide_tube, water)) + self.materials.add_materials((uo2, clad, water)) # Define surfaces. - # Pin cell - s1 = openmc.ZCylinder(R=0.54, surface_id=1) # Assembly/Problem Boundary - left = openmc.XPlane(x0=0.0, surface_id=20, + left = openmc.XPlane(x0=0.0, surface_id=200, boundary_type='reflective') - right = openmc.XPlane(x0=21.42, surface_id=21, + right = openmc.XPlane(x0=10.0, surface_id=201, boundary_type='reflective') - bottom = openmc.YPlane(y0=0.0, surface_id=22, + bottom = openmc.YPlane(y0=0.0, surface_id=300, boundary_type='reflective') - top = openmc.YPlane(y0=21.42, surface_id=23, - boundary_type='reflective') - down = openmc.ZPlane(z0=0.0, surface_id=24, - boundary_type='reflective') - up = openmc.ZPlane(z0=21.42, surface_id=25, + top = openmc.YPlane(y0=10.0, surface_id=301, boundary_type='reflective') - # Define pin cells - # uo2 pin - c10 = openmc.Cell(cell_id=10) - c10.region = -s1 - c10.fill = uo2 - c11 = openmc.Cell(cell_id=11) - c11.region = +s1 - c11.fill = water - fuel_pin = openmc.Universe(name='Fuel pin', universe_id=1) - fuel_pin.add_cells((c10, c11)) + down = openmc.ZPlane(z0=0.0, surface_id=0, + boundary_type='reflective') + fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) + clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) + up = openmc.ZPlane(z0=5.0, surface_id=3, + boundary_type='reflective') - # Fission chamber pin - c20 = openmc.Cell(cell_id=20) - c20.region = -s1 - c20.fill = fiss_cham - c21 = openmc.Cell(cell_id=21) - c21.region = +s1 - c21.fill = water - fiss_chamber_pin = openmc.Universe(name='Fission Chamber', universe_id=2) - fiss_chamber_pin.add_cells((c20, c21)) - - # Guide Tube pin - c30 = openmc.Cell(cell_id=30) - c30.region = -s1 - c30.fill = guide_tube - c31 = openmc.Cell(cell_id=31) - c31.region = +s1 - c31.fill = water - gt_pin = openmc.Universe(name='Guide Tube', universe_id=3) - gt_pin.add_cells((c30, c31)) - - # Define fuel lattice - l100 = openmc.RectLattice(name='UO2 assembly', lattice_id=100) - l100.dimension = (17, 17) - l100.lower_left = (-10.71, -10.71) - l100.pitch = (1.26, 1.26) - l100.universes = [ - [fuel_pin]*17, - [fuel_pin]*17, - [fuel_pin]*5 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*5, - [fuel_pin]*3 + [gt_pin] + [fuel_pin]*9 + [gt_pin] - + [fuel_pin]*3, - [fuel_pin]*17, - [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, - [fuel_pin]*17, - [fuel_pin]*17, - [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [fiss_chamber_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, - [fuel_pin]*17, - [fuel_pin]*17, - [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*2, - [fuel_pin]*17, - [fuel_pin]*3 + [gt_pin] + [fuel_pin]*9 + [gt_pin] - + [fuel_pin]*3, - [fuel_pin]*5 + [gt_pin] + [fuel_pin]*2 + [gt_pin] - + [fuel_pin]*2 + [gt_pin] + [fuel_pin]*5, - [fuel_pin]*17, - [fuel_pin]*17 ] - - # Define assemblies. - fa = openmc.Universe(name='Fuel assembly', universe_id=10) - c100 = openmc.Cell(cell_id=110) - c100.region = +down & -up - c100.fill = l100 - fa.add_cells((c100, )) - - # Define core lattices - l200 = openmc.RectLattice(name='Core lattice', lattice_id=200) - l200.dimension = (1, 1) - l200.lower_left = (0.0, 0.0) - l200.pitch = (21.42, 21.42) - l200.universes = [[fa]] + # Define cells + c1 = openmc.Cell(cell_id=1) + c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc + c1.fill = uo2 + c2 = openmc.Cell(cell_id=2) + c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc + c2.fill = clad + c3 = openmc.Cell(cell_id=3) + c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up + c3.fill = water # Define root universe. root = openmc.Universe(universe_id=0, name='root universe') - c1 = openmc.Cell(cell_id=1) - c1.region = +left & -right & +bottom & -top & +down & -up - c1.fill = l200 - root.add_cells((c1,)) + root.add_cells((c1,c2,c3)) # Define the geometry file. geometry = openmc.Geometry() @@ -713,15 +638,16 @@ class MGInputSet(InputSet): self.settings.batches = 10 self.settings.inactive = 5 self.settings.particles = 100 - self.settings.set_source_space('box', (0.0, 0.0, 0.0, 21.42, 21.42, 100.0)) + self.settings.set_source_space('box', (0.0, 0.0, 0.0, 10.0, 10.0, 2.0)) self.settings.energy_mode = "multi-group" - self.settings.cross_sections = "../c5g7_mgxs.xml" + self.settings.cross_sections = "../1d_mgxs.xml" def build_defualt_plots(self): plot = openmc.Plot() plot.filename = 'mat' - plot.origin = (10.71, 10.71, 50.0) - plot.width = (21.42, 21.42) + plot.origin = (5.0, 5.0, 2.5) + plot.width = (2.5, 2.5) + plot.basis = 'xz' plot.pixels = (3000, 3000) plot.color = 'mat' diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index d576cd402a..549172b1a9 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -b41c9621e2f068dab8f44b4fbf29aa5f075c04e463543550b7d1324b75b4709db810808e64474d2400c8c36465814bcca095650b0e19d640860dd4a860bb40a3 \ No newline at end of file +be47096ff6382e07c58c67870eb1c77402c961ee8cb9a4671b52627f6432fe282403e70f5825c90764758fcabe5a480653a961e24d7a0349929283848e79667d \ No newline at end of file diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 93683d28bb..35e2af7c06 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.359283E+00 7.465863E-02 +1.035488E+00 4.058903E-02 diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat new file mode 100644 index 0000000000..3529d50921 --- /dev/null +++ b/tests/test_mg_max_order/inputs_true.dat @@ -0,0 +1 @@ +7bd8b00b5aaad3913e0022269cf6ef92dfd0051bd79fb136838ea5a65d322d9711b454e62ef03dcf2b9dd75e31a4febcc633f968d7d07dcb6da2e0d36daf45db \ No newline at end of file diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat new file mode 100644 index 0000000000..dfb1c02d79 --- /dev/null +++ b/tests/test_mg_max_order/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +1.106635E+00 4.503267E-02 diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py new file mode 100644 index 0000000000..423f068f71 --- /dev/null +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import TestHarness, PyAPITestHarness +from input_set import MGInputSet +import openmc + +class MGNuclideInputSet(MGInputSet): + def build_default_materials_and_geometry(self): + # Define materials needed for 1D/1G slab problem + uo2_data = openmc.Macroscopic('uo2_iso', '71c') + uo2 = openmc.Material(name='UO2', material_id=1) + uo2.set_density('macro', 1.0) + uo2.add_macroscopic(uo2_data) + + clad_data = openmc.Macroscopic('clad_iso', '71c') + clad = openmc.Material(name='Clad', material_id=2) + clad.set_density('macro', 1.0) + clad.add_macroscopic(clad_data) + + water_data = openmc.Macroscopic('lwtr_iso', '71c') + water = openmc.Material(name='LWTR', material_id=3) + water.set_density('macro', 1.0) + water.add_macroscopic(water_data) + + # Define the materials file. + self.materials.default_xs = '71c' + self.materials.add_materials((uo2, clad, water)) + + # Define surfaces. + + # Assembly/Problem Boundary + left = openmc.XPlane(x0=0.0, surface_id=200, + boundary_type='reflective') + right = openmc.XPlane(x0=10.0, surface_id=201, + boundary_type='reflective') + bottom = openmc.YPlane(y0=0.0, surface_id=300, + boundary_type='reflective') + top = openmc.YPlane(y0=10.0, surface_id=301, + boundary_type='reflective') + + down = openmc.ZPlane(z0=0.0, surface_id=0, + boundary_type='reflective') + fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) + clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) + up = openmc.ZPlane(z0=5.0, surface_id=3, + boundary_type='reflective') + + # Define cells + c1 = openmc.Cell(cell_id=1) + c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc + c1.fill = uo2 + c2 = openmc.Cell(cell_id=2) + c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc + c2.fill = clad + c3 = openmc.Cell(cell_id=3) + c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up + c3.fill = water + + # Define root universe. + root = openmc.Universe(universe_id=0, name='root universe') + + root.add_cells((c1,c2,c3)) + + # Define the geometry file. + geometry = openmc.Geometry() + geometry.root_universe = root + + self.geometry.geometry = geometry + +class MGNuclideTestHarness(PyAPITestHarness): + def __init__(self, statepoint_name, tallies_present, mg=False): + TestHarness.__init__(self, statepoint_name, tallies_present) + self._input_set = MGNuclideInputSet() + + def _build_inputs(self): + super(MGNuclideTestHarness, self)._build_inputs() + # Set P1 scattering + self._input_set.settings.max_order = 1 + +if __name__ == '__main__': + harness = MGNuclideTestHarness('statepoint.10.*', False, mg=True) + harness.main() diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat new file mode 100644 index 0000000000..ea61b92221 --- /dev/null +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -0,0 +1 @@ +f3d614294177f34186bf0d439330d144438ac6a2402af9b5433efb7bf6a311043140c487c86f4d3cae9d51742f5042823d224c9da6365da6c8972b44edb7fb71 \ No newline at end of file diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat new file mode 100644 index 0000000000..26a41ade87 --- /dev/null +++ b/tests/test_mg_nuclide/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +1.271009E-01 6.377851E-03 diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py new file mode 100644 index 0000000000..736473bd9f --- /dev/null +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import TestHarness, PyAPITestHarness +from input_set import MGInputSet +import openmc + +class MGNuclideInputSet(MGInputSet): + def build_default_materials_and_geometry(self): + # Define materials needed for 1D/1G slab problem + # This time do using nuclide, not macroscopic + uo2 = openmc.Material(name='UO2', material_id=1) + uo2.set_density('g/cm3', 1.0) + uo2.add_nuclide("uo2_iso", 1.0) + + clad = openmc.Material(name='Clad', material_id=2) + clad.set_density('g/cm3', 1.0) + clad.add_nuclide("clad_ang_mu", 1.0) + + water_data = openmc.Nuclide('lwtr_iso_mu', '71c') + water = openmc.Material(name='LWTR', material_id=3) + water.set_density('g/cm3', 1.0) + water.add_nuclide("lwtr_iso_mu", 1.0) + + # Define the materials file. + self.materials.default_xs = '71c' + self.materials.add_materials((uo2, clad, water)) + + # Define surfaces. + + # Assembly/Problem Boundary + left = openmc.XPlane(x0=0.0, surface_id=200, + boundary_type='reflective') + right = openmc.XPlane(x0=10.0, surface_id=201, + boundary_type='reflective') + bottom = openmc.YPlane(y0=0.0, surface_id=300, + boundary_type='reflective') + top = openmc.YPlane(y0=10.0, surface_id=301, + boundary_type='reflective') + + down = openmc.ZPlane(z0=0.0, surface_id=0, + boundary_type='reflective') + fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) + clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) + up = openmc.ZPlane(z0=5.0, surface_id=3, + boundary_type='reflective') + + # Define cells + c1 = openmc.Cell(cell_id=1) + c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc + c1.fill = uo2 + c2 = openmc.Cell(cell_id=2) + c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc + c2.fill = clad + c3 = openmc.Cell(cell_id=3) + c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up + c3.fill = water + + # Define root universe. + root = openmc.Universe(universe_id=0, name='root universe') + + root.add_cells((c1,c2,c3)) + + # Define the geometry file. + geometry = openmc.Geometry() + geometry.root_universe = root + + self.geometry.geometry = geometry + +class MGNuclideTestHarness(PyAPITestHarness): + def __init__(self, statepoint_name, tallies_present, mg=False): + TestHarness.__init__(self, statepoint_name, tallies_present) + self._input_set = MGNuclideInputSet() + + def _build_inputs(self): + super(MGNuclideTestHarness, self)._build_inputs() + + + +if __name__ == '__main__': + harness = MGNuclideTestHarness('statepoint.10.*', False, mg=True) + harness.main() diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 44099dbd82..063b36923d 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -87d5adff4c8d53f020baa25db59d9ad6eada791ef010577e3586c543a9ee6cee6022d99e7a27911a94560acddba3602570c0748a0b4cba48f630b726221f14dc \ No newline at end of file +dcde495bd5d0ace409154be3529ae91d454e92f7060e38f00bc0880350d53c889b87edcfd481e6c8bcec2450bdf780e6fdc52240978eb1c67a6ef290ad85442d \ No newline at end of file diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index 920f5f3e36..4e27ab66b9 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,3482 +1,2906 @@ k-combined: -1.359283E+00 7.465863E-02 +1.035488E+00 4.058903E-02 tally 1: -2.847813E-01 -2.025790E-02 -1.172423E-02 -4.616814E-05 -6.871019E-01 -1.096320E-01 -5.348095E-03 -1.062108E-05 -1.340369E-02 -6.465987E-05 -1.682119E-01 -7.397131E-03 -9.038916E-03 -2.581353E-05 -4.138462E-01 -3.732581E-02 -4.267302E-03 -6.286845E-06 -1.058944E-02 -3.804411E-05 -3.633299E-01 -3.976542E-02 -2.487014E-02 -2.126766E-04 -6.982763E-01 -1.317345E-01 -1.257758E-02 -6.051328E-05 -3.075036E-02 -3.600723E-04 -2.492313E-01 -1.682228E-02 -1.380182E-02 -6.570494E-05 -5.765551E-01 -9.181006E-02 -7.743475E-03 -2.727482E-05 -1.902781E-02 -1.627120E-04 -2.191122E-01 -1.298025E-02 -1.148883E-02 -4.334141E-05 -5.203670E-01 -7.022054E-02 -5.000169E-03 -7.803760E-06 -1.236816E-02 -4.736991E-05 -2.269064E-01 -2.056966E-02 -1.410446E-02 -1.199602E-04 -4.515464E-01 -7.417552E-02 -7.887256E-03 -4.708793E-05 -1.932915E-02 -2.805214E-04 -2.364191E-01 -1.654063E-02 -1.415339E-02 -1.415624E-04 -4.940050E-01 -6.265173E-02 -6.299407E-03 -3.280872E-05 -1.540495E-02 -1.953911E-04 -3.192689E-01 -2.306298E-02 -1.230781E-02 -6.401926E-05 -6.470467E-01 -9.154956E-02 -5.234535E-03 -1.578586E-05 -1.286806E-02 -9.375617E-05 -2.540069E-01 -1.409067E-02 -7.206254E-03 -1.691929E-05 -6.264964E-01 -8.583680E-02 -1.958907E-03 -1.137122E-06 -4.944068E-03 -7.184508E-06 -3.299226E-01 -2.361991E-02 -1.153904E-02 -3.398774E-05 -7.350880E-01 -1.172602E-01 -4.976946E-03 -7.515943E-06 -1.226957E-02 -4.522435E-05 -2.734191E-01 -1.823188E-02 -1.314351E-02 -4.883110E-05 -5.162639E-01 -5.997683E-02 -5.567315E-03 -1.116578E-05 -1.355695E-02 -6.620192E-05 -1.971066E-01 -8.872106E-03 -7.289937E-03 -1.482506E-05 -3.624107E-01 -2.788172E-02 -3.946019E-03 -4.911976E-06 -9.796252E-03 -2.939620E-05 -2.435676E-01 -1.550957E-02 -1.471975E-02 -6.447073E-05 -3.711107E-01 -3.097190E-02 -8.485525E-03 -2.418503E-05 -2.074995E-02 -1.440717E-04 -2.427633E-01 -1.927418E-02 -1.659082E-02 -9.533795E-05 -3.947070E-01 -4.039320E-02 -8.721245E-03 -3.472785E-05 -2.129433E-02 -2.058398E-04 -2.930833E-01 -3.717078E-02 -1.961320E-02 -2.361042E-04 -5.029290E-01 -7.452592E-02 -1.162396E-02 -9.544883E-05 -2.835116E-02 -5.654990E-04 -3.612968E-01 -3.626192E-02 -2.275737E-02 -2.915981E-04 -6.836531E-01 -1.007739E-01 -1.386251E-02 -1.308722E-04 -3.381273E-02 -7.755475E-04 -3.379726E-01 -3.059811E-02 -1.034847E-02 -2.508685E-05 -7.876015E-01 -1.626433E-01 -4.304432E-03 -4.836158E-06 -1.080846E-02 -3.049489E-05 -2.207527E-01 -1.480236E-02 -9.133299E-03 -4.378685E-05 -5.306469E-01 -6.883187E-02 -3.832635E-03 -7.385540E-06 -9.542013E-03 -4.429238E-05 -1.746455E-01 -7.365091E-03 -6.210077E-03 -1.980262E-05 -4.018765E-01 -3.788658E-02 -3.022816E-03 -4.602873E-06 -7.491747E-03 -2.745170E-05 -2.568492E-01 -1.811320E-02 -1.821423E-02 -2.069737E-04 -4.656788E-01 -5.401259E-02 -1.232525E-02 -1.058384E-04 -3.013811E-02 -6.273405E-04 -2.225493E-01 -1.562018E-02 -1.010014E-02 -5.040357E-05 -4.589131E-01 -6.663804E-02 -5.258730E-03 -1.491454E-05 -1.298284E-02 -9.047317E-05 -2.447664E-01 -1.706786E-02 -1.478729E-02 -6.497711E-05 -5.983362E-01 -1.049331E-01 -6.596398E-03 -1.524559E-05 -1.633146E-02 -9.299953E-05 -2.413969E-01 -2.116589E-02 -2.021668E-02 -2.024522E-04 -3.619973E-01 -4.122998E-02 -1.346912E-02 -9.583517E-05 -3.286803E-02 -5.685240E-04 -2.049752E-01 -8.601175E-03 -1.025940E-02 -2.514980E-05 -4.043912E-01 -3.463281E-02 -4.452720E-03 -6.434910E-06 -1.096850E-02 -3.904161E-05 -3.102820E-01 -2.045820E-02 -1.459368E-02 -5.241789E-05 -6.773052E-01 -9.567203E-02 -7.341203E-03 -1.649958E-05 -1.800485E-02 -9.887491E-05 -2.550379E-01 -1.497142E-02 -1.091961E-02 -3.974930E-05 -5.647093E-01 -7.433920E-02 -5.249459E-03 -1.177345E-05 -1.284826E-02 -7.017030E-05 -3.556052E-01 -2.703280E-02 -2.735992E-02 -1.564623E-04 -6.683707E-01 -1.040515E-01 -1.590490E-02 -6.014424E-05 -3.877604E-02 -3.576128E-04 -2.497863E-01 -1.507086E-02 -1.494719E-02 -1.025755E-04 -4.762993E-01 -5.549879E-02 -8.527272E-03 -4.579896E-05 -2.085262E-02 -2.725955E-04 -1.839365E-01 -8.369442E-03 -1.237838E-02 -7.164219E-05 -3.775826E-01 -3.190193E-02 -7.884508E-03 -3.507069E-05 -1.929540E-02 -2.080904E-04 -1.708555E-01 -9.399504E-03 -7.715238E-03 -2.292805E-05 -3.732199E-01 -4.315843E-02 -3.978302E-03 -6.440288E-06 -9.770196E-03 -3.826434E-05 -3.241297E-01 -2.680732E-02 -2.827721E-02 -2.383010E-04 -5.925440E-01 -7.572445E-02 -1.805046E-02 -9.773692E-05 -4.409968E-02 -5.812383E-04 -2.602482E-01 -1.672576E-02 -7.932620E-03 -1.561951E-05 -5.580855E-01 -6.844216E-02 -2.088329E-03 -9.313432E-07 -5.186486E-03 -5.737715E-06 -2.890696E-01 -2.384728E-02 -1.015490E-02 -3.717081E-05 -6.111526E-01 -8.518321E-02 -4.213456E-03 -7.925859E-06 -1.037122E-02 -4.719897E-05 -3.855713E-01 -3.814941E-02 -1.595567E-02 -1.026684E-04 -8.322980E-01 -1.786719E-01 -6.646130E-03 -1.662975E-05 -1.674159E-02 -1.022582E-04 -1.897658E-01 -1.150551E-02 -8.071193E-03 -3.172610E-05 -4.219179E-01 -4.854116E-02 -3.808837E-03 -8.709924E-06 -9.434346E-03 -5.203901E-05 -2.195178E-01 -1.516218E-02 -7.926578E-03 -2.639446E-05 -5.306593E-01 -7.568838E-02 -2.106381E-03 -1.749456E-06 -5.313752E-03 -1.093384E-05 -3.256867E-01 -4.534052E-02 -2.131147E-02 -2.570637E-04 -5.297378E-01 -1.136688E-01 -1.158918E-02 -7.267385E-05 -2.831750E-02 -4.331969E-04 -1.414992E-01 -5.003890E-03 -4.258013E-03 -7.891903E-06 -3.615210E-01 -3.145749E-02 -1.093412E-03 -3.546225E-07 -2.758486E-03 -2.166206E-06 -1.514116E-01 -6.201312E-03 -4.857451E-03 -6.866877E-06 -3.984685E-01 -3.930815E-02 -2.038032E-03 -1.261346E-06 -5.152722E-03 -7.792008E-06 -3.159334E-01 -3.379738E-02 -2.905400E-03 -4.164258E-06 -5.469766E-01 -9.022824E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.132668E-01 -1.056200E-02 -9.631005E-03 -2.427206E-05 -4.566464E-01 -5.683176E-02 -4.166599E-03 -5.882400E-06 -1.031031E-02 -3.580708E-05 -2.912415E-01 -2.272338E-02 -1.775965E-02 -1.443229E-04 -4.943869E-01 -5.913494E-02 -1.104606E-02 -6.433295E-05 -2.697987E-02 -3.816975E-04 -2.570902E-01 -1.798689E-02 -2.361267E-03 -2.378626E-06 -4.065439E-01 -4.281600E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.949017E-01 -2.326343E-02 -1.187639E-02 -4.961037E-05 -6.020356E-01 -9.395273E-02 -6.276821E-03 -1.931834E-05 -1.538205E-02 -1.153434E-04 -2.558511E-01 -1.698459E-02 -1.575580E-02 -8.651862E-05 -5.875503E-01 -8.849521E-02 -7.883870E-03 -3.015633E-05 -1.949261E-02 -1.802377E-04 -1.839277E-01 -8.799415E-03 -9.390667E-04 -4.683772E-07 -4.384277E-01 -4.401825E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.609130E-01 -1.523879E-02 -1.198704E-02 -4.620730E-05 -6.275273E-01 -8.589709E-02 -6.342769E-03 -1.539049E-05 -1.563218E-02 -9.287339E-05 -2.481956E-01 -1.445135E-02 -7.512217E-03 -2.578216E-05 -5.254869E-01 -6.462207E-02 -4.109411E-03 -1.008346E-05 -1.011567E-02 -5.994042E-05 -2.029184E-01 -9.361823E-03 -5.088961E-03 -6.279329E-06 -4.979684E-01 -5.589905E-02 -1.833935E-03 -7.843470E-07 -4.590978E-03 -4.909945E-06 -2.259899E-01 -1.904652E-02 -1.437025E-02 -1.402125E-04 -5.175625E-01 -7.750371E-02 -8.659314E-03 -5.998348E-05 -2.125004E-02 -3.556838E-04 -2.491821E-01 -1.416884E-02 -1.505865E-02 -1.184227E-04 -6.046546E-01 -7.493539E-02 -9.648000E-03 -5.809858E-05 -2.378233E-02 -3.456642E-04 -2.380529E-01 -1.543764E-02 -1.826271E-02 -8.884450E-05 -4.803110E-01 -5.846859E-02 -8.805950E-03 -2.475992E-05 -2.159062E-02 -1.489502E-04 -2.026084E-01 -1.110441E-02 -8.160845E-03 -1.785658E-05 -4.437692E-01 -5.639028E-02 -3.565175E-03 -3.302071E-06 -8.864014E-03 -2.024481E-05 -2.224558E-01 -1.680211E-02 -1.555273E-02 -1.869799E-04 -4.173737E-01 -6.228541E-02 -9.135566E-03 -7.133316E-05 -2.241062E-02 -4.286070E-04 -2.004042E-01 -1.095639E-02 -1.437370E-03 -8.849524E-07 -4.174469E-01 -4.395281E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.755714E-01 -6.756269E-03 -8.983808E-03 -1.906916E-05 -4.261288E-01 -3.852168E-02 -3.247612E-03 -3.858076E-06 -8.028951E-03 -2.337512E-05 -2.223071E-01 -1.353146E-02 -1.705765E-02 -1.245386E-04 -5.197542E-01 -6.518812E-02 -9.805805E-03 -4.604085E-05 -2.405033E-02 -2.748160E-04 -1.948532E-01 -9.221640E-03 -1.164060E-02 -3.726891E-05 -4.394449E-01 -4.772119E-02 -5.615780E-03 -1.145305E-05 -1.379554E-02 -6.876959E-05 -1.729605E-01 -7.269018E-03 -7.081459E-03 -1.086510E-05 -3.596419E-01 -3.677088E-02 -2.576810E-03 -2.237622E-06 -6.357471E-03 -1.343160E-05 -2.686943E-01 -2.027464E-02 -1.549158E-02 -1.119369E-04 -4.683049E-01 -6.133136E-02 -8.958022E-03 -4.362320E-05 -2.185541E-02 -2.586495E-04 -2.805365E-01 -1.741332E-02 -1.350305E-02 -4.115261E-05 -6.438641E-01 -9.350345E-02 -5.285236E-03 -6.082302E-06 -1.295017E-02 -3.639939E-05 -2.572894E-01 -1.557396E-02 -9.152971E-03 -2.187378E-05 -5.397672E-01 -6.947168E-02 -3.989601E-03 -5.329696E-06 -9.816007E-03 -3.199508E-05 -1.844650E-01 -6.889035E-03 -9.054549E-03 -2.388416E-05 -4.959347E-01 -5.022290E-02 -6.016437E-03 -1.166505E-05 -1.483958E-02 -6.985694E-05 -2.448423E-01 -1.383982E-02 -1.979087E-02 -1.017532E-04 -5.292703E-01 -7.138674E-02 -1.203905E-02 -3.777525E-05 -2.948865E-02 -2.261060E-04 -3.678431E-01 -4.444197E-02 -3.828158E-03 -8.237670E-06 -5.902793E-01 -7.688814E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.935423E-01 -7.592536E-03 -6.894656E-03 -1.790118E-05 -4.320616E-01 -3.963147E-02 -2.212586E-03 -1.758405E-06 -5.535114E-03 -1.077459E-05 -2.000222E-01 -8.790536E-03 -6.130353E-03 -1.084913E-05 -5.241401E-01 -6.739015E-02 -2.660110E-03 -2.912115E-06 -6.629933E-03 -1.756202E-05 -2.006222E-01 -1.191794E-02 -3.681584E-03 -4.563880E-06 -4.694831E-01 -5.256578E-02 -1.424456E-03 -6.817103E-07 -3.630744E-03 -4.291288E-06 -1.427746E-01 -5.192636E-03 -1.037189E-02 -4.055885E-05 -3.029633E-01 -2.157045E-02 -4.326032E-03 -8.614945E-06 -1.057731E-02 -5.155246E-05 -1.646414E-01 -6.623537E-03 -5.439480E-03 -7.768447E-06 -4.145907E-01 -4.057023E-02 -1.461466E-03 -5.282344E-07 -3.707510E-03 -3.392769E-06 -1.648802E-01 -7.366519E-03 -1.070584E-02 -7.721854E-05 -3.742934E-01 -3.508076E-02 -6.499009E-03 -3.696865E-05 -1.592990E-02 -2.222355E-04 -2.180319E-01 -9.923859E-03 -7.969510E-03 -1.700099E-05 -5.221346E-01 -5.681643E-02 -3.896242E-03 -5.553555E-06 -9.611215E-03 -3.391405E-05 -2.292243E-01 -1.349466E-02 -1.175536E-02 -6.134192E-05 -5.588849E-01 -7.531263E-02 -5.067123E-03 -1.484964E-05 -1.251725E-02 -8.896195E-05 -3.324146E-01 -2.547046E-02 -2.018340E-02 -1.567704E-04 -7.652357E-01 -1.207356E-01 -1.178472E-02 -6.216943E-05 -2.903536E-02 -3.717118E-04 -2.285590E-01 -1.197525E-02 -6.912934E-03 -1.203784E-05 -4.578967E-01 -5.011634E-02 -2.559431E-03 -2.572737E-06 -6.387641E-03 -1.570623E-05 -1.930700E-01 -1.057009E-02 -6.872837E-03 -2.126589E-05 -3.910460E-01 -4.649162E-02 -3.546523E-03 -6.380991E-06 -8.655793E-03 -3.783828E-05 -3.934470E-01 -3.734695E-02 -2.227825E-02 -1.453115E-04 -6.775238E-01 -1.033120E-01 -1.338820E-02 -5.501040E-05 -3.274687E-02 -3.279809E-04 -3.088799E-01 -2.873704E-02 -1.749960E-02 -1.305258E-04 -5.601385E-01 -8.645103E-02 -1.038254E-02 -5.085454E-05 -2.542701E-02 -3.023135E-04 -3.700473E-01 -3.161307E-02 -2.646517E-02 -1.740940E-04 -6.414793E-01 -8.696363E-02 -1.500269E-02 -5.967096E-05 -3.661756E-02 -3.551291E-04 -3.565351E-01 -2.588617E-02 -2.829818E-02 -2.379254E-04 -6.754679E-01 -9.310347E-02 -1.785149E-02 -1.083839E-04 -4.359723E-02 -6.452495E-04 -2.956875E-01 -2.095277E-02 -1.344873E-02 -5.606169E-05 -5.669819E-01 -6.817515E-02 -7.251551E-03 -1.703252E-05 -1.777118E-02 -1.016817E-04 -2.506887E-01 -1.299858E-02 -1.588362E-02 -7.727995E-05 -4.753313E-01 -5.001149E-02 -1.000924E-02 -3.700899E-05 -2.445351E-02 -2.204775E-04 -2.126121E-01 -1.123409E-02 -1.190127E-02 -3.832263E-05 -3.707959E-01 -3.067361E-02 -5.030198E-03 -9.080178E-06 -1.230610E-02 -5.408354E-05 -2.764143E-01 -1.563717E-02 -1.790747E-02 -9.078882E-05 -5.678500E-01 -6.620735E-02 -1.046412E-02 -3.855578E-05 -2.561249E-02 -2.296019E-04 -2.902769E-01 -2.046134E-02 -1.234799E-02 -6.085833E-05 -6.155753E-01 -8.929554E-02 -6.140705E-03 -2.104623E-05 -1.517340E-02 -1.267427E-04 -2.178843E-01 -1.129871E-02 -6.208339E-03 -9.542966E-06 -5.034079E-01 -6.194116E-02 -2.128719E-03 -1.227568E-06 -5.264120E-03 -7.484188E-06 -2.125960E-01 -9.351344E-03 -6.822592E-03 -1.025641E-05 -4.869649E-01 -4.997451E-02 -2.293340E-03 -1.145791E-06 -5.665763E-03 -6.954001E-06 -2.709614E-01 -1.628033E-02 -1.293964E-03 -6.917833E-07 -6.177875E-01 -8.137663E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.314443E-01 -2.391247E-02 -1.873938E-02 -1.577380E-04 -6.121093E-01 -8.135846E-02 -1.073229E-02 -7.334175E-05 -2.617620E-02 -4.348152E-04 -3.166995E-01 -2.320865E-02 -2.036524E-02 -1.279210E-04 -6.658781E-01 -9.649554E-02 -9.461128E-03 -3.244725E-05 -2.313190E-02 -1.926149E-04 -3.297678E-01 -2.820763E-02 -1.923411E-03 -1.900405E-06 -8.093044E-01 -1.549168E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.456076E-01 -1.494726E-02 -1.107664E-02 -5.262577E-05 -4.808813E-01 -5.271759E-02 -5.560675E-03 -1.646259E-05 -1.363247E-02 -9.798701E-05 -2.427021E-01 -1.432013E-02 -1.238222E-02 -4.787991E-05 -4.944297E-01 -5.130649E-02 -6.815175E-03 -1.474275E-05 -1.672131E-02 -8.786745E-05 -3.752437E-01 -4.854811E-02 -3.614564E-03 -7.655432E-06 -6.782217E-01 -1.182298E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.647096E-01 -3.545521E-02 -1.786012E-02 -1.465595E-04 -6.852491E-01 -1.194618E-01 -8.922910E-03 -5.271906E-05 -2.195699E-02 -3.131230E-04 -3.739088E-01 -3.265037E-02 -2.215242E-02 -1.812199E-04 -7.104581E-01 -1.100949E-01 -1.112087E-02 -4.919605E-05 -2.716623E-02 -2.917209E-04 -3.646148E-01 -3.098153E-02 -3.468938E-03 -3.673617E-06 -6.439522E-01 -8.790186E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.988792E-01 -3.585276E-02 -1.769735E-02 -7.190181E-05 -7.203928E-01 -1.136161E-01 -8.994571E-03 -1.910703E-05 -2.195114E-02 -1.134487E-04 -2.180681E-01 -1.069385E-02 -1.207089E-02 -3.821459E-05 -4.543812E-01 -4.676007E-02 -5.078523E-03 -7.405974E-06 -1.242019E-02 -4.429054E-05 -3.387204E-01 -3.973516E-02 -3.338763E-03 -5.743416E-06 -6.143123E-01 -9.874284E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.573709E-01 -1.674382E-02 -1.789150E-02 -8.268291E-05 -4.926442E-01 -5.444271E-02 -1.080063E-02 -3.171383E-05 -2.644879E-02 -1.900877E-04 -3.675868E-01 -3.260765E-02 -3.091945E-02 -3.382288E-04 -6.630012E-01 -9.843066E-02 -1.886091E-02 -1.405418E-04 -4.605866E-02 -8.347384E-04 -2.393729E-01 -1.348727E-02 -9.089783E-03 -2.427644E-05 -5.291297E-01 -7.168179E-02 -4.297079E-03 -6.989668E-06 -1.057952E-02 -4.186885E-05 -3.231612E-01 -2.306799E-02 -1.049737E-02 -2.683860E-05 -6.962022E-01 -1.052928E-01 -3.906472E-03 -4.558902E-06 -9.688302E-03 -2.762523E-05 -3.081575E-01 -2.418407E-02 -1.147679E-02 -3.854959E-05 -6.947453E-01 -1.227514E-01 -5.492866E-03 -1.250383E-05 -1.366407E-02 -7.575691E-05 -3.601378E-01 -3.119766E-02 -1.856683E-02 -1.137752E-04 -6.790405E-01 -1.110025E-01 -1.005459E-02 -3.495544E-05 -2.461545E-02 -2.087020E-04 -3.505867E-01 -3.343394E-02 -1.851972E-02 -1.598653E-04 -6.695596E-01 -9.510495E-02 -1.018052E-02 -5.221675E-05 -2.496525E-02 -3.096426E-04 -3.832686E-01 -3.148793E-02 -1.999211E-02 -1.215996E-04 -7.990637E-01 -1.345049E-01 -1.016673E-02 -4.022763E-05 -2.487451E-02 -2.398045E-04 -3.238454E-01 -2.516992E-02 -1.603342E-02 -7.138171E-05 -6.930200E-01 -1.094620E-01 -9.610453E-03 -2.882518E-05 -2.367498E-02 -1.737604E-04 -2.433247E-01 -1.382228E-02 -1.026348E-02 -3.722424E-05 -6.058218E-01 -8.021503E-02 -5.222456E-03 -1.425419E-05 -1.293486E-02 -8.486641E-05 -3.405008E-01 -2.926643E-02 -1.702379E-02 -9.214884E-05 -6.732747E-01 -1.123595E-01 -7.705730E-03 -2.518557E-05 -1.891328E-02 -1.517838E-04 -2.619123E-01 -1.659685E-02 -6.964887E-03 -1.698405E-05 -5.916662E-01 -8.408950E-02 -2.958893E-03 -5.202669E-06 -7.307355E-03 -3.175251E-05 -5.917279E-01 -8.427634E-02 -3.884610E-02 -4.129413E-04 -1.054440E+00 -2.468893E-01 -2.320189E-02 -1.593770E-04 -5.690805E-02 -9.561233E-04 -4.377758E-01 -4.319166E-02 -2.986805E-02 -2.393363E-04 -8.248635E-01 -1.512547E-01 -1.372568E-02 -4.799401E-05 -3.349029E-02 -2.857467E-04 -3.421089E-01 -2.979789E-02 -2.249013E-02 -1.559001E-04 -6.850890E-01 -1.290414E-01 -1.160224E-02 -4.302043E-05 -2.846348E-02 -2.591994E-04 -3.722540E-01 -2.904052E-02 -2.335195E-02 -1.699377E-04 -6.863934E-01 -1.046451E-01 -1.439649E-02 -7.569328E-05 -3.524469E-02 -4.513332E-04 -3.015492E-01 -2.688128E-02 -2.018127E-02 -2.032826E-04 -6.714661E-01 -1.187385E-01 -1.212713E-02 -8.198620E-05 -2.973564E-02 -4.888576E-04 -2.528792E-01 -1.477470E-02 -1.121978E-02 -3.087195E-05 -6.406078E-01 -9.017936E-02 -5.885821E-03 -9.181268E-06 -1.457639E-02 -5.584147E-05 -2.038650E-01 -9.623965E-03 -1.310712E-02 -5.593573E-05 -4.908799E-01 -5.902527E-02 -6.946389E-03 -2.251232E-05 -1.702889E-02 -1.340271E-04 -1.139788E-01 -4.277809E-03 -4.614286E-03 -1.120138E-05 -2.704042E-01 -2.220192E-02 -1.076409E-03 -5.608463E-07 -2.705241E-03 -3.490247E-06 -2.370973E-01 -1.305565E-02 -7.409820E-03 -1.519920E-05 -5.419723E-01 -6.833854E-02 -3.405550E-03 -3.330468E-06 -8.520273E-03 -2.078583E-05 -2.382071E-01 -1.383356E-02 -9.254640E-03 -2.398783E-05 -6.083591E-01 -8.592760E-02 -4.554881E-03 -6.539019E-06 -1.130393E-02 -3.971676E-05 -2.799334E-01 -1.704488E-02 -1.745706E-02 -7.748191E-05 -5.327410E-01 -6.309686E-02 -8.374890E-03 -2.219332E-05 -2.046374E-02 -1.322507E-04 -3.299989E-01 -2.500153E-02 -1.662220E-02 -9.214247E-05 -5.777125E-01 -7.504937E-02 -9.185426E-03 -3.401334E-05 -2.245932E-02 -2.018294E-04 -2.480945E-01 -1.409562E-02 -1.027283E-02 -2.736596E-05 -5.305733E-01 -7.019314E-02 -4.898185E-03 -5.923984E-06 -1.209377E-02 -3.598246E-05 -2.435916E-01 -1.296299E-02 -1.168450E-02 -5.994065E-05 -5.303919E-01 -5.892047E-02 -6.394644E-03 -2.573114E-05 -1.573948E-02 -1.534027E-04 -3.382910E-01 -3.158552E-02 -1.585392E-02 -1.113895E-04 -6.399010E-01 -1.083590E-01 -6.841954E-03 -2.411006E-05 -1.678550E-02 -1.439749E-04 -3.981095E-01 -3.726016E-02 -2.142413E-02 -1.284486E-04 -7.603821E-01 -1.209106E-01 -1.046497E-02 -4.179315E-05 -2.573004E-02 -2.505335E-04 -3.874363E-01 -3.575389E-02 -2.107756E-02 -1.052519E-04 -8.211656E-01 -1.924162E-01 -1.256245E-02 -3.945660E-05 -3.082654E-02 -2.380887E-04 -4.456573E-01 -4.237155E-02 -2.596764E-02 -1.687922E-04 -8.729138E-01 -1.545134E-01 -1.510275E-02 -6.265801E-05 -3.696609E-02 -3.740070E-04 -3.992793E-01 -3.296068E-02 -2.048068E-02 -9.504244E-05 -8.331278E-01 -1.470933E-01 -1.127453E-02 -3.432997E-05 -2.760806E-02 -2.054207E-04 -3.886517E-01 -3.801441E-02 -2.253407E-02 -1.768474E-04 -7.039271E-01 -1.249249E-01 -1.248570E-02 -6.126807E-05 -3.052526E-02 -3.644213E-04 -3.138763E-01 -2.242983E-02 -2.691593E-02 -3.776077E-04 -6.449202E-01 -8.943446E-02 -1.834857E-02 -2.003405E-04 -4.483992E-02 -1.189482E-03 -3.304662E-01 -2.601947E-02 -1.705125E-02 -1.093125E-04 -7.576247E-01 -1.316185E-01 -8.728845E-03 -2.691230E-05 -2.149655E-02 -1.614671E-04 -3.542477E-01 -2.702674E-02 -2.469817E-02 -1.455831E-04 -7.115078E-01 -1.026190E-01 -1.552045E-02 -5.994661E-05 -3.791483E-02 -3.569299E-04 -2.614009E-01 -1.471316E-02 -9.277502E-03 -2.274093E-05 -5.564657E-01 -6.496526E-02 -3.380006E-03 -2.763922E-06 -8.448047E-03 -1.692336E-05 -4.068252E-01 -3.446693E-02 -2.245360E-02 -1.722882E-04 -7.532457E-01 -1.251856E-01 -1.415713E-02 -8.327501E-05 -3.483023E-02 -4.989609E-04 -3.836239E-01 -3.481679E-02 -2.946278E-02 -2.273732E-04 -6.795627E-01 -1.096060E-01 -1.842353E-02 -9.338437E-05 -4.498328E-02 -5.557198E-04 -2.678688E-01 -1.982541E-02 -1.936290E-03 -1.603437E-06 -5.664033E-01 -7.235502E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.540894E-01 -2.828987E-02 -1.435174E-02 -5.674926E-05 -6.973646E-01 -1.020010E-01 -6.832777E-03 -1.519381E-05 -1.682126E-02 -9.113421E-05 -3.455532E-01 -2.525192E-02 -2.020162E-02 -9.765516E-05 -7.040136E-01 -1.093402E-01 -1.088099E-02 -3.831955E-05 -2.661063E-02 -2.277881E-04 -2.776016E-01 -1.920243E-02 -2.052713E-03 -1.376197E-06 -6.585464E-01 -9.903277E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.091116E-01 -2.801257E-02 -2.024177E-02 -1.487498E-04 -6.138896E-01 -9.760701E-02 -1.262011E-02 -5.893128E-05 -3.079776E-02 -3.500582E-04 -4.487706E-01 -4.623185E-02 -4.373194E-02 -6.227096E-04 -8.118881E-01 -1.430088E-01 -2.909097E-02 -2.931199E-04 -7.090335E-02 -1.741024E-03 -4.974461E-01 -7.638705E-02 -5.262803E-03 -9.305275E-06 -8.298919E-01 -1.867351E-01 -4.223383E-07 -5.157240E-14 -1.028071E-06 -3.055838E-13 -3.906825E-01 -3.395073E-02 -2.733734E-02 -2.244620E-04 -7.121951E-01 -1.102604E-01 -1.681025E-02 -9.894122E-05 -4.107934E-02 -5.893557E-04 -2.885297E-01 -1.780804E-02 -1.916292E-02 -1.071634E-04 -6.439592E-01 -8.863510E-02 -1.116822E-02 -3.755311E-05 -2.741619E-02 -2.250014E-04 -3.733478E-01 -2.968457E-02 -2.417235E-03 -1.601471E-06 -8.160636E-01 -1.392543E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.807050E-01 -3.567435E-02 -1.639520E-02 -8.976183E-05 -8.352591E-01 -1.618917E-01 -7.549384E-03 -2.052873E-05 -1.868571E-02 -1.237926E-04 -4.113785E-01 -4.105596E-02 -2.760797E-02 -3.224706E-04 -8.312520E-01 -1.593787E-01 -1.755904E-02 -1.501020E-04 -4.309969E-02 -8.945939E-04 -4.264452E-01 -3.725052E-02 -2.761193E-03 -2.435650E-06 -9.907602E-01 -1.997766E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.190564E-01 -2.211691E-02 -2.297586E-02 -1.527095E-04 -6.146814E-01 -8.438195E-02 -1.406876E-02 -6.039729E-05 -3.440408E-02 -3.599638E-04 -3.441464E-01 -2.721527E-02 -2.208497E-02 -2.084304E-04 -6.754061E-01 -9.588273E-02 -1.249467E-02 -7.294249E-05 -3.053834E-02 -4.341021E-04 -4.902348E-01 -5.753291E-02 -4.141899E-02 -4.944456E-04 -8.677723E-01 -1.834890E-01 -2.563835E-02 -1.920950E-04 -6.257208E-02 -1.139519E-03 -3.219458E-01 -2.681583E-02 -1.509759E-02 -7.089200E-05 -7.411535E-01 -1.399501E-01 -7.267619E-03 -2.195119E-05 -1.781703E-02 -1.304167E-04 -3.460861E-01 -3.062496E-02 -2.305587E-02 -1.686535E-04 -7.279411E-01 -1.156782E-01 -1.567573E-02 -7.910023E-05 -3.843848E-02 -4.721498E-04 -3.706413E-01 -4.607848E-02 -2.101789E-02 -2.205947E-04 -6.385961E-01 -1.004148E-01 -1.096358E-02 -6.216344E-05 -2.682421E-02 -3.692258E-04 -4.326697E-01 -4.048321E-02 -2.321371E-02 -1.359451E-04 -8.057041E-01 -1.359077E-01 -1.178456E-02 -4.532462E-05 -2.882484E-02 -2.702988E-04 -3.700813E-01 -3.145900E-02 -1.629352E-02 -7.752174E-05 -7.168661E-01 -1.142671E-01 -8.563032E-03 -2.424964E-05 -2.094203E-02 -1.448273E-04 -4.171696E-01 -4.090198E-02 -1.942144E-02 -1.387048E-04 -7.827435E-01 -1.320064E-01 -1.123721E-02 -5.225505E-05 -2.747262E-02 -3.113824E-04 -3.936452E-01 -3.863175E-02 -1.864453E-02 -1.426388E-04 -7.621977E-01 -1.259923E-01 -1.114507E-02 -5.649068E-05 -2.735223E-02 -3.374133E-04 -4.146463E-01 -4.565600E-02 -2.051099E-02 -1.708674E-04 -8.092070E-01 -1.483485E-01 -1.068128E-02 -5.635889E-05 -2.623860E-02 -3.368690E-04 -3.502918E-01 -2.962552E-02 -2.245539E-02 -1.353853E-04 -6.798743E-01 -1.244576E-01 -1.299645E-02 -5.263601E-05 -3.188515E-02 -3.178466E-04 -3.664319E-01 -3.762644E-02 -1.543591E-02 -6.786902E-05 -7.257390E-01 -1.308037E-01 -7.920735E-03 -2.010753E-05 -1.954092E-02 -1.209187E-04 -2.881558E-01 -2.091566E-02 -1.253893E-02 -4.874752E-05 -6.867849E-01 -1.142347E-01 -6.304481E-03 -1.195351E-05 -1.563357E-02 -7.346975E-05 -4.226989E-01 -3.731519E-02 -1.464919E-02 -5.381568E-05 -9.709527E-01 -1.979486E-01 -5.624028E-03 -7.623772E-06 -1.400491E-02 -4.711591E-05 -4.177322E-01 -4.315006E-02 -1.820553E-02 -1.147713E-04 -8.897521E-01 -1.764672E-01 -8.738022E-03 -3.234864E-05 -2.155239E-02 -1.941292E-04 -4.092607E-01 -3.530369E-02 -2.094863E-02 -1.698700E-04 -9.371798E-01 -1.782535E-01 -1.252469E-02 -6.937532E-05 -3.076548E-02 -4.148830E-04 -3.694768E-01 -3.810772E-02 -1.842214E-02 -1.102654E-04 -7.440566E-01 -1.378317E-01 -1.077497E-02 -3.938422E-05 -2.649591E-02 -2.371539E-04 -3.561758E-01 -3.892218E-02 -1.971769E-02 -1.829864E-04 -7.613019E-01 -1.474240E-01 -1.192622E-02 -7.156692E-05 -2.936758E-02 -4.300051E-04 -2.527416E-01 -1.830741E-02 -1.645432E-02 -1.267160E-04 -5.925996E-01 -9.467855E-02 -8.871453E-03 -5.348101E-05 -2.184328E-02 -3.189633E-04 -3.300644E-01 -2.928166E-02 -1.882410E-02 -1.436109E-04 -7.237383E-01 -1.333008E-01 -9.519880E-03 -4.704072E-05 -2.342545E-02 -2.806433E-04 -3.764914E-01 -3.641557E-02 -1.821370E-02 -1.541319E-04 -7.651976E-01 -1.295027E-01 -1.036579E-02 -6.438503E-05 -2.552774E-02 -3.859463E-04 -2.999858E-01 -2.596841E-02 -2.166579E-02 -2.610355E-04 -6.375460E-01 -1.048518E-01 -1.456288E-02 -1.290713E-04 -3.563700E-02 -7.694303E-04 -4.842591E-01 -6.171881E-02 -2.321959E-02 -1.668178E-04 -8.833362E-01 -1.695389E-01 -1.327201E-02 -5.801276E-05 -3.246066E-02 -3.448393E-04 -5.214507E-01 -7.645410E-02 -2.106712E-02 -1.794528E-04 -8.149268E-01 -1.497643E-01 -1.099539E-02 -6.388195E-05 -2.693654E-02 -3.799114E-04 -4.660026E-01 -5.353148E-02 -2.651479E-02 -2.310878E-04 -8.389665E-01 -1.518968E-01 -1.651906E-02 -9.356467E-05 -4.039371E-02 -5.572969E-04 -5.848474E-01 -9.288276E-02 -4.985330E-02 -1.127634E-03 -1.055201E+00 -2.709678E-01 -3.348026E-02 -5.556505E-04 -8.197497E-02 -3.315235E-03 -4.139721E-01 -3.782370E-02 -1.933292E-02 -1.125655E-04 -9.059089E-01 -1.795184E-01 -9.265770E-03 -3.682450E-05 -2.278990E-02 -2.207751E-04 -3.882528E-01 -4.110026E-02 -1.561145E-02 -6.509900E-05 -6.762051E-01 -9.661914E-02 -7.561172E-03 -1.586464E-05 -1.861326E-02 -9.601481E-05 -3.055549E-01 -2.290439E-02 -1.869038E-02 -1.012810E-04 -6.519604E-01 -9.557502E-02 -1.045342E-02 -3.401674E-05 -2.561909E-02 -2.031141E-04 -3.784039E-01 -3.540818E-02 -1.144663E-02 -3.747954E-05 -7.982030E-01 -1.492246E-01 -3.743861E-03 -3.826041E-06 -9.336060E-03 -2.375886E-05 -3.893167E-01 -3.224146E-02 -1.465378E-02 -5.640030E-05 -8.519576E-01 -1.546319E-01 -7.851346E-03 -2.140423E-05 -1.941671E-02 -1.297116E-04 -4.628352E-01 -4.648532E-02 -3.104209E-02 -2.927221E-04 -9.424350E-01 -1.848692E-01 -1.805340E-02 -1.259139E-04 -4.411679E-02 -7.489332E-04 -5.036437E-01 -6.329907E-02 -3.701287E-02 -4.293191E-04 -9.845647E-01 -2.302864E-01 -2.189511E-02 -1.860705E-04 -5.357155E-02 -1.113432E-03 -3.651286E-01 -3.372208E-02 -1.898638E-02 -1.788233E-04 -7.283966E-01 -1.166080E-01 -1.159586E-02 -7.325796E-05 -2.849437E-02 -4.369152E-04 -3.712514E-01 -3.312825E-02 -2.124449E-02 -1.626400E-04 -7.116233E-01 -1.089685E-01 -1.329424E-02 -6.857983E-05 -3.257383E-02 -4.067854E-04 -2.729718E-01 -2.308771E-02 -5.130628E-03 -8.219165E-06 -7.257857E-01 -1.711422E-01 -1.662698E-03 -9.477833E-07 -4.314077E-03 -6.608852E-06 -2.780491E-01 -2.511642E-02 -1.327468E-02 -1.125406E-04 -5.815634E-01 -9.937798E-02 -6.802535E-03 -3.433855E-05 -1.678587E-02 -2.048151E-04 -4.836173E-01 -6.301714E-02 -5.126877E-03 -7.676969E-06 -7.235761E-01 -1.309488E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.031875E-01 -4.115015E-02 -2.401570E-02 -1.884922E-04 -7.226240E-01 -1.246862E-01 -1.365997E-02 -6.483039E-05 -3.348484E-02 -3.878250E-04 -3.969397E-01 -3.388912E-02 -1.954568E-02 -1.484093E-04 -8.502161E-01 -1.499123E-01 -1.000927E-02 -5.813943E-05 -2.452378E-02 -3.457355E-04 -5.393064E-01 -7.598949E-02 -4.596848E-03 -8.271188E-06 -9.233647E-01 -1.837028E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.305005E-01 -3.980527E-02 -3.622333E-02 -2.714888E-04 -7.562019E-01 -1.251870E-01 -2.210501E-02 -1.044787E-04 -5.402135E-02 -6.242016E-04 -4.150253E-01 -4.310022E-02 -3.055341E-02 -3.204376E-04 -8.383810E-01 -1.598344E-01 -1.799260E-02 -1.186722E-04 -4.421143E-02 -7.098098E-04 -5.053663E-01 -6.741744E-02 -4.302548E-03 -5.486457E-06 -1.001508E+00 -2.499069E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -5.305404E-01 -9.168988E-02 -4.204388E-02 -6.233654E-04 -1.019287E+00 -2.883833E-01 -2.692540E-02 -2.702944E-04 -6.578499E-02 -1.604933E-03 -2.979429E-01 -2.557053E-02 -1.270971E-02 -6.086980E-05 -6.133144E-01 -9.302940E-02 -6.554631E-03 -2.408980E-05 -1.614693E-02 -1.437968E-04 -2.985643E-01 -2.168009E-02 -1.675518E-03 -6.853400E-07 -6.603013E-01 -1.039248E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.978111E-01 -3.476147E-02 -2.583972E-02 -1.494411E-04 -8.471730E-01 -1.545734E-01 -1.585722E-02 -6.154411E-05 -3.885738E-02 -3.693284E-04 -5.202672E-01 -6.063991E-02 -2.696218E-02 -2.266432E-04 -1.106648E+00 -2.681959E-01 -1.522211E-02 -8.625903E-05 -3.740299E-02 -5.175445E-04 -4.764994E-01 -7.395612E-02 -4.506348E-03 -1.035606E-05 -9.157662E-01 -2.118046E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.132742E-01 -4.146437E-02 -3.375089E-02 -4.225536E-04 -7.921867E-01 -1.381808E-01 -2.045881E-02 -1.753311E-04 -5.005367E-02 -1.042462E-03 -2.661077E-01 -1.751445E-02 -1.121639E-02 -3.636881E-05 -5.712386E-01 -7.771405E-02 -6.533439E-03 -1.250013E-05 -1.610362E-02 -7.471829E-05 -3.425750E-01 -3.408776E-02 -1.156146E-02 -5.411528E-05 -8.276841E-01 -1.940431E-01 -6.001009E-03 -2.103242E-05 -1.484593E-02 -1.276999E-04 -3.790958E-01 -5.528325E-02 -2.035138E-02 -2.087186E-04 -7.464973E-01 -1.698540E-01 -1.056382E-02 -7.655648E-05 -2.594266E-02 -4.578317E-04 -4.673249E-01 -5.113730E-02 -2.751426E-02 -1.816642E-04 -8.149126E-01 -1.677855E-01 -1.476997E-02 -5.736790E-05 -3.624040E-02 -3.439634E-04 -4.969678E-01 -6.703663E-02 -3.324010E-02 -4.839680E-04 -7.957816E-01 -1.402618E-01 -1.787791E-02 -1.889011E-04 -4.366390E-02 -1.122265E-03 -3.987041E-01 -3.319083E-02 -1.717610E-02 -7.614560E-05 -8.405362E-01 -1.455051E-01 -9.116726E-03 -2.731734E-05 -2.243998E-02 -1.635133E-04 -3.557016E-01 -2.733014E-02 -1.946614E-02 -9.722258E-05 -8.042289E-01 -1.325000E-01 -1.081675E-02 -3.317997E-05 -2.660183E-02 -1.988697E-04 -4.238750E-01 -5.071137E-02 -3.860553E-02 -4.907754E-04 -6.818241E-01 -1.059015E-01 -2.594551E-02 -2.253483E-04 -6.329673E-02 -1.337276E-03 -4.845466E-01 -4.739927E-02 -3.781105E-02 -3.188017E-04 -8.754691E-01 -1.592141E-01 -2.256002E-02 -1.269857E-04 -5.521664E-02 -7.580381E-04 -4.762135E-01 -5.411538E-02 -2.732678E-02 -2.310254E-04 -7.810833E-01 -1.311139E-01 -1.597068E-02 -8.360266E-05 -3.898613E-02 -4.967345E-04 -4.626499E-01 -6.385872E-02 -2.294200E-02 -1.768315E-04 -9.372052E-01 -2.270799E-01 -1.299342E-02 -6.187834E-05 -3.189449E-02 -3.716202E-04 -3.261518E-01 -3.233233E-02 -1.344996E-02 -7.296974E-05 -6.438319E-01 -1.139836E-01 -6.902941E-03 -2.347639E-05 -1.691710E-02 -1.400440E-04 -4.352336E-01 -5.775668E-02 -2.123686E-02 -1.661853E-04 -8.342632E-01 -1.707879E-01 -1.088157E-02 -4.787467E-05 -2.666381E-02 -2.851629E-04 -4.309663E-01 -3.819583E-02 -2.280285E-02 -1.438300E-04 -8.522076E-01 -1.478770E-01 -1.272222E-02 -4.969054E-05 -3.123456E-02 -2.971660E-04 -3.545417E-01 -3.176670E-02 -2.104462E-02 -1.973843E-04 -6.924468E-01 -1.084661E-01 -1.359515E-02 -9.318781E-05 -3.323698E-02 -5.537381E-04 -2.601793E-01 -1.854037E-02 -7.292982E-03 -2.119725E-05 -5.911869E-01 -8.786472E-02 -3.411247E-03 -4.494329E-06 -8.395279E-03 -2.694816E-05 -2.856586E-01 -1.974948E-02 -1.054334E-02 -2.769649E-05 -6.966115E-01 -1.097272E-01 -4.020408E-03 -5.909802E-06 -1.002274E-02 -3.621226E-05 -2.990262E-01 -2.895771E-02 -1.524669E-02 -1.075200E-04 -5.511247E-01 -7.221915E-02 -7.850283E-03 -4.154474E-05 -1.921607E-02 -2.483852E-04 -2.734313E-01 -2.247782E-02 -1.398383E-02 -1.162049E-04 -6.576619E-01 -1.210529E-01 -8.907424E-03 -5.814670E-05 -2.190592E-02 -3.497392E-04 -2.815363E-01 -1.901069E-02 -1.186929E-02 -3.364035E-05 -6.515902E-01 -9.851410E-02 -6.886950E-03 -1.323736E-05 -1.695569E-02 -7.940407E-05 -3.484143E-01 -2.809808E-02 -2.158706E-02 -1.746308E-04 -6.459834E-01 -9.326184E-02 -1.339059E-02 -7.862843E-05 -3.279132E-02 -4.674908E-04 -4.872293E-01 -6.299198E-02 -4.535678E-03 -8.886458E-06 -7.995378E-01 -1.391013E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.517270E-01 -4.298933E-02 -2.983900E-02 -2.534533E-04 -9.003348E-01 -1.639649E-01 -1.797753E-02 -1.058508E-04 -4.408492E-02 -6.323324E-04 -3.840449E-01 -3.048942E-02 -2.304747E-02 -1.451405E-04 -7.696800E-01 -1.200152E-01 -1.291566E-02 -4.856104E-05 -3.169233E-02 -2.900548E-04 -3.899986E-01 -4.842017E-02 -3.398750E-02 -5.012913E-04 -7.289300E-01 -1.213432E-01 -2.225136E-02 -2.225919E-04 -5.443442E-02 -1.322013E-03 -5.598647E-01 -7.209791E-02 -3.636258E-02 -2.972603E-04 -9.425990E-01 -1.980189E-01 -2.180409E-02 -1.030147E-04 -5.325326E-02 -6.135525E-04 -5.137462E-01 -5.449795E-02 -2.968013E-02 -2.213205E-04 -1.089121E+00 -2.416550E-01 -1.633665E-02 -8.162297E-05 -4.019388E-02 -4.875490E-04 -4.289801E-01 -4.093477E-02 -2.010221E-02 -9.125869E-05 -8.441503E-01 -1.577640E-01 -1.121134E-02 -3.076206E-05 -2.749358E-02 -1.837347E-04 -4.669049E-01 -4.985409E-02 -3.155885E-02 -2.843354E-04 -8.541836E-01 -1.586915E-01 -1.971407E-02 -1.199500E-04 -4.819514E-02 -7.142000E-04 -5.476118E-01 -7.964842E-02 -3.671613E-02 -5.048684E-04 -9.819505E-01 -2.224104E-01 -2.057791E-02 -1.723983E-04 -5.020646E-02 -1.023284E-03 -3.570430E-01 -3.236156E-02 -2.642812E-02 -2.499237E-04 -6.566192E-01 -1.028336E-01 -1.658528E-02 -1.090997E-04 -4.052667E-02 -6.501756E-04 -3.157944E-01 -2.754029E-02 -2.510614E-03 -2.597981E-06 -6.619048E-01 -1.052488E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.796550E-01 -1.863344E-02 -1.041219E-02 -5.191551E-05 -6.609168E-01 -1.042598E-01 -6.108228E-03 -2.425637E-05 -1.502705E-02 -1.442032E-04 -2.179231E-01 -1.148681E-02 -1.158771E-02 -5.115165E-05 -5.338009E-01 -6.387573E-02 -6.955519E-03 -2.069739E-05 -1.714723E-02 -1.242632E-04 -2.723379E-01 -1.612703E-02 -1.661668E-02 -8.393477E-05 -6.115831E-01 -7.762931E-02 -8.158618E-03 -2.912656E-05 -2.012066E-02 -1.734434E-04 -4.177079E-01 -5.021689E-02 -1.465133E-02 -8.170592E-05 -8.821701E-01 -2.073297E-01 -5.279873E-03 -1.131685E-05 -1.297780E-02 -6.813348E-05 -4.389866E-01 -5.718767E-02 -2.509233E-02 -2.986289E-04 -8.525743E-01 -1.748816E-01 -1.369565E-02 -1.018308E-04 -3.355369E-02 -6.079070E-04 -4.137349E-01 -4.314157E-02 -2.371796E-02 -2.559421E-04 -7.149288E-01 -1.144426E-01 -1.335685E-02 -1.050731E-04 -3.269465E-02 -6.277716E-04 -6.493181E-01 -8.850590E-02 -4.003436E-02 -4.029382E-04 -1.240508E+00 -3.254748E-01 -2.412272E-02 -1.510168E-04 -5.916870E-02 -9.052554E-04 -4.999253E-01 -5.822974E-02 -2.648913E-02 -2.036552E-04 -8.603421E-01 -1.542102E-01 -1.503446E-02 -7.780397E-05 -3.680872E-02 -4.627887E-04 -2.140322E-01 -1.009989E-02 -9.821979E-04 -2.888126E-07 -5.412641E-01 -6.614023E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.473664E-01 -1.445695E-02 -1.115793E-02 -4.639483E-05 -6.402572E-01 -1.087519E-01 -6.977317E-03 -2.012165E-05 -1.726283E-02 -1.209389E-04 -4.106842E-01 -4.252374E-02 -2.865498E-02 -2.625513E-04 -6.937372E-01 -1.072413E-01 -1.818386E-02 -1.104345E-04 -4.446846E-02 -6.595035E-04 -4.211497E-01 -4.077958E-02 -2.971575E-03 -2.487030E-06 -8.520797E-01 -1.481605E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -5.226188E-01 -5.944362E-02 -2.960968E-02 -2.245340E-04 -9.222348E-01 -1.736139E-01 -1.631529E-02 -7.908945E-05 -3.982616E-02 -4.708490E-04 -4.418421E-01 -4.437957E-02 -2.517739E-02 -1.907600E-04 -7.787605E-01 -1.249305E-01 -1.536054E-02 -7.917968E-05 -3.755245E-02 -4.723672E-04 -4.343976E-01 -4.457981E-02 -3.388911E-03 -3.822692E-06 -8.737430E-01 -1.764940E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.598455E-01 -2.729560E-02 -2.418740E-02 -2.378985E-04 -7.302175E-01 -1.135251E-01 -1.616906E-02 -1.246680E-04 -3.949063E-02 -7.402107E-04 -2.619461E-01 -1.513254E-02 -8.926754E-03 -1.978809E-05 -6.435721E-01 -9.157538E-02 -4.651147E-03 -7.139204E-06 -1.149560E-02 -4.303315E-05 -3.477772E-01 -3.056585E-02 -1.223437E-02 -5.499474E-05 -7.995504E-01 -1.386715E-01 -6.975627E-03 -1.888125E-05 -1.734787E-02 -1.146221E-04 -3.619349E-01 -3.702197E-02 -1.807440E-02 -1.270513E-04 -7.778669E-01 -1.474144E-01 -1.099124E-02 -4.917455E-05 -2.701829E-02 -2.940738E-04 -3.162191E-01 -2.268893E-02 -1.158071E-02 -3.480324E-05 -7.692808E-01 -1.327980E-01 -4.095665E-03 -5.158750E-06 -1.022758E-02 -3.212100E-05 -5.342532E-01 -8.478330E-02 -2.903573E-02 -3.357498E-04 -1.120085E+00 -3.408745E-01 -1.690122E-02 -1.279478E-04 -4.141172E-02 -7.637947E-04 -4.496065E-01 -6.505133E-02 -2.635557E-02 -3.323123E-04 -9.612470E-01 -2.510212E-01 -1.538003E-02 -1.327695E-04 -3.782149E-02 -7.945656E-04 -4.847046E-01 -5.967696E-02 -2.535687E-02 -2.173087E-04 -1.077043E+00 -2.811943E-01 -1.097101E-02 -3.799483E-05 -2.709062E-02 -2.304602E-04 -5.175767E-01 -5.719466E-02 -1.973241E-02 -8.575798E-05 -9.679612E-01 -2.056860E-01 -8.303999E-03 -1.805765E-05 -2.040361E-02 -1.089188E-04 -5.517001E-01 -6.994072E-02 -2.497158E-02 -1.771114E-04 -1.098639E+00 -2.726418E-01 -1.399598E-02 -6.099098E-05 -3.430186E-02 -3.665835E-04 -2.863207E-01 -1.857525E-02 -8.336069E-03 -1.649811E-05 -6.476326E-01 -9.010693E-02 -3.429198E-03 -3.106979E-06 -8.565244E-03 -1.898164E-05 -2.620263E-01 -1.413830E-02 -1.486260E-02 -6.016669E-05 -5.979318E-01 -7.637631E-02 -7.005392E-03 -1.590920E-05 -1.730862E-02 -9.593066E-05 -3.655323E-01 -3.067786E-02 -2.564543E-02 -2.165772E-04 -7.572344E-01 -1.217887E-01 -1.473507E-02 -8.140802E-05 -3.619562E-02 -4.852029E-04 -3.419278E-01 -2.642670E-02 -2.272345E-02 -1.520173E-04 -6.406916E-01 -8.632502E-02 -1.398347E-02 -6.589014E-05 -3.414144E-02 -3.923320E-04 -4.462443E-01 -4.882939E-02 -3.221856E-02 -4.381937E-04 -7.714529E-01 -1.298248E-01 -2.030822E-02 -2.050592E-04 -4.959466E-02 -1.221874E-03 -4.241623E-01 -4.238067E-02 -3.017189E-02 -3.192439E-04 -8.184443E-01 -1.472953E-01 -1.653484E-02 -9.828819E-05 -4.040308E-02 -5.837728E-04 -5.468649E-01 -6.932849E-02 -3.506986E-02 -3.414126E-04 -9.081801E-01 -1.955422E-01 -2.067323E-02 -1.252268E-04 -5.051840E-02 -7.466097E-04 -4.049238E-01 -3.619626E-02 -1.820878E-02 -8.370629E-05 -7.947251E-01 -1.471574E-01 -6.827689E-03 -1.877378E-05 -1.682488E-02 -1.119968E-04 -3.181706E-01 -2.312073E-02 -1.853503E-02 -9.670338E-05 -7.307830E-01 -1.165409E-01 -1.133833E-02 -4.507577E-05 -2.784164E-02 -2.700020E-04 -4.535053E-01 -4.781822E-02 -2.298094E-02 -1.379435E-04 -9.393810E-01 -1.913101E-01 -1.088324E-02 -3.746573E-05 -2.670626E-02 -2.245210E-04 -3.711608E-01 -3.011209E-02 -2.135571E-02 -1.326869E-04 -7.941852E-01 -1.316708E-01 -1.330360E-02 -5.321889E-05 -3.253974E-02 -3.167152E-04 -4.121174E-01 -3.478939E-02 -1.586472E-02 -6.068678E-05 -1.040216E+00 -2.214218E-01 -5.758712E-03 -1.002333E-05 -1.426440E-02 -6.037119E-05 -4.435090E-01 -4.161468E-02 -1.602560E-02 -5.789996E-05 -1.002899E+00 -2.058070E-01 -7.221739E-03 -1.233021E-05 -1.798457E-02 -7.523251E-05 -4.605997E-01 -5.734630E-02 -1.933007E-02 -1.409861E-04 -1.082221E+00 -2.959635E-01 -9.105646E-03 -3.669942E-05 -2.256185E-02 -2.209209E-04 -4.760643E-01 -5.548670E-02 -2.305845E-02 -1.988737E-04 -1.108307E+00 -2.819143E-01 -1.141829E-02 -5.438996E-05 -2.821950E-02 -3.289724E-04 -2.990870E-01 -2.614044E-02 -1.379131E-02 -6.530395E-05 -6.526311E-01 -1.174214E-01 -6.340014E-03 -1.465241E-05 -1.577489E-02 -8.917934E-05 -4.539651E-01 -5.989053E-02 -3.706059E-02 -7.451853E-04 -9.479066E-01 -2.087790E-01 -2.371011E-02 -3.624597E-04 -5.802863E-02 -2.153033E-03 -3.550875E-01 -3.154848E-02 -1.517370E-02 -6.019907E-05 -8.233200E-01 -1.604220E-01 -7.096967E-03 -1.239328E-05 -1.749843E-02 -7.496910E-05 -2.669672E-01 -1.655119E-02 -9.921355E-03 -2.850701E-05 -6.229281E-01 -9.065592E-02 -3.525996E-03 -3.622432E-06 -8.763114E-03 -2.217997E-05 -3.117641E-01 -2.706928E-02 -1.301318E-02 -6.380468E-05 -7.069278E-01 -1.223940E-01 -5.520667E-03 -1.450549E-05 -1.364327E-02 -8.705049E-05 -4.253175E-01 -4.226465E-02 -3.130303E-02 -2.892976E-04 -8.847586E-01 -1.831350E-01 -1.869718E-02 -1.080033E-04 -4.581100E-02 -6.437392E-04 -4.373877E-01 -4.563513E-02 -2.171789E-02 -1.852469E-04 -8.427752E-01 -1.639163E-01 -1.193320E-02 -6.904423E-05 -2.934222E-02 -4.124494E-04 -3.309335E-01 -2.360277E-02 -1.782689E-02 -7.495262E-05 -7.435456E-01 -1.161667E-01 -9.806683E-03 -2.456418E-05 -2.407241E-02 -1.471923E-04 -3.295651E-01 -2.892136E-02 -9.136199E-03 -2.751683E-05 -7.402491E-01 -1.444989E-01 -4.232396E-03 -6.593472E-06 -1.064377E-02 -4.140318E-05 -2.646177E-01 -1.820511E-02 -6.560072E-03 -1.355487E-05 -6.853657E-01 -1.299412E-01 -2.501821E-03 -2.093278E-06 -6.398968E-03 -1.362528E-05 -5.276217E-01 -6.992447E-02 -4.094462E-02 -5.970189E-04 -1.098251E+00 -3.357754E-01 -2.710360E-02 -2.943539E-04 -6.624993E-02 -1.748479E-03 -4.706582E-01 -4.760382E-02 -1.885346E-02 -7.652927E-05 -9.303306E-01 -1.833640E-01 -9.384721E-03 -2.029091E-05 -2.290445E-02 -1.208163E-04 -5.382357E-01 -6.759212E-02 -2.981285E-02 -2.571507E-04 -1.218516E+00 -3.361214E-01 -1.807366E-02 -9.486632E-05 -4.459288E-02 -5.717156E-04 -5.926040E-01 -7.178398E-02 -4.360128E-02 -5.324114E-04 -1.307820E+00 -3.690548E-01 -2.600218E-02 -2.365448E-04 -6.382907E-02 -1.415541E-03 +2.737079E+00 +1.545362E+00 +7.475678E-02 +1.182688E-03 +3.895146E+00 +3.143927E+00 +3.051980E-02 +2.030656E-04 +7.566509E-02 +1.248142E-03 +2.564678E+00 +1.356531E+00 +6.888583E-02 +1.027172E-03 +3.639176E+00 +2.763465E+00 +2.785332E-02 +1.756457E-04 +6.905430E-02 +1.079605E-03 +2.513858E+00 +1.360648E+00 +7.106151E-02 +1.063532E-03 +3.598310E+00 +2.766916E+00 +2.957807E-02 +1.830650E-04 +7.333034E-02 +1.125208E-03 +2.680537E+00 +1.557625E+00 +7.458823E-02 +1.153071E-03 +3.874223E+00 +3.178628E+00 +3.085079E-02 +1.987973E-04 +7.648569E-02 +1.221907E-03 +2.747094E+00 +1.661126E+00 +7.366404E-02 +1.200019E-03 +3.949477E+00 +3.398210E+00 +2.983494E-02 +2.006053E-04 +7.396717E-02 +1.233020E-03 +2.832153E+00 +1.688117E+00 +7.768421E-02 +1.263525E-03 +4.057661E+00 +3.441857E+00 +3.181289E-02 +2.134911E-04 +7.887092E-02 +1.312222E-03 +2.818292E+00 +1.727700E+00 +8.151103E-02 +1.400727E-03 +4.087366E+00 +3.555489E+00 +3.440824E-02 +2.483234E-04 +8.530537E-02 +1.526319E-03 +2.673498E+00 +1.597867E+00 +8.179404E-02 +1.455604E-03 +4.005194E+00 +3.520971E+00 +3.564373E-02 +2.749065E-04 +8.836840E-02 +1.689712E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.694430E+00 +1.482997E+00 +7.661360E-02 +1.219010E-03 +3.956809E+00 +3.231298E+00 +3.211518E-02 +2.179122E-04 +7.962036E-02 +1.339397E-03 +2.572758E+00 +1.418791E+00 +7.213692E-02 +1.094985E-03 +3.692753E+00 +2.869867E+00 +2.991749E-02 +1.926648E-04 +7.417183E-02 +1.184214E-03 +2.477980E+00 +1.312803E+00 +6.912091E-02 +9.790394E-04 +3.581706E+00 +2.674317E+00 +2.863743E-02 +1.680509E-04 +7.099830E-02 +1.032924E-03 +2.845088E+00 +1.688617E+00 +8.173799E-02 +1.368439E-03 +4.131147E+00 +3.544636E+00 +3.438554E-02 +2.417440E-04 +8.524908E-02 +1.485879E-03 +2.793685E+00 +1.647743E+00 +8.194563E-02 +1.421503E-03 +4.186293E+00 +3.695916E+00 +3.501635E-02 +2.621854E-04 +8.681299E-02 +1.611522E-03 +2.638366E+00 +1.500052E+00 +8.011857E-02 +1.356165E-03 +4.000991E+00 +3.395409E+00 +3.487592E-02 +2.544883E-04 +8.646482E-02 +1.564211E-03 +2.842735E+00 +1.690237E+00 +8.154955E-02 +1.356837E-03 +4.156256E+00 +3.570439E+00 +3.435028E-02 +2.398488E-04 +8.516165E-02 +1.474230E-03 +2.196972E+00 +9.871590E-01 +6.781939E-02 +9.725975E-04 +3.352539E+00 +2.320436E+00 +2.976179E-02 +1.937147E-04 +7.378580E-02 +1.190667E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.641273E+00 +1.597870E+00 +7.598644E-02 +1.292899E-03 +3.853049E+00 +3.336280E+00 +3.203862E-02 +2.292746E-04 +7.943056E-02 +1.409235E-03 +2.708082E+00 +1.522839E+00 +7.654337E-02 +1.221093E-03 +3.905027E+00 +3.156770E+00 +3.189847E-02 +2.134574E-04 +7.908310E-02 +1.312015E-03 +2.691233E+00 +1.524379E+00 +8.054050E-02 +1.365756E-03 +3.962250E+00 +3.258368E+00 +3.462881E-02 +2.628049E-04 +8.585218E-02 +1.615329E-03 +3.018386E+00 +1.917223E+00 +8.348614E-02 +1.445746E-03 +4.283272E+00 +3.833787E+00 +3.429972E-02 +2.430307E-04 +8.503630E-02 +1.493787E-03 +2.929994E+00 +1.836911E+00 +8.927512E-02 +1.624433E-03 +4.372984E+00 +4.002348E+00 +3.882367E-02 +3.051257E-04 +9.625215E-02 +1.875454E-03 +3.119790E+00 +2.050856E+00 +9.534078E-02 +1.868390E-03 +4.698804E+00 +4.587809E+00 +4.157799E-02 +3.523492E-04 +1.030807E-01 +2.165713E-03 +2.868621E+00 +1.702964E+00 +8.398565E-02 +1.456555E-03 +4.247485E+00 +3.715607E+00 +3.580655E-02 +2.676357E-04 +8.877207E-02 +1.645022E-03 +2.497455E+00 +1.252375E+00 +6.446362E-02 +8.477811E-04 +3.507541E+00 +2.474088E+00 +2.542963E-02 +1.367733E-04 +6.304548E-02 +8.406768E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.623441E+00 +1.490238E+00 +8.737054E-02 +1.670677E-03 +4.075246E+00 +3.570201E+00 +3.969459E-02 +3.510115E-04 +9.841135E-02 +2.157491E-03 +2.429458E+00 +1.296272E+00 +7.433515E-02 +1.195439E-03 +3.603045E+00 +2.814355E+00 +3.233556E-02 +2.266091E-04 +8.016674E-02 +1.392852E-03 +2.655653E+00 +1.503631E+00 +7.556244E-02 +1.216313E-03 +3.876149E+00 +3.192723E+00 +3.167217E-02 +2.160892E-04 +7.852205E-02 +1.328191E-03 +2.687380E+00 +1.496815E+00 +7.570314E-02 +1.262722E-03 +3.940616E+00 +3.291028E+00 +3.159442E-02 +2.339022E-04 +7.832928E-02 +1.437679E-03 +2.990160E+00 +1.889612E+00 +7.623143E-02 +1.208898E-03 +4.207001E+00 +3.697140E+00 +2.984188E-02 +1.859848E-04 +7.398438E-02 +1.143155E-03 +2.853430E+00 +1.655915E+00 +7.908369E-02 +1.262135E-03 +4.101975E+00 +3.406862E+00 +3.260559E-02 +2.168450E-04 +8.083620E-02 +1.332837E-03 +2.730969E+00 +1.615691E+00 +7.764021E-02 +1.314394E-03 +3.991873E+00 +3.443169E+00 +3.252644E-02 +2.371617E-04 +8.063998E-02 +1.457714E-03 +2.187664E+00 +9.957750E-01 +6.436381E-02 +8.515751E-04 +3.270736E+00 +2.197812E+00 +2.754849E-02 +1.554780E-04 +6.829858E-02 +9.556448E-04 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.126226E+00 +2.054101E+00 +9.308386E-02 +1.840170E-03 +4.585435E+00 +4.425166E+00 +3.991071E-02 +3.454637E-04 +9.894716E-02 +2.123391E-03 +2.628975E+00 +1.442927E+00 +7.480586E-02 +1.136055E-03 +3.849243E+00 +3.050079E+00 +3.136784E-02 +1.990547E-04 +7.776755E-02 +1.223489E-03 +2.740162E+00 +1.737335E+00 +7.647229E-02 +1.263465E-03 +4.009845E+00 +3.586955E+00 +3.173845E-02 +2.147512E-04 +7.868637E-02 +1.319968E-03 +2.761943E+00 +1.619005E+00 +7.846740E-02 +1.320872E-03 +4.097351E+00 +3.568014E+00 +3.295230E-02 +2.361898E-04 +8.169577E-02 +1.451740E-03 +2.855074E+00 +1.670686E+00 +7.845369E-02 +1.263464E-03 +4.103374E+00 +3.452249E+00 +3.220431E-02 +2.141592E-04 +7.984135E-02 +1.316329E-03 +2.690178E+00 +1.491926E+00 +7.527503E-02 +1.160972E-03 +3.903606E+00 +3.122977E+00 +3.125741E-02 +2.022968E-04 +7.749378E-02 +1.243417E-03 +2.512911E+00 +1.314036E+00 +7.800028E-02 +1.259212E-03 +3.791186E+00 +2.970061E+00 +3.426379E-02 +2.436930E-04 +8.494722E-02 +1.497858E-03 +2.273876E+00 +1.107297E+00 +7.120819E-02 +1.019386E-03 +3.428794E+00 +2.426375E+00 +3.139941E-02 +1.998412E-04 +7.784582E-02 +1.228323E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.416875E+00 +1.198797E+00 +7.051645E-02 +1.018987E-03 +3.608689E+00 +2.679252E+00 +3.004052E-02 +1.872854E-04 +7.447684E-02 +1.151149E-03 +2.573490E+00 +1.402205E+00 +6.633005E-02 +9.194585E-04 +3.559859E+00 +2.675099E+00 +2.604699E-02 +1.426679E-04 +6.457603E-02 +8.769077E-04 +2.701686E+00 +1.530274E+00 +7.570621E-02 +1.220650E-03 +3.972619E+00 +3.322266E+00 +3.152781E-02 +2.138949E-04 +7.816415E-02 +1.314704E-03 +2.920710E+00 +1.813750E+00 +8.167632E-02 +1.397805E-03 +4.220218E+00 +3.751891E+00 +3.388045E-02 +2.397875E-04 +8.399686E-02 +1.473853E-03 +2.886624E+00 +1.697663E+00 +8.812015E-02 +1.584550E-03 +4.350341E+00 +3.846411E+00 +3.842467E-02 +3.055861E-04 +9.526294E-02 +1.878284E-03 +2.805388E+00 +1.631826E+00 +9.017775E-02 +1.681160E-03 +4.264591E+00 +3.742270E+00 +4.026469E-02 +3.387007E-04 +9.982475E-02 +2.081823E-03 +2.789842E+00 +1.599838E+00 +9.325901E-02 +1.771117E-03 +4.331678E+00 +3.825425E+00 +4.241710E-02 +3.690107E-04 +1.051610E-01 +2.268123E-03 +2.406721E+00 +1.197504E+00 +7.197982E-02 +1.055123E-03 +3.523223E+00 +2.545571E+00 +3.093417E-02 +1.962555E-04 +7.669239E-02 +1.206284E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.670387E+00 +1.493829E+00 +7.916152E-02 +1.323249E-03 +3.980792E+00 +3.341124E+00 +3.398399E-02 +2.477152E-04 +8.425355E-02 +1.522581E-03 +2.643712E+00 +1.525085E+00 +7.477643E-02 +1.211244E-03 +3.829765E+00 +3.171826E+00 +3.119267E-02 +2.143333E-04 +7.733327E-02 +1.317399E-03 +2.775846E+00 +1.674648E+00 +8.464107E-02 +1.549143E-03 +4.133594E+00 +3.716316E+00 +3.679183E-02 +2.932382E-04 +9.121478E-02 +1.802388E-03 +2.954816E+00 +1.930285E+00 +7.887852E-02 +1.287632E-03 +4.192638E+00 +3.786782E+00 +3.177353E-02 +2.052824E-04 +7.877335E-02 +1.261768E-03 +3.031795E+00 +1.932684E+00 +9.082125E-02 +1.719186E-03 +4.462842E+00 +4.170125E+00 +3.909991E-02 +3.173523E-04 +9.693701E-02 +1.950605E-03 +2.773807E+00 +1.592371E+00 +8.755961E-02 +1.597915E-03 +4.234664E+00 +3.713430E+00 +3.882039E-02 +3.159470E-04 +9.624401E-02 +1.941967E-03 +2.528366E+00 +1.320356E+00 +8.486472E-02 +1.488520E-03 +3.935024E+00 +3.188413E+00 +3.866268E-02 +3.104697E-04 +9.585301E-02 +1.908301E-03 +2.814891E+00 +1.783998E+00 +7.956633E-02 +1.440608E-03 +4.087076E+00 +3.738124E+00 +3.321370E-02 +2.578118E-04 +8.234384E-02 +1.584639E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.360566E+00 +1.164965E+00 +7.582328E-02 +1.239719E-03 +3.614813E+00 +2.742787E+00 +3.388042E-02 +2.553121E-04 +8.399678E-02 +1.569275E-03 +2.546108E+00 +1.399288E+00 +7.762813E-02 +1.316168E-03 +3.859937E+00 +3.260243E+00 +3.384404E-02 +2.538541E-04 +8.390659E-02 +1.560314E-03 +3.332352E+00 +2.369626E+00 +8.799788E-02 +1.625343E-03 +4.655099E+00 +4.594468E+00 +3.514406E-02 +2.612097E-04 +8.712961E-02 +1.605525E-03 +2.601466E+00 +1.427019E+00 +7.052544E-02 +1.078356E-03 +3.725846E+00 +2.956429E+00 +2.871825E-02 +1.843049E-04 +7.119865E-02 +1.132829E-03 +2.954221E+00 +1.775439E+00 +8.854750E-02 +1.593113E-03 +4.427465E+00 +3.982350E+00 +3.824403E-02 +2.969669E-04 +9.481508E-02 +1.825306E-03 +2.855301E+00 +1.652640E+00 +8.473899E-02 +1.471257E-03 +4.218821E+00 +3.612250E+00 +3.633488E-02 +2.751925E-04 +9.008191E-02 +1.691470E-03 +2.632066E+00 +1.437779E+00 +7.298646E-02 +1.093885E-03 +3.785199E+00 +2.966958E+00 +3.009667E-02 +1.863207E-04 +7.461606E-02 +1.145219E-03 +2.629725E+00 +1.564381E+00 +8.162764E-02 +1.547184E-03 +3.953052E+00 +3.585289E+00 +3.581386E-02 +3.025695E-04 +8.879019E-02 +1.859742E-03 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 tally 2: -2.410000E+00 -1.233100E+00 -2.410000E+00 -1.233100E+00 -8.400000E-01 -1.434000E-01 -8.400000E-01 -1.434000E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.262000E+01 -3.207480E+01 -1.262000E+01 -3.207480E+01 -6.000000E-02 -1.800000E-03 -6.000000E-02 -1.800000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.220000E+00 -1.365100E+01 -8.220000E+00 -1.365100E+01 -9.000000E-02 -2.300000E-03 -9.000000E-02 -2.300000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.430000E+00 -2.409500E+00 -3.430000E+00 -2.409500E+00 -4.000000E-02 -4.000000E-04 -4.000000E-02 -4.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.450000E+00 -4.253000E-01 -1.450000E+00 -4.253000E-01 -7.000000E-02 -1.900000E-03 -7.000000E-02 -1.900000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -1.570000E+00 -5.095000E-01 -1.570000E+00 -5.095000E-01 -9.000000E-02 -2.300000E-03 -9.000000E-02 -2.300000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -9.000000E-02 -1.900000E-03 -9.000000E-02 -1.900000E-03 -2.010000E+00 -8.355000E-01 -2.010000E+00 -8.355000E-01 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -2.000000E-02 -2.000000E-04 -2.000000E-02 -2.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.000000E-02 -6.000000E-04 -4.000000E-02 -6.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.000000E-02 -4.000000E-04 -4.000000E-02 -4.000000E-04 -5.000000E-02 -5.000000E-04 -5.000000E-02 -5.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -7.000000E-02 -2.100000E-03 -7.000000E-02 -2.100000E-03 -1.000000E-01 -2.600000E-03 -1.000000E-01 -2.600000E-03 -8.000000E-02 -1.600000E-03 -8.000000E-02 -1.600000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.600000E-01 -1.528000E-01 -8.600000E-01 -1.528000E-01 -1.800000E-01 -8.000000E-03 -1.800000E-01 -8.000000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.600000E-01 -1.420000E-02 -2.600000E-01 -1.420000E-02 -1.600000E-01 -6.200000E-03 -1.600000E-01 -6.200000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -5.000000E-02 -9.000000E-04 -5.000000E-02 -9.000000E-04 -1.200000E-01 -3.800000E-03 -1.200000E-01 -3.800000E-03 -2.000000E-02 -2.000000E-04 -2.000000E-02 -2.000000E-04 -1.000000E-02 -1.000000E-04 -1.000000E-02 -1.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -9.000000E-02 -2.300000E-03 -9.000000E-02 -2.300000E-03 -1.500000E-01 -7.300000E-03 -1.500000E-01 -7.300000E-03 -3.000000E-02 -5.000000E-04 -3.000000E-02 -5.000000E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.400000E-01 -4.000000E-03 -1.400000E-01 -4.000000E-03 -1.000000E-01 -2.400000E-03 -1.000000E-01 -2.400000E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -4.000000E-02 -6.000000E-04 -4.000000E-02 -6.000000E-04 -1.140000E+00 -2.858000E-01 -1.140000E+00 -2.858000E-01 +4.012713E+01 +3.286443E+02 +4.014931E+01 +3.290078E+02 +5.982856E+00 +7.510508E+00 +5.983297E+00 +7.511618E+00 +1.223283E+02 +3.075680E+03 +1.223283E+02 +3.075680E+03 diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index a9b1860c59..c54fb4d32d 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -18,11 +18,9 @@ class MGTalliesTestHarness(PyAPITestHarness): # Instantiate some tally filters energy_filter = openmc.Filter(type='energy', - bins=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, - 1.0E-3, 0.5, 1.0, 20.0]) + bins=[0.0, 20.0]) energyout_filter = openmc.Filter(type='energyout', - bins=[1E-11, 0.0635E-6, 10.0E-6, - 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) + bins=[0.0, 20.0]) mesh_filter = openmc.Filter() mesh_filter.mesh = mesh From c532cc1189725e1aeb9067cb384880ca1a7f8698 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 20 Nov 2015 05:02:00 -0500 Subject: [PATCH 47/84] Fixed bug in mg tallying --- src/tally.F90 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tally.F90 b/src/tally.F90 index 6b9ee4e277..96dc5b5837 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -2548,6 +2548,9 @@ contains else matching_bins(i) = p % last_g end if + ! Tallies are ordered in increasing groups, group indices + ! however are the opposite, so switch + matching_bins(i) = energy_groups - matching_bins(i) + 1 else ! make sure the correct energy is used if (t % estimator == ESTIMATOR_TRACKLENGTH) then @@ -2573,6 +2576,10 @@ contains if (t % energyout_matches_groups) then ! Since all groups are filters, the filter bin is the group matching_bins(i) = p % g + + ! Tallies are ordered in increasing groups, group indices + ! however are the opposite, so switch + matching_bins(i) = energy_groups - matching_bins(i) + 1 else ! determine outgoing energy bin n = t % filters(i) % n_bins From 72518ee07dbac5f0956876afaa2c0fa69cc80a06 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 21 Nov 2015 13:24:33 -0500 Subject: [PATCH 48/84] Fixed my merge issue. Thats what I get for doing a git conflict resolution during the PSU-UM football game. --- openmc/settings.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openmc/settings.py b/openmc/settings.py index 7339a2e90d..a637816773 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -953,6 +953,16 @@ class SettingsFile(object): subelement = ET.SubElement(element, key) subelement.text = str(self._keff_trigger[key]).lower() + def _create_energy_mode_subelement(self): + if self._energy_mode is not None: + element = ET.SubElement(self._settings_file, "energy_mode") + element.text = str(self._energy_mode) + + def _create_max_order_subelement(self): + if self._max_order is not None: + element = ET.SubElement(self._settings_file, "max_order") + element.text = str(self._max_order) + def _create_source_subelement(self): self._create_source_space_subelement() self._create_source_energy_subelement() From 3381e8bd277f12dc7922a6b6007ff919ecdc0e3c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 24 Nov 2015 08:13:39 -0500 Subject: [PATCH 49/84] Moved some more methods from string to simple_string since they dont depend on global --- src/simple_string.F90 | 70 +++++++++++++++++++++++++++++++++++- src/string.F90 | 82 ++++--------------------------------------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/simple_string.F90 b/src/simple_string.F90 index 478a755562..65eb58ac0b 100644 --- a/src/simple_string.F90 +++ b/src/simple_string.F90 @@ -1,6 +1,6 @@ module simple_string - use constants, only: ERROR_REAL, ERROR_INT + use constants, only: ERROR_REAL, ERROR_INT, MAX_LINE_LEN implicit none @@ -237,4 +237,72 @@ contains end function real_to_str +!=============================================================================== +! STR_TO_INT converts a string to an integer. +!=============================================================================== + + pure function str_to_int(str) result(num) + + character(*), intent(in) :: str + integer(8) :: num + + character(5) :: fmt + integer :: w + integer :: ioError + + ! Determine width of string + w = len_trim(str) + + ! Create format specifier for reading string + write(UNIT=fmt, FMT='("(I",I2,")")') w + + ! read string into integer + read(UNIT=str, FMT=fmt, IOSTAT=ioError) num + if (ioError > 0) num = ERROR_INT + + end function str_to_int + +!=============================================================================== +! STR_TO_REAL converts an arbitrary string to a real(8) +!=============================================================================== + + pure function str_to_real(string) result(num) + + character(*), intent(in) :: string + real(8) :: num + + integer :: ioError + + ! Read string + read(UNIT=string, FMT=*, IOSTAT=ioError) num + if (ioError > 0) num = ERROR_REAL + + end function str_to_real + +!=============================================================================== +! CONCATENATE takes an array of words and concatenates them together in one +! string with a single space between words +! +! Arguments: +! words = array of words +! n_words = total number of words +! string = concatenated string +!=============================================================================== + + pure function concatenate(words, n_words) result(string) + + integer, intent(in) :: n_words + character(*), intent(in) :: words(n_words) + character(MAX_LINE_LEN) :: string + + integer :: i ! index + + string = words(1) + if (n_words == 1) return + do i = 2, n_words + string = trim(string) // ' ' // words(i) + end do + + end function concatenate + end module simple_string \ No newline at end of file diff --git a/src/string.F90 b/src/string.F90 index 5822895979..eee49242d2 100644 --- a/src/string.F90 +++ b/src/string.F90 @@ -1,11 +1,12 @@ module string - use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & - OP_LEFT_PAREN, OP_RIGHT_PAREN, OP_COMPLEMENT, & - OP_INTERSECTION, OP_UNION - use error, only: fatal_error, warning - use global, only: master - use stl_vector, only: VectorInt + use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & + OP_LEFT_PAREN, OP_RIGHT_PAREN, OP_COMPLEMENT, & + OP_INTERSECTION, OP_UNION + use error, only: fatal_error, warning + use global, only: master + use simple_string, only: str_to_int, str_to_real + use stl_vector, only: VectorInt implicit none @@ -152,33 +153,6 @@ contains end if end subroutine tokenize -!=============================================================================== -! CONCATENATE takes an array of words and concatenates them together in one -! string with a single space between words -! -! Arguments: -! words = array of words -! n_words = total number of words -! string = concatenated string -!=============================================================================== - - pure function concatenate(words, n_words) result(string) - - integer, intent(in) :: n_words - character(*), intent(in) :: words(n_words) - character(MAX_LINE_LEN) :: string - - integer :: i ! index - - string = words(1) - if (n_words == 1) return - do i = 2, n_words - string = trim(string) // ' ' // words(i) - end do - - end function concatenate - - !=============================================================================== ! ZERO_PADDED returns a string of the input integer padded with zeros to the @@ -213,46 +187,4 @@ contains write(str, zp_form) num end function zero_padded -!=============================================================================== -! STR_TO_INT converts a string to an integer. -!=============================================================================== - - pure function str_to_int(str) result(num) - - character(*), intent(in) :: str - integer(8) :: num - - character(5) :: fmt - integer :: w - integer :: ioError - - ! Determine width of string - w = len_trim(str) - - ! Create format specifier for reading string - write(UNIT=fmt, FMT='("(I",I2,")")') w - - ! read string into integer - read(UNIT=str, FMT=fmt, IOSTAT=ioError) num - if (ioError > 0) num = ERROR_INT - - end function str_to_int - -!=============================================================================== -! STR_TO_REAL converts an arbitrary string to a real(8) -!=============================================================================== - - pure function str_to_real(string) result(num) - - character(*), intent(in) :: string - real(8) :: num - - integer :: ioError - - ! Read string - read(UNIT=string, FMT=*, IOSTAT=ioError) num - if (ioError > 0) num = ERROR_REAL - - end function str_to_real - end module string From 42d2673ab9c891c59f21d4f38d6afbf2267aefd9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 25 Nov 2015 05:58:49 -0500 Subject: [PATCH 50/84] Made fission data optional in the MGXS library since it is not needed for tracking, only tallying. --- docs/source/usersguide/mgxs_library.rst | 3 +- src/macroxs.F90 | 2 - src/macroxs_header.F90 | 29 +++++--- src/mgxs_data.F90 | 93 +++++++++++++++---------- src/tally.F90 | 8 ++- 5 files changed, 82 insertions(+), 53 deletions(-) diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index f145f3bd0a..ab6be5cc38 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -244,7 +244,8 @@ attributes/sub-elements required to describe the meta-data: with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. - *Default*: None, this must be provided if the material is fissionable. + *Default*: None, this is required only if ``fission`` tallies are + requested and the material is fissionable. :k_fission: This element requires the group-wise kappa-fission cross section ordered by diff --git a/src/macroxs.F90 b/src/macroxs.F90 index 4dafd32c1b..c26e9e888b 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -32,7 +32,6 @@ contains xs % total = this % total(gin) xs % elastic = this % scattxs(gin) xs % absorption = this % absorption(gin) - xs % fission = this % fission(gin) xs % nu_fission = this % nu_fission(gin) type is (MacroXS_Angle) @@ -40,7 +39,6 @@ contains xs % total = this % total(gin, iazi, ipol) xs % elastic = this % scattxs(gin, iazi, ipol) xs % absorption = this % absorption(gin, iazi, ipol) - xs % fission = this % fission(gin, iazi, ipol) xs % nu_fission = this % nu_fission(gin, iazi, ipol) end select diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index b2d9a5fde6..95b61f695d 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -26,7 +26,7 @@ module macroxs_header end type MacroXS_Base abstract interface - subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, & + subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, & error_code, error_text) @@ -39,6 +39,7 @@ module macroxs_header type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups logical, intent(in) :: get_kfiss ! Should we get kfiss data? + logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? @@ -119,7 +120,7 @@ contains ! MACROXS*_INIT sets the MacroXS Data !=============================================================================== - subroutine macroxs_iso_init(this, mat, nuclides, groups, get_kfiss, & + subroutine macroxs_iso_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, error_code, error_text) class(MacroXS_Iso), intent(inout) :: this ! The MacroXS to initialize @@ -127,6 +128,7 @@ contains type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups logical, intent(in) :: get_kfiss ! Should we get kfiss data? + logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order integer, intent(in) :: scatt_type ! How is data presented integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? @@ -215,8 +217,10 @@ contains this % total = ZERO allocate(this % absorption(groups)) this % absorption = ZERO - allocate(this % fission(groups)) - this % fission = ZERO + if (get_fiss) then + allocate(this % fission(groups)) + this % fission = ZERO + end if if (get_kfiss) then allocate(this % k_fission(groups)) this % k_fission = ZERO @@ -261,7 +265,9 @@ contains sum(nuc % nu_fission(:,gin)) end do end if - this % fission = this % fission + atom_density * nuc % fission + if (get_fiss) then + this % fission = this % fission + atom_density * nuc % fission + end if if (get_kfiss) then this % k_fission = this % k_fission + atom_density * nuc % k_fission end if @@ -359,7 +365,7 @@ contains end subroutine macroxs_iso_init - subroutine macroxs_angle_init(this, mat, nuclides, groups, get_kfiss, & + subroutine macroxs_angle_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, error_code, error_text) class(MacroXS_Angle), intent(inout) :: this ! The MacroXS to initialize @@ -367,6 +373,7 @@ contains type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups logical, intent(in) :: get_kfiss ! Should we get kfiss data? + logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? @@ -493,8 +500,10 @@ contains this % total = ZERO allocate(this % absorption(groups,nazi,npol)) this % absorption = ZERO - allocate(this % fission(groups,nazi,npol)) - this % fission = ZERO + if (get_fiss) then + allocate(this % fission(groups,nazi,npol)) + this % fission = ZERO + end if if (get_kfiss) then allocate(this % k_fission(groups,nazi,npol)) this % k_fission = ZERO @@ -542,7 +551,9 @@ contains sum(nuc % nu_fission(:,gin,:,:),dim=1) end do end if - this % fission = this % fission + atom_density * nuc % fission + if (get_fiss) then + this % fission = this % fission + atom_density * nuc % fission + end if if (get_kfiss) then this % k_fission = this % k_fission + atom_density * nuc % k_fission end if diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 345c6a95d0..d568ab7b55 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -37,7 +37,7 @@ contains logical :: file_exists integer :: error_code character(MAX_LINE_LEN) :: error_text, temp_str - logical :: get_kfiss + logical :: get_kfiss, get_fiss integer :: l ! Check if cross_sections.xml exists @@ -63,16 +63,20 @@ contains allocate(micro_xs(n_nuclides_total)) !$omp end parallel - ! Find out if we need kappa fission (are there any k_fiss tallies?) + ! Find out if we need fission & kappa fission + ! (i.e., are there any SCORE_FISSION or SCORE_KAPPA_FISSION tallies?) get_kfiss = .false. + get_fiss = .false. do i = 1, n_tallies do l = 1, tallies(i) % n_score_bins if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then get_kfiss = .true. - exit + end if + if (tallies(i) % score_bins(l) == SCORE_FISSION) then + get_fiss = .true. end if end do - if (get_kfiss) & + if (get_kfiss .and. get_fiss) & exit end do @@ -123,7 +127,7 @@ contains ! Now read in the data specific to the type we just declared call nuclide_mg_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & - energy_groups, get_kfiss, error_code, & + energy_groups, get_kfiss, get_fiss, error_code, & error_text) ! Keep track of what listing is associated with this nuclide @@ -191,12 +195,13 @@ contains ! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed !=============================================================================== - subroutine nuclide_mg_init(this, node_xsdata, groups, get_kfiss, & + subroutine nuclide_mg_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) class(Nuclide_MG), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(inout) :: error_code ! Code signifying error character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print @@ -293,21 +298,22 @@ contains select type(this) type is (Nuclide_Iso) - call nuclide_iso_init(this, node_xsdata, groups, get_kfiss, & + call nuclide_iso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) type is (Nuclide_Angle) - call nuclide_angle_init(this, node_xsdata, groups, get_kfiss, & + call nuclide_angle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) end select end subroutine nuclide_mg_init - subroutine nuclide_iso_init(this, node_xsdata, groups, get_kfiss, & + subroutine nuclide_iso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) class(Nuclide_Iso), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Need fiss data? integer, intent(inout) :: error_code ! Code signifying error character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print @@ -317,7 +323,6 @@ contains ! Load the more specific data if (this % fissionable) then - allocate(this % fission(groups)) if (check_for_node(node_xsdata, "chi")) then ! Get chi @@ -352,12 +357,16 @@ contains return end if end if - if (check_for_node(node_xsdata, "fission")) then - call get_node_array(node_xsdata, "fission", this % fission) - else - error_code = 1 - error_text = "If fissionable, must provide fission!" - return + if (get_fiss) then + allocate(this % fission(groups)) + if (check_for_node(node_xsdata, "fission")) then + call get_node_array(node_xsdata, "fission", this % fission) + else + error_code = 1 + error_text = "Fission data missing, required due to fission& + & tallies in tallies.xml file!" + return + end if end if if (get_kfiss) then allocate(this % k_fission(groups)) @@ -429,13 +438,14 @@ contains end subroutine nuclide_iso_init - subroutine nuclide_angle_init(this, node_xsdata, groups, get_kfiss, & + subroutine nuclide_angle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) class(Nuclide_Angle), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - integer, intent(inout) :: error_code ! Code signifying error + type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(inout) :: error_code ! Code signifying error character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print real(8), allocatable :: temp_arr(:) @@ -535,16 +545,19 @@ contains return end if end if - if (check_for_node(node_xsdata, "fission")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) - call get_node_array(node_xsdata, "fission", temp_arr) - allocate(this % fission(groups, this % Nazi, this % Npol)) - this % fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "If fissionable, must provide fission!" - return + if (get_fiss) then + if (check_for_node(node_xsdata, "fission")) then + allocate(temp_arr(groups * this % Nazi * this % Npol)) + call get_node_array(node_xsdata, "fission", temp_arr) + allocate(this % fission(groups, this % Nazi, this % Npol)) + this % fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + deallocate(temp_arr) + else + error_code = 1 + error_text = "Fission data missing, required due to kappa-fission& + & tallies in tallies.xml file!" + return + end if end if if (get_kfiss) then if (check_for_node(node_xsdata, "k_fission")) then @@ -627,23 +640,27 @@ contains integer :: i ! loop index over nuclides integer :: l ! Loop over score bins type(Material), pointer :: mat ! current material - logical :: get_kfiss + logical :: get_kfiss, get_fiss integer :: error_code character(MAX_LINE_LEN) :: error_text integer :: representation integer :: scatt_type integer :: legendre_mu_points - ! Find out if we need kappa fission (are there any k_fiss tallies?) + ! Find out if we need fission & kappa fission + ! (i.e., are there any SCORE_FISSION or SCORE_KAPPA_FISSION tallies?) get_kfiss = .false. + get_fiss = .false. do i = 1, n_tallies do l = 1, tallies(i) % n_score_bins if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then get_kfiss = .true. - exit + end if + if (tallies(i) % score_bins(l) == SCORE_FISSION) then + get_fiss = .true. end if end do - if (get_kfiss) & + if (get_kfiss .and. get_fiss) & exit end do @@ -675,9 +692,9 @@ contains end select call macro_xs(i_mat) % obj % init(mat, nuclides_MG, energy_groups, & - get_kfiss, max_order, scatt_type, & - legendre_mu_points, error_code, & - error_text) + get_kfiss, get_fiss, max_order, & + scatt_type, legendre_mu_points, & + error_code, error_text) ! Handle any errors if (error_code /= 0) then call fatal_error(trim(error_text)) diff --git a/src/tally.F90 b/src/tally.F90 index 31260f16a4..85a603419b 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1114,7 +1114,9 @@ contains atom_density * flux end associate else - score = material_xs % fission * flux + score = flux * macro_xs(p % material) % obj % get_xs(p % g, & + 'fission', UVW=p % coord(i) % uvw) + end if end if @@ -1205,8 +1207,8 @@ contains * atom_density * flux end associate else - score = macro_xs(p % material) % obj % get_xs(p % g, 'k_fission', & - UVW=p % coord(i) % uvw) + score = flux * macro_xs(p % material) % obj % get_xs(p % g, & + 'k_fission', UVW=p % coord(i) % uvw) end if end if From ca602e8b97c1a34f92b86b3fc4c9dd50bc2fe079 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 25 Nov 2015 09:50:56 -0500 Subject: [PATCH 51/84] Fixed poor deallocation. :-( 6am coding == bugs. --- src/macroxs_header.F90 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 95b61f695d..63e6fecaed 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -667,7 +667,11 @@ contains if (allocated(this % total)) then deallocate(this % total, this % absorption, & - this % nu_fission, this % fission) + this % nu_fission) + end if + + if (allocated(this % fission)) then + deallocate(this % fission) end if if (allocated(this % k_fission)) then @@ -689,7 +693,11 @@ contains if (allocated(this % total)) then deallocate(this % total, this % absorption, & - this % nu_fission, this % fission) + this % nu_fission) + end if + + if (allocated(this % fission)) then + deallocate(this % fission) end if if (allocated(this % k_fission)) then From 0911de76eb6ac6d8fded05b26cce1a343aac0a50 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 28 Nov 2015 20:18:13 -0500 Subject: [PATCH 52/84] Added MGXS support for void materials --- src/tracking.F90 | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tracking.F90 b/src/tracking.F90 index 028ec3ee6c..24ade265be 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -91,8 +91,15 @@ contains else ! Since the MGXS can be angle dependent, this needs to be done ! After every collision for the MGXS mode - call calculate_mgxs(macro_xs(p % material) % obj, p % g, & - p % coord(p % n_coord) % uvw, material_xs) + if (p % material /= MATERIAL_VOID) then + call calculate_mgxs(macro_xs(p % material) % obj, p % g, & + p % coord(p % n_coord) % uvw, material_xs) + else + material_xs % total = ZERO + material_xs % elastic = ZERO + material_xs % absorption = ZERO + material_xs % nu_fission = ZERO + end if end if ! Find the distance to the nearest boundary From 05b600819aee5e3be8dd77bc6bf059acf562c63c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 7 Jan 2016 20:20:55 -0500 Subject: [PATCH 53/84] Updates to MGXS pyapi --- openmc/material.py | 3 +-- openmc/mgxs_library.py | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 4da4e0ae35..ca78bd61f2 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -339,8 +339,7 @@ class Material(object): # Ensure no nuclides, elements, or sab are added since these would be # incompatible with macroscopics - if ((len(self._nuclides.keys()) != 0) and - (len(self._elements.keys()) != 0) and (len(self._sab) != 0)): + if self._nuclides or self._elements or self._sab: msg = 'Unable to add a Macroscopic data set to Material ID="{0}" ' \ 'with a macroscopic value "{1}" as an incompatible data ' \ 'member (i.e., nuclide, element, or S(a,b) table) ' \ diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index d1c1f4e05f..5820c0ee52 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -20,6 +20,17 @@ REPRESENTATIONS = ['isotropic', 'angle'] def ndarray_to_string(arr): """Converts a numpy ndarray in to a join with spaces between entries similar to ' '.join(map(str,arr)) but applied to all sub-dimensions. + + Parameters + ---------- + arr : ndarray + Array to combine in to a string + + Returns + ------- + text : str + String representation of array in arr + """ shape = arr.shape @@ -67,8 +78,8 @@ def ndarray_to_string(arr): return text -class Xsdata(object): - """A multi-group cross section data set (xsdata) providing all the +class XSdata(object): + """A multi-group cross section data set providing all the multi-group data necessary for a multi-group OpenMC calculation. Parameters @@ -76,7 +87,6 @@ class Xsdata(object): name : str, optional Name of the mgxs data set. - representation : str Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' @@ -141,7 +151,6 @@ class Xsdata(object): def representation(self): return self._representation - @property def alias(self): return self._alias @@ -221,8 +230,8 @@ class Xsdata(object): check_type("energy_groups", energy_groups, EnergyGroups) # Check that there is one or more groups - if ((energy_groups.num_energy_groups.num_group is None) or - (energy_groups.num_energy_groups.num_group < 1)): + if ((energy_groups.num_groups is None) or + (energy_groups.num_groups < 1)): msg = 'energy_groups object incorrectly initialized.' raise ValueError(msg) @@ -429,7 +438,7 @@ class Xsdata(object): @nu_fission.setter def nu_fission(self, nu_fission): - # nu_fission ca nbe given as a vector or a matrix + # nu_fission can be given as a vector or a matrix # Vector is used when chi also exists. # Matrix is used when chi does not exist. # We have to check that the correct form is given, but only if @@ -563,6 +572,8 @@ class MGXSLibraryFile(object): Inverse of velocities, units of sec/cm filename : str XML file to write to. + xsdatas : Iterable of XSdata + Iterable of multi-Group cross section data objects """ def __init__(self, energy_groups): From 75093ea43d927e34ae8a9640e2361754567291ab Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 7 Jan 2016 20:31:56 -0500 Subject: [PATCH 54/84] Fixed failing build and renamed more Xsdatas to XSdata --- .../python/pincell_multigroup/build-xml.py | 4 +-- openmc/mgxs_library.py | 28 +++++++++---------- src/tally.F90 | 7 +++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index bb4c2db14f..2145a68a54 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -20,7 +20,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.Xsdata('UO2.300k', groups) +uo2_xsdata = openmc.XSdata('UO2.300k', groups) uo2_xsdata.order = 0 uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, 0.5644058]) @@ -43,7 +43,7 @@ uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, 0.0000E+00, 0.0000E+00, 0.0000E+00]) -h2o_xsdata = openmc.Xsdata('LWTR.300k', groups) +h2o_xsdata = openmc.XSdata('LWTR.300k', groups) h2o_xsdata.order = 0 h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, 0.718, 1.2544497, 2.650379]) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 5820c0ee52..80cec82943 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -221,7 +221,7 @@ class XSdata(object): @name.setter def name(self, name): - check_type('name for Xsdata', name, basestring) + check_type('name for XSdata', name, basestring) self._name = name @energy_groups.setter @@ -247,7 +247,7 @@ class XSdata(object): @alias.setter def alias(self, alias): if alias is not None: - check_type('alias for Xsdata', alias, basestring) + check_type('alias for XSdata', alias, basestring) self._alias = alias else: self._alias = self._name @@ -604,24 +604,24 @@ class MGXSLibraryFile(object): self._energy_groups = energy_groups def add_xsdata(self, xsdata): - """Add an xsdata entry to the file. + """Add an XSdata entry to the file. Parameters ---------- - xsdata : Xsdata + xsdata : XSdata MGXS information to add """ # Check the type - if not isinstance(xsdata, Xsdata): - msg = 'Unable to add a non-Xsdata "{0}" to the ' \ + if not isinstance(xsdata, XSdata): + msg = 'Unable to add a non-XSdata "{0}" to the ' \ 'MGXSLibraryFile'.format(xsdata) raise ValueError(msg) # Make sure energy groups match. if xsdata.energy_groups != self._energy_groups: - msg = 'Energy groups of Xsdata do not match that of MGXSLibraryFile!' + msg = 'Energy groups of XSdata do not match that of MGXSLibraryFile!' raise ValueError(msg) self._xsdatas.append(xsdata) @@ -631,8 +631,8 @@ class MGXSLibraryFile(object): Parameters ---------- - xsdatas : tuple or list of Xsdata - Xsdatas to add + xsdatas : tuple or list of XSdata + XSdatas to add """ @@ -649,14 +649,14 @@ class MGXSLibraryFile(object): Parameters ---------- - xsdata : Xsdata - Xsdata to remove + xsdata : XSdata + XSdata to remove """ - if not isinstance(xsdata, Xsdata): - msg = 'Unable to remove a non-Xsdata "{0}" from the ' \ - 'XsdatasFile'.format(xsdata) + if not isinstance(xsdata, XSdata): + msg = 'Unable to remove a non-XSdata "{0}" from the ' \ + 'XSdatasFile'.format(xsdata) raise ValueError(msg) self._xsdatas.remove(xsdata) diff --git a/src/tally.F90 b/src/tally.F90 index f16a87000a..5d978bdcba 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -2483,6 +2483,7 @@ contains integer :: i ! loop index for filters integer :: j integer :: n ! number of bins for single filter + integer :: distribcell_index ! index in distribcell arrays integer :: offset ! offset for distribcell real(8) :: theta, phi ! Polar and Azimuthal Angles, respectively real(8) :: E @@ -2528,12 +2529,14 @@ contains case (FILTER_DISTRIBCELL) ! determine next distribcell bin + distribcell_index = cells(t % filters(i) % int_bins(1)) & + % distribcell_index matching_bins(i) = NO_BIN_FOUND offset = 0 do j = 1, p % n_coord if (cells(p % coord(j) % cell) % type == CELL_FILL) then offset = offset + cells(p % coord(j) % cell) % & - offset(t % filters(i) % offset) + offset(distribcell_index) elseif(cells(p % coord(j) % cell) % type == CELL_LATTICE) then if (lattices(p % coord(j + 1) % lattice) % obj & % are_valid_indices([& @@ -2541,7 +2544,7 @@ contains p % coord(j + 1) % lattice_y, & p % coord(j + 1) % lattice_z])) then offset = offset + lattices(p % coord(j + 1) % lattice) % obj % & - offset(t % filters(i) % offset, & + offset(distribcell_index, & p % coord(j + 1) % lattice_x, & p % coord(j + 1) % lattice_y, & p % coord(j + 1) % lattice_z) From 08fdb8a91d0d4b9fbfe94fc89eb134daecc27817 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 9 Jan 2016 05:43:28 -0500 Subject: [PATCH 55/84] satisfying @wbinventors pyapi comments --- openmc/material.py | 16 ++++++++-------- openmc/mgxs/groups.py | 2 +- openmc/mgxs_library.py | 16 ++++++++-------- openmc/settings.py | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index ca78bd61f2..e429190dc1 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -332,7 +332,7 @@ class Material(object): Parameters ---------- - macroscopic : str or openmc.macroscopic.Macroscopic + macroscopic : str or Macroscopic Macroscopic to add """ @@ -371,7 +371,7 @@ class Material(object): Parameters ---------- - macroscopic : openmc.macroscopic.Macroscopic + macroscopic : Macroscopic Macroscopic to remove """ @@ -622,14 +622,14 @@ class Material(object): # Create element XML subelements subelements = self._get_elements_xml(self._elements, distrib=True) - for subelement_ele in subelements: - subelement.append(subelement_ele) + for subsubelement in subelements: + subelement.append(subsubelement) else: # Create macroscopic XML subelements - subelement_ele = self._get_macroscopic_xml(self, - self._macroscopic, - distrib=True) - subelement.append(subelement_ele) + subsubelement = self._get_macroscopic_xml(self, + self._macroscopic, + distrib=True) + subelement.append(subsubelement) if len(self._sab) > 0: for sab in self._sab: diff --git a/openmc/mgxs/groups.py b/openmc/mgxs/groups.py index e6838b36ba..3436c0e037 100644 --- a/openmc/mgxs/groups.py +++ b/openmc/mgxs/groups.py @@ -54,7 +54,7 @@ class EnergyGroups(object): def __eq__(self, other): if not isinstance(other, EnergyGroups): return False - elif (self.group_edges != other.group_edges).all(): + elif self.group_edges != other.group_edges: return False else: return True diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 80cec82943..605fc7064d 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -14,7 +14,7 @@ from openmc.checkvalue import check_type, check_value, check_greater_than, \ check_iterable_type from openmc.clean_xml import * -# MGXS Representations supported by OpenMC +# Supported incoming particle MGXS angular treatment representations REPRESENTATIONS = ['isotropic', 'angle'] def ndarray_to_string(arr): @@ -87,7 +87,7 @@ class XSdata(object): name : str, optional Name of the mgxs data set. - representation : str + representation : {'isotropic' or 'angle'} Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' @@ -99,11 +99,11 @@ class XSdata(object): Separate unique identifier for the xsdata object kT : float Temperature (in units of MeV) of this data set. - energy_groups : openmc.mgxs.EnergyGroups + energy_groups : EnergyGroups Energy group structure fissionable : boolean Whether or not this is a fissionable data set. - scatt_type : str + scatt_type : {'legendre', 'histogram', or 'tabular'} Angular distribution representation (legendre, histogram, or tabular) order : int Either the Legendre order, number of bins, or number of points used to @@ -111,9 +111,9 @@ class XSdata(object): transfer probability. tabular_legendre : dict Set how to treat the Legendre scattering kernel (tabular or leave in - Legendre polynomial form). Dict contains two keys: ``enable`` and - ``num_points``. ``enable`` is a boolean and ``num_points`` is the - number of points to use, if ``enable`` is True. + Legendre polynomial form). Dict contains two keys: 'enable' and + 'num_points'. 'enable' is a boolean and 'num_points' is the + number of points to use, if 'enable' is True. """ def __init__(self, name, energy_groups, representation="isotropic"): @@ -247,7 +247,7 @@ class XSdata(object): @alias.setter def alias(self, alias): if alias is not None: - check_type('alias for XSdata', alias, basestring) + check_type('alias', alias, basestring) self._alias = alias else: self._alias = self._name diff --git a/openmc/settings.py b/openmc/settings.py index 61017a7a5f..8a562a5455 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -79,7 +79,7 @@ class SettingsFile(object): Set whether the calculation should be continuous-energy or multi-group. Acceptable values are 'continuous-energy' or 'multi-group' max_order : int - Maximum scattering order to apply globally when in multi-grup mode. + Maximum scattering order to apply globally when in multi-group mode. ptables : bool Determine whether probability tables are used. run_cmfd : bool From 473d3220dca2a6a71115477fb6c3a216f1d8d5f9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 16 Jan 2016 13:48:06 -0500 Subject: [PATCH 56/84] Changes per comments of @smharper and @paulromano --- docs/source/usersguide/input.rst | 5 +- docs/source/usersguide/install.rst | 2 +- docs/source/usersguide/mgxs_library.rst | 73 +++---- docs/source/usersguide/output/source.rst | 5 +- docs/source/usersguide/output/statepoint.rst | 11 +- .../python/pincell_multigroup/build-xml.py | 17 +- examples/xml/pincell_multigroup/materials.xml | 4 +- examples/xml/pincell_multigroup/settings.xml | 6 - openmc/material.py | 11 +- openmc/mgxs/groups.py | 2 +- openmc/mgxs_library.py | 6 +- openmc/settings.py | 10 +- openmc/summary.py | 4 +- src/cmfd_input.F90 | 2 +- src/initialize.F90 | 2 +- src/input_xml.F90 | 191 +++++++++--------- src/mgxs_data.F90 | 18 +- src/state_point.F90 | 14 +- src/tally.F90 | 45 +++-- 19 files changed, 221 insertions(+), 207 deletions(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 754f815de4..6f73866e40 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -546,7 +546,8 @@ attributes/sub-elements: *Default*: 0.988 2.249 - .. note:: The above format should be used even when using the multi-group :ref:`energy_mode`. + .. note:: The above format should be used even when using the multi-group + :ref:`energy_mode`. :write_initial: An element specifying whether to write out the initial source bank used at @@ -1517,6 +1518,8 @@ The ```` element accepts the following sub-elements: .. note:: This score type is not used in the multi-group :ref:`energy_mode`. + .. _kappa_fission: + :kappa-fission: The recoverable energy production rate due to fission. The recoverable energy is defined as the fission product kinetic energy, prompt and diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 2bfdbc5820..9a62eac3a3 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -385,7 +385,7 @@ ACE data as described below. The TALYS-based evaluated nuclear data library, TENDL_, is also openly available in ACE format. In multi-group mode, OpenMC utilizes an XML-based library format which can be -used to describe nuclidic- or material-specific quantities. +used to describe nuclide- or material-specific quantities. Using ENDF/B-VII.1 Cross Sections from NNDC ------------------------------------------- diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index ab6be5cc38..d0dc1e54f5 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -87,18 +87,19 @@ attributes/sub-elements required to describe the meta-data: *Default*: None, this must be provided. :alias: - The number of total fission source iterations per batch. + An alternative name to use for the microscopic or macroscopic data set. *Default*: If no alias is provided, it will adopt the value of ``name``. :kT: - The temperature the data was generated at. + The temperature times Boltzmann's constant (in units of MeV) at which the + data was generated. *Default*: Room temperature, 2.53E-8 MeV :fissionable: This element states whether or not the data in question is fissionable. - Accepted values are ``true`` or ``false``. + Accepted values are "true" or "false". *Default*: None, this element must be provided. @@ -108,42 +109,42 @@ attributes/sub-elements required to describe the meta-data: scalar flux weighting (or reduced to an equivalent representation) and thus are angle-independent, or if the data was generated with angular dependent fluxes and thus the data is angle-dependent. The options are - either ``isotropic`` or ``angle``. + either "isotropic" or "angle". - *Default*: ``isotropic`` + *Default*: "isotropic" :num_azimuthal: This element provides the number of equi-width bins that the azimuthal angular domain is subdivided in the case of angle-dependent cross sections - (i.e., ``angle`` is passed to the ``representation`` element). + (i.e., "angle" is passed to the ``representation`` element). - *Default*: If ``representation`` is ``angle``, this must be provided. If + *Default*: If ``representation`` is "angle", this must be provided. If not, this parameter is not used. :num_polar: This element provides the number of equi-width bins that the polar angular domain is subdivided in the case of angle-dependent cross sections - (i.e., ``angle`` is passed to the ``representation`` element). + (i.e., "angle" is passed to the ``representation`` element). - *Default*: If ``representation`` is ``angle``, this must be provided. If + *Default*: If ``representation`` is "angle", this must be provided. If not, this parameter is not used. :scatt_type: This element provides the representation of the angular distribution associated with each group-to-group transfer probability. The options are - either ``legendre``, ``histogram``, or ``tabular``. - The ``legendre`` option means the angular distribution has been - expanded via Legendre polynomials of the order provided in the ``order`` + either "legendre", "histogram", or "tabular". + The "legendre" option means the angular distribution has been + expanded via Legendre polynomials of the order provided in the "order" element. - The ``histogram`` option means the angular distribution is provided in + The "histogram" option means the angular distribution is provided in an equi-width histogram format with a number of bins as provided in the - ``order`` element. This is useful when the angular distribution was + "order" element. This is useful when the angular distribution was obtained from a Monte Carlo tally and thus is natively in the histogram format. - The ``tabular`` option means the angular distribution is provided in an + The "tabular" option means the angular distribution is provided in an equi-spaced point-wise representation. - *Default*: ``legendre`` + *Default*: "legendre" :order: This element provides either the Legendre order, number of bins, or number @@ -165,17 +166,17 @@ attributes/sub-elements required to describe the meta-data: :enable: This attribute/sub-element denotes whether or not the conversion to the - tabular format should be performed or not. A value of ``true`` means - the conversion should be performed, ``false`` means it should not. + tabular format should be performed or not. A value of "true" means + the conversion should be performed, "false" means it should not. - *Default*: ``true`` + *Default*: "true" :num_points: If the conversion is to take place the number of tabular points is required. This attribute/sub-element allows the user to set the desired number of points. - *Default*: ``33`` + *Default*: 33 The following attributes/sub-elements are the cross section values to be used during the transport process. @@ -183,9 +184,9 @@ attributes/sub-elements required to describe the meta-data: :total: This element requires the group-wise total cross section ordered by increasing group index (i.e., fast to thermal). If ``representation`` is - ``isotropic``, then the length of this list should equal the number of + "isotropic", then the length of this list should equal the number of groups described in the ``groups`` element. If ``representation`` is - ``angle``, then the length of this list should equal the number of groups + "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. @@ -196,9 +197,9 @@ attributes/sub-elements required to describe the meta-data: :absorption: This element requires the group-wise absorption cross section ordered by increasing group index (i.e., fast to thermal). If ``representation`` is - ``isotropic``, then the length of this list should equal the number of + "isotropic", then the length of this list should equal the number of groups described in the ``groups`` element. If ``representation`` is - ``angle``, then the length of this list should equal the number of groups + "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. @@ -210,9 +211,9 @@ attributes/sub-elements required to describe the meta-data: columns representing incoming group and rows representing the outgoing group. That is, down-scatter will be above the diagonal of the resultant matrix. This matrix is repeated for every Legendre order (in order of - increasing orders) if ``scatt_type`` is ``legendre``; otherwise, this + increasing orders) if ``scatt_type`` is "legendre"; otherwise, this matrix is repeated for every bin of the histogram or tabular - representation. Finally, if ``representation`` is ``angle``, the above + representation. Finally, if ``representation`` is "angle", the above is repeated for every azimuthal angle and every polar angle, in that order. @@ -232,32 +233,32 @@ attributes/sub-elements required to describe the meta-data: neglected). The following fission-specific data are only needed should ``fissionable`` - be ``true``. + be "true". :fission: This element requires the group-wise fission cross section ordered by increasing group index (i.e., fast to thermal). If ``representation`` is - ``isotropic``, then the length of this list should equal the number of + "isotropic", then the length of this list should equal the number of groups described in the ``groups`` element. If ``representation`` is - ``angle``, then the length of this list should equal the number of groups + "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. - *Default*: None, this is required only if ``fission`` tallies are + *Default*: None, this is required only if fission tallies are requested and the material is fissionable. - :k_fission: + :kappa_fission: This element requires the group-wise kappa-fission cross section ordered by increasing group index (i.e., fast to thermal). If ``representation`` is - ``isotropic``, then the length of this list should equal the number of + "isotropic", then the length of this list should equal the number of groups described in the ``groups`` element. If ``representation`` is - ``angle``, then the length of this list should equal the number of groups + "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. - *Default*: None, this is required only if ``kappa-fission`` tallies are + *Default*: None, this is required only if :ref:`kappa_fission` tallies are requested and the material is fissionable. :chi: @@ -267,9 +268,9 @@ attributes/sub-elements required to describe the meta-data: not depend on incoming energy. If the user does not wish to make this approximation, then this should not be provided and this information included in the ``nu_fission`` element instead. If ``representation`` is - ``isotropic``, then the length of this list should equal the number of + "isotropic", then the length of this list should equal the number of groups described in the ``groups`` element. If ``representation`` is - ``angle``, then the length of this list should equal the number of groups + "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. diff --git a/docs/source/usersguide/output/source.rst b/docs/source/usersguide/output/source.rst index 2981b0f662..e8867083c1 100644 --- a/docs/source/usersguide/output/source.rst +++ b/docs/source/usersguide/output/source.rst @@ -15,5 +15,6 @@ is that documented here. **/source_bank** (Compound type) Source bank information for each particle. The compound type has fields - ``wgt``, ``xyz``, ``uvw``, and ``E`` which represent the weight, position, - direction, and energy of the source particle, respectively. + ``wgt``, ``xyz``, ``uvw``, ``E``, ``g``, and ``delayed_group``, which + represent the weight, position, direction, energy, energy group, and + delayed_group of the source particle, respectively. diff --git a/docs/source/usersguide/output/statepoint.rst b/docs/source/usersguide/output/statepoint.rst index 15bc79f739..2921258c97 100644 --- a/docs/source/usersguide/output/statepoint.rst +++ b/docs/source/usersguide/output/statepoint.rst @@ -39,6 +39,12 @@ The current revision of the statepoint file format is 14. Pseudo-random number generator seed. +**/run_CE** (*int*) + + Flag to denote continuous-energy or multi-group mode. A value of 1 + indicates a continuous-energy run while a value of 0 indicates a + multi-group run. + **/run_mode** (*char[]*) Run mode used. A value of 1 indicates a fixed-source run and a value of 2 @@ -251,5 +257,6 @@ if (run_mode == 'k-eigenvalue' and source_present > 0) **/source_bank** (Compound type) Source bank information for each particle. The compound type has fields - ``wgt``, ``xyz``, ``uvw``, and ``E`` which represent the weight, - position, direction, and energy of the source particle, respectively. + ``wgt``, ``xyz``, ``uvw``, ``E``, ``g``, and ``delayed_group``, which + represent the weight, position, direction, energy, energy group, and + delayed_group of the source particle, respectively. diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 2145a68a54..ba15370c3b 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -20,7 +20,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.XSdata('UO2.300k', groups) +uo2_xsdata = openmc.XSdata('UO2.300K', groups) uo2_xsdata.order = 0 uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, 0.5644058]) @@ -43,7 +43,7 @@ uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, 0.0000E+00, 0.0000E+00, 0.0000E+00]) -h2o_xsdata = openmc.XSdata('LWTR.300k', groups) +h2o_xsdata = openmc.XSdata('LWTR.300K', groups) h2o_xsdata.order = 0 h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, 0.718, 1.2544497, 2.650379]) @@ -57,7 +57,7 @@ scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0 [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]] -h2o_xsdata.scatter = np.array(scatter[:][:]) +h2o_xsdata.scatter = np.array(scatter) mg_cross_sections_file = openmc.MGXSLibraryFile(groups) mg_cross_sections_file.add_xsdatas([uo2_xsdata,h2o_xsdata]) @@ -69,8 +69,8 @@ mg_cross_sections_file.export_to_xml() ############################################################################### # Instantiate some Macroscopic Data -uo2_data = openmc.Macroscopic('UO2', '300k') -h2o_data = openmc.Macroscopic('LWTR', '300k') +uo2_data = openmc.Macroscopic('UO2', '300K') +h2o_data = openmc.Macroscopic('LWTR', '300K') # Instantiate some Materials and register the appropriate Nuclides uo2 = openmc.Material(material_id=1, name='UO2 fuel') @@ -83,7 +83,7 @@ water.add_macroscopic(h2o_data) # Instantiate a MaterialsFile, register all Materials, and export to XML materials_file = openmc.MaterialsFile() -materials_file.default_xs = '300k' +materials_file.default_xs = '300K' materials_file.add_materials([uo2, water]) materials_file.export_to_xml() @@ -145,11 +145,6 @@ settings_file.inactive = inactive settings_file.particles = particles settings_file.set_source_space('box', [-0.63, -0.63, -1, \ 0.63, 0.63, 1]) -settings_file.entropy_lower_left = [-0.54, -0.54, -1.e50] -settings_file.entropy_upper_right = [0.54, 0.54, 1.e50] -settings_file.entropy_dimension = [10, 10, 1] -settings_file.export_to_xml() - ############################################################################### # Exporting to OpenMC tallies.xml File diff --git a/examples/xml/pincell_multigroup/materials.xml b/examples/xml/pincell_multigroup/materials.xml index 930fc09085..4b14f4a795 100644 --- a/examples/xml/pincell_multigroup/materials.xml +++ b/examples/xml/pincell_multigroup/materials.xml @@ -1,7 +1,7 @@ - - 71c + + 300K diff --git a/examples/xml/pincell_multigroup/settings.xml b/examples/xml/pincell_multigroup/settings.xml index 6bd27df3dd..dfd2fac813 100644 --- a/examples/xml/pincell_multigroup/settings.xml +++ b/examples/xml/pincell_multigroup/settings.xml @@ -27,12 +27,6 @@ - - - 2000 - true - - true true diff --git a/openmc/material.py b/openmc/material.py index e429190dc1..e51586205d 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -50,8 +50,8 @@ class Material(object): Density of the material (units defined separately) density_units : str Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/cm3', - 'atom/b-cm', 'atom/cm3', 'sum', or 'macro' (the latter only applies - if in multi-group mode). + 'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only + applies in the case of a multi-group calculation. """ @@ -346,7 +346,7 @@ class Material(object): 'has already been added'.format(self._id, macroscopic) raise ValueError(msg) - if not isinstance(macroscopic, (openmc.Macroscopic, str)): + if not isinstance(macroscopic, (openmc.Macroscopic, basestring)): msg = 'Unable to add a Macroscopic to Material ID="{0}" with a ' \ 'non-Macroscopic value "{1}"'.format(self._id, macroscopic) raise ValueError(msg) @@ -511,7 +511,7 @@ class Material(object): return xml_element - def _get_macroscopic_xml(self, macroscopic, distrib=False): + def _get_macroscopic_xml(self, macroscopic): xml_element = ET.Element("macroscopic") xml_element.set("name", macroscopic._name) @@ -626,8 +626,7 @@ class Material(object): subelement.append(subsubelement) else: # Create macroscopic XML subelements - subsubelement = self._get_macroscopic_xml(self, - self._macroscopic, + subsubelement = self._get_macroscopic_xml(self._macroscopic, distrib=True) subelement.append(subsubelement) diff --git a/openmc/mgxs/groups.py b/openmc/mgxs/groups.py index 3436c0e037..e6838b36ba 100644 --- a/openmc/mgxs/groups.py +++ b/openmc/mgxs/groups.py @@ -54,7 +54,7 @@ class EnergyGroups(object): def __eq__(self, other): if not isinstance(other, EnergyGroups): return False - elif self.group_edges != other.group_edges: + elif (self.group_edges != other.group_edges).all(): return False else: return True diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 605fc7064d..3b6b7753ea 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -15,7 +15,7 @@ from openmc.checkvalue import check_type, check_value, check_greater_than, \ from openmc.clean_xml import * # Supported incoming particle MGXS angular treatment representations -REPRESENTATIONS = ['isotropic', 'angle'] +_REPRESENTATIONS = ['isotropic', 'angle'] def ndarray_to_string(arr): """Converts a numpy ndarray in to a join with spaces between entries @@ -87,7 +87,7 @@ class XSdata(object): name : str, optional Name of the mgxs data set. - representation : {'isotropic' or 'angle'} + representation : {'isotropic', 'angle'} Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' @@ -241,7 +241,7 @@ class XSdata(object): @representation.setter def representation(self, representation): # Check it is of valid type. - check_value('representation', representation, REPRESENTATIONS) + check_value('representation', representation, _REPRESENTATIONS) self._representation = representation @alias.setter diff --git a/openmc/settings.py b/openmc/settings.py index 8a562a5455..cf8b674cf7 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -72,12 +72,10 @@ class SettingsFile(object): environment variable will be used for continuous-energy calculations and :envvar:`MG_CROSS_SECTIONS` will be used for multi-group calculations to find the path to the XML cross section file. - energy_grid : str - Set the method used to search energy grids. Acceptable values are - 'nuclide', 'logarithm', and 'material-union'. - energy_mode : str + energy_grid : {'nuclide', 'logarithm', 'material-union'} + Set the method used to search energy grids. + energy_mode : {'continuous-energy', 'multi-group'} Set whether the calculation should be continuous-energy or multi-group. - Acceptable values are 'continuous-energy' or 'multi-group' max_order : int Maximum scattering order to apply globally when in multi-group mode. ptables : bool @@ -495,7 +493,7 @@ class SettingsFile(object): @max_order.setter def max_order(self, max_order): check_type('maximum scattering order', max_order, Integral) - check_greater_than('maximum scattering order', max_order, 0) + check_greater_than('maximum scattering order', max_order, 0, True) self._max_order = max_order @source_file.setter diff --git a/openmc/summary.py b/openmc/summary.py index 80f9fc3976..e3a5743f95 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -60,7 +60,7 @@ class Summary(object): self.date_and_time = self._f['date_and_time'][...] # Read if continuous-energy or multi-group - self.run_CE = bool(self._f['run_CE'].value) + self.run_CE = (self._f['run_CE'].value == 1) self.n_batches = self._f['n_batches'].value self.n_particles = self._f['n_particles'].value @@ -278,7 +278,7 @@ class Summary(object): # Get the distribcell index ind = self._f['geometry/cells'][key]['distribcell_index'].value if ind != 0: - cell.distribcell_index = ind + cell.distribcell_index = ind # Add the Cell to the global dictionary of all Cells self.cells[index] = cell diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index 4588444d05..5e22d38559 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -108,7 +108,7 @@ contains do i = 1, ng found = .false. do g = 1, energy_groups + 1 - if (cmfd%egrid(i) == energy_bins(g)) then + if (cmfd % egrid(i) == energy_bins(g)) then found = .true. exit end if diff --git a/src/initialize.F90 b/src/initialize.F90 index 820367f821..ed57652fb2 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -16,7 +16,7 @@ module initialize hdf5_tallyresult_t, hdf5_integer8_t use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml use material_header, only: Material - use mgxs_data + use mgxs_data, only: read_mgxs, same_nuclide_mg_list, create_macro_xs use output, only: title, header, print_version, write_message, & print_usage, write_xs_summary, print_plot use random_lcg, only: initialize_prng diff --git a/src/input_xml.F90 b/src/input_xml.F90 index a6f836ac61..963cf4a829 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -109,7 +109,7 @@ contains temp_str = trim(to_lower(temp_str)) if (temp_str == "mg" .or. temp_str == "multi-group") then run_CE = .false. - else if (temp_str == "ce" .or. temp_str == "continuous") then + else if (temp_str == "ce" .or. temp_str == "continuous-energy") then run_CE = .true. end if end if @@ -406,7 +406,7 @@ contains inquire(FILE=path_source, EXIST=file_exists) if (.not. file_exists) then call fatal_error("Binary source file '" // trim(path_source) & - &// "' does not exist!") + // "' does not exist!") end if else @@ -433,7 +433,7 @@ contains coeffs_reqd = 3 case default call fatal_error("Invalid spatial distribution for external source: "& - &// trim(type)) + // trim(type)) end select ! Determine number of parameters specified @@ -481,7 +481,7 @@ contains external_source % type_angle = SRC_ANGLE_TABULAR case default call fatal_error("Invalid angular distribution for external source: "& - &// trim(type)) + // trim(type)) end select ! Determine number of parameters specified @@ -532,7 +532,7 @@ contains external_source % type_energy = SRC_ENERGY_TABULAR case default call fatal_error("Invalid energy distribution for external source: " & - &// trim(type)) + // trim(type)) end select ! Determine number of parameters specified @@ -926,7 +926,7 @@ contains ! check to make sure a nuclide is specified if (.not. check_for_node(node_scatterer, "nuclide")) then call fatal_error("No nuclide specified for scatterer " & - &// trim(to_str(i)) // " in settings.xml file!") + // trim(to_str(i)) // " in settings.xml file!") end if call get_node_value(node_scatterer, "nuclide", & nuclides_0K(i) % nuclide) @@ -940,7 +940,7 @@ contains if (.not. check_for_node(node_scatterer, "xs_label")) then call fatal_error("Must specify the temperature dependent name of & &scatterer " // trim(to_str(i)) & - &// " given in cross_sections.xml") + // " given in cross_sections.xml") end if call get_node_value(node_scatterer, "xs_label", & nuclides_0K(i) % name) @@ -948,7 +948,7 @@ contains ! check to make sure 0K xs name for which method is applied is given if (.not. check_for_node(node_scatterer, "xs_label_0K")) then call fatal_error("Must specify the 0K name of scatterer " & - &// trim(to_str(i)) // " given in cross_sections.xml") + // trim(to_str(i)) // " given in cross_sections.xml") end if call get_node_value(node_scatterer, "xs_label_0K", & nuclides_0K(i) % name_0K) @@ -1008,7 +1008,7 @@ contains default_expand = JENDL_40 case default call fatal_error("Unknown natural element expansion option: " & - &// trim(temp_str)) + // trim(temp_str)) end select end if @@ -1125,7 +1125,7 @@ contains ! Check to make sure 'id' hasn't been used if (cell_dict % has_key(c % id)) then call fatal_error("Two or more cells use the same unique ID: " & - &// to_str(c % id)) + // to_str(c % id)) end if ! Read material @@ -1146,14 +1146,14 @@ contains ! Check for error if (c % material == ERROR_INT) then call fatal_error("Invalid material specified on cell " & - &// to_str(c % id)) + // to_str(c % id)) end if end select ! Check to make sure that either material or fill was specified if (c % material == NONE .and. c % fill == NONE) then call fatal_error("Neither material nor fill was specified for cell " & - &// trim(to_str(c % id))) + // trim(to_str(c % id))) end if ! Check to make sure that both material and fill haven't been @@ -1213,7 +1213,7 @@ contains n = get_arraysize_double(node_cell, "rotation") if (n /= 3) then call fatal_error("Incorrect number of rotation parameters on cell " & - &// to_str(c % id)) + // to_str(c % id)) end if ! Copy rotation angles in x,y,z directions @@ -1241,7 +1241,7 @@ contains ! another universe if (c % fill == NONE) then call fatal_error("Cannot apply a translation to cell " & - &// trim(to_str(c % id)) // " because it is not filled with & + // trim(to_str(c % id)) // " because it is not filled with & &another universe") end if @@ -1357,7 +1357,7 @@ contains ! Check to make sure 'id' hasn't been used if (surface_dict % has_key(s%id)) then call fatal_error("Two or more surfaces use the same unique ID: " & - &// to_str(s%id)) + // to_str(s%id)) end if ! Copy surface name @@ -1372,10 +1372,10 @@ contains n = get_arraysize_double(node_surf, "coeffs") if (n < coeffs_reqd) then call fatal_error("Not enough coefficients specified for surface: " & - &// trim(to_str(s%id))) + // trim(to_str(s%id))) elseif (n > coeffs_reqd) then call fatal_error("Too many coefficients specified for surface: " & - &// trim(to_str(s%id))) + // trim(to_str(s%id))) end if allocate(coeffs(n)) @@ -1501,7 +1501,7 @@ contains ! Check to make sure 'id' hasn't been used if (lattice_dict % has_key(lat % id)) then call fatal_error("Two or more lattices use the same unique ID: " & - &// to_str(lat % id)) + // to_str(lat % id)) end if ! Copy lattice name @@ -1629,7 +1629,7 @@ contains ! Check to make sure 'id' hasn't been used if (lattice_dict % has_key(lat % id)) then call fatal_error("Two or more lattices use the same unique ID: " & - &// to_str(lat % id)) + // to_str(lat % id)) end if ! Copy lattice name @@ -1883,7 +1883,7 @@ contains ! Check to make sure 'id' hasn't been used if (material_dict % has_key(mat % id)) then call fatal_error("Two or more materials use the same unique ID: " & - &// to_str(mat % id)) + // to_str(mat % id)) end if ! Copy material name @@ -1906,7 +1906,7 @@ contains call get_node_ptr(node_mat, "density", node_dens) else call fatal_error("Must specify density element in material " & - &// trim(to_str(mat % id))) + // trim(to_str(mat % id))) end if ! Initialize value to zero @@ -1943,7 +1943,7 @@ contains sum_density = .false. if (val <= ZERO) then call fatal_error("Need to specify a positive density on material " & - &// trim(to_str(mat % id)) // ".") + // trim(to_str(mat % id)) // ".") end if ! Adjust material density based on specified units @@ -1958,7 +1958,7 @@ contains mat % density = 1.0e-24_8 * val case default call fatal_error("Unkwown units '" // trim(units) & - &// "' specified on material " // trim(to_str(mat % id))) + // "' specified on material " // trim(to_str(mat % id))) end select end if @@ -1981,7 +1981,7 @@ contains call get_node_list(node_mat, "macroscopic", node_macro_list) if (get_list_size(node_macro_list) > 1) then call fatal_error("Only one macroscopic object permitted per material, " & - &// trim(to_str(mat % id))) + // trim(to_str(mat % id))) else if (get_list_size(node_macro_list) == 1) then call get_list_item(node_macro_list, 1, node_nuc) @@ -1989,7 +1989,7 @@ contains ! Check for empty name on nuclide if (.not.check_for_node(node_nuc, "name")) then call fatal_error("No name specified on macroscopic data in material " & - &// trim(to_str(mat % id))) + // trim(to_str(mat % id))) end if ! Check for cross section @@ -2033,7 +2033,7 @@ contains call list_density % append(ONE) else call fatal_error("Units can only be macro for macroscopic data " & - &// trim(name)) + // trim(name)) end if else @@ -2048,7 +2048,7 @@ contains ! Check for empty name on nuclide if (.not.check_for_node(node_nuc, "name")) then call fatal_error("No name specified on nuclide in material " & - &// trim(to_str(mat % id))) + // trim(to_str(mat % id))) end if ! Check for cross section @@ -2079,7 +2079,7 @@ contains if (.not.check_for_node(node_nuc, "ao") .and. & .not.check_for_node(node_nuc, "wo")) then call fatal_error("No atom or weight percent specified for nuclide " & - &// trim(name)) + // trim(name)) elseif (check_for_node(node_nuc, "ao") .and. & check_for_node(node_nuc, "wo")) then call fatal_error("Cannot specify both atom and weight percents for a & @@ -2110,7 +2110,7 @@ contains ! Check for empty name on natural element if (.not.check_for_node(node_ele, "name")) then call fatal_error("No name specified on nuclide in material " & - &// trim(to_str(mat % id))) + // trim(to_str(mat % id))) end if call get_node_value(node_ele, "name", name) @@ -2131,7 +2131,7 @@ contains if (.not.check_for_node(node_ele, "ao") .and. & .not.check_for_node(node_ele, "wo")) then call fatal_error("No atom or weight percent specified for element " & - &// trim(name)) + // trim(name)) elseif (check_for_node(node_ele, "ao") .and. & check_for_node(node_ele, "wo")) then call fatal_error("Cannot specify both atom and weight percents for & @@ -2191,7 +2191,7 @@ contains name = trim(list_names % get_item(j)) if (.not. xs_listing_dict % has_key(to_lower(name))) then call fatal_error("Could not find nuclide " // trim(name) & - &// " in cross_sections data file!") + // " in cross_sections data file!") end if if (run_CE) then @@ -2199,7 +2199,7 @@ contains n = len_trim(name) if (name(n:n) /= 'c') then call fatal_error("Cross-section table " // trim(name) & - &// " is not a continuous-energy neutron table.") + // " is not a continuous-energy neutron table.") end if end if @@ -2238,7 +2238,7 @@ contains if (.not. (all(mat % atom_density >= ZERO) .or. & all(mat % atom_density <= ZERO))) then call fatal_error("Cannot mix atom and weight percents in material " & - &// to_str(mat % id)) + // to_str(mat % id)) end if ! Determine density if it is a sum value @@ -2286,7 +2286,7 @@ contains ! Check that this nuclide is listed in the cross_sections.xml file if (.not. xs_listing_dict % has_key(to_lower(name))) then call fatal_error("Could not find S(a,b) table " // trim(name) & - &// " in cross_sections.xml file!") + // " in cross_sections.xml file!") end if ! Find index in xs_listing and set the name and alias according to the @@ -2448,7 +2448,7 @@ contains ! Check to make sure 'id' hasn't been used if (mesh_dict % has_key(m % id)) then call fatal_error("Two or more meshes use the same unique ID: " & - &// to_str(m % id)) + // to_str(m % id)) end if ! Read mesh type @@ -2589,7 +2589,7 @@ contains ! Check to make sure 'id' hasn't been used if (tally_dict % has_key(t % id)) then call fatal_error("Two or more tallies use the same unique ID: " & - &// to_str(t % id)) + // to_str(t % id)) end if ! Copy tally name @@ -2630,7 +2630,7 @@ contains end if else call fatal_error("Bins not set in filter on tally " & - &// trim(to_str(t % id))) + // trim(to_str(t % id))) end if ! Determine type of filter @@ -2722,7 +2722,7 @@ contains m => meshes(i_mesh) else call fatal_error("Could not find mesh " // trim(to_str(id)) & - &// " specified on tally " // trim(to_str(t % id))) + // " specified on tally " // trim(to_str(t % id))) end if ! Determine number of bins -- this is assuming that the tally is @@ -2906,8 +2906,8 @@ contains case default ! Specified tally filter is invalid, raise error call fatal_error("Unknown filter type '" & - &// trim(temp_str) // "' on tally " & - &// trim(to_str(t % id)) // ".") + // trim(temp_str) // "' on tally " & + // trim(to_str(t % id)) // ".") end select @@ -3003,8 +3003,8 @@ contains ! Check if no nuclide was found if (.not. associated(pair_list)) then call fatal_error("Could not find the nuclide " & - &// trim(word) // " specified in tally " & - &// trim(to_str(t % id)) // " in any material.") + // trim(word) // " specified in tally " & + // trim(to_str(t % id)) // " in any material.") end if deallocate(pair_list) @@ -3072,12 +3072,12 @@ contains ! maximum order. ! The above scheme will essentially take the absolute value if (master) call warning("Invalid scattering order of " & - &// trim(to_str(n_order)) // " requested. Setting to the & + // trim(to_str(n_order)) // " requested. Setting to the & &maximum permissible value, " & - &// trim(to_str(MAX_ANG_ORDER))) + // trim(to_str(MAX_ANG_ORDER))) n_order = MAX_ANG_ORDER sarray(j) = trim(MOMENT_STRS(imomstr)) & - &// trim(to_str(MAX_ANG_ORDER)) + // trim(to_str(MAX_ANG_ORDER)) end if ! Find total number of bins for this case if (imomstr >= YN_LOC) then @@ -3139,9 +3139,9 @@ contains ! maximum order. ! The above scheme will essentially take the absolute value if (master) call warning("Invalid scattering order of " & - &// trim(to_str(n_order)) // " requested. Setting to & + // trim(to_str(n_order)) // " requested. Setting to & &the maximum permissible value, " & - &// trim(to_str(MAX_ANG_ORDER))) + // trim(to_str(MAX_ANG_ORDER))) n_order = MAX_ANG_ORDER end if score_name = trim(MOMENT_N_STRS(imomstr)) // "n" @@ -3293,9 +3293,21 @@ contains case ('n2n', '(n,2n)') t % score_bins(j) = N_2N + ! Disallow for MG mode since data not present + if (.not. run_CE) then + call fatal_error("Cannot tally (n,2n) reaction rate in & + &multi-group mode") + end if + case ('n3n', '(n,3n)') t % score_bins(j) = N_3N + ! Disallow for MG mode since data not present + if (.not. run_CE) then + call fatal_error("Cannot tally (n,3n) reaction rate in & + &multi-group mode") + end if + case ('n4n', '(n,4n)') t % score_bins(j) = N_4N @@ -3480,13 +3492,13 @@ contains t % score_bins(j) = MT else call fatal_error("Invalid MT on : " & - &// trim(sarray(l))) + // trim(sarray(l))) end if else ! Specified score was not an integer call fatal_error("Unknown scoring function: " & - &// trim(sarray(l))) + // trim(sarray(l))) end if end select @@ -3507,7 +3519,7 @@ contains deallocate(sarray) else call fatal_error("No specified on tally " & - &// trim(to_str(t % id)) // ".") + // trim(to_str(t % id)) // ".") end if ! If settings.xml trigger is turned on, create tally triggers @@ -3768,7 +3780,7 @@ contains inquire(FILE=filename, EXIST=file_exists) if (.not. file_exists) then call fatal_error("Plots XML file '" // trim(filename) & - &// "' does not exist!") + // "' does not exist!") end if ! Display output message @@ -3800,7 +3812,7 @@ contains ! Check to make sure 'id' hasn't been used if (plot_dict % has_key(pl % id)) then call fatal_error("Two or more plots use the same unique ID: " & - &// to_str(pl % id)) + // to_str(pl % id)) end if ! Copy plot type @@ -3815,7 +3827,7 @@ contains pl % type = PLOT_TYPE_VOXEL case default call fatal_error("Unsupported plot type '" // trim(temp_str) & - &// "' in plot " // trim(to_str(pl % id))) + // "' in plot " // trim(to_str(pl % id))) end select ! Set output file path @@ -3835,14 +3847,14 @@ contains call get_node_array(node_plot, "pixels", pl % pixels(1:2)) else call fatal_error(" must be length 2 in slice plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if else if (pl % type == PLOT_TYPE_VOXEL) then if (get_arraysize_integer(node_plot, "pixels") == 3) then call get_node_array(node_plot, "pixels", pl % pixels(1:3)) else call fatal_error(" must be length 3 in voxel plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if end if @@ -3850,13 +3862,13 @@ contains if (check_for_node(node_plot, "background")) then if (pl % type == PLOT_TYPE_VOXEL) then if (master) call warning("Background color ignored in voxel plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if if (get_arraysize_integer(node_plot, "background") == 3) then call get_node_array(node_plot, "background", pl % not_found % rgb) else call fatal_error("Bad background RGB in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if else pl % not_found % rgb = (/ 255, 255, 255 /) @@ -3877,7 +3889,7 @@ contains pl % basis = PLOT_BASIS_YZ case default call fatal_error("Unsupported plot basis '" // trim(temp_str) & - &// "' in plot " // trim(to_str(pl % id))) + // "' in plot " // trim(to_str(pl % id))) end select end if @@ -3886,7 +3898,7 @@ contains call get_node_array(node_plot, "origin", pl % origin) else call fatal_error("Origin must be length 3 in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if ! Copy plotting width @@ -3895,14 +3907,14 @@ contains call get_node_array(node_plot, "width", pl % width(1:2)) else call fatal_error(" must be length 2 in slice plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if else if (pl % type == PLOT_TYPE_VOXEL) then if (get_arraysize_double(node_plot, "width") == 3) then call get_node_array(node_plot, "width", pl % width(1:3)) else call fatal_error(" must be length 3 in voxel plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if end if @@ -3912,7 +3924,7 @@ contains if (pl % level < 0) then call fatal_error("Bad universe level in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if else pl % level = PLOT_LEVEL_LOWEST @@ -3946,7 +3958,7 @@ contains case default call fatal_error("Unsupported plot color type '" // trim(temp_str) & - &// "' in plot " // trim(to_str(pl % id))) + // "' in plot " // trim(to_str(pl % id))) end select ! Get the number of nodes and get a list of them @@ -3969,7 +3981,7 @@ contains ! Check and make sure 3 values are specified for RGB if (get_arraysize_double(node_col, "rgb") /= 3) then call fatal_error("Bad RGB in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if ! Ensure that there is an id for this color specification @@ -3988,7 +4000,7 @@ contains call get_node_array(node_col, "rgb", pl % colors(col_id) % rgb) else call fatal_error("Could not find cell " // trim(to_str(col_id)) & - &// " specified in plot " // trim(to_str(pl % id))) + // " specified in plot " // trim(to_str(pl % id))) end if else if (pl % color_by == PLOT_COLOR_MATS) then @@ -3998,8 +4010,8 @@ contains call get_node_array(node_col, "rgb", pl % colors(col_id) % rgb) else call fatal_error("Could not find material " & - &// trim(to_str(col_id)) // " specified in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(col_id)) // " specified in plot " & + // trim(to_str(pl % id))) end if end if @@ -4013,7 +4025,7 @@ contains if (pl % type == PLOT_TYPE_VOXEL) then call warning("Meshlines ignored in voxel plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if select case(n_meshlines) @@ -4047,7 +4059,7 @@ contains ! Check and make sure 3 values are specified for RGB if (get_arraysize_double(node_meshlines, "color") /= 3) then call fatal_error("Bad RGB for meshlines color in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if call get_node_array(node_meshlines, "color", & @@ -4064,7 +4076,7 @@ contains if (.not. associated(ufs_mesh)) then call fatal_error("No UFS mesh for meshlines on plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if pl % meshlines_mesh => ufs_mesh @@ -4085,7 +4097,7 @@ contains if (.not. associated(entropy_mesh)) then call fatal_error("No entropy mesh for meshlines on plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if if (.not. allocated(entropy_mesh % dimension)) then @@ -4114,18 +4126,18 @@ contains end if else call fatal_error("Could not find mesh " & - &// trim(to_str(meshid)) // " specified in meshlines for & + // trim(to_str(meshid)) // " specified in meshlines for & &plot " // trim(to_str(pl % id))) end if case default call fatal_error("Invalid type for meshlines on plot " & - &// trim(to_str(pl % id)) // ": " // trim(meshtype)) + // trim(to_str(pl % id)) // ": " // trim(meshtype)) end select case default call fatal_error("Mutliple meshlines specified in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end select end if @@ -4137,13 +4149,13 @@ contains if (pl % type == PLOT_TYPE_VOXEL) then if (master) call warning("Mask ignored in voxel plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if select case(n_masks) case default call fatal_error("Mutliple masks specified in plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) case (1) ! Get pointer to mask @@ -4154,7 +4166,7 @@ contains n_comp = get_arraysize_integer(node_mask, "components") if (n_comp == 0) then call fatal_error("Missing in mask of plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if allocate(iarray(n_comp)) call get_node_array(node_mask, "components", iarray) @@ -4170,7 +4182,7 @@ contains iarray(j) = cell_dict % get_key(col_id) else call fatal_error("Could not find cell " & - &// trim(to_str(col_id)) // " specified in the mask in & + // trim(to_str(col_id)) // " specified in the mask in & &plot " // trim(to_str(pl % id))) end if @@ -4180,7 +4192,7 @@ contains iarray(j) = material_dict % get_key(col_id) else call fatal_error("Could not find material " & - &// trim(to_str(col_id)) // " specified in the mask in & + // trim(to_str(col_id)) // " specified in the mask in & &plot " // trim(to_str(pl % id))) end if @@ -4194,7 +4206,7 @@ contains call get_node_array(node_mask, "background", pl % colors(j) % rgb) else call fatal_error("Missing in mask of plot " & - &// trim(to_str(pl % id))) + // trim(to_str(pl % id))) end if end if end do @@ -4239,7 +4251,7 @@ contains if (.not. file_exists) then ! Could not find cross_sections.xml file call fatal_error("Cross sections XML file '" & - &// trim(path_cross_sections) // "' does not exist!") + // trim(path_cross_sections) // "' does not exist!") end if call write_message("Reading cross sections XML file...", 5) @@ -4269,7 +4281,7 @@ contains filetype = ASCII else call fatal_error("Unknown filetype in cross_sections.xml: " & - &// trim(temp_str)) + // trim(temp_str)) end if ! copy default record length and entries for binary files @@ -4367,8 +4379,8 @@ contains do i = 1, n_res_scatterers_total if (.not. xs_listing_dict % has_key(trim(nuclides_0K(i) % name_0K))) then call fatal_error("Could not find nuclide " & - &// trim(nuclides_0K(i) % name_0K) & - &// " in cross_sections.xml file!") + // trim(nuclides_0K(i) % name_0K) & + // " in cross_sections.xml file!") end if end do @@ -4385,14 +4397,13 @@ contains type(Node), pointer :: doc => null() type(Node), pointer :: node_xsdata => null() type(NodeList), pointer :: node_xsdata_list => null() - ! character(MAX_LINE_LEN) :: temp_str ! Check if cross_sections.xml exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then ! Could not find cross_sections.xml file call fatal_error("Cross sections XML file '" & - &// trim(path_cross_sections) // "' does not exist!") + // trim(path_cross_sections) // "' does not exist!") end if call write_message("Reading cross sections XML file...", 5) @@ -4417,7 +4428,7 @@ contains allocate(energy_bin_avg(energy_groups)) do i = 1, energy_groups - energy_bin_avg(i) = 0.5_8 * (energy_bins(i) + energy_bins(i + 1)) + energy_bin_avg(i) = HALF * (energy_bins(i) + energy_bins(i + 1)) end do allocate(inverse_velocities(energy_groups)) @@ -4440,8 +4451,8 @@ contains ! Allocate xs_listings array if (n_listings == 0) then - call fatal_error("No XSDATA listings present in cross_sections.xml & - &file!") + call fatal_error("At least one element must be present in & + &cross_sections.xml file!") else allocate(xs_listings(n_listings)) end if @@ -4474,7 +4485,7 @@ contains if (check_for_node(node_xsdata, "kT")) then call get_node_value(node_xsdata, "kT", listing % kT) else - listing % kT = 2.53E-8_8 + listing % kT = 293.6_8 * K_BOLTZMANN end if ! determine type of cross section diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index d568ab7b55..8109087363 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -370,12 +370,12 @@ contains end if if (get_kfiss) then allocate(this % k_fission(groups)) - if (check_for_node(node_xsdata, "k_fission")) then - call get_node_array(node_xsdata, "k_fission", this % k_fission) + if (check_for_node(node_xsdata, "kappa_fission")) then + call get_node_array(node_xsdata, "kappa_fission", this % k_fission) else error_code = 1 - error_text = "k_fission data missing, required due to kappa-fission& - & tallies in tallies.xml file!" + error_text = "kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!" return end if end if @@ -554,22 +554,22 @@ contains deallocate(temp_arr) else error_code = 1 - error_text = "Fission data missing, required due to kappa-fission& + error_text = "Fission data missing, required due to fission& & tallies in tallies.xml file!" return end if end if if (get_kfiss) then - if (check_for_node(node_xsdata, "k_fission")) then + if (check_for_node(node_xsdata, "kappa_fission")) then allocate(temp_arr(groups * this % Nazi * this % Npol)) - call get_node_array(node_xsdata, "k_fission", temp_arr) + call get_node_array(node_xsdata, "kappa_fission", temp_arr) allocate(this % k_fission(groups, this % Nazi, this % Npol)) this % k_fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) deallocate(temp_arr) else error_code = 1 - error_text = "k_fission data missing, required due to kappa-fission& - & tallies in tallies.xml file!" + error_text = "kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!" return end if end if diff --git a/src/state_point.F90 b/src/state_point.F90 index 4b58cb7704..a49c88cad6 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -727,14 +727,12 @@ contains ! It is not impossible for a state point to be generated from a CE run but ! to be loaded in to an MG run (or vice versa), check to prevent that. call read_dataset(file_id, "run_CE", sp_run_CE) - if (sp_run_CE == 0) then - if (run_CE) & - call fatal_error("State point file is from multi-group run but & - & current run is continous-energy!") - else if (sp_run_CE == 1) then - if (.not. run_CE) & - call fatal_error("State point file is from continuous-energy run but & - & current run is multi-group!") + if (sp_run_CE == 0 .and. run_CE) then + call fatal_error("State point file is from multi-group run but & + & current run is continous-energy!") + else if (sp_run_CE == 1 .and. .not. run_CE) then + call fatal_error("State point file is from continuous-energy run but & + & current run is multi-group!") end if ! Read and overwrite run information except number of batches diff --git a/src/tally.F90 b/src/tally.F90 index 5d978bdcba..842b7644ea 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -778,7 +778,6 @@ contains end if end if - end select !######################################################################### @@ -807,6 +806,14 @@ contains real(8) :: macro_total ! material macro total xs real(8) :: macro_scatt ! material macro scatt xs real(8) :: micro_abs ! nuclidic microscopic abs + real(8) :: p_uvw(3) ! Particle's current uvw + + ! Set the direction, if needed for nuclidic data, so that nuc % get_xs + ! knows wihch direction it should be using for direction-dependent + ! mgxs + if (i_nuclide > 0) then + p_uvw = p % coord(p % n_coord) % uvw + end if i = 0 SCORE_LOOP: do q = 1, t % n_user_score_bins @@ -860,7 +867,7 @@ contains else if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'total', UVW=p % coord(i) % uvw) * & + score = nuc % get_xs(p % g, 'total', UVW=p_uvw) * & atom_density * flux end associate else @@ -902,7 +909,7 @@ contains ! Note SCORE_SCATTER_N not available for tracklength/collision. if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'scatter', UVW=p % coord(i) % uvw) * & + score = nuc % get_xs(p % g, 'scatter', UVW=p_uvw) * & atom_density * flux end associate else @@ -1069,7 +1076,7 @@ contains else if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) & + score = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) & * atom_density * flux end associate else @@ -1085,10 +1092,10 @@ contains ! calculate fraction of absorptions that would have resulted in ! fission associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) & + nuc % get_xs(p % g, 'fission', UVW=p_uvw) & / micro_abs else score = ZERO @@ -1102,20 +1109,20 @@ contains ! fission reaction rate associate (nuc => nuclides_MG(i_nuclide) % obj) score = p % last_wgt & - * nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) & - / nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + * nuc % get_xs(p % g, 'fission', UVW=p_uvw) & + / nuc % get_xs(p % g, 'absorption', UVW=p_uvw) end associate end if else if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) * & + score = nuc % get_xs(p % g, 'fission', UVW=p_uvw) * & atom_density * flux end associate else score = flux * macro_xs(p % material) % obj % get_xs(p % g, & - 'fission', UVW=p % coord(i) % uvw) + 'fission', UVW=p_uvw) end if end if @@ -1139,10 +1146,10 @@ contains ! calculate fraction of absorptions that would have resulted in ! nu-fission associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) / & + nuc % get_xs(p % g, 'fission', UVW=p_uvw) / & micro_abs else score = ZERO @@ -1162,7 +1169,7 @@ contains else if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(i) % uvw) & + score = nuc % get_xs(p % g, 'nu_fission', UVW=p_uvw) & * atom_density * flux end associate else @@ -1180,10 +1187,10 @@ contains ! calculate fraction of absorptions that would have resulted in ! fission scale by kappa-fission associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) if (micro_abs > ZERO) then score = p % absorb_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / & + nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) / & micro_abs end if end associate @@ -1195,20 +1202,20 @@ contains ! the fission energy production rate associate (nuc => nuclides_MG(i_nuclide) % obj) score = p % last_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / & - nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) + nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) / & + nuc % get_xs(p % g, 'absorption', UVW=p_uvw) end associate end if else if (i_nuclide > 0) then associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) & + score = nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) & * atom_density * flux end associate else score = flux * macro_xs(p % material) % obj % get_xs(p % g, & - 'k_fission', UVW=p % coord(i) % uvw) + 'k_fission', UVW=p_uvw) end if end if From 63744db9097e6d59ab9c9fdd357d398bcbcbb8ae Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 3 Feb 2016 10:36:16 -0500 Subject: [PATCH 57/84] Fixing bugs, partially there --- src/ace.F90 | 8 +++-- src/distribution_multivariate.F90 | 6 ++-- src/distribution_univariate.F90 | 10 +++--- src/energy_distribution.F90 | 2 +- src/interpolation.F90 | 6 ++-- src/nuclide_header.F90 | 42 +++++++++-------------- src/output.F90 | 2 +- src/physics.F90 | 4 +-- src/physics_common.F90 | 53 ----------------------------- src/physics_mg.F90 | 6 +--- src/sab_header.F90 | 43 ++++++++++++------------ src/spectra.F90 | 56 ++++++++++++++++++++++++++++++- 12 files changed, 113 insertions(+), 125 deletions(-) diff --git a/src/ace.F90 b/src/ace.F90 index a92d8b8c5a..57564f0b91 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -1,6 +1,6 @@ module ace - use ace_header, only: Nuclide, Reaction, SAlphaBeta, XsListing + use ace_header, only: Reaction use constants use distribution_univariate, only: Uniform, Equiprobable, Tabular use endf, only: is_fission, is_disappearance @@ -11,13 +11,15 @@ module ace use global use list_header, only: ListInt use material_header, only: Material + use nuclide_header use output, only: write_message + use sab_header use set_header, only: SetChar use secondary_header, only: AngleEnergy use secondary_correlated, only: CorrelatedAngleEnergy use secondary_kalbach, only: KalbachMann use secondary_uncorrelated, only: UncorrelatedAngleEnergy - use string, only: to_str, to_lower + use simple_string, only: to_str, to_lower implicit none @@ -1472,7 +1474,7 @@ contains !=============================================================================== subroutine generate_nu_fission(nuc) - type(Nuclide), intent(inout) :: nuc + type(Nuclide_CE), intent(inout) :: nuc integer :: i ! index on nuclide energy grid real(8) :: E ! energy diff --git a/src/distribution_multivariate.F90 b/src/distribution_multivariate.F90 index c288c40c19..e7be36db84 100644 --- a/src/distribution_multivariate.F90 +++ b/src/distribution_multivariate.F90 @@ -1,9 +1,9 @@ module distribution_multivariate - use constants, only: ONE, TWO, PI + use constants, only: ONE, TWO, PI use distribution_univariate, only: Distribution - use math, only: rotate_angle - use random_lcg, only: prn + use random_lcg, only: prn + use spectra, only: rotate_angle implicit none diff --git a/src/distribution_univariate.F90 b/src/distribution_univariate.F90 index f596536d0b..274c6b1155 100644 --- a/src/distribution_univariate.F90 +++ b/src/distribution_univariate.F90 @@ -1,11 +1,11 @@ module distribution_univariate - use constants, only: ZERO, ONE, HALF, HISTOGRAM, LINEAR_LINEAR, & + use constants, only: ZERO, ONE, HALF, HISTOGRAM, LINEAR_LINEAR, & MAX_LINE_LEN, MAX_WORD_LEN - use error, only: fatal_error - use math, only: maxwell_spectrum, watt_spectrum - use random_lcg, only: prn - use string, only: to_lower + use error, only: fatal_error + use random_lcg, only: prn + use spectra, only: maxwell_spectrum, watt_spectrum + use simple_string, only: to_lower use xml_interface implicit none diff --git a/src/energy_distribution.F90 b/src/energy_distribution.F90 index db3dcc4411..7d136ab10e 100644 --- a/src/energy_distribution.F90 +++ b/src/energy_distribution.F90 @@ -3,9 +3,9 @@ module energy_distribution use constants, only: ZERO, ONE, TWO, PI, HISTOGRAM, LINEAR_LINEAR use endf_header, only: Tab1 use interpolation, only: interpolate_tab1 - use math, only: maxwell_spectrum, watt_spectrum use random_lcg, only: prn use search, only: binary_search + use spectra, only: maxwell_spectrum, watt_spectrum !=============================================================================== ! ENERGYDISTRIBUTION (abstract) defines an energy distribution that is a diff --git a/src/interpolation.F90 b/src/interpolation.F90 index 5f87870677..49d3de7fe8 100644 --- a/src/interpolation.F90 +++ b/src/interpolation.F90 @@ -1,9 +1,9 @@ module interpolation use constants - use endf_header, only: Tab1 - use search, only: binary_search - use string, only: to_str + use endf_header, only: Tab1 + use search, only: binary_search + use simple_string, only: to_str implicit none diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index a632f0fc13..72e1a4dc66 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -94,7 +94,7 @@ module nuclide_header integer :: n_precursor ! # of delayed neutron precursors real(8), allocatable :: nu_d_data(:) real(8), allocatable :: nu_d_precursor_data(:) - type(DistEnergy), pointer :: nu_d_edist(:) => null() + type(AngleEnergyContainer), allocatable :: nu_d_edist(:) ! Unresolved resonance data logical :: urr_present @@ -308,16 +308,7 @@ module nuclide_header integer :: i ! Loop counter - if (associated(this % nu_d_edist)) then - do i = 1, size(this % nu_d_edist) - call this % nu_d_edist(i) % clear() - end do - deallocate(this % nu_d_edist) - end if - - if (associated(this % urr_data)) then - deallocate(this % urr_data) - end if + if (associated(this % urr_data)) deallocate(this % urr_data) if (allocated(this % reactions)) then do i = 1, size(this % reactions) @@ -389,7 +380,6 @@ module nuclide_header subroutine nuclide_ce_print(this, unit) class(Nuclide_CE), intent(in) :: this - type(Nuclide), intent(in) :: nuc integer, intent(in), optional :: unit integer :: i ! loop index over nuclides @@ -410,36 +400,36 @@ module nuclide_header size_xs = 0 ! Basic nuclide information - write(unit_,*) 'Nuclide ' // trim(nuc % name) - write(unit_,*) ' zaid = ' // trim(to_str(nuc % zaid)) - write(unit_,*) ' awr = ' // trim(to_str(nuc % awr)) - write(unit_,*) ' kT = ' // trim(to_str(nuc % kT)) - write(unit_,*) ' # of grid points = ' // trim(to_str(nuc % n_grid)) - write(unit_,*) ' Fissionable = ', nuc % fissionable - write(unit_,*) ' # of fission reactions = ' // trim(to_str(nuc % n_fission)) - write(unit_,*) ' # of reactions = ' // trim(to_str(nuc % n_reaction)) + write(unit_,*) 'Nuclide ' // trim(this % name) + write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid)) + write(unit_,*) ' Fissionable = ', this % fissionable + write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission)) + write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction)) ! Information on each reaction write(unit_,*) ' Reaction Q-value COM IE' - do i = 1, nuc % n_reaction - associate (rxn => nuc % reactions(i)) + do i = 1, this % n_reaction + associate (rxn => this % reactions(i)) write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,I6)') & reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, & rxn % threshold ! Accumulate data size - size_xs = size_xs + (nuc % n_grid - rxn%threshold + 1) * 8 + size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8 end associate end do ! Add memory required for summary reactions (total, absorption, fission, ! nu-fission) - size_xs = 8 * nuc % n_grid * 4 + size_xs = 8 * this % n_grid * 4 ! Write information about URR probability tables size_urr = 0 - if (nuc % urr_present) then - urr => nuc % urr_data + if (this % urr_present) then + urr => this % urr_data write(unit_,*) ' Unresolved resonance probability table:' write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy)) write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob)) diff --git a/src/output.F90 b/src/output.F90 index 826bff10cb..5379555ff0 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -2,7 +2,7 @@ module output use, intrinsic :: ISO_FORTRAN_ENV - use ace_header, only: Nuclide, Reaction, UrrData + use ace_header, only: Reaction, UrrData use constants use endf, only: reaction_name use error, only: fatal_error, warning diff --git a/src/physics.F90 b/src/physics.F90 index 9afd6146e4..2212269209 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -1,6 +1,6 @@ module physics - use ace_header, only: Reaction, DistEnergy + use ace_header, only: Reaction use constants use cross_section, only: elastic_xs_0K use endf, only: reaction_name @@ -1343,7 +1343,7 @@ contains p % wgt = yield * p % wgt else do i = 1, rxn % multiplicity - 1 - call p % create_secondary(p % coord(1) % uvw, NEUTRON) + call p % create_secondary(p % coord(1) % uvw, NEUTRON, run_CE=.True.) end do end if diff --git a/src/physics_common.F90 b/src/physics_common.F90 index 9fa45d324b..98d240c077 100644 --- a/src/physics_common.F90 +++ b/src/physics_common.F90 @@ -30,57 +30,4 @@ contains end subroutine russian_roulette -!=============================================================================== -! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is -! mu and through an azimuthal angle sampled uniformly. Note that this is done -! with direct sampling rather than rejection as is done in MCNP and SERPENT. -!=============================================================================== - - function rotate_angle(uvw0, mu, phi) result(uvw) - real(8), intent(in) :: uvw0(3) ! directional cosine - real(8), intent(in) :: mu ! cosine of angle in lab or CM - real(8), optional :: phi ! azimuthal angle - real(8) :: uvw(3) ! rotated directional cosine - - real(8) :: phi_ ! azimuthal angle - real(8) :: sinphi ! sine of azimuthal angle - real(8) :: cosphi ! cosine of azimuthal angle - real(8) :: a ! sqrt(1 - mu^2) - real(8) :: b ! sqrt(1 - w^2) - real(8) :: u0 ! original cosine in x direction - real(8) :: v0 ! original cosine in y direction - real(8) :: w0 ! original cosine in z direction - - ! Copy original directional cosines - u0 = uvw0(1) - v0 = uvw0(2) - w0 = uvw0(3) - - ! Sample azimuthal angle in [0,2pi) if none provided - if (present(phi)) then - phi_ = phi - else - phi_ = TWO * PI * prn() - end if - - ! Precompute factors to save flops - sinphi = sin(phi_) - cosphi = cos(phi_) - a = sqrt(max(ZERO, ONE - mu*mu)) - b = sqrt(max(ZERO, ONE - w0*w0)) - - ! Need to treat special case where sqrt(1 - w**2) is close to zero by - ! expanding about the v component rather than the w component - if (b > 1e-10) then - uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b - uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b - uvw(3) = mu*w0 - a*b*cosphi - else - b = sqrt(ONE - v0*v0) - uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b - uvw(2) = mu*v0 - a*b*cosphi - uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b - end if - - end function rotate_angle end module physics_common diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 5d6167d788..a5272e1f47 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -16,6 +16,7 @@ module physics_mg use random_lcg, only: prn use scattdata_header use simple_string, only: to_str + use spectra, only: rotate_angle implicit none @@ -71,7 +72,6 @@ contains ! absorption (including fission) if (mat % fissionable) then - call sample_fission(i_nuclide, i_reaction) if (run_mode == MODE_EIGENVALUE) then call create_fission_sites(p, fission_bank, n_bank) elseif (run_mode == MODE_FIXEDSOURCE) then @@ -234,10 +234,6 @@ contains ! Bank source neutrons if (nu == 0 .or. size_bank == size(bank_array)) return - ! Initialize counter of delayed neutrons encountered for each delayed group - ! to zero. - nu_d(:) = 0 - p % fission = .true. ! Fission neutrons will be banked do i = int(size_bank,4) + 1, int(min(size_bank + nu, int(size(bank_array),8)),4) ! Bank source neutrons by copying particle data diff --git a/src/sab_header.F90 b/src/sab_header.F90 index b303fee688..a2d70d4f21 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -66,19 +66,18 @@ module sab_header contains - !=============================================================================== ! PRINT_SAB_TABLE displays information about a S(a,b) table containing data ! describing thermal scattering from bound materials such as hydrogen in water. !=============================================================================== subroutine print_sab_table(this, unit) - type(SAlphaBeta), intent(in) :: sab + class(SAlphaBeta), intent(in) :: this integer, intent(in), optional :: unit integer :: size_sab ! memory used by S(a,b) table integer :: unit_ ! unit to write to - integer :: i ! Loop counter for parsing through sab % zaid + integer :: i ! Loop counter for parsing through this % zaid integer :: char_count ! Counter for the number of characters on a line ! set default unit for writing information @@ -89,11 +88,11 @@ module sab_header end if ! Basic S(a,b) table information - write(unit_,*) 'S(a,b) Table ' // trim(sab % name) + write(unit_,*) 'S(a,b) Table ' // trim(this % name) write(unit_,'(A)',advance="no") ' zaids = ' ! Initialize the counter based on the above string char_count = 11 - do i = 1, sab % n_zaid + do i = 1, this % n_zaid ! Deal with a line thats too long if (char_count >= 73) then ! 73 = 80 - (5 ZAID chars + 1 space + 1 comma) ! End the line @@ -103,44 +102,44 @@ module sab_header ! reset the counter to 11 char_count = 11 end if - if (i < sab % n_zaid) then + if (i < this % n_zaid) then ! Include a comma - write(unit_,'(A)',advance="no") trim(to_str(sab % zaid(i))) // ", " - char_count = char_count + len(trim(to_str(sab % zaid(i)))) + 2 + write(unit_,'(A)',advance="no") trim(to_str(this % zaid(i))) // ", " + char_count = char_count + len(trim(to_str(this % zaid(i)))) + 2 else ! Don't include a comma, since we are all done - write(unit_,'(A)',advance="no") trim(to_str(sab % zaid(i))) + write(unit_,'(A)',advance="no") trim(to_str(this % zaid(i))) end if end do write(unit_,*) "" ! Move to next line - write(unit_,*) ' awr = ' // trim(to_str(sab % awr)) - write(unit_,*) ' kT = ' // trim(to_str(sab % kT)) + write(unit_,*) ' awr = ' // trim(to_str(this % awr)) + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) ! Inelastic data write(unit_,*) ' # of Incoming Energies (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_e_in)) + trim(to_str(this % n_inelastic_e_in)) write(unit_,*) ' # of Outgoing Energies (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_e_out)) + trim(to_str(this % n_inelastic_e_out)) write(unit_,*) ' # of Outgoing Angles (Inelastic) = ' // & - trim(to_str(sab % n_inelastic_mu)) + trim(to_str(this % n_inelastic_mu)) write(unit_,*) ' Threshold for Inelastic = ' // & - trim(to_str(sab % threshold_inelastic)) + trim(to_str(this % threshold_inelastic)) ! Elastic data - if (sab % n_elastic_e_in > 0) then + if (this % n_elastic_e_in > 0) then write(unit_,*) ' # of Incoming Energies (Elastic) = ' // & - trim(to_str(sab % n_elastic_e_in)) + trim(to_str(this % n_elastic_e_in)) write(unit_,*) ' # of Outgoing Angles (Elastic) = ' // & - trim(to_str(sab % n_elastic_mu)) + trim(to_str(this % n_elastic_mu)) write(unit_,*) ' Threshold for Elastic = ' // & - trim(to_str(sab % threshold_elastic)) + trim(to_str(this % threshold_elastic)) end if ! Determine memory used by S(a,b) table and write out - size_sab = 8 * (sab % n_inelastic_e_in * (2 + sab % n_inelastic_e_out * & - (1 + sab % n_inelastic_mu)) + sab % n_elastic_e_in * & - (2 + sab % n_elastic_mu)) + size_sab = 8 * (this % n_inelastic_e_in * (2 + this % n_inelastic_e_out * & + (1 + this % n_inelastic_mu)) + this % n_elastic_e_in * & + (2 + this % n_elastic_mu)) write(unit_,*) ' Memory Used = ' // trim(to_str(size_sab)) // ' bytes' ! Blank line at end diff --git a/src/spectra.F90 b/src/spectra.F90 index acdde78206..7f96bb69e5 100644 --- a/src/spectra.F90 +++ b/src/spectra.F90 @@ -1,6 +1,6 @@ module spectra -use constants, only: ONE, TWO, PI +use constants, only: ZERO, ONE, TWO, PI use random_lcg, only: prn implicit none @@ -55,4 +55,58 @@ contains end function watt_spectrum +!=============================================================================== +! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is +! mu and through an azimuthal angle sampled uniformly. Note that this is done +! with direct sampling rather than rejection as is done in MCNP and SERPENT. +!=============================================================================== + + function rotate_angle(uvw0, mu, phi) result(uvw) + real(8), intent(in) :: uvw0(3) ! directional cosine + real(8), intent(in) :: mu ! cosine of angle in lab or CM + real(8), optional :: phi ! azimuthal angle + real(8) :: uvw(3) ! rotated directional cosine + + real(8) :: phi_ ! azimuthal angle + real(8) :: sinphi ! sine of azimuthal angle + real(8) :: cosphi ! cosine of azimuthal angle + real(8) :: a ! sqrt(1 - mu^2) + real(8) :: b ! sqrt(1 - w^2) + real(8) :: u0 ! original cosine in x direction + real(8) :: v0 ! original cosine in y direction + real(8) :: w0 ! original cosine in z direction + + ! Copy original directional cosines + u0 = uvw0(1) + v0 = uvw0(2) + w0 = uvw0(3) + + ! Sample azimuthal angle in [0,2pi) if none provided + if (present(phi)) then + phi_ = phi + else + phi_ = TWO * PI * prn() + end if + + ! Precompute factors to save flops + sinphi = sin(phi_) + cosphi = cos(phi_) + a = sqrt(max(ZERO, ONE - mu*mu)) + b = sqrt(max(ZERO, ONE - w0*w0)) + + ! Need to treat special case where sqrt(1 - w**2) is close to zero by + ! expanding about the v component rather than the w component + if (b > 1e-10) then + uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b + uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b + uvw(3) = mu*w0 - a*b*cosphi + else + b = sqrt(ONE - v0*v0) + uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b + uvw(2) = mu*v0 - a*b*cosphi + uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b + end if + + end function rotate_angle + end module spectra \ No newline at end of file From f83d6344ca79ff4aa0a155a74f81ad392b11bc4e Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 3 Feb 2016 10:42:24 -0500 Subject: [PATCH 58/84] Wow. I think I survived that merge... that was brutal --- src/constants.F90 | 4 ++-- src/input_xml.F90 | 15 --------------- src/mgxs_data.F90 | 18 +++++++++--------- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/constants.F90 b/src/constants.F90 index 6d4d2a0d54..0c208e6d34 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -214,8 +214,8 @@ module constants ! MGXS Table Types integer, parameter :: & - ISOTROPIC = 1, & ! Isotropically Weighted Data - ANGLE = 2 ! Data by Angular Bins + MGXS_ISOTROPIC = 1, & ! Isotropically Weighted Data + MGXS_ANGLE = 2 ! Data by Angular Bins ! Fission neutron emission (nu) type integer, parameter :: & diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 81e5896306..fde77f498e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -428,22 +428,7 @@ contains &// "' does not exist!") end if - ! Read parameters for spatial distribution - if (n < coeffs_reqd) then - call fatal_error("Not enough parameters specified for spatial & - &distribution of external source.") - elseif (n > coeffs_reqd) then - call fatal_error("Too many parameters specified for spatial & - &distribution of external source.") - elseif (n > 0) then - allocate(external_source % params_space(n)) - call get_node_array(node_dist, "parameters", & - external_source % params_space) - end if else - call fatal_error("No spatial distribution specified for external & - &source.") - end if ! Spatial distribution for external source if (check_for_node(node_source, "space")) then diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 8109087363..f48238afa9 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -106,22 +106,22 @@ contains call get_node_value(node_xsdata, "representation", temp_str) temp_str = trim(to_lower(temp_str)) if (temp_str == 'isotropic' .or. temp_str == 'iso') then - representation = ISOTROPIC + representation = MGXS_ISOTROPIC else if (temp_str == 'angle') then - representation = ANGLE + representation = MGXS_ANGLE else call fatal_error("Invalid Data Representation!") end if else ! Default to isotropic representation - representation = ISOTROPIC + representation = MGXS_ISOTROPIC end if ! Now allocate accordingly select case(representation) - case(ISOTROPIC) + case(MGXS_ISOTROPIC) allocate(Nuclide_Iso :: nuclides_MG(i_nuclide) % obj) - case(ANGLE) + case(MGXS_ANGLE) allocate(Nuclide_Angle :: nuclides_MG(i_nuclide) % obj) end select @@ -677,17 +677,17 @@ contains legendre_mu_points = nuclides_MG(mat % nuclide(1)) % obj % legendre_mu_points select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) type is (Nuclide_Iso) - representation = ISOTROPIC + representation = MGXS_ISOTROPIC type is (Nuclide_Angle) - representation = ANGLE + representation = MGXS_ANGLE end select scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type ! Now allocate accordingly select case(representation) - case(ISOTROPIC) + case(MGXS_ISOTROPIC) allocate(MacroXS_Iso :: macro_xs(i_mat) % obj) - case(ANGLE) + case(MGXS_ANGLE) allocate(MacroXS_Angle :: macro_xs(i_mat) % obj) end select From 1aa80bbac86be7f1e13072e82caaec836a71aa89 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 3 Feb 2016 13:00:55 -0500 Subject: [PATCH 59/84] I think I fixed the failing tests. Travis, do your thing --- openmc/settings.py | 2 ++ tests/input_set.py | 3 ++- tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_max_order/inputs_true.dat | 2 +- tests/test_mg_max_order/test_mg_max_order.py | 8 ++++---- tests/test_mg_nuclide/inputs_true.dat | 2 +- tests/test_mg_nuclide/test_mg_nuclide.py | 2 +- tests/test_mg_tallies/inputs_true.dat | 2 +- tests/testing_harness.py | 2 +- 9 files changed, 14 insertions(+), 11 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index 2e4a3f3ce8..2777e8cc14 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1063,6 +1063,8 @@ class SettingsFile(object): self._create_confidence_intervals() self._create_cross_sections_subelement() self._create_energy_grid_subelement() + self._create_energy_mode_subelement() + self._create_max_order_subelement() self._create_ptables_subelement() self._create_run_cmfd_subelement() self._create_seed_subelement() diff --git a/tests/input_set.py b/tests/input_set.py index 956fa81ce1..daff38ba1e 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -641,7 +641,8 @@ class MGInputSet(InputSet): self.settings.batches = 10 self.settings.inactive = 5 self.settings.particles = 100 - self.settings.set_source_space('box', (0.0, 0.0, 0.0, 10.0, 10.0, 2.0)) + self.settings.source = Source(space=Box([0.0, 0.0, 0.0], + [10.0, 10.0, 2.0])) self.settings.energy_mode = "multi-group" self.settings.cross_sections = "../1d_mgxs.xml" diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index 549172b1a9..fdbdb1c968 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -be47096ff6382e07c58c67870eb1c77402c961ee8cb9a4671b52627f6432fe282403e70f5825c90764758fcabe5a480653a961e24d7a0349929283848e79667d \ No newline at end of file +04b4a5099f0097bbe02983c67dea691d0d0d4ece7fb7c264b9b2c29955baa9e870b6fa999480da08ead1e5a0c078ae33ce1b0a5c8594ad465aedf9bf3933e104 \ No newline at end of file diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index 3529d50921..1ad336e195 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1 +1 @@ -7bd8b00b5aaad3913e0022269cf6ef92dfd0051bd79fb136838ea5a65d322d9711b454e62ef03dcf2b9dd75e31a4febcc633f968d7d07dcb6da2e0d36daf45db \ No newline at end of file +abe20c626d613e73ccb1a3f8468ad1b9aecca528afa9e8131a411d754eb86b8ab64a6fb1fdc9c0b8b8158ff7c82f548de5912041bf035aa5a2d4532cfe0c9510 \ No newline at end of file diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py index 423f068f71..2f5ee4e4e6 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -70,16 +70,16 @@ class MGNuclideInputSet(MGInputSet): self.geometry.geometry = geometry -class MGNuclideTestHarness(PyAPITestHarness): +class MGMaxOrderTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): - TestHarness.__init__(self, statepoint_name, tallies_present) + PyAPITestHarness.__init__(self, statepoint_name, tallies_present) self._input_set = MGNuclideInputSet() def _build_inputs(self): - super(MGNuclideTestHarness, self)._build_inputs() + super(MGMaxOrderTestHarness, self)._build_inputs() # Set P1 scattering self._input_set.settings.max_order = 1 if __name__ == '__main__': - harness = MGNuclideTestHarness('statepoint.10.*', False, mg=True) + harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True) harness.main() diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index ea61b92221..eb643bbaf4 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1 +1 @@ -f3d614294177f34186bf0d439330d144438ac6a2402af9b5433efb7bf6a311043140c487c86f4d3cae9d51742f5042823d224c9da6365da6c8972b44edb7fb71 \ No newline at end of file +c9f9e7211bfb2af58130bedfd64592d093b7bfa424953eba433ecf08940595a96b8de7a892f12d1ab465cebd8e5dd784114c1b1299b534ed329df92752c9ed1f \ No newline at end of file diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index 736473bd9f..deb784bad9 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -71,7 +71,7 @@ class MGNuclideInputSet(MGInputSet): class MGNuclideTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): - TestHarness.__init__(self, statepoint_name, tallies_present) + PyAPITestHarness.__init__(self, statepoint_name, tallies_present) self._input_set = MGNuclideInputSet() def _build_inputs(self): diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 063b36923d..304d2e8880 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -dcde495bd5d0ace409154be3529ae91d454e92f7060e38f00bc0880350d53c889b87edcfd481e6c8bcec2450bdf780e6fdc52240978eb1c67a6ef290ad85442d \ No newline at end of file +ca8490e0e4549fed727ddc75b6d92cfe5162e11b905218a0afaa3ce2ee0763e2ff38074de27aaa678818624f49c5823650475dfa8f66f502a98fc03145399c0d \ No newline at end of file diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 78e6e1076d..7d6dbc914f 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -244,7 +244,7 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): def __init__(self, statepoint_name, tallies_present=False, mg=False): - super(PyAPITestHarness, self).__init__(statepoint_name, tallies_present) + super(PyAPITestHarness, self).__init__(statepoint_name, tallies_present) self.parser.add_option('--build-inputs', dest='build_only', action='store_true', default=False) if mg: From 89910d71fd75dcd7013837df7369752fbfef47f1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 3 Feb 2016 13:20:01 -0500 Subject: [PATCH 60/84] Removed need for simple string, merged back in with string --- src/ace.F90 | 2 +- src/cmfd_data.F90 | 30 ++-- src/cmfd_execute.F90 | 22 +-- src/cmfd_input.F90 | 6 +- src/distribution_univariate.F90 | 10 +- src/eigenvalue.F90 | 16 +- src/endf.F90 | 2 +- src/geometry.F90 | 2 +- src/initialize.F90 | 49 +++-- src/input_xml.F90 | 4 +- src/interpolation.F90 | 6 +- src/mgxs_data.F90 | 10 +- src/nuclide_header.F90 | 3 +- src/output.F90 | 2 +- src/particle_restart_write.F90 | 6 +- src/physics.F90 | 2 +- src/physics_mg.F90 | 2 +- src/plot.F90 | 2 +- src/sab_header.F90 | 2 +- src/simple_string.F90 | 308 -------------------------------- src/simulation.F90 | 2 +- src/source.F90 | 2 +- src/state_point.F90 | 3 +- src/string.F90 | 305 ++++++++++++++++++++++++++++++- src/summary.F90 | 2 +- src/tally.F90 | 2 +- src/track_output.F90 | 4 +- src/tracking.F90 | 2 +- src/trigger.F90 | 12 +- 29 files changed, 403 insertions(+), 417 deletions(-) delete mode 100644 src/simple_string.F90 diff --git a/src/ace.F90 b/src/ace.F90 index 57564f0b91..45b58a8d54 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -19,7 +19,7 @@ module ace use secondary_correlated, only: CorrelatedAngleEnergy use secondary_kalbach, only: KalbachMann use secondary_uncorrelated, only: UncorrelatedAngleEnergy - use simple_string, only: to_str, to_lower + use string, only: to_str, to_lower implicit none diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index b624e839d7..347351e318 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -49,17 +49,17 @@ contains subroutine compute_xs() - use constants, only: FILTER_MESH, FILTER_ENERGYIN, FILTER_ENERGYOUT, & - FILTER_SURFACE, IN_RIGHT, OUT_RIGHT, IN_FRONT, & - OUT_FRONT, IN_TOP, OUT_TOP, CMFD_NOACCEL, ZERO, & - ONE, TINY_BIT - use error, only: fatal_error - use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,& - matching_bins - use mesh, only: mesh_indices_to_bin - use mesh_header, only: RegularMesh - use simple_string, only: to_str - use tally_header, only: TallyObject + use constants, only: FILTER_MESH, FILTER_ENERGYIN, FILTER_ENERGYOUT, & + FILTER_SURFACE, IN_RIGHT, OUT_RIGHT, IN_FRONT, & + OUT_FRONT, IN_TOP, OUT_TOP, CMFD_NOACCEL, ZERO, & + ONE, TINY_BIT + use error, only: fatal_error + use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,& + matching_bins + use mesh, only: mesh_indices_to_bin + use mesh_header, only: RegularMesh + use string, only: to_str + use tally_header, only: TallyObject integer :: nx ! number of mesh cells in x direction integer :: ny ! number of mesh cells in y direction @@ -625,10 +625,10 @@ contains subroutine compute_dhat() - use constants, only: CMFD_NOACCEL, ZERO - use global, only: cmfd, cmfd_coremap, dhat_reset - use output, only: write_message - use simple_string, only: to_str + use constants, only: CMFD_NOACCEL, ZERO + use global, only: cmfd, cmfd_coremap, dhat_reset + use output, only: write_message + use string, only: to_str integer :: nx ! maximum number of cells in x direction integer :: ny ! maximum number of cells in y direction diff --git a/src/cmfd_execute.F90 b/src/cmfd_execute.F90 index af6991e47d..b7d0cc3879 100644 --- a/src/cmfd_execute.F90 +++ b/src/cmfd_execute.F90 @@ -89,9 +89,9 @@ contains subroutine calc_fission_source() - use constants, only: CMFD_NOACCEL, ZERO, TWO - use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch - use simple_string, only: to_str + use constants, only: CMFD_NOACCEL, ZERO, TWO + use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch + use string, only: to_str #ifdef MPI use global, only: mpi_err @@ -213,14 +213,14 @@ contains subroutine cmfd_reweight(new_weights) - use constants, only: ZERO, ONE - use error, only: warning, fatal_error - use global, only: meshes, source_bank, work, n_user_meshes, cmfd, & - master - use mesh_header, only: RegularMesh - use mesh, only: count_bank_sites, get_mesh_indices - use search, only: binary_search - use simple_string, only: to_str + use constants, only: ZERO, ONE + use error, only: warning, fatal_error + use global, only: meshes, source_bank, work, n_user_meshes, cmfd, & + master + use mesh_header, only: RegularMesh + use mesh, only: count_bank_sites, get_mesh_indices + use search, only: binary_search + use string, only: to_str #ifdef MPI use global, only: mpi_err diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index 5e22d38559..2d9df4182c 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -45,10 +45,10 @@ contains subroutine read_cmfd_xml() use constants, only: ZERO, ONE - use error, only: fatal_error, warning + use error, only: fatal_error, warning use global - use output, only: write_message - use simple_string, only: to_lower + use output, only: write_message + use string, only: to_lower use xml_interface use, intrinsic :: ISO_FORTRAN_ENV diff --git a/src/distribution_univariate.F90 b/src/distribution_univariate.F90 index 274c6b1155..0ec2959c3b 100644 --- a/src/distribution_univariate.F90 +++ b/src/distribution_univariate.F90 @@ -1,11 +1,11 @@ module distribution_univariate - use constants, only: ZERO, ONE, HALF, HISTOGRAM, LINEAR_LINEAR, & + use constants, only: ZERO, ONE, HALF, HISTOGRAM, LINEAR_LINEAR, & MAX_LINE_LEN, MAX_WORD_LEN - use error, only: fatal_error - use random_lcg, only: prn - use spectra, only: maxwell_spectrum, watt_spectrum - use simple_string, only: to_lower + use error, only: fatal_error + use random_lcg, only: prn + use spectra, only: maxwell_spectrum, watt_spectrum + use string, only: to_lower use xml_interface implicit none diff --git a/src/eigenvalue.F90 b/src/eigenvalue.F90 index 7ed6c34f01..e735bc8d8a 100644 --- a/src/eigenvalue.F90 +++ b/src/eigenvalue.F90 @@ -4,15 +4,15 @@ module eigenvalue use message_passing #endif - use constants, only: ZERO - use error, only: fatal_error, warning + use constants, only: ZERO + use error, only: fatal_error, warning use global - use math, only: t_percentile - use mesh, only: count_bank_sites - use mesh_header, only: RegularMesh - use random_lcg, only: prn, set_particle_seed, prn_skip - use search, only: binary_search - use simple_string, only: to_str + use math, only: t_percentile + use mesh, only: count_bank_sites + use mesh_header, only: RegularMesh + use random_lcg, only: prn, set_particle_seed, prn_skip + use search, only: binary_search + use string, only: to_str implicit none diff --git a/src/endf.F90 b/src/endf.F90 index 0539e8b9d2..64f26539a9 100644 --- a/src/endf.F90 +++ b/src/endf.F90 @@ -1,7 +1,7 @@ module endf use constants - use simple_string, only: to_str + use string, only: to_str implicit none diff --git a/src/geometry.F90 b/src/geometry.F90 index 53e2f29fc2..8a38f982b5 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -10,7 +10,7 @@ module geometry use particle_restart_write, only: write_particle_restart use surface_header use stl_vector, only: VectorInt - use simple_string, only: to_str + use string, only: to_str use tally, only: score_surface_current implicit none diff --git a/src/initialize.F90 b/src/initialize.F90 index 00e5bab443..74bba03e72 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -1,32 +1,31 @@ module initialize - use ace, only: read_ace_xs, same_nuclide_list - use bank_header, only: Bank + use ace, only: read_ace_xs, same_nuclide_list + use bank_header, only: Bank use constants - use dict_header, only: DictIntInt, ElemKeyValueII - use set_header, only: SetInt - use energy_grid, only: logarithmic_grid, grid_method, unionized_grid - use error, only: fatal_error, warning - use geometry, only: neighbor_lists, count_instance, calc_offsets, & - maximum_levels - use geometry_header, only: Cell, Universe, Lattice, RectLattice, HexLattice,& - &BASE_UNIVERSE + use dict_header, only: DictIntInt, ElemKeyValueII + use set_header, only: SetInt + use energy_grid, only: logarithmic_grid, grid_method, unionized_grid + use error, only: fatal_error, warning + use geometry, only: neighbor_lists, count_instance, calc_offsets, & + maximum_levels + use geometry_header, only: Cell, Universe, Lattice, RectLattice, HexLattice,& + &BASE_UNIVERSE use global - use hdf5_interface, only: file_open, read_dataset, file_close, hdf5_bank_t,& - hdf5_tallyresult_t, hdf5_integer8_t - use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml - use material_header, only: Material - use mgxs_data, only: read_mgxs, same_nuclide_mg_list, create_macro_xs - use output, only: title, header, print_version, write_message, & - print_usage, write_xs_summary, print_plot - use random_lcg, only: initialize_prng - use state_point, only: load_state_point - use simple_string, only: to_str, starts_with, ends_with - use string, only: str_to_int - use summary, only: write_summary - use tally_header, only: TallyObject, TallyResult, TallyFilter - use tally_initialize, only: configure_tallies - use tally, only: init_tally_routines + use hdf5_interface, only: file_open, read_dataset, file_close, hdf5_bank_t,& + hdf5_tallyresult_t, hdf5_integer8_t + use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml + use material_header, only: Material + use mgxs_data, only: read_mgxs, same_nuclide_mg_list, create_macro_xs + use output, only: title, header, print_version, write_message, & + print_usage, write_xs_summary, print_plot + use random_lcg, only: initialize_prng + use state_point, only: load_state_point + use string, only: to_str, starts_with, ends_with, str_to_int + use summary, only: write_summary + use tally_header, only: TallyObject, TallyResult, TallyFilter + use tally_initialize,only: configure_tallies + use tally, only: init_tally_routines #ifdef MPI use message_passing diff --git a/src/input_xml.F90 b/src/input_xml.F90 index fde77f498e..e726b6f403 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -17,8 +17,8 @@ module input_xml use random_lcg, only: prn, seed use surface_header use stl_vector, only: VectorInt - use simple_string, only: to_lower, to_str, starts_with, ends_with - use string, only: str_to_int, str_to_real, tokenize + use string, only: str_to_int, str_to_real, tokenize, & + to_lower, to_str, starts_with, ends_with use tally_header, only: TallyObject, TallyFilter use tally_initialize, only: add_tallies use xml_interface diff --git a/src/interpolation.F90 b/src/interpolation.F90 index 49d3de7fe8..5f87870677 100644 --- a/src/interpolation.F90 +++ b/src/interpolation.F90 @@ -1,9 +1,9 @@ module interpolation use constants - use endf_header, only: Tab1 - use search, only: binary_search - use simple_string, only: to_str + use endf_header, only: Tab1 + use search, only: binary_search + use string, only: to_str implicit none diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index f48238afa9..880764edad 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -1,14 +1,14 @@ module mgxs_data use constants - use error, only: fatal_error + use error, only: fatal_error use global use macroxs_header - use material_header, only: Material + use material_header, only: Material use nuclide_header - use output, only: write_message - use set_header, only: SetChar - use simple_string, only: to_lower + use output, only: write_message + use set_header, only: SetChar + use string, only: to_lower use xml_interface implicit none diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 72e1a4dc66..398e91eb20 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -7,8 +7,7 @@ module nuclide_header use endf, only: reaction_name use list_header, only: ListInt use math, only: evaluate_legendre - !use scattdata_header - use simple_string + use string implicit none diff --git a/src/output.F90 b/src/output.F90 index 5379555ff0..29844076e6 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -16,7 +16,7 @@ module output use particle_header, only: LocalCoord, Particle use plot_header use sab_header, only: SAlphaBeta - use simple_string, only: to_upper, to_str + use string, only: to_upper, to_str use tally_header, only: TallyObject implicit none diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index 324e96bc7a..e1a280e9fa 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -1,10 +1,10 @@ module particle_restart_write - use bank_header, only: Bank + use bank_header, only: Bank use global use hdf5_interface - use particle_header, only: Particle - use simple_string, only: to_str + use particle_header, only: Particle + use string, only: to_str use hdf5 diff --git a/src/physics.F90 b/src/physics.F90 index 2212269209..cb216467cd 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -18,7 +18,7 @@ module physics use random_lcg, only: prn use search, only: binary_search use secondary_uncorrelated, only: UncorrelatedAngleEnergy - use simple_string, only: to_str + use string, only: to_str use spectra implicit none diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index a5272e1f47..a8a9084171 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -15,7 +15,7 @@ module physics_mg use physics_common use random_lcg, only: prn use scattdata_header - use simple_string, only: to_str + use string, only: to_str use spectra, only: rotate_angle implicit none diff --git a/src/plot.F90 b/src/plot.F90 index cdddc6d706..796cce6afa 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -14,7 +14,7 @@ module plot use ppmlib, only: Image, init_image, allocate_image, & deallocate_image, set_pixel use progress_header, only: ProgressBar - use simple_string, only: to_str + use string, only: to_str use hdf5 diff --git a/src/sab_header.F90 b/src/sab_header.F90 index a2d70d4f21..56617dd01d 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -3,7 +3,7 @@ module sab_header use, intrinsic :: ISO_FORTRAN_ENV use constants - use simple_string, only: to_str + use string, only: to_str implicit none diff --git a/src/simple_string.F90 b/src/simple_string.F90 deleted file mode 100644 index 65eb58ac0b..0000000000 --- a/src/simple_string.F90 +++ /dev/null @@ -1,308 +0,0 @@ -module simple_string - - use constants, only: ERROR_REAL, ERROR_INT, MAX_LINE_LEN - - implicit none - - interface to_str - module procedure int4_to_str, int8_to_str, real_to_str - end interface - -contains - -!=============================================================================== -! TO_LOWER converts a string to all lower case characters -!=============================================================================== - - pure function to_lower(word) result(word_lower) - character(*), intent(in) :: word - character(len=len(word)) :: word_lower - - integer :: i - integer :: ic - - do i = 1, len(word) - ic = ichar(word(i:i)) - if (ic >= 65 .and. ic <= 90) then - word_lower(i:i) = char(ic+32) - else - word_lower(i:i) = word(i:i) - end if - end do - - end function to_lower - -!=============================================================================== -! TO_UPPER converts a string to all upper case characters -!=============================================================================== - - pure function to_upper(word) result(word_upper) - character(*), intent(in) :: word - character(len=len(word)) :: word_upper - - integer :: i - integer :: ic - - do i = 1, len(word) - ic = ichar(word(i:i)) - if (ic >= 97 .and. ic <= 122) then - word_upper(i:i) = char(ic-32) - else - word_upper(i:i) = word(i:i) - end if - end do - - end function to_upper - -!=============================================================================== -! IS_NUMBER determines whether a string of characters is all 0-9 characters -!=============================================================================== - - pure function is_number(word) result(number) - character(*), intent(in) :: word - logical :: number - - integer :: i - integer :: ic - - number = .true. - do i = 1, len_trim(word) - ic = ichar(word(i:i)) - if (ic < 48 .or. ic >= 58) number = .false. - end do - - end function is_number - -!=============================================================================== -! STARTS_WITH determines whether a string starts with a certain -! sequence of characters -!=============================================================================== - - pure logical function starts_with(str, seq) - character(*), intent(in) :: str ! string to check - character(*), intent(in) :: seq ! sequence of characters - - integer :: i - integer :: i_start - integer :: str_len - integer :: seq_len - - str_len = len_trim(str) - seq_len = len_trim(seq) - - ! determine how many spaces are at beginning of string - i_start = 0 - do i = 1, str_len - if (str(i:i) == ' ' .or. str(i:i) == achar(9)) cycle - i_start = i - exit - end do - - ! Check if string starts with sequence using INDEX intrinsic - if (index(str(1:str_len), seq(1:seq_len)) == i_start) then - starts_with = .true. - else - starts_with = .false. - end if - - end function starts_with - -!=============================================================================== -! ENDS_WITH determines whether a string ends with a certain sequence -! of characters -!=============================================================================== - - pure logical function ends_with(str, seq) - character(*), intent(in) :: str ! string to check - character(*), intent(in) :: seq ! sequence of characters - - integer :: i_start - integer :: str_len - integer :: seq_len - - str_len = len_trim(str) - seq_len = len_trim(seq) - - ! determine how many spaces are at beginning of string - i_start = str_len - seq_len + 1 - - ! Check if string starts with sequence using INDEX intrinsic - if (index(str(1:str_len), seq(1:seq_len), .true.) == i_start) then - ends_with = .true. - else - ends_with = .false. - end if - - end function ends_with - -!=============================================================================== -! COUNT_DIGITS returns the number of digits needed to represent the input -! integer. -!=============================================================================== - - pure function count_digits(num) result(n_digits) - integer, intent(in) :: num - integer :: n_digits - - n_digits = 1 - do while (num / 10**(n_digits) /= 0 .and. abs(num / 10 **(n_digits-1)) /= 1& - &.and. n_digits /= 10) - ! Note that 10 digits is the maximum needed to represent an integer(4) so - ! the loop automatically exits when n_digits = 10. - n_digits = n_digits + 1 - end do - - end function count_digits - -!=============================================================================== -! INT4_TO_STR converts an integer(4) to a string. -!=============================================================================== - - pure function int4_to_str(num) result(str) - - integer, intent(in) :: num - character(11) :: str - - write (str, '(I11)') num - str = adjustl(str) - - end function int4_to_str - -!=============================================================================== -! INT8_TO_STR converts an integer(8) to a string. -!=============================================================================== - - pure function int8_to_str(num) result(str) - - integer(8), intent(in) :: num - character(21) :: str - - write (str, '(I21)') num - str = adjustl(str) - - end function int8_to_str - -!=============================================================================== -! REAL_TO_STR converts a real(8) to a string based on how large the value is and -! how many significant digits are desired. By default, six significants digits -! are used. -!=============================================================================== - - pure function real_to_str(num, sig_digits) result(string) - - real(8), intent(in) :: num ! number to convert - integer, optional, intent(in) :: sig_digits ! # of significant digits - character(15) :: string ! string returned - - integer :: decimal ! number of places after decimal - integer :: width ! total field width - real(8) :: num2 ! absolute value of number - character(9) :: fmt ! format specifier for writing number - - ! set default field width - width = 15 - - ! set number of places after decimal - if (present(sig_digits)) then - decimal = sig_digits - else - decimal = 6 - end if - - ! Create format specifier for writing character - num2 = abs(num) - if (num2 == 0.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, 1 - elseif (num2 < 1.0e-1_8) then - write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 - elseif (num2 >= 1.0e-1_8 .and. num2 < 1.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, decimal - elseif (num2 >= 1.0_8 .and. num2 < 10.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-1, 0) - elseif (num2 >= 10.0_8 .and. num2 < 100.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-2, 0) - elseif (num2 >= 100.0_8 .and. num2 < 1000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-3, 0) - elseif (num2 >= 100.0_8 .and. num2 < 10000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-4, 0) - elseif (num2 >= 10000.0_8 .and. num2 < 100000.0_8) then - write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-5, 0) - else - write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 - end if - - ! Write string and left adjust - write(string, fmt) num - string = adjustl(string) - - end function real_to_str - -!=============================================================================== -! STR_TO_INT converts a string to an integer. -!=============================================================================== - - pure function str_to_int(str) result(num) - - character(*), intent(in) :: str - integer(8) :: num - - character(5) :: fmt - integer :: w - integer :: ioError - - ! Determine width of string - w = len_trim(str) - - ! Create format specifier for reading string - write(UNIT=fmt, FMT='("(I",I2,")")') w - - ! read string into integer - read(UNIT=str, FMT=fmt, IOSTAT=ioError) num - if (ioError > 0) num = ERROR_INT - - end function str_to_int - -!=============================================================================== -! STR_TO_REAL converts an arbitrary string to a real(8) -!=============================================================================== - - pure function str_to_real(string) result(num) - - character(*), intent(in) :: string - real(8) :: num - - integer :: ioError - - ! Read string - read(UNIT=string, FMT=*, IOSTAT=ioError) num - if (ioError > 0) num = ERROR_REAL - - end function str_to_real - -!=============================================================================== -! CONCATENATE takes an array of words and concatenates them together in one -! string with a single space between words -! -! Arguments: -! words = array of words -! n_words = total number of words -! string = concatenated string -!=============================================================================== - - pure function concatenate(words, n_words) result(string) - - integer, intent(in) :: n_words - character(*), intent(in) :: words(n_words) - character(MAX_LINE_LEN) :: string - - integer :: i ! index - - string = words(1) - if (n_words == 1) return - do i = 2, n_words - string = trim(string) // ' ' // words(i) - end do - - end function concatenate - -end module simple_string \ No newline at end of file diff --git a/src/simulation.F90 b/src/simulation.F90 index d1b96d8b08..4a419df906 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -19,7 +19,7 @@ module simulation use random_lcg, only: set_particle_seed use source, only: initialize_source use state_point, only: write_state_point, write_source_point - use simple_string, only: to_str + use string, only: to_str use tally, only: synchronize_tallies, setup_active_usertallies, & reset_result use trigger, only: check_triggers diff --git a/src/source.F90 b/src/source.F90 index 7f56b240b7..601232192a 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -13,7 +13,7 @@ module source use particle_header, only: Particle use random_lcg, only: prn, set_particle_seed, prn_set_stream use search, only: binary_search - use simple_string, only: to_str + use string, only: to_str use spectra use state_point, only: read_source_bank, write_source_bank diff --git a/src/state_point.F90 b/src/state_point.F90 index a46450fc5a..2249e3d45e 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -18,8 +18,7 @@ module state_point use global use hdf5_interface use output, only: write_message, time_stamp - use simple_string, only: to_str, count_digits - use string, only: zero_padded + use string, only: to_str, count_digits, zero_padded use tally_header, only: TallyObject use mesh_header, only: RegularMesh use dict_header, only: ElemKeyValueII, ElemKeyValueCI diff --git a/src/string.F90 b/src/string.F90 index e5f09a50d4..b51763a611 100644 --- a/src/string.F90 +++ b/src/string.F90 @@ -1,13 +1,16 @@ module string - use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & + use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL, & OP_LEFT_PAREN, OP_RIGHT_PAREN, OP_COMPLEMENT, OP_INTERSECTION, OP_UNION - use error, only: fatal_error, warning - use simple_string, only: str_to_int, str_to_real - use stl_vector, only: VectorInt + use error, only: fatal_error, warning + use stl_vector, only: VectorInt implicit none + interface to_str + module procedure int4_to_str, int8_to_str, real_to_str + end interface + contains !=============================================================================== @@ -151,6 +154,75 @@ contains end if end subroutine tokenize +!=============================================================================== +! CONCATENATE takes an array of words and concatenates them together in one +! string with a single space between words +! +! Arguments: +! words = array of words +! n_words = total number of words +! string = concatenated string +!=============================================================================== + + pure function concatenate(words, n_words) result(string) + + integer, intent(in) :: n_words + character(*), intent(in) :: words(n_words) + character(MAX_LINE_LEN) :: string + + integer :: i ! index + + string = words(1) + if (n_words == 1) return + do i = 2, n_words + string = trim(string) // ' ' // words(i) + end do + + end function concatenate + +!=============================================================================== +! TO_LOWER converts a string to all lower case characters +!=============================================================================== + + pure function to_lower(word) result(word_lower) + character(*), intent(in) :: word + character(len=len(word)) :: word_lower + + integer :: i + integer :: ic + + do i = 1, len(word) + ic = ichar(word(i:i)) + if (ic >= 65 .and. ic <= 90) then + word_lower(i:i) = char(ic+32) + else + word_lower(i:i) = word(i:i) + end if + end do + + end function to_lower + +!=============================================================================== +! TO_UPPER converts a string to all upper case characters +!=============================================================================== + + pure function to_upper(word) result(word_upper) + character(*), intent(in) :: word + character(len=len(word)) :: word_upper + + integer :: i + integer :: ic + + do i = 1, len(word) + ic = ichar(word(i:i)) + if (ic >= 97 .and. ic <= 122) then + word_upper(i:i) = char(ic-32) + else + word_upper(i:i) = word(i:i) + end if + end do + + end function to_upper !=============================================================================== ! ZERO_PADDED returns a string of the input integer padded with zeros to the @@ -185,4 +257,229 @@ contains write(str, zp_form) num end function zero_padded +!=============================================================================== +! IS_NUMBER determines whether a string of characters is all 0-9 characters +!=============================================================================== + + pure function is_number(word) result(number) + character(*), intent(in) :: word + logical :: number + + integer :: i + integer :: ic + + number = .true. + do i = 1, len_trim(word) + ic = ichar(word(i:i)) + if (ic < 48 .or. ic >= 58) number = .false. + end do + + end function is_number + +!=============================================================================== +! STARTS_WITH determines whether a string starts with a certain +! sequence of characters +!=============================================================================== + + pure logical function starts_with(str, seq) + character(*), intent(in) :: str ! string to check + character(*), intent(in) :: seq ! sequence of characters + + integer :: i + integer :: i_start + integer :: str_len + integer :: seq_len + + str_len = len_trim(str) + seq_len = len_trim(seq) + + ! determine how many spaces are at beginning of string + i_start = 0 + do i = 1, str_len + if (str(i:i) == ' ' .or. str(i:i) == achar(9)) cycle + i_start = i + exit + end do + + ! Check if string starts with sequence using INDEX intrinsic + if (index(str(1:str_len), seq(1:seq_len)) == i_start) then + starts_with = .true. + else + starts_with = .false. + end if + + end function starts_with + +!=============================================================================== +! ENDS_WITH determines whether a string ends with a certain sequence +! of characters +!=============================================================================== + + pure logical function ends_with(str, seq) + character(*), intent(in) :: str ! string to check + character(*), intent(in) :: seq ! sequence of characters + + integer :: i_start + integer :: str_len + integer :: seq_len + + str_len = len_trim(str) + seq_len = len_trim(seq) + + ! determine how many spaces are at beginning of string + i_start = str_len - seq_len + 1 + + ! Check if string starts with sequence using INDEX intrinsic + if (index(str(1:str_len), seq(1:seq_len), .true.) == i_start) then + ends_with = .true. + else + ends_with = .false. + end if + + end function ends_with + +!=============================================================================== +! COUNT_DIGITS returns the number of digits needed to represent the input +! integer. +!=============================================================================== + + pure function count_digits(num) result(n_digits) + integer, intent(in) :: num + integer :: n_digits + + n_digits = 1 + do while (num / 10**(n_digits) /= 0 .and. abs(num / 10 **(n_digits-1)) /= 1& + &.and. n_digits /= 10) + ! Note that 10 digits is the maximum needed to represent an integer(4) so + ! the loop automatically exits when n_digits = 10. + n_digits = n_digits + 1 + end do + + end function count_digits + +!=============================================================================== +! INT4_TO_STR converts an integer(4) to a string. +!=============================================================================== + + pure function int4_to_str(num) result(str) + + integer, intent(in) :: num + character(11) :: str + + write (str, '(I11)') num + str = adjustl(str) + + end function int4_to_str + +!=============================================================================== +! INT8_TO_STR converts an integer(8) to a string. +!=============================================================================== + + pure function int8_to_str(num) result(str) + + integer(8), intent(in) :: num + character(21) :: str + + write (str, '(I21)') num + str = adjustl(str) + + end function int8_to_str + +!=============================================================================== +! STR_TO_INT converts a string to an integer. +!=============================================================================== + + pure function str_to_int(str) result(num) + + character(*), intent(in) :: str + integer(8) :: num + + character(5) :: fmt + integer :: w + integer :: ioError + + ! Determine width of string + w = len_trim(str) + + ! Create format specifier for reading string + write(UNIT=fmt, FMT='("(I",I2,")")') w + + ! read string into integer + read(UNIT=str, FMT=fmt, IOSTAT=ioError) num + if (ioError > 0) num = ERROR_INT + + end function str_to_int + +!=============================================================================== +! STR_TO_REAL converts an arbitrary string to a real(8) +!=============================================================================== + + pure function str_to_real(string) result(num) + + character(*), intent(in) :: string + real(8) :: num + + integer :: ioError + + ! Read string + read(UNIT=string, FMT=*, IOSTAT=ioError) num + if (ioError > 0) num = ERROR_REAL + + end function str_to_real + +!=============================================================================== +! REAL_TO_STR converts a real(8) to a string based on how large the value is and +! how many significant digits are desired. By default, six significants digits +! are used. +!=============================================================================== + + pure function real_to_str(num, sig_digits) result(string) + + real(8), intent(in) :: num ! number to convert + integer, optional, intent(in) :: sig_digits ! # of significant digits + character(15) :: string ! string returned + + integer :: decimal ! number of places after decimal + integer :: width ! total field width + real(8) :: num2 ! absolute value of number + character(9) :: fmt ! format specifier for writing number + + ! set default field width + width = 15 + + ! set number of places after decimal + if (present(sig_digits)) then + decimal = sig_digits + else + decimal = 6 + end if + + ! Create format specifier for writing character + num2 = abs(num) + if (num2 == 0.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, 1 + elseif (num2 < 1.0e-1_8) then + write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 + elseif (num2 >= 1.0e-1_8 .and. num2 < 1.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, decimal + elseif (num2 >= 1.0_8 .and. num2 < 10.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-1, 0) + elseif (num2 >= 10.0_8 .and. num2 < 100.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-2, 0) + elseif (num2 >= 100.0_8 .and. num2 < 1000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-3, 0) + elseif (num2 >= 100.0_8 .and. num2 < 10000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-4, 0) + elseif (num2 >= 10000.0_8 .and. num2 < 100000.0_8) then + write(fmt, '("(F",I2,".",I2,")")') width, max(decimal-5, 0) + else + write(fmt, '("(ES",I2,".",I2,")")') width, decimal - 1 + end if + + ! Write string and left adjust + write(string, fmt) num + string = adjustl(string) + + end function real_to_str + end module string diff --git a/src/summary.F90 b/src/summary.F90 index 2f255a4fc5..e662aa473b 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -12,7 +12,7 @@ module summary use nuclide_header use output, only: time_stamp use surface_header - use simple_string, only: to_str + use string, only: to_str use tally_header, only: TallyObject use hdf5 diff --git a/src/tally.F90 b/src/tally.F90 index 842b7644ea..bbe099c3e4 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -13,7 +13,7 @@ module tally use output, only: header use particle_header, only: LocalCoord, Particle use search, only: binary_search - use simple_string, only: to_str + use string, only: to_str use tally_header, only: TallyResult, TallyMapItem, TallyMapElement use fission, only: nu_total, nu_delayed, yield_delayed use interpolation, only: interpolate_tab1 diff --git a/src/track_output.F90 b/src/track_output.F90 index 87dbfbfa44..1411738622 100644 --- a/src/track_output.F90 +++ b/src/track_output.F90 @@ -7,8 +7,8 @@ module track_output use global use hdf5_interface - use particle_header, only: Particle - use simple_string, only: to_str + use particle_header, only: Particle + use string, only: to_str use hdf5 diff --git a/src/tracking.F90 b/src/tracking.F90 index 992cc2ca95..0b2719ef5d 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -13,7 +13,7 @@ module tracking use physics, only: collision use physics_mg, only: collision_mg use random_lcg, only: prn - use simple_string, only: to_str + use string, only: to_str use tally, only: score_analog_tally, score_tracklength_tally, & score_collision_tally, score_surface_current use track_output, only: initialize_particle_track, write_particle_track, & diff --git a/src/trigger.F90 b/src/trigger.F90 index 967d74b14e..ed362154b4 100644 --- a/src/trigger.F90 +++ b/src/trigger.F90 @@ -6,12 +6,12 @@ module trigger use constants use global - use simple_string, only: to_str - use output, only: warning, write_message - use mesh, only: mesh_indices_to_bin - use mesh_header, only: RegularMesh - use trigger_header, only: TriggerObject - use tally, only: TallyObject + use string, only: to_str + use output, only: warning, write_message + use mesh, only: mesh_indices_to_bin + use mesh_header, only: RegularMesh + use trigger_header, only: TriggerObject + use tally, only: TallyObject implicit none From 989569ac5e4adb3eb8ea989768c87d5e3e1943fd Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 3 Feb 2016 13:25:51 -0500 Subject: [PATCH 61/84] Removing need for spectra (putting back in math) --- src/distribution_multivariate.F90 | 2 +- src/distribution_univariate.F90 | 2 +- src/energy_distribution.F90 | 10 +-- src/math.F90 | 106 +++++++++++++++++++++++++++- src/physics.F90 | 2 +- src/physics_mg.F90 | 2 +- src/source.F90 | 2 +- src/spectra.F90 | 112 ------------------------------ 8 files changed, 115 insertions(+), 123 deletions(-) delete mode 100644 src/spectra.F90 diff --git a/src/distribution_multivariate.F90 b/src/distribution_multivariate.F90 index e7be36db84..694fac3013 100644 --- a/src/distribution_multivariate.F90 +++ b/src/distribution_multivariate.F90 @@ -3,7 +3,7 @@ module distribution_multivariate use constants, only: ONE, TWO, PI use distribution_univariate, only: Distribution use random_lcg, only: prn - use spectra, only: rotate_angle + use math, only: rotate_angle implicit none diff --git a/src/distribution_univariate.F90 b/src/distribution_univariate.F90 index 0ec2959c3b..f3e4fdee2e 100644 --- a/src/distribution_univariate.F90 +++ b/src/distribution_univariate.F90 @@ -4,7 +4,7 @@ module distribution_univariate MAX_LINE_LEN, MAX_WORD_LEN use error, only: fatal_error use random_lcg, only: prn - use spectra, only: maxwell_spectrum, watt_spectrum + use math, only: maxwell_spectrum, watt_spectrum use string, only: to_lower use xml_interface diff --git a/src/energy_distribution.F90 b/src/energy_distribution.F90 index 7d136ab10e..2cfc1b1841 100644 --- a/src/energy_distribution.F90 +++ b/src/energy_distribution.F90 @@ -1,11 +1,11 @@ module energy_distribution - use constants, only: ZERO, ONE, TWO, PI, HISTOGRAM, LINEAR_LINEAR - use endf_header, only: Tab1 + use constants, only: ZERO, ONE, TWO, PI, HISTOGRAM, LINEAR_LINEAR + use endf_header, only: Tab1 use interpolation, only: interpolate_tab1 - use random_lcg, only: prn - use search, only: binary_search - use spectra, only: maxwell_spectrum, watt_spectrum + use math, only: maxwell_spectrum, watt_spectrum + use random_lcg, only: prn + use search, only: binary_search !=============================================================================== ! ENERGYDISTRIBUTION (abstract) defines an energy distribution that is a diff --git a/src/math.F90 b/src/math.F90 index 9ed82dabb2..aedf182358 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -1,6 +1,7 @@ module math use constants + use random_lcg, only: prn implicit none @@ -580,7 +581,8 @@ contains end function expand_harmonic !=============================================================================== -! EVALUATE_LEGENDRE +! EVALUATE_LEGENDRE Find the value of f(x) given a set of Legendre coefficients +! and the value of x !=============================================================================== pure function evaluate_legendre(data, x) result(val) real(8), intent(in) :: data(:) @@ -596,4 +598,106 @@ contains end function evaluate_legendre +!=============================================================================== +! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is +! mu and through an azimuthal angle sampled uniformly. Note that this is done +! with direct sampling rather than rejection as is done in MCNP and SERPENT. +!=============================================================================== + + function rotate_angle(uvw0, mu, phi) result(uvw) + real(8), intent(in) :: uvw0(3) ! directional cosine + real(8), intent(in) :: mu ! cosine of angle in lab or CM + real(8), optional :: phi ! azimuthal angle + real(8) :: uvw(3) ! rotated directional cosine + + real(8) :: phi_ ! azimuthal angle + real(8) :: sinphi ! sine of azimuthal angle + real(8) :: cosphi ! cosine of azimuthal angle + real(8) :: a ! sqrt(1 - mu^2) + real(8) :: b ! sqrt(1 - w^2) + real(8) :: u0 ! original cosine in x direction + real(8) :: v0 ! original cosine in y direction + real(8) :: w0 ! original cosine in z direction + + ! Copy original directional cosines + u0 = uvw0(1) + v0 = uvw0(2) + w0 = uvw0(3) + + ! Sample azimuthal angle in [0,2pi) if none provided + if (present(phi)) then + phi_ = phi + else + phi_ = TWO * PI * prn() + end if + + ! Precompute factors to save flops + sinphi = sin(phi_) + cosphi = cos(phi_) + a = sqrt(max(ZERO, ONE - mu*mu)) + b = sqrt(max(ZERO, ONE - w0*w0)) + + ! Need to treat special case where sqrt(1 - w**2) is close to zero by + ! expanding about the v component rather than the w component + if (b > 1e-10) then + uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b + uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b + uvw(3) = mu*w0 - a*b*cosphi + else + b = sqrt(ONE - v0*v0) + uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b + uvw(2) = mu*v0 - a*b*cosphi + uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b + end if + + end function rotate_angle + +!=============================================================================== +! MAXWELL_SPECTRUM samples an energy from the Maxwell fission distribution based +! on a direct sampling scheme. The probability distribution function for a +! Maxwellian is given as p(x) = 2/(T*sqrt(pi))*sqrt(x/T)*exp(-x/T). This PDF can +! be sampled using rule C64 in the Monte Carlo Sampler LA-9721-MS. +!=============================================================================== + + function maxwell_spectrum(T) result(E_out) + + real(8), intent(in) :: T ! tabulated function of incoming E + real(8) :: E_out ! sampled energy + + real(8) :: r1, r2, r3 ! random numbers + real(8) :: c ! cosine of pi/2*r3 + + r1 = prn() + r2 = prn() + r3 = prn() + + ! determine cosine of pi/2*r + c = cos(PI/TWO*r3) + + ! determine outgoing energy + E_out = -T*(log(r1) + log(r2)*c*c) + + end function maxwell_spectrum + +!=============================================================================== +! WATT_SPECTRUM samples the outgoing energy from a Watt energy-dependent fission +! spectrum. Although fitted parameters exist for many nuclides, generally the +! continuous tabular distributions (LAW 4) should be used in lieu of the Watt +! spectrum. This direct sampling scheme is an unpublished scheme based on the +! original Watt spectrum derivation (See F. Brown's MC lectures). +!=============================================================================== + + function watt_spectrum(a, b) result(E_out) + + real(8), intent(in) :: a ! Watt parameter a + real(8), intent(in) :: b ! Watt parameter b + real(8) :: E_out ! energy of emitted neutron + + real(8) :: w ! sampled from Maxwellian + + w = maxwell_spectrum(a) + E_out = w + a*a*b/4. + (TWO*prn() - ONE)*sqrt(a*a*b*w) + + end function watt_spectrum + end module math diff --git a/src/physics.F90 b/src/physics.F90 index cb216467cd..13a311d5e3 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -9,6 +9,7 @@ module physics use global use interpolation, only: interpolate_tab1 use material_header, only: Material + use math use mesh, only: get_mesh_indices use nuclide_header use output, only: write_message @@ -19,7 +20,6 @@ module physics use search, only: binary_search use secondary_uncorrelated, only: UncorrelatedAngleEnergy use string, only: to_str - use spectra implicit none diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index a8a9084171..048f3ce54f 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -8,6 +8,7 @@ module physics_mg use macroxs_header, only: MacroXS_Base, MacroXSContainer use macroxs, only: sample_fission_energy, sample_scatter use material_header, only: Material + use math, only: rotate_angle use mesh, only: get_mesh_indices use output, only: write_message use particle_header, only: Particle @@ -16,7 +17,6 @@ module physics_mg use random_lcg, only: prn use scattdata_header use string, only: to_str - use spectra, only: rotate_angle implicit none diff --git a/src/source.F90 b/src/source.F90 index 601232192a..1fb9de5c58 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -14,7 +14,7 @@ module source use random_lcg, only: prn, set_particle_seed, prn_set_stream use search, only: binary_search use string, only: to_str - use spectra + use math use state_point, only: read_source_bank, write_source_bank #ifdef MPI diff --git a/src/spectra.F90 b/src/spectra.F90 deleted file mode 100644 index 7f96bb69e5..0000000000 --- a/src/spectra.F90 +++ /dev/null @@ -1,112 +0,0 @@ -module spectra - -use constants, only: ZERO, ONE, TWO, PI -use random_lcg, only: prn - -implicit none - -contains - -!=============================================================================== -! MAXWELL_SPECTRUM samples an energy from the Maxwell fission distribution based -! on a direct sampling scheme. The probability distribution function for a -! Maxwellian is given as p(x) = 2/(T*sqrt(pi))*sqrt(x/T)*exp(-x/T). This PDF can -! be sampled using rule C64 in the Monte Carlo Sampler LA-9721-MS. -!=============================================================================== - - function maxwell_spectrum(T) result(E_out) - - real(8), intent(in) :: T ! tabulated function of incoming E - real(8) :: E_out ! sampled energy - - real(8) :: r1, r2, r3 ! random numbers - real(8) :: c ! cosine of pi/2*r3 - - r1 = prn() - r2 = prn() - r3 = prn() - - ! determine cosine of pi/2*r - c = cos(PI/TWO*r3) - - ! determine outgoing energy - E_out = -T*(log(r1) + log(r2)*c*c) - - end function maxwell_spectrum - -!=============================================================================== -! WATT_SPECTRUM samples the outgoing energy from a Watt energy-dependent fission -! spectrum. Although fitted parameters exist for many nuclides, generally the -! continuous tabular distributions (LAW 4) should be used in lieu of the Watt -! spectrum. This direct sampling scheme is an unpublished scheme based on the -! original Watt spectrum derivation (See F. Brown's MC lectures). -!=============================================================================== - - function watt_spectrum(a, b) result(E_out) - - real(8), intent(in) :: a ! Watt parameter a - real(8), intent(in) :: b ! Watt parameter b - real(8) :: E_out ! energy of emitted neutron - - real(8) :: w ! sampled from Maxwellian - - w = maxwell_spectrum(a) - E_out = w + a*a*b/4.0_8 + (TWO*prn() - ONE)*sqrt(a*a*b*w) - - end function watt_spectrum - -!=============================================================================== -! ROTATE_ANGLE rotates direction cosines through a polar angle whose cosine is -! mu and through an azimuthal angle sampled uniformly. Note that this is done -! with direct sampling rather than rejection as is done in MCNP and SERPENT. -!=============================================================================== - - function rotate_angle(uvw0, mu, phi) result(uvw) - real(8), intent(in) :: uvw0(3) ! directional cosine - real(8), intent(in) :: mu ! cosine of angle in lab or CM - real(8), optional :: phi ! azimuthal angle - real(8) :: uvw(3) ! rotated directional cosine - - real(8) :: phi_ ! azimuthal angle - real(8) :: sinphi ! sine of azimuthal angle - real(8) :: cosphi ! cosine of azimuthal angle - real(8) :: a ! sqrt(1 - mu^2) - real(8) :: b ! sqrt(1 - w^2) - real(8) :: u0 ! original cosine in x direction - real(8) :: v0 ! original cosine in y direction - real(8) :: w0 ! original cosine in z direction - - ! Copy original directional cosines - u0 = uvw0(1) - v0 = uvw0(2) - w0 = uvw0(3) - - ! Sample azimuthal angle in [0,2pi) if none provided - if (present(phi)) then - phi_ = phi - else - phi_ = TWO * PI * prn() - end if - - ! Precompute factors to save flops - sinphi = sin(phi_) - cosphi = cos(phi_) - a = sqrt(max(ZERO, ONE - mu*mu)) - b = sqrt(max(ZERO, ONE - w0*w0)) - - ! Need to treat special case where sqrt(1 - w**2) is close to zero by - ! expanding about the v component rather than the w component - if (b > 1e-10) then - uvw(1) = mu*u0 + a*(u0*w0*cosphi - v0*sinphi)/b - uvw(2) = mu*v0 + a*(v0*w0*cosphi + u0*sinphi)/b - uvw(3) = mu*w0 - a*b*cosphi - else - b = sqrt(ONE - v0*v0) - uvw(1) = mu*u0 + a*(u0*v0*cosphi + w0*sinphi)/b - uvw(2) = mu*v0 - a*b*cosphi - uvw(3) = mu*w0 + a*(v0*w0*cosphi - u0*sinphi)/b - end if - - end function rotate_angle - -end module spectra \ No newline at end of file From 86d5600eb25e75b60bcdbfab175a71c7d45e8598 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 5 Feb 2016 05:37:50 -0500 Subject: [PATCH 62/84] fixes per @smharpers comments --- docs/source/usersguide/mgxs_library.rst | 25 +- .../python/pincell_multigroup/build-xml.py | 2 +- openmc/macroscopic.py | 2 +- src/global.F90 | 4 - src/input_xml.F90 | 2 +- src/macroxs.F90 | 2 +- src/macroxs_header.F90 | 213 +----------------- src/math.F90 | 2 +- src/mgxs_data.F90 | 3 +- src/nuclide_header.F90 | 10 +- src/particle_header.F90 | 1 - src/scattdata_header.F90 | 87 ++----- src/tally.F90 | 148 ++++++------ 13 files changed, 124 insertions(+), 377 deletions(-) diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index d0dc1e54f5..478b060024 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -114,20 +114,25 @@ attributes/sub-elements required to describe the meta-data: *Default*: "isotropic" :num_azimuthal: - This element provides the number of equi-width bins that the azimuthal - angular domain is subdivided in the case of angle-dependent cross sections - (i.e., "angle" is passed to the ``representation`` element). + This element provides the number of equal width angular bins that the + azimuthal angular domain is subdivided in the case of angle-dependent + cross sections (i.e., "angle" is passed to the ``representation`` element). + Note that these bins are equal in azimuthal angle widths, not equal in the + cosine of the azimuthal angle widths. - *Default*: If ``representation`` is "angle", this must be provided. If - not, this parameter is not used. + *Default*: If ``representation`` is "angle", this must be provided. This + parameter is not used for other ``representation`` types. :num_polar: - This element provides the number of equi-width bins that the polar angular - domain is subdivided in the case of angle-dependent cross sections - (i.e., "angle" is passed to the ``representation`` element). + This element provides the number of equal width angular bins that the + polar angular domain is subdivided in the case of angle-dependent + cross sections (i.e., "angle" is passed to the ``representation`` element). + Note that these bins are equal in polar angle widths, not equal in the + cosine of the polar angle widths. - *Default*: If ``representation`` is "angle", this must be provided. If - not, this parameter is not used. + + *Default*: If ``representation`` is "angle", this must be provided. This + parameter is not used for other ``representation`` types. :scatt_type: This element provides the representation of the angular distribution diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index ba15370c3b..17fbae9941 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -72,7 +72,7 @@ mg_cross_sections_file.export_to_xml() uo2_data = openmc.Macroscopic('UO2', '300K') h2o_data = openmc.Macroscopic('LWTR', '300K') -# Instantiate some Materials and register the appropriate Nuclides +# Instantiate some Materials and register the appropriate Macroscopic objects uo2 = openmc.Material(material_id=1, name='UO2 fuel') uo2.set_density('macro', 1.0) uo2.add_macroscopic(uo2_data) diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py index 094fa50421..9f67a50ba4 100644 --- a/openmc/macroscopic.py +++ b/openmc/macroscopic.py @@ -8,7 +8,7 @@ if sys.version_info[0] >= 3: class Macroscopic(object): - """A nuclide that can be used in a material. + """A Macroscopic object that can be used in a material. Parameters ---------- diff --git a/src/global.F90 b/src/global.F90 index 9b68eab6a4..dda4e0aea2 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -490,10 +490,6 @@ contains end if if (allocated(macro_xs)) then - ! First call the clear routines - do i = 1, size(macro_xs) - call macro_xs(i) % obj % clear() - end do deallocate(macro_xs) end if diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e726b6f403..2a21bac215 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2071,7 +2071,7 @@ contains call get_list_item(node_macro_list, 1, node_nuc) ! Check for empty name on nuclide - if (.not.check_for_node(node_nuc, "name")) then + if (.not. check_for_node(node_nuc, "name")) then call fatal_error("No name specified on macroscopic data in material " & // trim(to_str(mat % id))) end if diff --git a/src/macroxs.F90 b/src/macroxs.F90 index c26e9e888b..f44f87f66f 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -140,7 +140,7 @@ contains !=============================================================================== subroutine macroxs_sample_scatter(scatt, gin, gout, mu, wgt) - Class(ScattData_Base), intent(in) :: scatt ! Scattering Object to Use + class(ScattData_Base), intent(in) :: scatt ! Scattering Object to Use integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group real(8), intent(out) :: mu ! Sampled change in angle diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 63e6fecaed..17ee8a1e0e 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -19,10 +19,9 @@ module macroxs_header integer :: order ! Type-Bound procedures - contains - procedure(macroxs_init_), deferred, pass :: init ! initializes object - procedure(macroxs_clear_), deferred, pass :: clear ! Deallocates object - procedure(macroxs_get_xs_), deferred, pass :: get_xs ! Return xs + contains + procedure(macroxs_init_), deferred, pass :: init ! initializes object + procedure(macroxs_get_xs_), deferred, pass :: get_xs ! Return xs end type MacroXS_Base abstract interface @@ -79,11 +78,10 @@ module macroxs_header real(8), allocatable :: scattxs(:) ! scattering xs real(8), allocatable :: chi(:,:) ! fission spectra - ! Type-Bound procedures - contains - procedure, pass :: init => macroxs_iso_init ! inits object - procedure, pass :: clear => macroxs_iso_clear ! Deallocates object - procedure, pass :: get_xs => macroxs_iso_get_xs ! Returns xs + ! Type-Bound procedures + contains + procedure, pass :: init => macroxs_iso_init ! inits object + procedure, pass :: get_xs => macroxs_iso_get_xs ! Returns xs end type MacroXS_Iso type, extends(MacroXS_Base) :: MacroXS_Angle @@ -99,11 +97,10 @@ module macroxs_header real(8), allocatable :: polar(:) ! polar angles real(8), allocatable :: azimuthal(:) ! azimuthal angles - ! Type-Bound procedures - contains - procedure, pass :: init => macroxs_angle_init ! inits object - procedure, pass :: clear => macroxs_angle_clear ! Deallocates object - procedure, pass :: get_xs => macroxs_angle_get_xs ! Returns xs + ! Type-Bound procedures + contains + procedure, pass :: init => macroxs_angle_init ! inits object + procedure, pass :: get_xs => macroxs_angle_get_xs ! Returns xs end type MacroXS_Angle !=============================================================================== @@ -657,68 +654,6 @@ contains end subroutine macroxs_angle_init -!=============================================================================== -! MACROXS*_CLEAR resets and deallocates data in MacroXS. -!=============================================================================== - - subroutine macroxs_iso_clear(this) - - class(MacroXS_Iso), intent(inout) :: this ! The MacroXS to clear - - if (allocated(this % total)) then - deallocate(this % total, this % absorption, & - this % nu_fission) - end if - - if (allocated(this % fission)) then - deallocate(this % fission) - end if - - if (allocated(this % k_fission)) then - deallocate(this % k_fission) - end if - - call this % scatter % clear() - - if (allocated(this % chi)) then - deallocate(this % chi) - end if - - end subroutine macroxs_iso_clear - - subroutine macroxs_angle_clear(this) - - class(MacroXS_Angle), intent(inout) :: this ! The MacroXS to clear - integer :: i, j - - if (allocated(this % total)) then - deallocate(this % total, this % absorption, & - this % nu_fission) - end if - - if (allocated(this % fission)) then - deallocate(this % fission) - end if - - if (allocated(this % k_fission)) then - deallocate(this % k_fission) - end if - - do i = 1, size(this % scatter,dim=2) - do j = 1, size(this % scatter,dim=1) - call this % scatter(j,i) % obj % clear() - end do - end do - if (allocated(this % scatter)) then - deallocate(this % scatter) - end if - - if (allocated(this % chi)) then - deallocate(this % chi) - end if - - end subroutine macroxs_angle_clear - !=============================================================================== ! MACROXS_*_GET_XS returns the requested data type !=============================================================================== @@ -790,130 +725,4 @@ contains end function macroxs_angle_get_xs -!=============================================================================== -! THIN_GRID thins an (x,y) set while also thinning an associated y2 -!=============================================================================== - - subroutine thin_grid(xout, yout, yout2, tol, compression, maxerr) - real(8), allocatable, intent(inout) :: xout(:) ! Resultant x grid - real(8), allocatable, intent(inout) :: yout(:) ! Resultant y values - real(8), allocatable, intent(inout) :: yout2(:) ! Secondary y values - real(8), intent(in) :: tol ! Desired fractional error to maintain - real(8), intent(out) :: compression ! Data reduction fraction - real(8), intent(inout) :: maxerr ! Maximum error due to compression - - real(8), allocatable :: xin(:) ! Incoming x grid - real(8), allocatable :: yin(:) ! Incoming y values - real(8), allocatable :: yin2(:) ! Secondary Incoming y values - integer :: k, klo, khi - integer :: all_ok - real(8) :: x1, y1, x2, y2, x, y, testval - integer :: num_keep, remove_it - real(8) :: initial_size - real(8) :: error - real(8) :: x_frac - - initial_size = real(size(xout), 8) - - allocate(xin(size(xout))) - xin = xout - allocate(yin(size(yout))) - yin = yout - allocate(yin2(size(yout2))) - yin2 = yout2 - - all_ok = size(yin) - maxerr = 0.0_8 - - ! This loop will step through each entry in dim==3 and check to see if - ! all of the values in other 2 dims can be replaced with linear interp. - ! If not, the value will be saved to a new array, if so, it will be - ! skipped. - - xout = 0.0_8 - yout = 0.0_8 - - ! Keep first point's data - xout(1) = xin(1) - yout(1) = yin(1) - yout2(1) = yin2(1) - - ! Initialize data - num_keep = 1 - klo = 1 - khi = 3 - k = 2 - do while (khi <= size(xin)) - remove_it = 0 - x1 = xin(klo) - x2 = xin(khi) - x = xin(k) - x_frac = 1.0_8 / (x2 - x1) * (x - x1) ! Linear interp. - - ! Check for removal. Otherwise, it stays. This is accomplished by leaving - ! remove_it as 0, entering the else portion of if(remove_it==all_ok) - y1 = yin(klo) - y2 = yin(khi) - y = yin(k) - - testval = y1 + (y2 - y1) * x_frac - error = abs(testval - y) - if (y /= 0.0_8) then - error = error / y - end if - if (error <= tol) then - remove_it = remove_it + 1 - if (error > maxerr) then - maxerr = abs(testval - y) - end if - end if - ! Now place the point in to the proper bin and advance iterators. - if (remove_it /= 0) then - ! Then don't put it in the new grid but advance iterators - k = k + 1 - khi = khi + 1 - else - ! Put it in new grid and advance iterators accordingly - num_keep = num_keep + 1 - xout(num_keep) = xin(k) - yout(num_keep) = yin(k) - yout2(num_keep) = yin2(k) - klo = k - k = k + 1 - khi = khi + 1 - end if - end do - ! Save the last point's data - num_keep = num_keep + 1 - xout(num_keep) = xin(size(xin)) - yout(num_keep) = yin(size(xin)) - yout2(num_keep) = yin2(size(xin)) - - ! Finally, xout and yout were sized to match xin and yin since we knew - ! they would be no larger than those. Now we must resize these arrays - ! and copy only the useful data in. Will use xin/yin for temp arrays. - xin = xout(1:num_keep) - yin = yout(1:num_keep) - yin2 = yout2(1:num_keep) - - deallocate(xout) - deallocate(yout) - deallocate(yout2) - allocate(xout(num_keep)) - allocate(yout(size(yin))) - allocate(yout2(size(yin2))) - - xout = xin(1:num_keep) - yout = yin(1:num_keep) - yout2 = yin2(1:num_keep) - - ! Clean up - deallocate(xin) - deallocate(yin) - deallocate(yin2) - - compression = (initial_size - real(size(xout),8)) / initial_size - - end subroutine thin_grid - end module macroxs_header diff --git a/src/math.F90 b/src/math.F90 index aedf182358..36c65a2402 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -558,7 +558,7 @@ contains end function calc_rn !=============================================================================== -! EXPAND_HARMONIC expands a given series of harmonics +! EXPAND_HARMONIC expands a given series of real spherical harmonics !=============================================================================== pure function expand_harmonic(data, order, uvw) result(val) real(8), intent(in) :: data(:) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 880764edad..f73f3f5a27 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -76,8 +76,7 @@ contains get_fiss = .true. end if end do - if (get_kfiss .and. get_fiss) & - exit + if (get_kfiss .and. get_fiss) exit end do ! ========================================================================== diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 398e91eb20..95f9833b4c 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -155,7 +155,7 @@ module nuclide_header end function nuclide_calc_f_ end interface - !=============================================================================== +!=============================================================================== ! NUCLIDE_ISO contains the base MGXS data for a nuclide specifically for ! isotropically weighted MGXS !=============================================================================== @@ -688,11 +688,12 @@ module nuclide_header end function nuclide_angle_get_xs !=============================================================================== -! NUCLIDE_*_CALC_F Finds the value of f(mu), the scattering probability, given mu +! NUCLIDE_*_CALC_F Finds the value of f(mu), the scattering angle probability, +! given mu !=============================================================================== - pure function nuclide_mg_iso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & - result(f) + pure function nuclide_mg_iso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & + result(f) class(Nuclide_Iso), intent(in) :: this integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group @@ -791,6 +792,7 @@ module nuclide_header end if end function nuclide_mg_angle_calc_f + !=============================================================================== ! find_angle finds the closest angle on the data grid and returns that index !=============================================================================== diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 0e9fc0263a..0426acd924 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -132,7 +132,6 @@ contains this % fission = .false. this % delayed_group = 0 this % n_delayed_bank(:) = 0 - ! Initialize this % g so there is always at least some initialized value this % g = 1 ! Set up base level coordinates diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 29ab616e0a..091a77741a 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -16,11 +16,10 @@ module scattdata_header real(8), allocatable :: mult(:,:) ! (Gout x Gin) real(8), allocatable :: data(:,:,:) ! (Order/Nmu x Gout x Gin) - ! Type-Bound procedures - contains - procedure(init_), deferred, pass :: init ! Initializes ScattData - procedure(calc_f_), deferred, pass :: calc_f ! Calculates f, given mu - procedure(clear_), deferred, pass :: clear ! Deallocates ScattData + ! Type-Bound procedures + contains + procedure(init_), deferred, pass :: init ! Initializes ScattData + procedure(calc_f_), deferred, pass :: calc_f ! Calculates f, given mu end type ScattData_Base abstract interface @@ -42,37 +41,29 @@ module scattdata_header real(8) :: f ! Return value of f(mu) end function calc_f_ - - subroutine clear_(this) - import ScattData_Base - class(ScattData_Base), intent(inout) :: this ! The ScattData to clear - end subroutine clear_ end interface type, extends(ScattData_Base) :: ScattData_Legendre - contains - procedure, pass :: init => scattdata_legendre_init - procedure, pass :: calc_f => scattdata_legendre_calc_f - procedure, pass :: clear => scattdata_legendre_clear + contains + procedure, pass :: init => scattdata_legendre_init + procedure, pass :: calc_f => scattdata_legendre_calc_f end type ScattData_Legendre type, extends(ScattData_Base) :: ScattData_Histogram real(8), allocatable :: mu(:) ! Mu bins real(8) :: dmu ! Mu spacing - contains - procedure, pass :: init => scattdata_histogram_init - procedure, pass :: calc_f => scattdata_histogram_calc_f - procedure, pass :: clear => scattdata_histogram_clear + contains + procedure, pass :: init => scattdata_histogram_init + procedure, pass :: calc_f => scattdata_histogram_calc_f end type ScattData_Histogram type, extends(ScattData_Base) :: ScattData_Tabular real(8), allocatable :: mu(:) ! Mu bins real(8) :: dmu ! Mu spacing real(8), allocatable :: fmu(:,:,:) ! PDF of f(mu) - contains - procedure, pass :: init => scattdata_tabular_init - procedure, pass :: calc_f => scattdata_tabular_calc_f - procedure, pass :: clear => scattdata_tabular_clear + contains + procedure, pass :: init => scattdata_tabular_init + procedure, pass :: calc_f => scattdata_tabular_calc_f end type ScattData_Tabular !=============================================================================== @@ -239,56 +230,6 @@ contains end subroutine scattdata_tabular_init -!=============================================================================== -! SCATTDATA_CLEAR resets and deallocates data in ScattData. -!=============================================================================== - - subroutine scattdata_base_clear(this) - class(ScattData_Base), intent(inout) :: this - - if (allocated(this % energy)) then - deallocate(this % energy) - end if - - if (allocated(this % mult)) then - deallocate(this % mult) - end if - - if (allocated(this % data)) then - deallocate(this % data) - end if - - end subroutine scattdata_base_clear - - subroutine scattdata_legendre_clear(this) - class(ScattData_Legendre), intent(inout) :: this - - call scattdata_base_clear(this) - - end subroutine scattdata_legendre_clear - - subroutine scattdata_histogram_clear(this) - class(ScattData_Histogram), intent(inout) :: this - - call scattdata_base_clear(this) - - if (allocated(this % mu)) then - deallocate(this % mu) - end if - - end subroutine scattdata_histogram_clear - - subroutine scattdata_tabular_clear(this) - class(ScattData_Tabular), intent(inout) :: this - - call scattdata_base_clear(this) - - if (allocated(this % mu)) then - deallocate(this % mu) - end if - - end subroutine scattdata_tabular_clear - !=============================================================================== ! SCATTDATA_*_CALC_F Calculates the value of f given mu (and gin,gout pair) !=============================================================================== @@ -350,6 +291,4 @@ contains end function scattdata_tabular_calc_f - - end module scattdata_header \ No newline at end of file diff --git a/src/tally.F90 b/src/tally.F90 index bbe099c3e4..e127cf0378 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -26,6 +26,8 @@ module tally integer :: position(N_FILTER_TYPES - 3) = 0 ! Tally map positioning array +!$omp threadprivate(position) + procedure(score_general_intfc), pointer :: score_general => null() procedure(get_scoring_bins_intfc), pointer :: get_scoring_bins => null() @@ -52,8 +54,6 @@ module tally end interface -!$omp threadprivate(position) - contains !=============================================================================== @@ -1255,97 +1255,95 @@ contains real(8) :: uvw(3) select case(score_bin) - - - case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N) - ! Find the scattering order for a singly requested moment, and - ! store its moment contribution. - if (t % moment_order(i) == 1) then - score = score * p % mu ! avoid function call overhead - else - score = score * calc_pn(t % moment_order(i), p % mu) - endif + case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N) + ! Find the scattering order for a singly requested moment, and + ! store its moment contribution. + if (t % moment_order(i) == 1) then + score = score * p % mu ! avoid function call overhead + else + score = score * calc_pn(t % moment_order(i), p % mu) + endif !$omp atomic - t % results(score_index, filter_index) % value = & - t % results(score_index, filter_index) % value + score + t % results(score_index, filter_index) % value = & + t % results(score_index, filter_index) % value + score - case(SCORE_SCATTER_YN, SCORE_NU_SCATTER_YN) - score_index = score_index - 1 - num_nm = 1 - ! Find the order for a collection of requested moments - ! and store the moment contribution of each - do n = 0, t % moment_order(i) - ! determine scoring bin index - score_index = score_index + num_nm - ! Update number of total n,m bins for this n (m = [-n: n]) - num_nm = 2 * n + 1 + case(SCORE_SCATTER_YN, SCORE_NU_SCATTER_YN) + score_index = score_index - 1 + num_nm = 1 + ! Find the order for a collection of requested moments + ! and store the moment contribution of each + do n = 0, t % moment_order(i) + ! determine scoring bin index + score_index = score_index + num_nm + ! Update number of total n,m bins for this n (m = [-n: n]) + num_nm = 2 * n + 1 - ! multiply score by the angular flux moments and store + ! multiply score by the angular flux moments and store !$omp critical (score_general_scatt_yn) - t % results(score_index: score_index + num_nm - 1, filter_index) & - % value = t & - % results(score_index: score_index + num_nm - 1, filter_index)& - % value & - + score * calc_pn(n, p % mu) * calc_rn(n, p % last_uvw) + t % results(score_index: score_index + num_nm - 1, filter_index) & + % value = t & + % results(score_index: score_index + num_nm - 1, filter_index)& + % value & + + score * calc_pn(n, p % mu) * calc_rn(n, p % last_uvw) !$omp end critical (score_general_scatt_yn) - end do - i = i + (t % moment_order(i) + 1)**2 - 1 + end do + i = i + (t % moment_order(i) + 1)**2 - 1 - case(SCORE_FLUX_YN, SCORE_TOTAL_YN) - score_index = score_index - 1 - num_nm = 1 - if (t % estimator == ESTIMATOR_ANALOG .or. & - t % estimator == ESTIMATOR_COLLISION) then - uvw = p % last_uvw - else if (t % estimator == ESTIMATOR_TRACKLENGTH) then - uvw = p % coord(1) % uvw - end if - ! Find the order for a collection of requested moments - ! and store the moment contribution of each - do n = 0, t % moment_order(i) - ! determine scoring bin index - score_index = score_index + num_nm - ! Update number of total n,m bins for this n (m = [-n: n]) - num_nm = 2 * n + 1 + case(SCORE_FLUX_YN, SCORE_TOTAL_YN) + score_index = score_index - 1 + num_nm = 1 + if (t % estimator == ESTIMATOR_ANALOG .or. & + t % estimator == ESTIMATOR_COLLISION) then + uvw = p % last_uvw + else if (t % estimator == ESTIMATOR_TRACKLENGTH) then + uvw = p % coord(1) % uvw + end if + ! Find the order for a collection of requested moments + ! and store the moment contribution of each + do n = 0, t % moment_order(i) + ! determine scoring bin index + score_index = score_index + num_nm + ! Update number of total n,m bins for this n (m = [-n: n]) + num_nm = 2 * n + 1 - ! multiply score by the angular flux moments and store + ! multiply score by the angular flux moments and store !$omp critical (score_general_flux_tot_yn) - t % results(score_index: score_index + num_nm - 1, filter_index) & - % value = t & - % results(score_index: score_index + num_nm - 1, filter_index)& - % value & - + score * calc_rn(n, uvw) + t % results(score_index: score_index + num_nm - 1, filter_index) & + % value = t & + % results(score_index: score_index + num_nm - 1, filter_index)& + % value & + + score * calc_rn(n, uvw) !$omp end critical (score_general_flux_tot_yn) - end do - i = i + (t % moment_order(i) + 1)**2 - 1 + end do + i = i + (t % moment_order(i) + 1)**2 - 1 - case (SCORE_SCATTER_PN, SCORE_NU_SCATTER_PN) - score_index = score_index - 1 - ! Find the scattering order for a collection of requested moments - ! and store the moment contribution of each - do n = 0, t % moment_order(i) - ! determine scoring bin index - score_index = score_index + 1 + case (SCORE_SCATTER_PN, SCORE_NU_SCATTER_PN) + score_index = score_index - 1 + ! Find the scattering order for a collection of requested moments + ! and store the moment contribution of each + do n = 0, t % moment_order(i) + ! determine scoring bin index + score_index = score_index + 1 - ! get the score and tally it -!$omp atomic - t % results(score_index, filter_index) % value = & - t % results(score_index, filter_index) % value & - + score * calc_pn(n, p % mu) - end do - i = i + t % moment_order(i) - - - case default + ! get the score and tally it !$omp atomic t % results(score_index, filter_index) % value = & - t % results(score_index, filter_index) % value + score + t % results(score_index, filter_index) % value & + + score * calc_pn(n, p % mu) + end do + i = i + t % moment_order(i) - end select + case default +!$omp atomic + t % results(score_index, filter_index) % value = & + t % results(score_index, filter_index) % value + score + + + end select end subroutine expand_and_score From 4d27f7eab042f050bbe83dfa20e57cf1a23f0146 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 5 Feb 2016 21:13:54 -0500 Subject: [PATCH 63/84] Renaming Nuclide_* to Nuclide* --- src/ace.F90 | 18 ++--- src/cross_section.F90 | 6 +- src/energy_grid.F90 | 6 +- src/fission.F90 | 10 +-- src/global.F90 | 2 +- src/initialize.F90 | 4 +- src/macroxs.F90 | 2 +- src/macroxs_header.F90 | 18 ++--- src/mgxs_data.F90 | 40 +++++----- src/nuclide_header.F90 | 162 ++++++++++++++++++++--------------------- src/output.F90 | 4 +- src/physics.F90 | 18 ++--- 12 files changed, 145 insertions(+), 145 deletions(-) diff --git a/src/ace.F90 b/src/ace.F90 index 45b58a8d54..5012c9b884 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -54,7 +54,7 @@ contains character(12) :: name ! name of isotope, e.g. 92235.03c character(12) :: alias ! alias of nuclide, e.g. U-235.03c type(Material), pointer :: mat - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc type(SAlphaBeta), pointer :: sab type(SetChar) :: already_read @@ -265,7 +265,7 @@ contains character(10) :: mat ! material identifier character(70) :: comment ! comment for ACE table character(MAX_FILE_LEN) :: filename ! path to ACE cross section library - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc type(SAlphaBeta), pointer :: sab type(XsListing), pointer :: listing @@ -422,7 +422,7 @@ contains !=============================================================================== subroutine read_esz(nuc, data_0K) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc logical, intent(in) :: data_0K ! are we reading 0K data? integer :: NE ! number of energy points for total and elastic cross sections @@ -510,7 +510,7 @@ contains !=============================================================================== subroutine read_nu_data(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: i ! loop index integer :: JXS2 ! location for fission nu data @@ -714,7 +714,7 @@ contains !=============================================================================== subroutine read_reactions(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: i ! loop indices integer :: i_fission ! index in nuc % index_fission @@ -894,7 +894,7 @@ contains !=============================================================================== subroutine read_angular_dist(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: LOCB ! location of angular distribution for given MT integer :: NE ! number of incoming energies @@ -998,7 +998,7 @@ contains !=============================================================================== subroutine read_energy_dist(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: i ! loop index integer :: n @@ -1386,7 +1386,7 @@ contains !=============================================================================== subroutine read_unr_res(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: JXS23 ! location of URR data integer :: lc ! locator @@ -1474,7 +1474,7 @@ contains !=============================================================================== subroutine generate_nu_fission(nuc) - type(Nuclide_CE), intent(inout) :: nuc + type(NuclideCE), intent(inout) :: nuc integer :: i ! index on nuclide energy grid real(8) :: E ! energy diff --git a/src/cross_section.F90 b/src/cross_section.F90 index e6422de1f8..4f5d2252ce 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -148,7 +148,7 @@ contains integer :: i_low ! lower logarithmic mapping index integer :: i_high ! upper logarithmic mapping index real(8) :: f ! interp factor on nuclide energy grid - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc type(Material), pointer :: mat ! Set pointer to nuclide and material @@ -367,7 +367,7 @@ contains real(8) :: inelastic ! inelastic cross section logical :: same_nuc ! do we know the xs for this nuclide at this energy? type(UrrData), pointer :: urr - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc micro_xs(i_nuclide) % use_ptable = .true. @@ -534,7 +534,7 @@ contains pure function elastic_xs_0K(E, nuc) result(xs_out) real(8), intent(in) :: E ! trial energy - type(Nuclide_CE), intent(in) :: nuc ! target nuclide at temperature + type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature real(8) :: xs_out ! 0K xs at trial energy integer :: i_grid ! index on nuclide energy grid diff --git a/src/energy_grid.F90 b/src/energy_grid.F90 index fa56b04956..248462f70c 100644 --- a/src/energy_grid.F90 +++ b/src/energy_grid.F90 @@ -27,7 +27,7 @@ contains integer :: i ! index in nuclides array integer :: j ! index in materials array type(ListReal) :: list - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc type(Material), pointer :: mat call write_message("Creating unionized energy grid...", 5) @@ -70,7 +70,7 @@ contains real(8) :: E_max ! Maximum energy in MeV real(8) :: E_min ! Minimum energy in MeV real(8), allocatable :: umesh(:) ! Equally log-spaced energy grid - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc ! Set minimum/maximum energies E_max = energy_max_neutron @@ -179,7 +179,7 @@ contains integer :: index_e ! index on union energy grid real(8) :: union_energy ! energy on union grid real(8) :: energy ! energy on nuclide grid - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc type(Material), pointer :: mat do k = 1, n_materials diff --git a/src/fission.F90 b/src/fission.F90 index 98cccc5582..77ee641787 100644 --- a/src/fission.F90 +++ b/src/fission.F90 @@ -1,6 +1,6 @@ module fission - use nuclide_header, only: Nuclide_CE + use nuclide_header, only: NuclideCE use constants use error, only: fatal_error use interpolation, only: interpolate_tab1 @@ -16,7 +16,7 @@ contains !=============================================================================== pure function nu_total(nuc, E) result(nu) - type(Nuclide_CE), intent(in) :: nuc ! nuclide from which to find nu + type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu real(8), intent(in) :: E ! energy of incoming neutron real(8) :: nu ! number of total neutrons emitted per fission @@ -49,7 +49,7 @@ contains !=============================================================================== pure function nu_prompt(nuc, E) result(nu) - type(Nuclide_CE), intent(in) :: nuc ! nuclide from which to find nu + type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu real(8), intent(in) :: E ! energy of incoming neutron real(8) :: nu ! number of prompt neutrons emitted per fission @@ -86,7 +86,7 @@ contains !=============================================================================== pure function nu_delayed(nuc, E) result(nu) - type(Nuclide_CE), intent(in) :: nuc ! nuclide from which to find nu + type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu real(8), intent(in) :: E ! energy of incoming neutron real(8) :: nu ! number of delayed neutrons emitted per fission @@ -109,7 +109,7 @@ contains !=============================================================================== pure function yield_delayed(nuc, E, g) result(yield) - type(Nuclide_CE), intent(in) :: nuc ! nuclide from which to find nu + type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu real(8), intent(in) :: E ! energy of incoming neutron real(8) :: yield ! delayed neutron precursor yield integer, intent(in) :: g ! the delayed neutron precursor group diff --git a/src/global.F90 b/src/global.F90 index dda4e0aea2..dcbf7b1e48 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -86,7 +86,7 @@ module global ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES ! Cross section arrays - type(Nuclide_CE), allocatable, target :: nuclides(:) ! Nuclide cross-sections + type(NuclideCE), allocatable, target :: nuclides(:) ! Nuclide cross-sections type(SAlphaBeta), allocatable, target :: sab_tables(:) ! S(a,b) tables integer :: n_sab_tables ! Number of S(a,b) thermal scattering tables diff --git a/src/initialize.F90 b/src/initialize.F90 index 74bba03e72..88a10fb550 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -16,7 +16,7 @@ module initialize hdf5_tallyresult_t, hdf5_integer8_t use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml use material_header, only: Material - use mgxs_data, only: read_mgxs, same_nuclide_mg_list, create_macro_xs + use mgxs_data, only: read_mgxs, same_NuclideMG_list, create_macro_xs use output, only: title, header, print_version, write_message, & print_usage, write_xs_summary, print_plot use random_lcg, only: initialize_prng @@ -126,7 +126,7 @@ contains if (run_CE) then call same_nuclide_list() else - call same_nuclide_mg_list() + call same_NuclideMG_list() end if ! Construct information needed for nuclear data diff --git a/src/macroxs.F90 b/src/macroxs.F90 index f44f87f66f..170f5fb19a 100644 --- a/src/macroxs.F90 +++ b/src/macroxs.F90 @@ -6,7 +6,7 @@ module macroxs use material_header, only: Material use math use nuclide_header, only: find_angle, MaterialMacroXS, NuclideMicroXS, & - Nuclide_MG, NuclideMGContainer + NuclideMG, NuclideMGContainer use random_lcg, only: prn use scattdata_header use search diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 17ee8a1e0e..95053789f5 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -135,7 +135,7 @@ contains integer :: i ! loop index over nuclides integer :: gin, gout ! group indices real(8) :: atom_density ! atom density of a nuclide - ! class(Nuclide_Base), pointer :: nuc ! current nuclide + ! class(NuclideBase), pointer :: nuc ! current nuclide integer :: imu real(8) :: norm integer :: mat_max_order, order, l @@ -239,7 +239,7 @@ contains ! Perform our operations which depend upon the type select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (Nuclide_Iso) + type is (NuclideIso) ! Add contributions to total, absorption, and fission data (if necessary) this % total = this % total + atom_density * nuc % total @@ -305,9 +305,9 @@ contains nuc % mult(gout,gin) end do end do - type is (Nuclide_Angle) + type is (NuclideAngle) error_code = 1 - error_text = "Invalid Passing of Nuclide_Angle to MacroXS_Iso Object" + error_text = "Invalid Passing of NuclideAngle to MacroXS_Iso Object" return end select end do @@ -393,12 +393,12 @@ contains error_text = '' ! Get the number of each polar and azi angles and make sure all the - ! Nuclide_Angle types have the same number of these angles + ! NuclideAngle types have the same number of these angles npol = -1 nazi = -1 do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (Nuclide_Angle) + type is (NuclideAngle) if (npol == -1) then npol = nuc % Npol nazi = nuc % Nazi @@ -522,11 +522,11 @@ contains ! Perform our operations which depend upon the type select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (Nuclide_Iso) + type is (NuclideIso) error_code = 1 - error_text = "Invalid Passing of Nuclide_Iso to MacroXS_Angle Object" + error_text = "Invalid Passing of NuclideIso to MacroXS_Angle Object" return - type is (Nuclide_Angle) + type is (NuclideAngle) ! Add contributions to total, absorption, and fission data (if necessary) this % total = this % total + atom_density * nuc % total this % absorption = this % absorption + & diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index f73f3f5a27..d9c397f5bb 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -119,13 +119,13 @@ contains ! Now allocate accordingly select case(representation) case(MGXS_ISOTROPIC) - allocate(Nuclide_Iso :: nuclides_MG(i_nuclide) % obj) + allocate(NuclideIso :: nuclides_MG(i_nuclide) % obj) case(MGXS_ANGLE) - allocate(Nuclide_Angle :: nuclides_MG(i_nuclide) % obj) + allocate(NuclideAngle :: nuclides_MG(i_nuclide) % obj) end select ! Now read in the data specific to the type we just declared - call nuclide_mg_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & + call NuclideMG_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & energy_groups, get_kfiss, get_fiss, error_code, & error_text) @@ -175,7 +175,7 @@ contains ! in multiple entries in the nuclides array for a single zaid number. !=============================================================================== - subroutine same_nuclide_mg_list() + subroutine same_NuclideMG_list() integer :: i ! index in nuclides array integer :: j ! index in nuclides array @@ -188,15 +188,15 @@ contains end do end do - end subroutine same_nuclide_mg_list + end subroutine same_NuclideMG_list !=============================================================================== ! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed !=============================================================================== - subroutine nuclide_mg_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + subroutine NuclideMG_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) - class(Nuclide_MG), intent(inout) :: this ! Working Object + class(NuclideMG), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups logical, intent(in) :: get_kfiss ! Need Kappa-Fission? @@ -296,19 +296,19 @@ contains end if select type(this) - type is (Nuclide_Iso) - call nuclide_iso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + type is (NuclideIso) + call NuclideIso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) - type is (Nuclide_Angle) - call nuclide_angle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + type is (NuclideAngle) + call NuclideAngle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) end select - end subroutine nuclide_mg_init + end subroutine NuclideMG_init - subroutine nuclide_iso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + subroutine NuclideIso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) - class(Nuclide_Iso), intent(inout) :: this ! Working Object + class(NuclideIso), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups logical, intent(in) :: get_kfiss ! Need Kappa-Fission? @@ -435,11 +435,11 @@ contains this % mult = ONE end if - end subroutine nuclide_iso_init + end subroutine NuclideIso_init - subroutine nuclide_angle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + subroutine NuclideAngle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) - class(Nuclide_Angle), intent(inout) :: this ! Working Object + class(NuclideAngle), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups logical, intent(in) :: get_kfiss ! Need Kappa-Fission? @@ -627,7 +627,7 @@ contains this % mult = ONE end if - end subroutine nuclide_angle_init + end subroutine NuclideAngle_init !=============================================================================== @@ -675,9 +675,9 @@ contains ! how we allocate the scatter object within macroxs legendre_mu_points = nuclides_MG(mat % nuclide(1)) % obj % legendre_mu_points select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) - type is (Nuclide_Iso) + type is (NuclideIso) representation = MGXS_ISOTROPIC - type is (Nuclide_Angle) + type is (NuclideAngle) representation = MGXS_ANGLE end select scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 95f9833b4c..fc9c53ff30 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -12,12 +12,12 @@ module nuclide_header implicit none !=============================================================================== -! NUCLIDE_BASE contains the base nuclidic data for a nuclide, which does not depend +! NuclideBase contains the base nuclidic data for a nuclide, which does not depend ! upon how the nuclear data is represented (i.e., CE, or any variant of MG). -! The extended types, Nuclide_CE and Nuclide_MG deal with the rest +! The extended types, NuclideCE and NuclideMG deal with the rest !=============================================================================== - type, abstract :: Nuclide_Base + type, abstract :: NuclideBase character(12) :: name ! name of nuclide, e.g. 92235.03c integer :: zaid ! Z and A identifier, e.g. 92235 real(8) :: awr ! Atomic Weight Ratio @@ -31,26 +31,26 @@ module nuclide_header logical :: fissionable ! nuclide is fissionable? contains - procedure(nuclide_base_clear_), deferred, pass :: clear ! Deallocates Nuclide - procedure(print_nuclide_), deferred, pass :: print ! Writes nuclide info - end type Nuclide_Base + procedure(nuclidebase_clear_), deferred, pass :: clear ! Deallocates Nuclide + procedure(print_nuclide_), deferred, pass :: print ! Writes nuclide info + end type NuclideBase abstract interface - subroutine nuclide_base_clear_(this) - import Nuclide_Base - class(Nuclide_Base), intent(inout) :: this - end subroutine nuclide_base_clear_ + subroutine nuclidebase_clear_(this) + import NuclideBase + class(NuclideBase), intent(inout) :: this + end subroutine nuclidebase_clear_ subroutine print_nuclide_(this, unit) - import Nuclide_Base - class(Nuclide_Base),intent(in) :: this + import NuclideBase + class(NuclideBase),intent(in) :: this integer, optional, intent(in) :: unit end subroutine print_nuclide_ end interface - type, extends(Nuclide_Base) :: Nuclide_CE + type, extends(NuclideBase) :: NuclideCE ! Energy grid information integer :: n_grid ! # of nuclide grid points integer, allocatable :: grid_index(:) ! log grid mapping indices @@ -108,29 +108,29 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclide_ce_clear - procedure, pass :: print => nuclide_ce_print - end type Nuclide_CE + procedure, pass :: clear => nuclidece_clear + procedure, pass :: print => nuclidece_print + end type NuclideCE - type, abstract, extends(Nuclide_Base) :: Nuclide_MG + type, abstract, extends(NuclideBase) :: NuclideMG ! Scattering Order Information - integer :: order ! Order of data (Scattering for Nuclide_Iso, - ! Number of angles for all in Nuclide_Angle) + integer :: order ! Order of data (Scattering for NuclideIso, + ! Number of angles for all in NuclideAngle) integer :: scatt_type ! either legendre, histogram, or tabular. integer :: legendre_mu_points ! Number of tabular points to use to represent ! Legendre distribs, -1 if sample with the ! Legendres themselves ! Type-Bound procedures contains - procedure(nuclide_mg_get_xs_), deferred, pass :: get_xs ! Get the xs - procedure(nuclide_calc_f_), deferred, pass :: calc_f ! Calculates f, given mu - end type Nuclide_MG + procedure(nuclidemg_get_xs), deferred, pass :: get_xs ! Get the xs + procedure(nuclide_calc_f_), deferred, pass :: calc_f ! Calculates f, given mu + end type NuclideMG abstract interface - function nuclide_mg_get_xs_(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & + function nuclidemg_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) - import Nuclide_MG - class(Nuclide_MG), intent(in) :: this + import NuclideMG + class(NuclideMG), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group @@ -139,11 +139,11 @@ module nuclide_header integer, optional, intent(in) :: i_azi ! Azimuthal Index integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs - end function nuclide_mg_get_xs_ + end function nuclidemg_get_xs pure function nuclide_calc_f_(this, gin, gout, mu, uvw, i_azi, i_pol) result(f) - import Nuclide_MG - class(Nuclide_MG), intent(in) :: this + import NuclideMG + class(NuclideMG), intent(in) :: this integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -156,11 +156,11 @@ module nuclide_header end interface !=============================================================================== -! NUCLIDE_ISO contains the base MGXS data for a nuclide specifically for +! NuclideIso contains the base MGXS data for a nuclide specifically for ! isotropically weighted MGXS !=============================================================================== - type, extends(Nuclide_MG) :: Nuclide_Iso + type, extends(NuclideMG) :: NuclideIso ! Microscopic cross sections real(8), allocatable :: total(:) ! total cross section @@ -174,18 +174,18 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclide_iso_clear ! Deallocates Nuclide - procedure, pass :: print => nuclide_iso_print ! Writes nuclide info - procedure, pass :: get_xs => nuclide_iso_get_xs ! Gets Size of Data w/in Object - procedure, pass :: calc_f => nuclide_mg_iso_calc_f ! Calcs f given mu - end type Nuclide_Iso + procedure, pass :: clear => nuclideiso_clear ! Deallocates Nuclide + procedure, pass :: print => nuclideiso_print ! Writes nuclide info + procedure, pass :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object + procedure, pass :: calc_f => nuclideiso_calc_f ! Calcs f given mu + end type NuclideIso !=============================================================================== -! NUCLIDE_ANGLE contains the base MGXS data for a nuclide specifically for +! NuclideAngle contains the base MGXS data for a nuclide specifically for ! explicit angle-dependent weighted MGXS !=============================================================================== - type, extends(Nuclide_MG) :: Nuclide_Angle + type, extends(NuclideMG) :: NuclideAngle ! Microscopic cross sections. Dimensions are: (Npol, Nazi, Nl, Ng, Ng) real(8), allocatable :: total(:,:,:) ! total cross section @@ -205,23 +205,23 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclide_angle_clear ! Deallocates Nuclide - procedure, pass :: print => nuclide_angle_print ! Gets Size of Data w/in Object - procedure, pass :: get_xs => nuclide_angle_get_xs ! Gets Size of Data w/in Object - procedure, pass :: calc_f => nuclide_mg_angle_calc_f ! Calcs f given mu - end type Nuclide_Angle + procedure, pass :: clear => nuclideangle_clear ! Deallocates Nuclide + procedure, pass :: print => nuclideangle_print ! Gets Size of Data w/in Object + procedure, pass :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object + procedure, pass :: calc_f => nuclideangle_calc_f ! Calcs f given mu + end type NuclideAngle !=============================================================================== ! NUCLIDEMGCONTAINER pointer array for storing Nuclides !=============================================================================== type NuclideMGContainer - class(Nuclide_MG), pointer :: obj + class(NuclideMG), pointer :: obj end type NuclideMGContainer !=============================================================================== ! NUCLIDE0K temporarily contains all 0K cross section data and other parameters -! needed to treat resonance scattering before transferring them to NUCLIDE_CE +! needed to treat resonance scattering before transferring them to NuclideCE !=============================================================================== type Nuclide0K @@ -297,13 +297,13 @@ module nuclide_header contains !=============================================================================== -! NUCLIDE_*_CLEAR resets and deallocates data in Nuclide_Base, Nuclide_Iso -! or Nuclide_Angle +! NUCLIDE_*_CLEAR resets and deallocates data in NuclideBase, NuclideIso +! or NuclideAngle !=============================================================================== - subroutine nuclide_ce_clear(this) + subroutine nuclidece_clear(this) - class(Nuclide_CE), intent(inout) :: this ! The Nuclide object to clear + class(NuclideCE), intent(inout) :: this ! The Nuclide object to clear integer :: i ! Loop counter @@ -317,11 +317,11 @@ module nuclide_header call this % reaction_index % clear() - end subroutine nuclide_ce_clear + end subroutine nuclidece_clear - subroutine nuclide_iso_clear(this) + subroutine nuclideiso_clear(this) - class(Nuclide_Iso), intent(inout) :: this ! The Nuclide object to clear + class(NuclideIso), intent(inout) :: this ! The Nuclide object to clear ! Cler the extended information if (allocated(this % total)) then @@ -340,11 +340,11 @@ module nuclide_header deallocate(this % mult) end if - end subroutine nuclide_iso_clear + end subroutine nuclideiso_clear - subroutine nuclide_angle_clear(this) + subroutine nuclideangle_clear(this) - class(Nuclide_Angle), intent(inout) :: this ! The Nuclide object to clear + class(NuclideAngle), intent(inout) :: this ! The Nuclide object to clear ! Cler the extended information if (allocated(this % total)) then @@ -370,15 +370,15 @@ module nuclide_header deallocate(this % mult) end if - end subroutine nuclide_angle_clear + end subroutine nuclideangle_clear !=============================================================================== ! PRINT_NUCLIDE_* displays information about a continuous-energy neutron ! cross_section table and its reactions and secondary angle/energy distributions !=============================================================================== - subroutine nuclide_ce_print(this, unit) - class(Nuclide_CE), intent(in) :: this + subroutine nuclidece_print(this, unit) + class(NuclideCE), intent(in) :: this integer, intent(in), optional :: unit integer :: i ! loop index over nuclides @@ -451,10 +451,10 @@ module nuclide_header ! Blank line at end of nuclide write(unit_,*) - end subroutine nuclide_ce_print + end subroutine nuclidece_print - subroutine nuclide_mg_print(this, unit_) - class(Nuclide_MG), intent(in) :: this + subroutine nuclidemg_print(this, unit_) + class(NuclideMG), intent(in) :: this integer, intent(in) :: unit_ character(MAX_LINE_LEN) :: temp_str @@ -484,11 +484,11 @@ module nuclide_header end if write(unit_,*) ' Fissionable = ', this % fissionable - end subroutine nuclide_mg_print + end subroutine nuclidemg_print - subroutine nuclide_iso_print(this, unit) + subroutine nuclideiso_print(this, unit) - class(Nuclide_Iso), intent(in) :: this + class(NuclideIso), intent(in) :: this integer, optional, intent(in) :: unit integer :: unit_ ! unit to write to @@ -502,7 +502,7 @@ module nuclide_header end if ! Write Basic Nuclide Information - call nuclide_mg_print(this, unit_) + call nuclidemg_print(this, unit_) ! Determine size of mgxs and scattering matrices size_scattmat = (size(this % scatter) + size(this % mult)) * 8 @@ -524,11 +524,11 @@ module nuclide_header ! Blank line at end of nuclide write(unit_,*) - end subroutine nuclide_iso_print + end subroutine nuclideiso_print - subroutine nuclide_angle_print(this, unit) + subroutine nuclideangle_print(this, unit) - class(Nuclide_Angle), intent(in) :: this + class(NuclideAngle), intent(in) :: this integer, optional, intent(in) :: unit integer :: unit_ ! unit to write to @@ -542,7 +542,7 @@ module nuclide_header end if ! Write Basic Nuclide Information - call nuclide_mg_print(this, unit_) + call nuclidemg_print(this, unit_) write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % Npol)) write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % Nazi)) @@ -567,15 +567,15 @@ module nuclide_header write(unit_,*) - end subroutine nuclide_angle_print + end subroutine nuclideangle_print !=============================================================================== ! NUCLIDE_*_GET_XS Returns the requested data type !=============================================================================== - function nuclide_iso_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & + function nuclideiso_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) - class(Nuclide_Iso), intent(in) :: this + class(NuclideIso), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group @@ -622,11 +622,11 @@ module nuclide_header xs = this % total(g) - this % absorption(g) end select end if - end function nuclide_iso_get_xs + end function nuclideiso_get_xs - function nuclide_angle_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & + function nuclideangle_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) - class(Nuclide_Angle), intent(in) :: this + class(NuclideAngle), intent(in) :: this integer, intent(in) :: g ! Incoming Energy group character(*), intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Group @@ -685,16 +685,16 @@ module nuclide_header end select end if - end function nuclide_angle_get_xs + end function nuclideangle_get_xs !=============================================================================== ! NUCLIDE_*_CALC_F Finds the value of f(mu), the scattering angle probability, ! given mu !=============================================================================== - pure function nuclide_mg_iso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & + pure function nuclideiso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & result(f) - class(Nuclide_Iso), intent(in) :: this + class(NuclideIso), intent(in) :: this integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -737,11 +737,11 @@ module nuclide_header end if - end function nuclide_mg_iso_calc_f + end function nuclideiso_calc_f - pure function nuclide_mg_angle_calc_f(this, gin, gout, mu, uvw, i_azi, & + pure function nuclideangle_calc_f(this, gin, gout, mu, uvw, i_azi, & i_pol) result(f) - class(Nuclide_Angle), intent(in) :: this + class(NuclideAngle), intent(in) :: this integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -791,7 +791,7 @@ module nuclide_header end if - end function nuclide_mg_angle_calc_f + end function nuclideangle_calc_f !=============================================================================== ! find_angle finds the closest angle on the data grid and returns that index diff --git a/src/output.F90 b/src/output.F90 index 29844076e6..125fe010bc 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -350,10 +350,10 @@ contains call sab_tables(i) % print(unit=unit_xs) end do SAB_TABLES_LOOP else - NUCLIDE_MG_LOOP: do i = 1, n_nuclides_total + NuclideMG_LOOP: do i = 1, n_nuclides_total ! Print information about nuclide call nuclides_mg(i) % obj % print(unit=unit_xs) - end do NUCLIDE_MG_LOOP + end do NuclideMG_LOOP end if ! Close cross section summary file diff --git a/src/physics.F90 b/src/physics.F90 index 13a311d5e3..e41b3b4e9e 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -75,7 +75,7 @@ contains integer :: i_nuclide ! index in nuclides array integer :: i_nuc_mat ! index in material's nuclides array integer :: i_reaction ! index in nuc % reactions array - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc call sample_nuclide(p, 'total ', i_nuclide, i_nuc_mat) @@ -198,7 +198,7 @@ contains real(8) :: f real(8) :: prob real(8) :: cutoff - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc ! Get pointer to nuclide nuc => nuclides(i_nuclide) @@ -296,7 +296,7 @@ contains real(8) :: uvw_new(3) ! outgoing uvw for iso-in-lab scattering real(8) :: uvw_old(3) ! incoming uvw for iso-in-lab scattering real(8) :: phi ! azimuthal angle for iso-in-lab scattering - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc ! copy incoming direction uvw_old(:) = p % coord(1) % uvw @@ -411,7 +411,7 @@ contains real(8) :: v_cm(3) ! velocity of center-of-mass real(8) :: v_t(3) ! velocity of target nucleus real(8) :: uvw_cm(3) ! directional cosines in center-of-mass - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc ! get pointer to nuclide nuc => nuclides(i_nuclide) @@ -737,7 +737,7 @@ contains !=============================================================================== subroutine sample_target_velocity(nuc, v_target, E, uvw, v_neut, wgt, xs_eff) - type(Nuclide_CE), intent(in) :: nuc ! target nuclide at temperature T + type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature T real(8), intent(out) :: v_target(3) ! target velocity real(8), intent(in) :: v_neut(3) ! neutron velocity real(8), intent(in) :: E ! particle energy @@ -982,7 +982,7 @@ contains !=============================================================================== subroutine sample_cxs_target_velocity(nuc, v_target, E, uvw) - type(Nuclide_CE), intent(in) :: nuc ! target nuclide at temperature + type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature real(8), intent(out) :: v_target(3) real(8), intent(in) :: E real(8), intent(in) :: uvw(3) @@ -1070,7 +1070,7 @@ contains real(8) :: phi ! fission neutron azimuthal angle real(8) :: weight ! weight adjustment for ufs method logical :: in_mesh ! source site in ufs mesh? - type(Nuclide_CE), pointer :: nuc + type(NuclideCE), pointer :: nuc ! Get pointers nuc => nuclides(i_nuclide) @@ -1180,7 +1180,7 @@ contains function sample_fission_energy(nuc, rxn, p) result(E_out) - type(Nuclide_CE), intent(in) :: nuc + type(NuclideCE), intent(in) :: nuc type(Reaction), intent(in) :: rxn type(Particle), intent(inout) :: p ! Particle causing fission real(8) :: E_out ! outgoing energy of fission neutron @@ -1293,7 +1293,7 @@ contains !=============================================================================== subroutine inelastic_scatter(nuc, rxn, p) - type(Nuclide_CE), intent(in) :: nuc + type(NuclideCE), intent(in) :: nuc type(Reaction), intent(in) :: rxn type(Particle), intent(inout) :: p From cf213cf86e5b2f23fabc608922cf084271652b4b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 5 Feb 2016 21:25:42 -0500 Subject: [PATCH 64/84] Clearing up the clear routines from NuclideMG extended types. Now THATS punny --- src/global.F90 | 4 --- src/nuclide_header.F90 | 69 +++--------------------------------------- 2 files changed, 4 insertions(+), 69 deletions(-) diff --git a/src/global.F90 b/src/global.F90 index dcbf7b1e48..02f53a4f7d 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -482,10 +482,6 @@ contains end if if (allocated(nuclides_MG)) then - ! First call the clear routines - do i = 1, size(nuclides_MG) - call nuclides_MG(i) % obj % clear() - end do deallocate(nuclides_MG) end if diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index fc9c53ff30..095155a33b 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -31,17 +31,11 @@ module nuclide_header logical :: fissionable ! nuclide is fissionable? contains - procedure(nuclidebase_clear_), deferred, pass :: clear ! Deallocates Nuclide procedure(print_nuclide_), deferred, pass :: print ! Writes nuclide info end type NuclideBase abstract interface - subroutine nuclidebase_clear_(this) - import NuclideBase - class(NuclideBase), intent(inout) :: this - end subroutine nuclidebase_clear_ - subroutine print_nuclide_(this, unit) import NuclideBase class(NuclideBase),intent(in) :: this @@ -174,7 +168,6 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclideiso_clear ! Deallocates Nuclide procedure, pass :: print => nuclideiso_print ! Writes nuclide info procedure, pass :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object procedure, pass :: calc_f => nuclideiso_calc_f ! Calcs f given mu @@ -205,7 +198,6 @@ module nuclide_header ! Type-Bound procedures contains - procedure, pass :: clear => nuclideangle_clear ! Deallocates Nuclide procedure, pass :: print => nuclideangle_print ! Gets Size of Data w/in Object procedure, pass :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object procedure, pass :: calc_f => nuclideangle_calc_f ! Calcs f given mu @@ -297,7 +289,7 @@ module nuclide_header contains !=============================================================================== -! NUCLIDE_*_CLEAR resets and deallocates data in NuclideBase, NuclideIso +! NUCLIDECE_CLEAR resets and deallocates data in NuclideBase, NuclideIso ! or NuclideAngle !=============================================================================== @@ -319,61 +311,8 @@ module nuclide_header end subroutine nuclidece_clear - subroutine nuclideiso_clear(this) - - class(NuclideIso), intent(inout) :: this ! The Nuclide object to clear - - ! Cler the extended information - if (allocated(this % total)) then - deallocate(this % total, this % absorption, this % scatter) - end if - if (allocated(this % fission)) then - deallocate(this % fission, this % nu_fission) - end if - if (allocated(this % k_fission)) then - deallocate(this % k_fission) - end if - if (allocated(this % chi)) then - deallocate(this % chi) - end if - if (allocated(this % mult)) then - deallocate(this % mult) - end if - - end subroutine nuclideiso_clear - - subroutine nuclideangle_clear(this) - - class(NuclideAngle), intent(inout) :: this ! The Nuclide object to clear - - ! Cler the extended information - if (allocated(this % total)) then - deallocate(this % total, this % absorption, this % scatter) - end if - if (allocated(this % fission)) then - deallocate(this % fission, this % nu_fission) - end if - if (allocated(this % k_fission)) then - deallocate(this % k_fission) - end if - if (allocated(this % chi)) then - deallocate(this % chi) - end if - - if (allocated(this % polar)) then - deallocate(this % polar) - end if - if (allocated(this % azimuthal)) then - deallocate(this % azimuthal) - end if - if (allocated(this % mult)) then - deallocate(this % mult) - end if - - end subroutine nuclideangle_clear - !=============================================================================== -! PRINT_NUCLIDE_* displays information about a continuous-energy neutron +! NUCLIDE*_PRINT displays information about a continuous-energy neutron ! cross_section table and its reactions and secondary angle/energy distributions !=============================================================================== @@ -570,7 +509,7 @@ module nuclide_header end subroutine nuclideangle_print !=============================================================================== -! NUCLIDE_*_GET_XS Returns the requested data type +! NUCLIDE*_GET_XS Returns the requested data type !=============================================================================== function nuclideiso_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & @@ -688,7 +627,7 @@ module nuclide_header end function nuclideangle_get_xs !=============================================================================== -! NUCLIDE_*_CALC_F Finds the value of f(mu), the scattering angle probability, +! NUCLIDE*_CALC_F Finds the value of f(mu), the scattering angle probability, ! given mu !=============================================================================== From 7543e9df661623b424b6f3d5a9c12ca48cf1742c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Feb 2016 08:12:12 -0500 Subject: [PATCH 65/84] Updating output file revision numbers as i neglected to do so earlier --- docs/source/usersguide/output/particle_restart.rst | 10 ++++++++-- docs/source/usersguide/output/statepoint.rst | 2 +- src/constants.F90 | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/source/usersguide/output/particle_restart.rst b/docs/source/usersguide/output/particle_restart.rst index e0d89a5156..eeb40a526e 100644 --- a/docs/source/usersguide/output/particle_restart.rst +++ b/docs/source/usersguide/output/particle_restart.rst @@ -4,7 +4,7 @@ Particle Restart File Format ============================ -The current revision of the particle restart file format is 1. +The current revision of the particle restart file format is 2. **/filetype** (*char[]*) @@ -46,7 +46,13 @@ The current revision of the particle restart file format is 1. **/energy** (*double*) - Energy of the particle in MeV. + Energy of the particle in MeV. This is always provided but only used + for continuous-energy mode. + +**/energy_group** (*double*) + + Energy group of the particle. This is always provided but only used + for multi-group mode. **/xyz** (*double[3]*) diff --git a/docs/source/usersguide/output/statepoint.rst b/docs/source/usersguide/output/statepoint.rst index 2921258c97..2251619653 100644 --- a/docs/source/usersguide/output/statepoint.rst +++ b/docs/source/usersguide/output/statepoint.rst @@ -4,7 +4,7 @@ State Point File Format ======================= -The current revision of the statepoint file format is 14. +The current revision of the statepoint file format is 15. **/filetype** (*char[]*) diff --git a/src/constants.F90 b/src/constants.F90 index 0c208e6d34..b93abae2b7 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -11,10 +11,10 @@ module constants integer, parameter :: VERSION_RELEASE = 1 ! Revision numbers for binary files - integer, parameter :: REVISION_STATEPOINT = 14 - integer, parameter :: REVISION_PARTICLE_RESTART = 1 + integer, parameter :: REVISION_STATEPOINT = 15 + integer, parameter :: REVISION_PARTICLE_RESTART = 2 integer, parameter :: REVISION_TRACK = 1 - integer, parameter :: REVISION_SUMMARY = 2 + integer, parameter :: REVISION_SUMMARY = 3 ! ============================================================================ ! ADJUSTABLE PARAMETERS From 596c819be7650c299d4f97d673e009e5f719382b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Feb 2016 15:54:53 -0500 Subject: [PATCH 66/84] 2 more revision nmbers to update in python api --- openmc/particle_restart.py | 4 ++-- openmc/statepoint.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/particle_restart.py b/openmc/particle_restart.py index 72bf3ac3de..4aad111325 100644 --- a/openmc/particle_restart.py +++ b/openmc/particle_restart.py @@ -43,11 +43,11 @@ class Particle(object): if 'filetype' not in self._f or self._f[ 'filetype'].value.decode() != 'particle restart': raise IOError('{} is not a particle restart file.'.format(filename)) - if self._f['revision'].value != 1: + if self._f['revision'].value != 2: raise IOError('Particle restart file has a file revision of {} ' 'which is not consistent with the revision this ' 'version of OpenMC expects ({}).'.format( - self._f['revision'].value, 1)) + self._f['revision'].value, 2)) @property def current_batch(self): diff --git a/openmc/statepoint.py b/openmc/statepoint.py index f5b5b2e72d..003b088180 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -103,11 +103,11 @@ class StatePoint(object): raise IOError('Could not read statepoint file. This most likely ' 'means the statepoint file was produced by a different ' 'version of OpenMC than the one you are using.') - if self._f['revision'].value != 14: + if self._f['revision'].value != 15: raise IOError('Statepoint file has a file revision of {} ' 'which is not consistent with the revision this ' 'version of OpenMC expects ({}).'.format( - self._f['revision'].value, 14)) + self._f['revision'].value, 15)) # Set flags for what data has been read self._meshes_read = False From 2098487bcbb13e7d43cd06d7f3df4fbb1756caf0 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 7 Feb 2016 05:37:07 -0500 Subject: [PATCH 67/84] Correcting some more EnergyGroups.num_group issues --- openmc/mgxs/groups.py | 2 +- openmc/mgxs_library.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/mgxs/groups.py b/openmc/mgxs/groups.py index e6838b36ba..253df520ee 100644 --- a/openmc/mgxs/groups.py +++ b/openmc/mgxs/groups.py @@ -24,7 +24,7 @@ class EnergyGroups(object): ---------- group_edges : Iterable of Real The energy group boundaries [MeV] - num_group : Integral + num_groups : Integral The number of energy groups """ diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 3b6b7753ea..f3e7b92184 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -418,12 +418,12 @@ class XSdata(object): @multiplicity.setter def multiplicity(self, multiplicity): if self._representation is 'isotropic': - shape = (self._energy_groups.num_group, + shape = (self._energy_groups.num_groups, self._energy_groups.num_groups) max_depth = 2 elif self._representation is 'angle': shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group, + self._energy_groups.num_groups, self._energy_groups.num_groups) max_depth = 4 # check we have a numpy list @@ -455,7 +455,7 @@ class XSdata(object): shape_vec = (self._num_polar, self._num_azimuthal, self._energy_groups.num_groups) shape_mat = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_group, + self._energy_groups.num_groups, self._energy_groups.num_groups) # Begin by checking the case when chi has already been given and thus From 65825b1b4ff68acff6f01c41c0efd3942a534b15 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 8 Feb 2016 19:43:35 -0500 Subject: [PATCH 68/84] Resolving style comments from @paulromano --- .../usersguide/output/particle_restart.rst | 2 +- src/ace_header.F90 | 5 +- src/global.F90 | 2 +- src/macroxs_header.F90 | 97 ++++++-------- src/{macroxs.F90 => macroxs_operations.F90} | 62 ++++----- src/mgxs_data.F90 | 8 +- src/nuclide_header.F90 | 64 +++++---- src/particle_header.F90 | 8 +- src/physics_mg.F90 | 6 +- src/sab_header.F90 | 4 +- src/scattdata_header.F90 | 121 +++++++++--------- src/tracking.F90 | 34 ++--- 12 files changed, 194 insertions(+), 219 deletions(-) rename src/{macroxs.F90 => macroxs_operations.F90} (80%) diff --git a/docs/source/usersguide/output/particle_restart.rst b/docs/source/usersguide/output/particle_restart.rst index eeb40a526e..1ed6077108 100644 --- a/docs/source/usersguide/output/particle_restart.rst +++ b/docs/source/usersguide/output/particle_restart.rst @@ -49,7 +49,7 @@ The current revision of the particle restart file format is 2. Energy of the particle in MeV. This is always provided but only used for continuous-energy mode. -**/energy_group** (*double*) +**/energy_group** (*int*) Energy group of the particle. This is always provided but only used for multi-group mode. diff --git a/src/ace_header.F90 b/src/ace_header.F90 index 497a16d3bf..ae5000e5ab 100644 --- a/src/ace_header.F90 +++ b/src/ace_header.F90 @@ -24,9 +24,8 @@ module ace_header real(8), allocatable :: sigma(:) ! Cross section values type(SecondaryDistribution) :: secondary - ! Type-Bound procedures - contains - procedure :: clear => reaction_clear ! Deallocates Reaction + contains + procedure :: clear => reaction_clear ! Deallocates Reaction end type Reaction !=============================================================================== diff --git a/src/global.F90 b/src/global.F90 index 02f53a4f7d..17477ed80b 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -5,7 +5,7 @@ module global use constants use dict_header, only: DictCharInt, DictIntInt use geometry_header, only: Cell, Universe, Lattice, LatticeContainer - use macroxs_header, only: MacroXS_Base, MacroXSContainer + use macroxs_header, only: MacroXSContainer use material_header, only: Material use mesh_header, only: RegularMesh use nuclide_header diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 95053789f5..0f838967ea 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -14,26 +14,24 @@ module macroxs_header ! particle is traveling through !=============================================================================== - type, abstract :: MacroXS_Base + type, abstract :: MacroXS ! Data Order integer :: order - ! Type-Bound procedures contains - procedure(macroxs_init_), deferred, pass :: init ! initializes object - procedure(macroxs_get_xs_), deferred, pass :: get_xs ! Return xs - end type MacroXS_Base + procedure(macroxs_init_), deferred :: init ! initializes object + procedure(macroxs_get_xs_), deferred :: get_xs ! Return xs + end type MacroXS abstract interface subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, & error_code, error_text) - - import MacroXS_Base + import MacroXS import Material import NuclideMGContainer import MAX_LINE_LEN - class(MacroXS_Base), intent(inout) :: this ! The MacroXS to initialize + class(MacroXS), intent(inout) :: this ! The MacroXS to initialize type(Material), pointer, intent(in) :: mat ! base material type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups @@ -44,47 +42,36 @@ module macroxs_header integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? integer, intent(inout) :: error_code ! Code signifying error character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - end subroutine macroxs_init_ function macroxs_get_xs_(this, g, xstype, gout, uvw) result(xs) - import MacroXS_Base - class(MacroXS_Base), intent(in) :: this ! The MacroXS to initialize + import MacroXS + class(MacroXS), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Cross Section Type integer, optional, intent(in) :: gout ! Outgoing Energy group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8) :: xs ! Resultant xs - end function macroxs_get_xs_ - - subroutine macroxs_clear_(this) - - import MacroXS_Base - class(MacroXS_Base), intent(inout) :: this ! The MacroXS to clear - - end subroutine macroxs_clear_ - end interface - type, extends(MacroXS_Base) :: MacroXS_Iso + type, extends(MacroXS) :: MacroXSIso ! Microscopic cross sections real(8), allocatable :: total(:) ! total cross section real(8), allocatable :: absorption(:) ! absorption cross section - class(ScattData_Base), allocatable :: scatter ! scattering information + class(ScattData), allocatable :: scatter ! scattering information real(8), allocatable :: nu_fission(:) ! nu-fission real(8), allocatable :: k_fission(:) ! kappa-fission real(8), allocatable :: fission(:) ! fission x/s real(8), allocatable :: scattxs(:) ! scattering xs real(8), allocatable :: chi(:,:) ! fission spectra - ! Type-Bound procedures contains - procedure, pass :: init => macroxs_iso_init ! inits object - procedure, pass :: get_xs => macroxs_iso_get_xs ! Returns xs - end type MacroXS_Iso + procedure :: init => macroxsiso_init ! inits object + procedure :: get_xs => macroxsiso_get_xs ! Returns xs + end type MacroXSIso - type, extends(MacroXS_Base) :: MacroXS_Angle + type, extends(MacroXS) :: MacroXSAngle ! Macroscopic cross sections real(8), allocatable :: total(:,:,:) ! total cross section real(8), allocatable :: absorption(:,:,:) ! absorption cross section @@ -97,18 +84,17 @@ module macroxs_header real(8), allocatable :: polar(:) ! polar angles real(8), allocatable :: azimuthal(:) ! azimuthal angles - ! Type-Bound procedures contains - procedure, pass :: init => macroxs_angle_init ! inits object - procedure, pass :: get_xs => macroxs_angle_get_xs ! Returns xs - end type MacroXS_Angle + procedure :: init => macroxsangle_init ! inits object + procedure :: get_xs => macroxsangle_get_xs ! Returns xs + end type MacroXSAngle !=============================================================================== ! MACROXSCONTAINER pointer array for storing MacroXS objects. !=============================================================================== type MacroXSContainer - class(MacroXS_Base), allocatable :: obj + class(MacroXS), allocatable :: obj end type MacroXSContainer contains @@ -117,10 +103,9 @@ contains ! MACROXS*_INIT sets the MacroXS Data !=============================================================================== - subroutine macroxs_iso_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & + subroutine macroxsiso_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, error_code, error_text) - - class(MacroXS_Iso), intent(inout) :: this ! The MacroXS to initialize + class(MacroXSIso), intent(inout) :: this ! The MacroXS to initialize type(Material), pointer, intent(in) :: mat ! base material type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups @@ -135,7 +120,6 @@ contains integer :: i ! loop index over nuclides integer :: gin, gout ! group indices real(8) :: atom_density ! atom density of a nuclide - ! class(NuclideBase), pointer :: nuc ! current nuclide integer :: imu real(8) :: norm integer :: mat_max_order, order, l @@ -164,7 +148,7 @@ contains ! Allocate stuff for later allocate(scatt_coeffs(order, groups, groups)) scatt_coeffs = ZERO - allocate(ScattData_Histogram :: this % scatter) + allocate(ScattDataHistogram :: this % scatter) else if (scatt_type == ANGLE_TABULAR) then ! Check all scattering data of same size @@ -182,7 +166,7 @@ contains ! Allocate stuff for later allocate(scatt_coeffs(order, groups, groups)) scatt_coeffs = ZERO - allocate(ScattData_Tabular :: this % scatter) + allocate(ScattDataTabular :: this % scatter) else if (scatt_type == ANGLE_LEGENDRE) then ! Otherwise find the maximum scattering order @@ -203,9 +187,9 @@ contains allocate(scatt_coeffs(order + 1, groups, groups)) scatt_coeffs = ZERO if (legendre_mu_points == 1) then - allocate(ScattData_Legendre :: this % scatter) + allocate(ScattDataLegendre :: this % scatter) else - allocate(ScattData_Tabular :: this % scatter) + allocate(ScattDataTabular :: this % scatter) end if end if @@ -307,7 +291,7 @@ contains end do type is (NuclideAngle) error_code = 1 - error_text = "Invalid Passing of NuclideAngle to MacroXS_Iso Object" + error_text = "Invalid Passing of NuclideAngle to MacroXSIso Object" return end select end do @@ -360,12 +344,11 @@ contains ! Deallocate temporaries for the next material deallocate(scatt_coeffs, temp_energy, temp_mult) - end subroutine macroxs_iso_init + end subroutine macroxsiso_init - subroutine macroxs_angle_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & + subroutine macroxsangle_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, error_code, error_text) - - class(MacroXS_Angle), intent(inout) :: this ! The MacroXS to initialize + class(MacroXSAngle), intent(inout) :: this ! The MacroXS to initialize type(Material), pointer, intent(in) :: mat ! base material type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups @@ -435,7 +418,7 @@ contains allocate(this % scatter(nazi, npol)) do ipol = 1, npol do iazi = 1, nazi - allocate(ScattData_Histogram :: this % scatter(iazi, ipol) % obj) + allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) end do end do @@ -458,7 +441,7 @@ contains allocate(this % scatter(nazi, npol)) do ipol = 1, npol do iazi = 1, nazi - allocate(ScattData_Tabular :: this % scatter(iazi, ipol) % obj) + allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) end do end do @@ -484,9 +467,9 @@ contains do ipol = 1, npol do iazi = 1, nazi if (legendre_mu_points == 1) then - allocate(ScattData_Legendre :: this % scatter(iazi, ipol) % obj) + allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) else - allocate(ScattData_Tabular :: this % scatter(iazi, ipol) % obj) + allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) end if end do end do @@ -524,7 +507,7 @@ contains select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (NuclideIso) error_code = 1 - error_text = "Invalid Passing of NuclideIso to MacroXS_Angle Object" + error_text = "Invalid Passing of NuclideIso to MacroXSAngle Object" return type is (NuclideAngle) ! Add contributions to total, absorption, and fission data (if necessary) @@ -652,14 +635,14 @@ contains ! Deallocate temporaries for the next material deallocate(scatt_coeffs, temp_energy, temp_mult) - end subroutine macroxs_angle_init + end subroutine macroxsangle_init !=============================================================================== ! MACROXS_*_GET_XS returns the requested data type !=============================================================================== - function macroxs_iso_get_xs(this, g, xstype, gout, uvw) result(xs) - class(MacroXS_Iso), intent(in) :: this ! The MacroXS to initialize + function macroxsiso_get_xs(this, g, xstype, gout, uvw) result(xs) + class(MacroXSIso), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Type of xs requested integer, optional, intent(in) :: gout ! Outgoing Energy group @@ -687,10 +670,10 @@ contains end if end select - end function macroxs_iso_get_xs + end function macroxsiso_get_xs - function macroxs_angle_get_xs(this, g, xstype, gout,uvw) result(xs) - class(MacroXS_Angle), intent(in) :: this ! The MacroXS to initialize + function macroxsangle_get_xs(this, g, xstype, gout,uvw) result(xs) + class(MacroXSAngle), intent(in) :: this ! The MacroXS to initialize integer, intent(in) :: g ! Incoming Energy group character(*) , intent(in) :: xstype ! Type of xs requested integer, optional, intent(in) :: gout ! Outgoing Energy group @@ -723,6 +706,6 @@ contains end select end if - end function macroxs_angle_get_xs + end function macroxsangle_get_xs end module macroxs_header diff --git a/src/macroxs.F90 b/src/macroxs_operations.F90 similarity index 80% rename from src/macroxs.F90 rename to src/macroxs_operations.F90 index 170f5fb19a..4fc13910ca 100644 --- a/src/macroxs.F90 +++ b/src/macroxs_operations.F90 @@ -1,7 +1,7 @@ -module macroxs +module macroxs_operations use constants - use macroxs_header, only: MacroXS_Base, MacroXS_Iso, MacroXS_Angle, & + use macroxs_header, only: MacroXS, MacroXSIso, MacroXSAngle, & expand_harmonic use material_header, only: Material use math @@ -20,7 +20,7 @@ contains !=============================================================================== subroutine calculate_mgxs(this, gin, uvw, xs) - class(MacroXS_Base), intent(in) :: this + class(MacroXS), intent(in) :: this integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs @@ -28,13 +28,13 @@ contains integer :: iazi, ipol select type(this) - type is (MacroXS_Iso) + type is (MacroXSIso) xs % total = this % total(gin) xs % elastic = this % scattxs(gin) xs % absorption = this % absorption(gin) xs % nu_fission = this % nu_fission(gin) - type is (MacroXS_Angle) + type is (MacroXSAngle) call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) xs % total = this % total(gin, iazi, ipol) xs % elastic = this % scattxs(gin, iazi, ipol) @@ -50,16 +50,16 @@ contains !=============================================================================== function sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXS_Base), intent(in) :: this ! Data to work with + class(MacroXS), intent(in) :: this ! Data to work with integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group select type(this) - type is (MacroXS_Iso) - gout = macroxs_iso_sample_fission_energy(this, gin, uvw) - type is (MacroXS_Angle) - gout = macroxs_angle_sample_fission_energy(this, gin, uvw) + type is (MacroXSIso) + gout = macroxsiso_sample_fission_energy(this, gin, uvw) + type is (MacroXSAngle) + gout = macroxsangle_sample_fission_energy(this, gin, uvw) end select end function sample_fission_energy @@ -69,11 +69,11 @@ contains ! Implemented as % scatter. !=============================================================================== - function macroxs_iso_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXS_Iso), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group + function macroxsiso_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXSIso), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group real(8) :: xi ! Our random number real(8) :: prob ! Running probability @@ -86,10 +86,10 @@ contains prob = prob + this % chi(gout,gin) end do - end function macroxs_iso_sample_fission_energy + end function macroxsiso_sample_fission_energy - function macroxs_angle_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXS_Angle), intent(in) :: this ! Data to work with + function macroxsangle_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXSAngle), intent(in) :: this ! Data to work with integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group @@ -108,14 +108,14 @@ contains prob = prob + this % chi(gout,gin,iazi,ipol) end do - end function macroxs_angle_sample_fission_energy + end function macroxsangle_sample_fission_energy !=============================================================================== ! SAMPLE_SCATTER acts as a templating code for macroxs_*_sample_scatter !=============================================================================== subroutine sample_scatter(this, uvw, gin, gout, mu, wgt) - class(MacroXS_Base), intent(in) :: this + class(MacroXS), intent(in) :: this real(8), intent(in) :: uvw(3) ! Incoming neutron direction integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group @@ -125,9 +125,9 @@ contains integer :: iazi, ipol ! Angular indices select type(this) - type is (MacroXS_Iso) + type is (MacroXSIso) call macroxs_sample_scatter(this % scatter, gin, gout, mu, wgt) - type is (MacroXS_Angle) + type is (MacroXSAngle) call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) call macroxs_sample_scatter(this % scatter(iazi,ipol) % obj,gin,gout,mu,wgt) end select @@ -140,11 +140,11 @@ contains !=============================================================================== subroutine macroxs_sample_scatter(scatt, gin, gout, mu, wgt) - class(ScattData_Base), intent(in) :: scatt ! Scattering Object to Use - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight + class(ScattData), intent(in) :: scatt ! Scattering Object to Use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight real(8) :: xi ! Our random number real(8) :: prob ! Running probability @@ -164,7 +164,7 @@ contains end do select type (scatt) - type is (ScattData_Histogram) + type is (ScattDataHistogram) xi = prn() if (xi < scatt % data(1,gout,gin)) then imu = 1 @@ -176,7 +176,7 @@ contains ! Randomly select a mu in this bin. mu = prn() * scatt % dmu + scatt % mu(imu) - type is (ScattData_Tabular) + type is (ScattDataTabular) ! determine outgoing cosine bin NP = size(scatt % data(:,gout,gin)) xi = prn() @@ -211,7 +211,7 @@ contains mu = ONE end if - type is (ScattData_Legendre) + type is (ScattDataLegendre) ! Now we can sample mu using the legendre representation of the scattering ! kernel in data(1:this % order) @@ -240,4 +240,4 @@ contains end subroutine macroxs_sample_scatter -end module macroxs \ No newline at end of file +end module macroxs_operations \ No newline at end of file diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index d9c397f5bb..94546c10dc 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -486,7 +486,7 @@ contains return call get_node_array(node_xsdata, "polar", this % polar) else - dangle = PI / (real(this % Npol,8)) + dangle = PI / real(this % Npol,8) do iangle = 1, this % Npol this % polar(iangle) = (real(iangle,8) - 0.5_8) * dangle end do @@ -497,7 +497,7 @@ contains return call get_node_array(node_xsdata, "azimuthal", this % azimuthal) else - dangle = TWO * PI / (real(this % Nazi,8)) + dangle = TWO * PI / real(this % Nazi,8) do iangle = 1, this % Nazi this % azimuthal(iangle) = -PI + (real(iangle,8) - 0.5_8) * dangle end do @@ -685,9 +685,9 @@ contains ! Now allocate accordingly select case(representation) case(MGXS_ISOTROPIC) - allocate(MacroXS_Iso :: macro_xs(i_mat) % obj) + allocate(MacroXSIso :: macro_xs(i_mat) % obj) case(MGXS_ANGLE) - allocate(MacroXS_Angle :: macro_xs(i_mat) % obj) + allocate(MacroXSAngle :: macro_xs(i_mat) % obj) end select call macro_xs(i_mat) % obj % init(mat, nuclides_MG, energy_groups, & diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 095155a33b..caf0c10729 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -12,12 +12,12 @@ module nuclide_header implicit none !=============================================================================== -! NuclideBase contains the base nuclidic data for a nuclide, which does not depend +! Nuclide contains the base nuclidic data for a nuclide, which does not depend ! upon how the nuclear data is represented (i.e., CE, or any variant of MG). ! The extended types, NuclideCE and NuclideMG deal with the rest !=============================================================================== - type, abstract :: NuclideBase + type, abstract :: Nuclide character(12) :: name ! name of nuclide, e.g. 92235.03c integer :: zaid ! Z and A identifier, e.g. 92235 real(8) :: awr ! Atomic Weight Ratio @@ -30,21 +30,21 @@ module nuclide_header ! Fission information logical :: fissionable ! nuclide is fissionable? - contains - procedure(print_nuclide_), deferred, pass :: print ! Writes nuclide info - end type NuclideBase + contains + procedure(print_nuclide_), deferred :: print ! Writes nuclide info + end type Nuclide abstract interface subroutine print_nuclide_(this, unit) - import NuclideBase - class(NuclideBase),intent(in) :: this - integer, optional, intent(in) :: unit + import Nuclide + class(Nuclide),intent(in) :: this + integer, optional, intent(in) :: unit end subroutine print_nuclide_ end interface - type, extends(NuclideBase) :: NuclideCE + type, extends(Nuclide) :: NuclideCE ! Energy grid information integer :: n_grid ! # of nuclide grid points integer, allocatable :: grid_index(:) ! log grid mapping indices @@ -100,13 +100,12 @@ module nuclide_header type(DictIntInt) :: reaction_index ! map MT values to index in reactions ! array; used at tally-time - ! Type-Bound procedures - contains - procedure, pass :: clear => nuclidece_clear - procedure, pass :: print => nuclidece_print + contains + procedure :: clear => nuclidece_clear + procedure :: print => nuclidece_print end type NuclideCE - type, abstract, extends(NuclideBase) :: NuclideMG + type, abstract, extends(Nuclide) :: NuclideMG ! Scattering Order Information integer :: order ! Order of data (Scattering for NuclideIso, ! Number of angles for all in NuclideAngle) @@ -114,10 +113,9 @@ module nuclide_header integer :: legendre_mu_points ! Number of tabular points to use to represent ! Legendre distribs, -1 if sample with the ! Legendres themselves -! Type-Bound procedures - contains - procedure(nuclidemg_get_xs), deferred, pass :: get_xs ! Get the xs - procedure(nuclide_calc_f_), deferred, pass :: calc_f ! Calculates f, given mu + contains + procedure(nuclidemg_get_xs), deferred :: get_xs ! Get the xs + procedure(nuclide_calc_f_), deferred :: calc_f ! Calculates f, given mu end type NuclideMG abstract interface @@ -166,11 +164,10 @@ module nuclide_header real(8), allocatable :: chi(:) ! Fission Spectra real(8), allocatable :: mult(:,:) ! Scatter multiplicity (Gout x Gin) - ! Type-Bound procedures - contains - procedure, pass :: print => nuclideiso_print ! Writes nuclide info - procedure, pass :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object - procedure, pass :: calc_f => nuclideiso_calc_f ! Calcs f given mu + contains + procedure :: print => nuclideiso_print ! Writes nuclide info + procedure :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object + procedure :: calc_f => nuclideiso_calc_f ! Calcs f given mu end type NuclideIso !=============================================================================== @@ -196,11 +193,10 @@ module nuclide_header real(8), allocatable :: polar(:) ! polar angles real(8), allocatable :: azimuthal(:) ! azimuthal angles - ! Type-Bound procedures - contains - procedure, pass :: print => nuclideangle_print ! Gets Size of Data w/in Object - procedure, pass :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object - procedure, pass :: calc_f => nuclideangle_calc_f ! Calcs f given mu + contains + procedure :: print => nuclideangle_print ! Gets Size of Data w/in Object + procedure :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object + procedure :: calc_f => nuclideangle_calc_f ! Calcs f given mu end type NuclideAngle !=============================================================================== @@ -217,14 +213,12 @@ module nuclide_header !=============================================================================== type Nuclide0K - character(10) :: nuclide ! name of nuclide, e.g. U-238 character(16) :: scheme = 'ares' ! target velocity sampling scheme character(10) :: name ! name of nuclide, e.g. 92235.03c character(10) :: name_0K ! name of 0K nuclide, e.g. 92235.00c real(8) :: E_min = 0.01e-6_8 ! lower cutoff energy for res scattering real(8) :: E_max = 1000.0e-6_8 ! upper cutoff energy for res scattering - end type Nuclide0K !=============================================================================== @@ -289,7 +283,7 @@ module nuclide_header contains !=============================================================================== -! NUCLIDECE_CLEAR resets and deallocates data in NuclideBase, NuclideIso +! NUCLIDECE_CLEAR resets and deallocates data in Nuclide, NuclideIso ! or NuclideAngle !=============================================================================== @@ -648,7 +642,7 @@ module nuclide_header if (this % scatt_type == ANGLE_LEGENDRE) then f = evaluate_legendre(this % scatter(gout,gin,:), mu) else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / (real(this % order) - 1) + dmu = TWO / real(this % order - 1) ! Find mu bin algebraically, knowing that the spacing is equal f = (mu + ONE) / dmu + ONE imu = floor(f) @@ -702,7 +696,7 @@ module nuclide_header if (this % scatt_type == ANGLE_LEGENDRE) then f = evaluate_legendre(this % scatter(gout,gin,:,i_azi_,i_pol_), mu) else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / (real(this % order) - 1) + dmu = TWO / real(this % order - 1) ! Find mu bin algebraically, knowing that the spacing is equal f = (mu + ONE) / dmu + ONE imu = floor(f) @@ -751,9 +745,9 @@ module nuclide_header my_azi = atan2(uvw(2), uvw(1)) ! Search for equi-binned angles - dangle = PI / (real(size(polar),8)) + dangle = PI / real(size(polar),8) i_pol = floor(my_pol / dangle + ONE) - dangle = TWO * PI / (real(size(azimuthal),8)) + dangle = TWO * PI / real(size(azimuthal),8) i_azi = floor((my_azi + PI) / dangle + ONE) end subroutine find_angle diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 0426acd924..3c687eb02f 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -94,10 +94,10 @@ module particle_header type(Bank) :: secondary_bank(MAX_SECONDARY) contains - procedure, pass :: initialize => initialize_particle - procedure, pass :: clear => clear_particle - procedure, pass :: initialize_from_source => initialize_from_source - procedure, pass :: create_secondary => create_secondary + procedure :: initialize => initialize_particle + procedure :: clear => clear_particle + procedure :: initialize_from_source => initialize_from_source + procedure :: create_secondary => create_secondary end type Particle contains diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 048f3ce54f..a0d8eb6e1d 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -5,8 +5,8 @@ module physics_mg use constants use error, only: fatal_error, warning use global - use macroxs_header, only: MacroXS_Base, MacroXSContainer - use macroxs, only: sample_fission_energy, sample_scatter + use macroxs_header, only: MacroXS, MacroXSContainer + use macroxs_operations, only: sample_fission_energy, sample_scatter use material_header, only: Material use math, only: rotate_angle use mesh, only: get_mesh_indices @@ -179,7 +179,7 @@ contains real(8) :: phi ! fission neutron azimuthal angle real(8) :: weight ! weight adjustment for ufs method logical :: in_mesh ! source site in ufs mesh? - class(MacroXS_Base), pointer :: xs + class(MacroXS), pointer :: xs ! Get Pointers xs => macro_xs(p % material) % obj diff --git a/src/sab_header.F90 b/src/sab_header.F90 index 56617dd01d..695f735c05 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -60,8 +60,8 @@ module sab_header real(8), allocatable :: elastic_e_in(:) real(8), allocatable :: elastic_P(:) real(8), allocatable :: elastic_mu(:,:) - contains - procedure, pass :: print => print_sab_table + contains + procedure :: print => print_sab_table end type SAlphaBeta contains diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 091a77741a..62b382d36c 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -10,68 +10,67 @@ module scattdata_header ! angular distribution !=============================================================================== - type, abstract :: ScattData_Base + type, abstract :: ScattData ! p0 matrix on its own for sampling energy real(8), allocatable :: energy(:,:) ! (Gout x Gin) real(8), allocatable :: mult(:,:) ! (Gout x Gin) real(8), allocatable :: data(:,:,:) ! (Order/Nmu x Gout x Gin) - ! Type-Bound procedures contains - procedure(init_), deferred, pass :: init ! Initializes ScattData - procedure(calc_f_), deferred, pass :: calc_f ! Calculates f, given mu - end type ScattData_Base + procedure(init_), deferred :: init ! Initializes ScattData + procedure(calc_f_), deferred :: calc_f ! Calculates f, given mu + end type ScattData abstract interface subroutine init_(this, order, energy, mult, coeffs) - import ScattData_Base - class(ScattData_Base), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + import ScattData + class(ScattData), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use end subroutine init_ pure function calc_f_(this, gin, gout, mu) result(f) - import ScattData_Base - class(ScattData_Base), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) + import ScattData + class(ScattData), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) end function calc_f_ end interface - type, extends(ScattData_Base) :: ScattData_Legendre + type, extends(ScattData) :: ScattDataLegendre contains - procedure, pass :: init => scattdata_legendre_init - procedure, pass :: calc_f => scattdata_legendre_calc_f - end type ScattData_Legendre + procedure :: init => scattdatalegendre_init + procedure :: calc_f => scattdatalegendre_calc_f + end type ScattDataLegendre - type, extends(ScattData_Base) :: ScattData_Histogram - real(8), allocatable :: mu(:) ! Mu bins - real(8) :: dmu ! Mu spacing + type, extends(ScattData) :: ScattDataHistogram + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing contains - procedure, pass :: init => scattdata_histogram_init - procedure, pass :: calc_f => scattdata_histogram_calc_f - end type ScattData_Histogram + procedure :: init => scattdatahistogram_init + procedure :: calc_f => scattdatahistogram_calc_f + end type ScattDataHistogram - type, extends(ScattData_Base) :: ScattData_Tabular - real(8), allocatable :: mu(:) ! Mu bins - real(8) :: dmu ! Mu spacing - real(8), allocatable :: fmu(:,:,:) ! PDF of f(mu) + type, extends(ScattData) :: ScattDataTabular + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing + real(8), allocatable :: fmu(:,:,:) ! PDF of f(mu) contains - procedure, pass :: init => scattdata_tabular_init - procedure, pass :: calc_f => scattdata_tabular_calc_f - end type ScattData_Tabular + procedure :: init => scattdatatabular_init + procedure :: calc_f => scattdatatabular_calc_f + end type ScattDataTabular !=============================================================================== ! SCATTDATACONTAINER allocatable array for storing ScattData Objects (for angle) !=============================================================================== type ScattDataContainer - class(ScattData_Base), allocatable :: obj + class(ScattData), allocatable :: obj end type ScattDataContainer contains @@ -80,8 +79,8 @@ contains ! SCATTDATA_INIT builds the scattdata object !=============================================================================== - subroutine scattdata_base_init(this, order, energy, mult) - class(ScattData_Base), intent(inout) :: this ! Object to work on + subroutine scattdatabase_init(this, order, energy, mult) + class(ScattData), intent(inout) :: this ! Object to work on integer, intent(in) :: order ! Data Order real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix @@ -97,23 +96,23 @@ contains allocate(this % data(order, groups, groups)) this % data = ZERO - end subroutine scattdata_base_init + end subroutine scattdatabase_init - subroutine scattdata_legendre_init(this, order, energy, mult, coeffs) - class(ScattData_Legendre), intent(inout) :: this ! Object to work on + subroutine scattdatalegendre_init(this, order, energy, mult, coeffs) + class(ScattDataLegendre), intent(inout) :: this ! Object to work on integer, intent(in) :: order ! Data Order real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use - call scattdata_base_init(this, order, energy, mult) + call scattdatabase_init(this, order, energy, mult) this % data = coeffs - end subroutine scattdata_legendre_init + end subroutine scattdatalegendre_init - subroutine scattdata_histogram_init(this, order, energy, mult, coeffs) - class(ScattData_Histogram), intent(inout) :: this ! Object to work on + subroutine scattdatahistogram_init(this, order, energy, mult, coeffs) + class(ScattDataHistogram), intent(inout) :: this ! Object to work on integer, intent(in) :: order ! Data Order real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix @@ -124,10 +123,10 @@ contains groups = size(energy,dim=1) - call scattdata_base_init(this, order, energy, mult) + call scattdatabase_init(this, order, energy, mult) allocate(this % mu(order)) - this % dmu = TWO / (real(order,8)) + this % dmu = TWO / real(order,8) this % mu(1) = -ONE do imu = 2, order this % mu(imu) = -ONE + (imu - 1) * this % dmu @@ -152,10 +151,10 @@ contains end do end do - end subroutine scattdata_histogram_init + end subroutine scattdatahistogram_init - subroutine scattdata_tabular_init(this, order, energy, mult, coeffs) - class(ScattData_Tabular), intent(inout) :: this ! Object to work on + subroutine scattdatatabular_init(this, order, energy, mult, coeffs) + class(ScattDataTabular), intent(inout) :: this ! Object to work on integer, intent(in) :: order ! Data Order real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix @@ -176,10 +175,10 @@ contains groups = size(energy,dim=1) - call scattdata_base_init(this, this_order, energy, mult) + call scattdatabase_init(this, this_order, energy, mult) allocate(this % mu(this_order)) - this % dmu = TWO / (real(this_order) - 1) + this % dmu = TWO / real(this_order - 1) do imu = 1, this_order - 1 this % mu(imu) = -ONE + real(imu - 1) * this % dmu end do @@ -228,14 +227,14 @@ contains end do end do - end subroutine scattdata_tabular_init + end subroutine scattdatatabular_init !=============================================================================== ! SCATTDATA_*_CALC_F Calculates the value of f given mu (and gin,gout pair) !=============================================================================== - pure function scattdata_legendre_calc_f(this, gin, gout, mu) result(f) - class(ScattData_Legendre), intent(in) :: this ! The ScattData to evaluate + pure function scattdatalegendre_calc_f(this, gin, gout, mu) result(f) + class(ScattDataLegendre), intent(in) :: this ! The ScattData to evaluate integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -244,10 +243,10 @@ contains ! Plug mu in to the legendre expansion and go from there f = evaluate_legendre(this % data(:, gout, gin), mu) - end function scattdata_legendre_calc_f + end function scattdatalegendre_calc_f - pure function scattdata_histogram_calc_f(this, gin, gout, mu) result(f) - class(ScattData_Histogram), intent(in) :: this ! The ScattData to evaluate + pure function scattdatahistogram_calc_f(this, gin, gout, mu) result(f) + class(ScattDataHistogram), intent(in) :: this ! The ScattData to evaluate integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -265,10 +264,10 @@ contains ! Use histogram interpolation to find f(mu) f = this % data(imu, gout, gin) - end function scattdata_histogram_calc_f + end function scattdatahistogram_calc_f - pure function scattdata_tabular_calc_f(this, gin, gout, mu) result(f) - class(ScattData_Tabular), intent(in) :: this ! The ScattData to evaluate + pure function scattdatatabular_calc_f(this, gin, gout, mu) result(f) + class(ScattDataTabular), intent(in) :: this ! The ScattData to evaluate integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -289,6 +288,6 @@ contains f = (ONE - r) * this % data(imu, gout, gin) + & r * this % data(imu + 1, gout, gin) - end function scattdata_tabular_calc_f + end function scattdatatabular_calc_f end module scattdata_header \ No newline at end of file diff --git a/src/tracking.F90 b/src/tracking.F90 index 0b2719ef5d..98e5483a0a 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -1,23 +1,23 @@ module tracking - use constants, only: MODE_EIGENVALUE - use cross_section, only: calculate_xs - use error, only: fatal_error, warning - use geometry, only: find_cell, distance_to_boundary, cross_surface, & - cross_lattice, check_cell_overlap - use geometry_header, only: Universe, BASE_UNIVERSE + use constants, only: MODE_EIGENVALUE + use cross_section, only: calculate_xs + use error, only: fatal_error, warning + use geometry, only: find_cell, distance_to_boundary, cross_surface, & + cross_lattice, check_cell_overlap + use geometry_header, only: Universe, BASE_UNIVERSE use global - use macroxs, only: calculate_mgxs - use output, only: write_message - use particle_header, only: LocalCoord, Particle - use physics, only: collision - use physics_mg, only: collision_mg - use random_lcg, only: prn - use string, only: to_str - use tally, only: score_analog_tally, score_tracklength_tally, & - score_collision_tally, score_surface_current - use track_output, only: initialize_particle_track, write_particle_track, & - add_particle_track, finalize_particle_track + use macroxs_operations, only: calculate_mgxs + use output, only: write_message + use particle_header, only: LocalCoord, Particle + use physics, only: collision + use physics_mg, only: collision_mg + use random_lcg, only: prn + use string, only: to_str + use tally, only: score_analog_tally, score_tracklength_tally, & + score_collision_tally, score_surface_current + use track_output, only: initialize_particle_track, write_particle_track, & + add_particle_track, finalize_particle_track implicit none From 307617538c887a3ed8db2fd0a19640b6383553b4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 10 Feb 2016 20:39:03 -0500 Subject: [PATCH 69/84] Fixing bugs associated with enabling tabular representation of legendre data --- openmc/mgxs_library.py | 5 ++++- src/mgxs_data.F90 | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index f3e7b92184..ea6407f968 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -289,7 +289,10 @@ class XSdata(object): check_value('num_points', num_points, Integral) check_greater_than('num_points', num_points, 0) else: - num_points = 33 + if enable == False: + num_points = 1 + else: + num_points = 33 self._tabular_legendre = {'enable': enable, 'num_points': num_points} @num_polar.setter diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 94546c10dc..715b52b132 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -261,6 +261,7 @@ contains enable_leg_mu = .true. elseif (temp_str == 'false' .or. temp_str == '0') then enable_leg_mu = .false. + this % legendre_mu_points = 1 else call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) end if From 9f02388647d31d529d10a4c0e179fcbfab364d4a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 12 Feb 2016 04:58:11 -0500 Subject: [PATCH 70/84] Implementing minor edits from review on 1/11 by @paulromano --- src/initialize.F90 | 2 +- src/input_xml.F90 | 68 ++++++++------------ src/macroxs_header.F90 | 11 ++-- src/math.F90 | 6 +- src/mgxs_data.F90 | 131 ++++++++++++++++++--------------------- src/nuclide_header.F90 | 10 +-- src/particle_header.F90 | 4 +- src/scattdata_header.F90 | 10 +-- src/source.F90 | 48 +++++++------- 9 files changed, 130 insertions(+), 160 deletions(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index 88a10fb550..d8bbcb0d8c 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -126,7 +126,7 @@ contains if (run_CE) then call same_nuclide_list() else - call same_NuclideMG_list() + call same_nuclidemg_list() end if ! Construct information needed for nuclear data diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 2a21bac215..50e8ca30dc 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -216,8 +216,8 @@ contains end if ! Make sure that either eigenvalue or fixed source was specified - if (.not.check_for_node(doc, "eigenvalue") .and. & - .not.check_for_node(doc, "fixed_source")) then + if (.not. check_for_node(doc, "eigenvalue") .and. & + .not. check_for_node(doc, "fixed_source")) then call fatal_error(" or not specified.") end if @@ -230,7 +230,7 @@ contains call get_node_ptr(doc, "eigenvalue", node_mode) ! Check number of particles - if (.not.check_for_node(node_mode, "particles")) then + if (.not. check_for_node(node_mode, "particles")) then call fatal_error("Need to specify number of particles per generation.") end if @@ -300,7 +300,7 @@ contains call get_node_ptr(doc, "fixed_source", node_mode) ! Check number of particles - if (.not.check_for_node(node_mode, "particles")) then + if (.not. check_for_node(node_mode, "particles")) then call fatal_error("Need to specify number of particles per batch.") end if @@ -2050,9 +2050,9 @@ contains ! READ AND PARSE TAGS ! Check to ensure material has at least one nuclide - if ((.not. check_for_node(node_mat, "nuclide") .and. & - .not. check_for_node(node_mat, "element")) .and. & - (.not. check_for_node(node_mat, "macroscopic"))) then + if (.not. check_for_node(node_mat, "nuclide") .and. & + .not. check_for_node(node_mat, "element") .and. & + .not. check_for_node(node_mat, "macroscopic")) then call fatal_error("No macroscopic data, nuclides or natural elements & &specified on material " // trim(to_str(mat % id))) end if @@ -2061,7 +2061,7 @@ contains ! them as nuclides. This is all really a facade so the user thinks they ! are entering in macroscopic data but the code treats them the same ! as nuclides internally. - ! Get pointer list of XML + ! Get pointer list of XML call get_node_list(node_mat, "macroscopic", node_macro_list) if (get_list_size(node_macro_list) > 1) then call fatal_error("Only one macroscopic object permitted per material, " & @@ -2077,7 +2077,7 @@ contains end if ! Check for cross section - if (.not.check_for_node(node_nuc, "xs")) then + if (.not. check_for_node(node_nuc, "xs")) then if (default_xs == '') then call fatal_error("No cross section specified for macroscopic data & & in material " // trim(to_str(mat % id))) @@ -2130,13 +2130,13 @@ contains call get_list_item(node_nuc_list, j, node_nuc) ! Check for empty name on nuclide - if (.not.check_for_node(node_nuc, "name")) then + if (.not. check_for_node(node_nuc, "name")) then call fatal_error("No name specified on nuclide in material " & // trim(to_str(mat % id))) end if ! Check for cross section - if (.not.check_for_node(node_nuc, "xs")) then + if (.not. check_for_node(node_nuc, "xs")) then if (default_xs == '') then call fatal_error("No cross section specified for nuclide in & &material " // trim(to_str(mat % id))) @@ -2160,8 +2160,8 @@ contains if (units == 'macro') then call list_density % append(ONE) else - if (.not.check_for_node(node_nuc, "ao") .and. & - .not.check_for_node(node_nuc, "wo")) then + if (.not. check_for_node(node_nuc, "ao") .and. & + .not. check_for_node(node_nuc, "wo")) then call fatal_error("No atom or weight percent specified for nuclide " & // trim(name)) elseif (check_for_node(node_nuc, "ao") .and. & @@ -2192,7 +2192,7 @@ contains call get_list_item(node_ele_list, j, node_ele) ! Check for empty name on natural element - if (.not.check_for_node(node_ele, "name")) then + if (.not. check_for_node(node_ele, "name")) then call fatal_error("No name specified on nuclide in material " & // trim(to_str(mat % id))) end if @@ -2212,8 +2212,8 @@ contains ! Check if no atom/weight percents were specified or if both atom and ! weight percents were specified - if (.not.check_for_node(node_ele, "ao") .and. & - .not.check_for_node(node_ele, "wo")) then + if (.not. check_for_node(node_ele, "ao") .and. & + .not. check_for_node(node_ele, "wo")) then call fatal_error("No atom or weight percent specified for element " & // trim(name)) elseif (check_for_node(node_ele, "ao") .and. & @@ -2357,8 +2357,8 @@ contains call get_list_item(node_sab_list, j, node_sab) ! Determine name of S(a,b) table - if (.not.check_for_node(node_sab, "name") .or. & - .not.check_for_node(node_sab, "xs")) then + if (.not. check_for_node(node_sab, "name") .or. & + .not. check_for_node(node_sab, "xs")) then call fatal_error("Need to specify and for S(a,b) & &table.") end if @@ -2588,8 +2588,8 @@ contains end if ! Make sure either upper-right or width was specified - if (.not.check_for_node(node_mesh, "upper_right") .and. & - .not.check_for_node(node_mesh, "width")) then + if (.not. check_for_node(node_mesh, "upper_right") .and. & + .not. check_for_node(node_mesh, "width")) then call fatal_error("Must specify either and on a & &tally mesh.") end if @@ -3377,30 +3377,12 @@ contains case ('n2n', '(n,2n)') t % score_bins(j) = N_2N - ! Disallow for MG mode since data not present - if (.not. run_CE) then - call fatal_error("Cannot tally (n,2n) reaction rate in & - &multi-group mode") - end if - case ('n3n', '(n,3n)') t % score_bins(j) = N_3N - ! Disallow for MG mode since data not present - if (.not. run_CE) then - call fatal_error("Cannot tally (n,3n) reaction rate in & - &multi-group mode") - end if - case ('n4n', '(n,4n)') t % score_bins(j) = N_4N - ! Disallow for MG mode since data not present - if (.not. run_CE) then - call fatal_error("Cannot tally (n,4n) reaction rate in & - &multi-group mode") - end if - case ('absorption') t % score_bins(j) = SCORE_ABSORPTION if (t % find_filter(FILTER_ENERGYOUT) > 0) then @@ -3590,10 +3572,10 @@ contains ! Do a check at the end (instead of for every case) to make sure ! the tallies are compatible with MG mode where we have less detailed ! nuclear data - if (.not. run_CE .and. t % score_bins(j) > 0) then - call fatal_error("Cannot tally " // trim(score_name) // & - " reaction rate in multi-group mode") - end if + if (.not. run_CE .and. t % score_bins(j) > 0) then + call fatal_error("Cannot tally " // trim(score_name) // & + " reaction rate in multi-group mode") + end if end do t % n_score_bins = n_scores @@ -4455,7 +4437,7 @@ contains end if ! determine metastable state - if (.not.check_for_node(node_ace, "metastable")) then + if (.not. check_for_node(node_ace, "metastable")) then listing % metastable = .false. else listing % metastable = .true. diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index 0f838967ea..c435686b5d 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -27,10 +27,7 @@ module macroxs_header subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, get_fiss, & max_order, scatt_type, legendre_mu_points, & error_code, error_text) - import MacroXS - import Material - import NuclideMGContainer - import MAX_LINE_LEN + import MacroXS, Material, NuclideMGContainer, MAX_LINE_LEN class(MacroXS), intent(inout) :: this ! The MacroXS to initialize type(Material), pointer, intent(in) :: mat ! base material type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from @@ -383,14 +380,14 @@ contains select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (NuclideAngle) if (npol == -1) then - npol = nuc % Npol - nazi = nuc % Nazi + npol = nuc % n_pol + nazi = nuc % n_azi allocate(this % polar(npol)) this % polar = nuc % polar allocate(this % azimuthal(nazi)) this % azimuthal = nuc % azimuthal else - if ((npol /= nuc % Npol) .or. (nazi /= nuc % Nazi)) then + if ((npol /= nuc % n_pol) .or. (nazi /= nuc % n_azi)) then error_code = 1 error_text = "All Angular Data Must Be Same Length!" end if diff --git a/src/math.F90 b/src/math.F90 index 36c65a2402..c7ede8d2a5 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -560,6 +560,7 @@ contains !=============================================================================== ! EXPAND_HARMONIC expands a given series of real spherical harmonics !=============================================================================== + pure function expand_harmonic(data, order, uvw) result(val) real(8), intent(in) :: data(:) integer, intent(in) :: order @@ -584,6 +585,7 @@ contains ! EVALUATE_LEGENDRE Find the value of f(x) given a set of Legendre coefficients ! and the value of x !=============================================================================== + pure function evaluate_legendre(data, x) result(val) real(8), intent(in) :: data(:) real(8), intent(in) :: x @@ -591,9 +593,9 @@ contains integer :: l - val = 0.5_8 * data(1) + val = HALF * data(1) do l = 1, size(data) - 1 - val = val + (real(l,8) + 0.5_8) * data(l + 1) * calc_pn(l,x) + val = val + (real(l,8) + HALF) * data(l + 1) * calc_pn(l,x) end do end function evaluate_legendre diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 715b52b132..9fa0aeb2ba 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -125,7 +125,7 @@ contains end select ! Now read in the data specific to the type we just declared - call NuclideMG_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & + call nuclidemg_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & energy_groups, get_kfiss, get_fiss, error_code, & error_text) @@ -169,13 +169,13 @@ contains end subroutine read_mgxs !=============================================================================== -! SAME_NUCLIDE_LIST creates a linked list for each nuclide containing the +! SAME_NUCLIDEMG_LIST creates a linked list for each nuclide containing the ! indices in the nuclides array of all other instances of that nuclide. For ! example, the same nuclide may exist at multiple temperatures resulting ! in multiple entries in the nuclides array for a single zaid number. !=============================================================================== - subroutine same_NuclideMG_list() + subroutine same_nuclidemg_list() integer :: i ! index in nuclides array integer :: j ! index in nuclides array @@ -188,21 +188,21 @@ contains end do end do - end subroutine same_NuclideMG_list + end subroutine same_nuclidemg_list !=============================================================================== ! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed !=============================================================================== - subroutine NuclideMG_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + subroutine nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) class(NuclideMG), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print + type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(inout) :: error_code ! Code signifying error + character(MAX_LINE_LEN), intent(inout) :: error_text ! Error to print type(Node), pointer :: node_legendre_mu character(MAX_LINE_LEN) :: temp_str @@ -298,16 +298,16 @@ contains select type(this) type is (NuclideIso) - call NuclideIso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + call nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) type is (NuclideAngle) - call NuclideAngle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + call nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) end select - end subroutine NuclideMG_init + end subroutine nuclidemg_init - subroutine NuclideIso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + subroutine nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & error_code, error_text) class(NuclideIso), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml @@ -436,10 +436,10 @@ contains this % mult = ONE end if - end subroutine NuclideIso_init + end subroutine nuclideiso_init - subroutine NuclideAngle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) + subroutine nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & + error_code, error_text) class(NuclideAngle), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml integer, intent(in) :: groups ! Number of Energy groups @@ -463,7 +463,7 @@ contains end if if (check_for_node(node_xsdata, "num_polar")) then - call get_node_value(node_xsdata, "num_polar", this % Npol) + call get_node_value(node_xsdata, "num_polar", this % n_pol) else error_code = 1 error_text = "num_polar Must Be Provided!" @@ -471,7 +471,7 @@ contains end if if (check_for_node(node_xsdata, "num_azimuthal")) then - call get_node_value(node_xsdata, "num_azimuthal", this % Nazi) + call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) else error_code = 1 error_text = "num_azimuthal Must Be Provided!" @@ -479,17 +479,17 @@ contains end if ! Load angle data, if present (else equally spaced) - allocate(this % polar(this % Npol)) - allocate(this % azimuthal(this % Nazi)) + allocate(this % polar(this % n_pol)) + allocate(this % azimuthal(this % n_azi)) if (check_for_node(node_xsdata, "polar")) then error_code = 1 error_text = "User-Specified polar angle bins not yet supported!" return call get_node_array(node_xsdata, "polar", this % polar) else - dangle = PI / real(this % Npol,8) - do iangle = 1, this % Npol - this % polar(iangle) = (real(iangle,8) - 0.5_8) * dangle + dangle = PI / real(this % n_pol,8) + do iangle = 1, this % n_pol + this % polar(iangle) = (real(iangle,8) - HALF) * dangle end do end if if (check_for_node(node_xsdata, "azimuthal")) then @@ -498,9 +498,9 @@ contains return call get_node_array(node_xsdata, "azimuthal", this % azimuthal) else - dangle = TWO * PI / real(this % Nazi,8) - do iangle = 1, this % Nazi - this % azimuthal(iangle) = -PI + (real(iangle,8) - 0.5_8) * dangle + dangle = TWO * PI / real(this % n_azi,8) + do iangle = 1, this % n_azi + this % azimuthal(iangle) = -PI + (real(iangle,8) - HALF) * dangle end do end if @@ -509,19 +509,19 @@ contains if (check_for_node(node_xsdata, "chi")) then ! Get chi - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "chi", temp_arr) - allocate(this % chi(groups, this % Nazi, this % Npol)) - this % chi = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + allocate(this % chi(groups, this % n_azi, this % n_pol)) + this % chi = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) ! Get nu_fission (as a vector) if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, 1, this % Nazi, this % Npol)) - this % nu_fission = reshape(temp_arr, (/groups, 1, this % Nazi, & - this % Npol/)) + allocate(this % nu_fission(groups, 1, this % n_azi, this % n_pol)) + this % nu_fission = reshape(temp_arr, (/groups, 1, this % n_azi, & + this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -533,11 +533,11 @@ contains ! Get nu_fission (as a matrix) if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, groups, this % Nazi, this % Npol)) + allocate(this % nu_fission(groups, groups, this % n_azi, this % n_pol)) this % nu_fission = reshape(temp_arr, (/groups, groups, & - this % Nazi, this % Npol/)) + this % n_azi, this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -547,10 +547,10 @@ contains end if if (get_fiss) then if (check_for_node(node_xsdata, "fission")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "fission", temp_arr) - allocate(this % fission(groups, this % Nazi, this % Npol)) - this % fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + allocate(this % fission(groups, this % n_azi, this % n_pol)) + this % fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -561,10 +561,10 @@ contains end if if (get_kfiss) then if (check_for_node(node_xsdata, "kappa_fission")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "kappa_fission", temp_arr) - allocate(this % k_fission(groups, this % Nazi, this % Npol)) - this % k_fission = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + allocate(this % k_fission(groups, this % n_azi, this % n_pol)) + this % k_fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -576,10 +576,10 @@ contains end if if (check_for_node(node_xsdata, "absorption")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "absorption", temp_arr) - allocate(this % absorption(groups, this % Nazi, this % Npol)) - this % absorption = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + allocate(this % absorption(groups, this % n_azi, this % n_pol)) + this % absorption = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -587,12 +587,12 @@ contains return end if - allocate(this % scatter(groups, groups, order_dim, this % Nazi, this % Npol)) + allocate(this % scatter(groups, groups, order_dim, this % n_azi, this % n_pol)) if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim * this % Nazi * this%Npol)) + allocate(temp_arr(groups * groups * order_dim * this % n_azi * this%n_pol)) call get_node_array(node_xsdata, "scatter", temp_arr) this % scatter = reshape(temp_arr, (/groups, groups, order_dim, & - this%Nazi,this%Npol/)) + this%n_azi,this%n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -601,23 +601,23 @@ contains end if if (check_for_node(node_xsdata, "total")) then - allocate(temp_arr(groups * this % Nazi * this % Npol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call get_node_array(node_xsdata, "total", temp_arr) - allocate(this % total(groups, this % Nazi, this % Npol)) - this % total = reshape(temp_arr, (/groups, this % Nazi, this % Npol/)) + allocate(this % total(groups, this % n_azi, this % n_pol)) + this % total = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) else this % total = this % absorption + sum(this%scatter(:,:,1,:,:),dim=1) end if ! Get Mult Data - allocate(this % mult(groups, groups, this % Nazi, this % Npol)) + allocate(this % mult(groups, groups, this % n_azi, this % n_pol)) if (check_for_node(node_xsdata, "multiplicity")) then arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups * this % Nazi * this % Npol) then + if (arr_len == groups * groups * this % n_azi * this % n_pol) then allocate(temp_arr(arr_len)) call get_node_array(node_xsdata, "multiplicity", temp_arr) - this % mult = reshape(temp_arr, (/groups, groups, this % Nazi, this % Npol/)) + this % mult = reshape(temp_arr, (/groups, groups, this % n_azi, this % n_pol/)) deallocate(temp_arr) else error_code = 1 @@ -628,7 +628,7 @@ contains this % mult = ONE end if - end subroutine NuclideAngle_init + end subroutine nuclideangle_init !=============================================================================== @@ -643,7 +643,6 @@ contains logical :: get_kfiss, get_fiss integer :: error_code character(MAX_LINE_LEN) :: error_text - integer :: representation integer :: scatt_type integer :: legendre_mu_points @@ -675,19 +674,11 @@ contains ! At the same time, we will find the scattering type, as that will dictate ! how we allocate the scatter object within macroxs legendre_mu_points = nuclides_MG(mat % nuclide(1)) % obj % legendre_mu_points + scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) type is (NuclideIso) - representation = MGXS_ISOTROPIC - type is (NuclideAngle) - representation = MGXS_ANGLE - end select - scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type - - ! Now allocate accordingly - select case(representation) - case(MGXS_ISOTROPIC) allocate(MacroXSIso :: macro_xs(i_mat) % obj) - case(MGXS_ANGLE) + type is (NuclideAngle) allocate(MacroXSAngle :: macro_xs(i_mat) % obj) end select @@ -696,9 +687,7 @@ contains scatt_type, legendre_mu_points, & error_code, error_text) ! Handle any errors - if (error_code /= 0) then - call fatal_error(trim(error_text)) - end if + if (error_code /= 0) call fatal_error(trim(error_text)) end do end subroutine create_macro_xs diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index caf0c10729..2f62b86672 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -177,7 +177,7 @@ module nuclide_header type, extends(NuclideMG) :: NuclideAngle - ! Microscopic cross sections. Dimensions are: (Npol, Nazi, Nl, Ng, Ng) + ! Microscopic cross sections. Dimensions are: (n_pol, n_azi, Nl, Ng, Ng) real(8), allocatable :: total(:,:,:) ! total cross section real(8), allocatable :: absorption(:,:,:) ! absorption cross section real(8), allocatable :: scatter(:,:,:,:,:) ! scattering information @@ -188,8 +188,8 @@ module nuclide_header real(8), allocatable :: mult(:,:,:,:) ! Scatter multiplicity (Gout x Gin) ! In all cases, right-most indices are theta, phi - integer :: Npol ! Number of polar angles - integer :: Nazi ! Number of azimuthal angles + integer :: n_pol ! Number of polar angles + integer :: n_azi ! Number of azimuthal angles real(8), allocatable :: polar(:) ! polar angles real(8), allocatable :: azimuthal(:) ! azimuthal angles @@ -476,8 +476,8 @@ module nuclide_header ! Write Basic Nuclide Information call nuclidemg_print(this, unit_) - write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % Npol)) - write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % Nazi)) + write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % n_pol)) + write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % n_azi)) ! Determine size of mgxs and scattering matrices size_scattmat = (size(this % scatter) + size(this % mult)) * 8 diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 3c687eb02f..bf820ceb35 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -96,8 +96,8 @@ module particle_header contains procedure :: initialize => initialize_particle procedure :: clear => clear_particle - procedure :: initialize_from_source => initialize_from_source - procedure :: create_secondary => create_secondary + procedure :: initialize_from_source + procedure :: create_secondary end type Particle contains diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 62b382d36c..b9dcdadd41 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -79,7 +79,7 @@ contains ! SCATTDATA_INIT builds the scattdata object !=============================================================================== - subroutine scattdatabase_init(this, order, energy, mult) + subroutine scattdata_init(this, order, energy, mult) class(ScattData), intent(inout) :: this ! Object to work on integer, intent(in) :: order ! Data Order real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix @@ -96,7 +96,7 @@ contains allocate(this % data(order, groups, groups)) this % data = ZERO - end subroutine scattdatabase_init + end subroutine scattdata_init subroutine scattdatalegendre_init(this, order, energy, mult, coeffs) class(ScattDataLegendre), intent(inout) :: this ! Object to work on @@ -105,7 +105,7 @@ contains real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use - call scattdatabase_init(this, order, energy, mult) + call scattdata_init(this, order, energy, mult) this % data = coeffs @@ -123,7 +123,7 @@ contains groups = size(energy,dim=1) - call scattdatabase_init(this, order, energy, mult) + call scattdata_init(this, order, energy, mult) allocate(this % mu(order)) this % dmu = TWO / real(order,8) @@ -175,7 +175,7 @@ contains groups = size(energy,dim=1) - call scattdatabase_init(this, this_order, energy, mult) + call scattdata_init(this, this_order, energy, mult) allocate(this % mu(this_order)) this % dmu = TWO / real(this_order - 1) diff --git a/src/source.F90 b/src/source.F90 index 1fb9de5c58..0a7fa790d5 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -110,7 +110,7 @@ contains integer, save :: num_resamples = 0 ! Number of resamples encountered ! Set weight to one by default - site%wgt = ONE + site % wgt = ONE ! Set the random number generator to the source stream. call prn_set_stream(STREAM_SOURCE) @@ -118,10 +118,10 @@ contains ! Sample from among multiple source distributions n_source = size(external_source) if (n_source > 1) then - r(1) = prn()*sum(external_source(:)%strength) + r(1) = prn()*sum(external_source(:) % strength) c = ZERO do i = 1, n_source - c = c + external_source(i)%strength + c = c + external_source(i) % strength if (r(1) < c) exit end do else @@ -132,14 +132,14 @@ contains found = .false. do while (.not.found) ! Set particle defaults - call p%initialize() + call p % initialize() ! Sample spatial distribution - site%xyz(:) = external_source(i)%space%sample() + site % xyz(:) = external_source(i) % space % sample() ! Fill p with needed data - p%coord(1)%xyz(:) = site%xyz - p%coord(1)%uvw(:) = [ ONE, ZERO, ZERO ] + p % coord(1) % xyz(:) = site % xyz + p % coord(1) % uvw(:) = [ ONE, ZERO, ZERO ] ! Now search to see if location exists in geometry call find_cell(p, found) @@ -152,27 +152,27 @@ contains end if ! Check if spatial site is in fissionable material - select type (space => external_source(i)%space) + select type (space => external_source(i) % space) type is (SpatialBox) - if (space%only_fissionable) then - if (p%material == MATERIAL_VOID) then + if (space % only_fissionable) then + if (p % material == MATERIAL_VOID) then found = .false. - elseif (.not. materials(p%material)%fissionable) then + elseif (.not. materials(p % material) % fissionable) then found = .false. end if end if end select end do - call p%clear() + call p % clear() ! Sample angle - site%uvw(:) = external_source(i)%angle%sample() + site % uvw(:) = external_source(i) % angle % sample() ! Check for monoenergetic source above maximum neutron energy - select type (energy => external_source(i)%energy) + select type (energy => external_source(i) % energy) type is (Discrete) - if (any(energy%x >= energy_max_neutron)) then + if (any(energy % x >= energy_max_neutron)) then call fatal_error("Source energy above range of energies of at least & &one cross section table") end if @@ -180,23 +180,23 @@ contains do ! Sample energy spectrum - site%E = external_source(i)%energy%sample() + site % E = external_source(i) % energy % sample() ! resample if energy is greater than maximum neutron energy - if (site%E < energy_max_neutron) exit + if (site % E < energy_max_neutron) exit end do ! Set delayed group - site%delayed_group = 0 + site % delayed_group = 0 - ! If running in MG, convert site%E to group + ! If running in MG, convert site % E to group if (.not. run_CE) then - if (site%E <= energy_bins(1)) then - site%g = 1 - else if (site%E > energy_bins(energy_groups + 1)) then - site%g = energy_groups + if (site % E <= energy_bins(1)) then + site % g = 1 + else if (site % E > energy_bins(energy_groups + 1)) then + site % g = energy_groups else - site%g = binary_search(energy_bins, energy_groups + 1, site%E) + site % g = binary_search(energy_bins, energy_groups + 1, site % E) end if end if From 02a9441522163bd0092285e6e7241018a7ee723b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 12 Feb 2016 05:22:18 -0500 Subject: [PATCH 71/84] Fixes to move nuclidemg_init routines to the actual class, now that circular dependencies are gone --- src/mgxs_data.F90 | 454 +---------------------------------------- src/nuclide_header.F90 | 417 ++++++++++++++++++++++++++++++++++++- 2 files changed, 412 insertions(+), 459 deletions(-) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 9fa0aeb2ba..796269151c 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -35,8 +35,7 @@ contains type(Node), pointer :: node_xsdata type(NodeList), pointer :: node_xsdata_list => null() logical :: file_exists - integer :: error_code - character(MAX_LINE_LEN) :: error_text, temp_str + character(MAX_LINE_LEN) :: temp_str logical :: get_kfiss, get_fiss integer :: l @@ -125,18 +124,12 @@ contains end select ! Now read in the data specific to the type we just declared - call nuclidemg_init(nuclides_MG(i_nuclide) % obj, node_xsdata, & - energy_groups, get_kfiss, get_fiss, error_code, & - error_text) + call nuclides_MG(i_nuclide) % obj % init(node_xsdata, energy_groups, & + get_kfiss, get_fiss) ! Keep track of what listing is associated with this nuclide nuclides_MG(i_nuclide) % obj % listing = i_listing - ! Handle any errors - if (error_code /= 0) then - call fatal_error(trim(error_text)) - end if - ! Add name and alias to dictionary call already_read % add(name) call already_read % add(alias) @@ -190,447 +183,6 @@ contains end subroutine same_nuclidemg_list -!=============================================================================== -! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed -!=============================================================================== - - subroutine nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) - class(NuclideMG), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error to print - - type(Node), pointer :: node_legendre_mu - character(MAX_LINE_LEN) :: temp_str - logical :: enable_leg_mu - - ! Initialize error data - error_code = 0 - error_text = '' - - ! Load the data - call get_node_value(node_xsdata, "name", this % name) - this % name = to_lower(this % name) - if (check_for_node(node_xsdata, "kT")) then - call get_node_value(node_xsdata, "kT", this % kT) - else - this % kT = ZERO - end if - if (check_for_node(node_xsdata, "zaid")) then - call get_node_value(node_xsdata, "zaid", this % zaid) - else - this % zaid = -1 - end if - if (check_for_node(node_xsdata, "scatt_type")) then - call get_node_value(node_xsdata, "scatt_type", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'legendre') then - this % scatt_type = ANGLE_LEGENDRE - else if (temp_str == 'histogram') then - this % scatt_type = ANGLE_HISTOGRAM - else if (temp_str == 'tabular') then - this % scatt_type = ANGLE_TABULAR - else - error_code = 1 - error_text = "Invalid Scatt Type Option!" - return - end if - else - this % scatt_type = ANGLE_LEGENDRE - end if - - if (check_for_node(node_xsdata, "order")) then - call get_node_value(node_xsdata, "order", this % order) - else - error_code = 1 - error_text = "Order Must Be Provided!" - return - end if - - ! Get scattering treatment - if (check_for_node(node_xsdata, "tabular_legendre")) then - call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) - if (check_for_node(node_legendre_mu, "enable")) then - call get_node_value(node_legendre_mu, "enable", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'true' .or. temp_str == '1') then - enable_leg_mu = .true. - elseif (temp_str == 'false' .or. temp_str == '0') then - enable_leg_mu = .false. - this % legendre_mu_points = 1 - else - call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) - end if - else - enable_leg_mu = .true. - this % legendre_mu_points = 33 - end if - if (enable_leg_mu .and. & - check_for_node(node_legendre_mu, "num_points")) then - call get_node_value(node_legendre_mu, "num_points", & - this % legendre_mu_points) - if (this % legendre_mu_points <= 0) then - call fatal_error("num_points element must be positive and non-zero!") - end if - this % legendre_mu_points = -1 * this % legendre_mu_points - end if - else - this % legendre_mu_points = 1 - end if - - if (check_for_node(node_xsdata, "fissionable")) then - call get_node_value(node_xsdata, "fissionable", temp_str) - temp_str = to_lower(temp_str) - if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then - this % fissionable = .true. - else - this % fissionable = .false. - end if - else - error_code = 1 - error_text = "Fissionable element must be set!" - return - end if - - select type(this) - type is (NuclideIso) - call nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) - type is (NuclideAngle) - call nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) - end select - - end subroutine nuclidemg_init - - subroutine nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) - class(NuclideIso), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Need fiss data? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - - real(8), allocatable :: temp_arr(:) - integer :: arr_len - integer :: order_dim - - ! Load the more specific data - if (this % fissionable) then - - if (check_for_node(node_xsdata, "chi")) then - ! Get chi - allocate(this % chi(groups)) - call get_node_array(node_xsdata, "chi", this % chi) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * 1)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, 1)) - this % nu_fission = reshape(temp_arr, (/groups, 1/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "If fissionable, must provide nu_fission!" - return - end if - - else - ! Get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - - allocate(temp_arr(groups*groups)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, groups)) - this % nu_fission = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "If fissionable, must provide nu_fission!" - return - end if - end if - if (get_fiss) then - allocate(this % fission(groups)) - if (check_for_node(node_xsdata, "fission")) then - call get_node_array(node_xsdata, "fission", this % fission) - else - error_code = 1 - error_text = "Fission data missing, required due to fission& - & tallies in tallies.xml file!" - return - end if - end if - if (get_kfiss) then - allocate(this % k_fission(groups)) - if (check_for_node(node_xsdata, "kappa_fission")) then - call get_node_array(node_xsdata, "kappa_fission", this % k_fission) - else - error_code = 1 - error_text = "kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!" - return - end if - end if - end if - - allocate(this % absorption(groups)) - if (check_for_node(node_xsdata, "absorption")) then - call get_node_array(node_xsdata, "absorption", this % absorption) - else - error_code = 1 - error_text = "Must provide absorption!" - return - end if - - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = this % order + 1 - else if (this % scatt_type == ANGLE_HISTOGRAM) then - order_dim = this % order - else if (this % scatt_type == ANGLE_TABULAR) then - order_dim = this % order - end if - - allocate(this % scatter(groups, groups, order_dim)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim)) - call get_node_array(node_xsdata, "scatter", temp_arr) - this % scatter = reshape(temp_arr, (/groups, groups, order_dim/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Must provide scatter!" - return - end if - - - allocate(this % total(groups)) - if (check_for_node(node_xsdata, "total")) then - call get_node_array(node_xsdata, "total", this % total) - else - this % total = this % absorption + sum(this%scatter(:,:,1),dim=1) - end if - - ! Get Mult Data - allocate(this % mult(groups, groups)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - this % mult = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Multiplicity Length Not Same as number of groups squared!" - return - end if - else - this % mult = ONE - end if - - end subroutine nuclideiso_init - - subroutine nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss, & - error_code, error_text) - class(NuclideAngle), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from data.xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - - real(8), allocatable :: temp_arr(:) - integer :: arr_len - real(8) :: dangle - integer :: iangle - integer :: order_dim - - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = this % order + 1 - else if (this % scatt_type == ANGLE_HISTOGRAM) then - order_dim = this % order - else if (this % scatt_type == ANGLE_TABULAR) then - order_dim = this % order - end if - - if (check_for_node(node_xsdata, "num_polar")) then - call get_node_value(node_xsdata, "num_polar", this % n_pol) - else - error_code = 1 - error_text = "num_polar Must Be Provided!" - return - end if - - if (check_for_node(node_xsdata, "num_azimuthal")) then - call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) - else - error_code = 1 - error_text = "num_azimuthal Must Be Provided!" - return - end if - - ! Load angle data, if present (else equally spaced) - allocate(this % polar(this % n_pol)) - allocate(this % azimuthal(this % n_azi)) - if (check_for_node(node_xsdata, "polar")) then - error_code = 1 - error_text = "User-Specified polar angle bins not yet supported!" - return - call get_node_array(node_xsdata, "polar", this % polar) - else - dangle = PI / real(this % n_pol,8) - do iangle = 1, this % n_pol - this % polar(iangle) = (real(iangle,8) - HALF) * dangle - end do - end if - if (check_for_node(node_xsdata, "azimuthal")) then - error_code = 1 - error_text = "User-Specified azimuthal angle bins not yet supported!" - return - call get_node_array(node_xsdata, "azimuthal", this % azimuthal) - else - dangle = TWO * PI / real(this % n_azi,8) - do iangle = 1, this % n_azi - this % azimuthal(iangle) = -PI + (real(iangle,8) - HALF) * dangle - end do - end if - - ! Load the more specific data - if (this % fissionable) then - - if (check_for_node(node_xsdata, "chi")) then - ! Get chi - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "chi", temp_arr) - allocate(this % chi(groups, this % n_azi, this % n_pol)) - this % chi = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, 1, this % n_azi, this % n_pol)) - this % nu_fission = reshape(temp_arr, (/groups, 1, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "If fissionable, must provide nu_fission!" - return - end if - - else - ! Get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, groups, this % n_azi, this % n_pol)) - this % nu_fission = reshape(temp_arr, (/groups, groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "If fissionable, must provide nu_fission!" - return - end if - end if - if (get_fiss) then - if (check_for_node(node_xsdata, "fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "fission", temp_arr) - allocate(this % fission(groups, this % n_azi, this % n_pol)) - this % fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Fission data missing, required due to fission& - & tallies in tallies.xml file!" - return - end if - end if - if (get_kfiss) then - if (check_for_node(node_xsdata, "kappa_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "kappa_fission", temp_arr) - allocate(this % k_fission(groups, this % n_azi, this % n_pol)) - this % k_fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!" - return - end if - end if - end if - - if (check_for_node(node_xsdata, "absorption")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "absorption", temp_arr) - allocate(this % absorption(groups, this % n_azi, this % n_pol)) - this % absorption = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Must provide absorption!" - return - end if - - allocate(this % scatter(groups, groups, order_dim, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim * this % n_azi * this%n_pol)) - call get_node_array(node_xsdata, "scatter", temp_arr) - this % scatter = reshape(temp_arr, (/groups, groups, order_dim, & - this%n_azi,this%n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Must provide scatter!" - return - end if - - if (check_for_node(node_xsdata, "total")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "total", temp_arr) - allocate(this % total(groups, this % n_azi, this % n_pol)) - this % total = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - this % total = this % absorption + sum(this%scatter(:,:,1,:,:),dim=1) - end if - - ! Get Mult Data - allocate(this % mult(groups, groups, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups * this % n_azi * this % n_pol) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - this % mult = reshape(temp_arr, (/groups, groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - error_code = 1 - error_text = "Multiplicity Length Does Not Match!" - return - end if - else - this % mult = ONE - end if - - end subroutine nuclideangle_init - - !=============================================================================== ! CREATE_MACRO_XS generates the macroscopic x/s from the microscopic input data !=============================================================================== diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 2f62b86672..7569d9ea80 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -5,10 +5,11 @@ module nuclide_header use ace_header use constants use endf, only: reaction_name + use error, only: fatal_error use list_header, only: ListInt use math, only: evaluate_legendre use string - + use xml_interface implicit none !=============================================================================== @@ -31,7 +32,7 @@ module nuclide_header logical :: fissionable ! nuclide is fissionable? contains - procedure(print_nuclide_), deferred :: print ! Writes nuclide info + procedure(print_nuclide_), deferred :: print ! Writes nuclide info end type Nuclide abstract interface @@ -114,12 +115,23 @@ module nuclide_header ! Legendre distribs, -1 if sample with the ! Legendres themselves contains - procedure(nuclidemg_get_xs), deferred :: get_xs ! Get the xs - procedure(nuclide_calc_f_), deferred :: calc_f ! Calculates f, given mu + procedure(nuclidemg_init_), deferred :: init ! Initialize the data + procedure(nuclidemg_get_xs_), deferred :: get_xs ! Get the requested xs + procedure(nuclidemg_calc_f_), deferred :: calc_f ! Calculates f, given mu end type NuclideMG abstract interface - function nuclidemg_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & + + subroutine nuclidemg_init_(this, node_xsdata, groups, get_kfiss, get_fiss) + import NuclideMG, Node + class(NuclideMG), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + end subroutine nuclidemg_init_ + + function nuclidemg_get_xs_(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & result(xs) import NuclideMG class(NuclideMG), intent(in) :: this @@ -131,9 +143,9 @@ module nuclide_header integer, optional, intent(in) :: i_azi ! Azimuthal Index integer, optional, intent(in) :: i_pol ! Polar Index real(8) :: xs ! Resultant xs - end function nuclidemg_get_xs + end function nuclidemg_get_xs_ - pure function nuclide_calc_f_(this, gin, gout, mu, uvw, i_azi, i_pol) result(f) + pure function nuclidemg_calc_f_(this, gin, gout, mu, uvw, i_azi, i_pol) result(f) import NuclideMG class(NuclideMG), intent(in) :: this integer, intent(in) :: gin ! Incoming Energy Group @@ -144,7 +156,7 @@ module nuclide_header integer, intent(in), optional :: i_pol ! Outgoing Energy Group real(8) :: f ! Return value of f(mu) - end function nuclide_calc_f_ + end function nuclidemg_calc_f_ end interface !=============================================================================== @@ -165,6 +177,7 @@ module nuclide_header real(8), allocatable :: mult(:,:) ! Scatter multiplicity (Gout x Gin) contains + procedure :: init => nuclideiso_init ! Initialize Nuclidic MGXS Data procedure :: print => nuclideiso_print ! Writes nuclide info procedure :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object procedure :: calc_f => nuclideiso_calc_f ! Calcs f given mu @@ -194,6 +207,7 @@ module nuclide_header real(8), allocatable :: azimuthal(:) ! azimuthal angles contains + procedure :: init => nuclideangle_init ! Initialize Nuclidic MGXS Data procedure :: print => nuclideangle_print ! Gets Size of Data w/in Object procedure :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object procedure :: calc_f => nuclideangle_calc_f ! Calcs f given mu @@ -282,6 +296,393 @@ module nuclide_header contains +!=============================================================================== +! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed +!=============================================================================== + + subroutine nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + class(NuclideMG), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + + type(Node), pointer :: node_legendre_mu + character(MAX_LINE_LEN) :: temp_str + logical :: enable_leg_mu + + ! Load the data + call get_node_value(node_xsdata, "name", this % name) + this % name = to_lower(this % name) + if (check_for_node(node_xsdata, "kT")) then + call get_node_value(node_xsdata, "kT", this % kT) + else + this % kT = ZERO + end if + if (check_for_node(node_xsdata, "zaid")) then + call get_node_value(node_xsdata, "zaid", this % zaid) + else + this % zaid = -1 + end if + if (check_for_node(node_xsdata, "scatt_type")) then + call get_node_value(node_xsdata, "scatt_type", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'legendre') then + this % scatt_type = ANGLE_LEGENDRE + else if (temp_str == 'histogram') then + this % scatt_type = ANGLE_HISTOGRAM + else if (temp_str == 'tabular') then + this % scatt_type = ANGLE_TABULAR + else + call fatal_error("Invalid Scatt Type Option!") + end if + else + this % scatt_type = ANGLE_LEGENDRE + end if + + if (check_for_node(node_xsdata, "order")) then + call get_node_value(node_xsdata, "order", this % order) + else + call fatal_error("Order Must Be Provided!") + end if + + ! Get scattering treatment + if (check_for_node(node_xsdata, "tabular_legendre")) then + call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) + if (check_for_node(node_legendre_mu, "enable")) then + call get_node_value(node_legendre_mu, "enable", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'true' .or. temp_str == '1') then + enable_leg_mu = .true. + elseif (temp_str == 'false' .or. temp_str == '0') then + enable_leg_mu = .false. + this % legendre_mu_points = 1 + else + call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) + end if + else + enable_leg_mu = .true. + this % legendre_mu_points = 33 + end if + if (enable_leg_mu .and. & + check_for_node(node_legendre_mu, "num_points")) then + call get_node_value(node_legendre_mu, "num_points", & + this % legendre_mu_points) + if (this % legendre_mu_points <= 0) then + call fatal_error("num_points element must be positive and non-zero!") + end if + this % legendre_mu_points = -1 * this % legendre_mu_points + end if + else + this % legendre_mu_points = 1 + end if + + if (check_for_node(node_xsdata, "fissionable")) then + call get_node_value(node_xsdata, "fissionable", temp_str) + temp_str = to_lower(temp_str) + if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then + this % fissionable = .true. + else + this % fissionable = .false. + end if + else + call fatal_error("Fissionable element must be set!") + end if + + end subroutine nuclidemg_init + + subroutine nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss) + class(NuclideIso), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Need fiss data? + + real(8), allocatable :: temp_arr(:) + integer :: arr_len + integer :: order_dim + + ! Call generic data gathering routine + call nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + + ! Load the more specific data + if (this % fissionable) then + + if (check_for_node(node_xsdata, "chi")) then + ! Get chi + allocate(this % chi(groups)) + call get_node_array(node_xsdata, "chi", this % chi) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * 1)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, 1)) + this % nu_fission = reshape(temp_arr, (/groups, 1/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + else + ! Get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + + allocate(temp_arr(groups*groups)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, groups)) + this % nu_fission = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + end if + if (get_fiss) then + allocate(this % fission(groups)) + if (check_for_node(node_xsdata, "fission")) then + call get_node_array(node_xsdata, "fission", this % fission) + else + call fatal_error("Fission data missing, required due to fission& + & tallies in tallies.xml file!") + end if + end if + if (get_kfiss) then + allocate(this % k_fission(groups)) + if (check_for_node(node_xsdata, "kappa_fission")) then + call get_node_array(node_xsdata, "kappa_fission", this % k_fission) + else + call fatal_error("kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!") + end if + end if + end if + + allocate(this % absorption(groups)) + if (check_for_node(node_xsdata, "absorption")) then + call get_node_array(node_xsdata, "absorption", this % absorption) + else + call fatal_error("Must provide absorption!") + end if + + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = this % order + 1 + else if (this % scatt_type == ANGLE_HISTOGRAM) then + order_dim = this % order + else if (this % scatt_type == ANGLE_TABULAR) then + order_dim = this % order + end if + + allocate(this % scatter(groups, groups, order_dim)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim)) + call get_node_array(node_xsdata, "scatter", temp_arr) + this % scatter = reshape(temp_arr, (/groups, groups, order_dim/)) + deallocate(temp_arr) + else + call fatal_error("Must provide scatter!") + return + end if + + + allocate(this % total(groups)) + if (check_for_node(node_xsdata, "total")) then + call get_node_array(node_xsdata, "total", this % total) + else + this % total = this % absorption + sum(this%scatter(:,:,1),dim=1) + end if + + ! Get Mult Data + allocate(this % mult(groups, groups)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + this % mult = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + call fatal_error("Multiplicity length not same as number of groups& + & squared!") + return + end if + else + this % mult = ONE + end if + + end subroutine nuclideiso_init + + subroutine nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss) + class(NuclideAngle), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + + real(8), allocatable :: temp_arr(:) + integer :: arr_len + real(8) :: dangle + integer :: iangle + integer :: order_dim + + ! Call generic data gathering routine + call nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = this % order + 1 + else if (this % scatt_type == ANGLE_HISTOGRAM) then + order_dim = this % order + else if (this % scatt_type == ANGLE_TABULAR) then + order_dim = this % order + end if + + if (check_for_node(node_xsdata, "num_polar")) then + call get_node_value(node_xsdata, "num_polar", this % n_pol) + else + call fatal_error("num_polar Must Be Provided!") + end if + + if (check_for_node(node_xsdata, "num_azimuthal")) then + call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) + else + call fatal_error("num_azimuthal Must Be Provided!") + end if + + ! Load angle data, if present (else equally spaced) + allocate(this % polar(this % n_pol)) + allocate(this % azimuthal(this % n_azi)) + if (check_for_node(node_xsdata, "polar")) then + call fatal_error("User-Specified polar angle bins not yet supported!") + ! When this feature is supported, this line will be activated + call get_node_array(node_xsdata, "polar", this % polar) + else + dangle = PI / real(this % n_pol,8) + do iangle = 1, this % n_pol + this % polar(iangle) = (real(iangle,8) - HALF) * dangle + end do + end if + if (check_for_node(node_xsdata, "azimuthal")) then + call fatal_error("User-Specified azimuthal angle bins not yet supported!") + ! When this feature is supported, this line will be activated + call get_node_array(node_xsdata, "azimuthal", this % azimuthal) + else + dangle = TWO * PI / real(this % n_azi,8) + do iangle = 1, this % n_azi + this % azimuthal(iangle) = -PI + (real(iangle,8) - HALF) * dangle + end do + end if + + ! Load the more specific data + if (this % fissionable) then + + if (check_for_node(node_xsdata, "chi")) then + ! Get chi + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "chi", temp_arr) + allocate(this % chi(groups, this % n_azi, this % n_pol)) + this % chi = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, 1, this % n_azi, this % n_pol)) + this % nu_fission = reshape(temp_arr, (/groups, 1, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + else + ! Get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(this % nu_fission(groups, groups, this % n_azi, this % n_pol)) + this % nu_fission = reshape(temp_arr, (/groups, groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + end if + if (get_fiss) then + if (check_for_node(node_xsdata, "fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "fission", temp_arr) + allocate(this % fission(groups, this % n_azi, this % n_pol)) + this % fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Fission data missing, required due to fission& + & tallies in tallies.xml file!") + end if + end if + if (get_kfiss) then + if (check_for_node(node_xsdata, "kappa_fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "kappa_fission", temp_arr) + allocate(this % k_fission(groups, this % n_azi, this % n_pol)) + this % k_fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!") + end if + end if + end if + + if (check_for_node(node_xsdata, "absorption")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "absorption", temp_arr) + allocate(this % absorption(groups, this % n_azi, this % n_pol)) + this % absorption = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Must provide absorption!") + end if + + allocate(this % scatter(groups, groups, order_dim, this % n_azi, this % n_pol)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim * this % n_azi * this%n_pol)) + call get_node_array(node_xsdata, "scatter", temp_arr) + this % scatter = reshape(temp_arr, (/groups, groups, order_dim, & + this%n_azi,this%n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Must provide scatter!") + end if + + if (check_for_node(node_xsdata, "total")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "total", temp_arr) + allocate(this % total(groups, this % n_azi, this % n_pol)) + this % total = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + this % total = this % absorption + sum(this%scatter(:,:,1,:,:),dim=1) + end if + + ! Get Mult Data + allocate(this % mult(groups, groups, this % n_azi, this % n_pol)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups * this % n_azi * this % n_pol) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + this % mult = reshape(temp_arr, (/groups, groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Multiplicity Length Does Not Match!") + end if + else + this % mult = ONE + end if + + end subroutine nuclideangle_init + !=============================================================================== ! NUCLIDECE_CLEAR resets and deallocates data in Nuclide, NuclideIso ! or NuclideAngle From 8a14d600b08b7046409fc332f03a2803bbb49a55 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 12 Feb 2016 06:23:23 -0500 Subject: [PATCH 72/84] fixed check_source finds --- src/input_xml.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 50e8ca30dc..eca7e8ca15 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2051,8 +2051,8 @@ contains ! Check to ensure material has at least one nuclide if (.not. check_for_node(node_mat, "nuclide") .and. & - .not. check_for_node(node_mat, "element") .and. & - .not. check_for_node(node_mat, "macroscopic")) then + .not. check_for_node(node_mat, "element") .and. & + .not. check_for_node(node_mat, "macroscopic")) then call fatal_error("No macroscopic data, nuclides or natural elements & &specified on material " // trim(to_str(mat % id))) end if From 8c43a32130664e6173d1448727f83c2717e2f81c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 12 Feb 2016 21:44:21 -0500 Subject: [PATCH 73/84] Resolved almost all of the comments from @paulromano, save for rejection sampling of the Legendre polynomial. also fixed @samuelshaner comment about the pincell_multigroup problem --- docs/source/usersguide/mgxs_library.rst | 6 +- .../python/pincell_multigroup/build-xml.py | 15 +- examples/xml/pincell_multigroup/materials.xml | 4 +- .../pincell_multigroup/mg_cross_sections.xml | 32 +-- src/input_xml.F90 | 5 +- src/macroxs_header.F90 | 162 +++++++++++- src/macroxs_operations.F90 | 243 ------------------ src/math.F90 | 27 ++ src/nuclide_header.F90 | 50 +--- src/physics_mg.F90 | 9 +- src/scattdata_header.F90 | 164 +++++++++++- src/tracking.F90 | 6 +- 12 files changed, 400 insertions(+), 323 deletions(-) delete mode 100644 src/macroxs_operations.F90 diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index 478b060024..ae4ee6681e 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -82,7 +82,11 @@ well as the actual cross section data. The following are the attributes/sub-elements required to describe the meta-data: :name: - The name of the microscopic or macroscopic data set. + The name of the microscopic or macroscopic data set. An extension to the + name must be provided (e.g., the ``.70m`` in ``UO2.70m``). This extension, + similar to the equivalent in the continuous-energy ``cross_sections.xml`` + file is used to denote variants of the particular nuclide or material of + interest (i.e. the ``UO2`` in this example). *Default*: None, this must be provided. diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 17fbae9941..7b8926c346 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -1,5 +1,7 @@ import openmc import openmc.mgxs +from openmc.source import Source +from openmc.stats import Box import numpy as np ############################################################################### @@ -20,7 +22,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.XSdata('UO2.300K', groups) +uo2_xsdata = openmc.XSdata('UO2.70m', groups) uo2_xsdata.order = 0 uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, 0.5644058]) @@ -43,7 +45,7 @@ uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, 0.0000E+00, 0.0000E+00, 0.0000E+00]) -h2o_xsdata = openmc.XSdata('LWTR.300K', groups) +h2o_xsdata = openmc.XSdata('LWTR.70m', groups) h2o_xsdata.order = 0 h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, 0.718, 1.2544497, 2.650379]) @@ -69,8 +71,8 @@ mg_cross_sections_file.export_to_xml() ############################################################################### # Instantiate some Macroscopic Data -uo2_data = openmc.Macroscopic('UO2', '300K') -h2o_data = openmc.Macroscopic('LWTR', '300K') +uo2_data = openmc.Macroscopic('UO2', '70m') +h2o_data = openmc.Macroscopic('LWTR', '70m') # Instantiate some Materials and register the appropriate Macroscopic objects uo2 = openmc.Material(material_id=1, name='UO2 fuel') @@ -83,7 +85,7 @@ water.add_macroscopic(h2o_data) # Instantiate a MaterialsFile, register all Materials, and export to XML materials_file = openmc.MaterialsFile() -materials_file.default_xs = '300K' +materials_file.default_xs = '70m' materials_file.add_materials([uo2, water]) materials_file.export_to_xml() @@ -143,8 +145,7 @@ settings_file.cross_sections = "./mg_cross_sections.xml" settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles -settings_file.set_source_space('box', [-0.63, -0.63, -1, \ - 0.63, 0.63, 1]) +settings_file.source = Source(space=Box([-0.63, -0.63, -1.], [0.63, 0.63, 1.])) ############################################################################### # Exporting to OpenMC tallies.xml File diff --git a/examples/xml/pincell_multigroup/materials.xml b/examples/xml/pincell_multigroup/materials.xml index 4b14f4a795..c94629665b 100644 --- a/examples/xml/pincell_multigroup/materials.xml +++ b/examples/xml/pincell_multigroup/materials.xml @@ -1,7 +1,7 @@ - - 300K + + 70m diff --git a/examples/xml/pincell_multigroup/mg_cross_sections.xml b/examples/xml/pincell_multigroup/mg_cross_sections.xml index ec85d4b593..d38d2d9c21 100644 --- a/examples/xml/pincell_multigroup/mg_cross_sections.xml +++ b/examples/xml/pincell_multigroup/mg_cross_sections.xml @@ -11,8 +11,8 @@ --> - UO2.71c - UO2.71c + UO2.70m + UO2.70m 2.53E-8 0 true @@ -67,8 +67,8 @@ - MOX1.71c - MOX1.71c + MOX1.70m + MOX1.70m 2.53E-8 0 true @@ -124,8 +124,8 @@ - MOX2.71c - MOX2.71c + MOX2.70m + MOX2.70m 2.53E-8 0 true @@ -180,8 +180,8 @@ - MOX3.71c - MOX3.71c + MOX3.70m + MOX3.70m 2.53E-8 0 true @@ -236,8 +236,8 @@ - FC.71c - FC.71c + FC.70m + FC.70m 2.53E-8 0 true @@ -286,8 +286,8 @@ - GT.71c - GT.71c + GT.70m + GT.70m 2.53E-8 0 false @@ -318,8 +318,8 @@ - LWTR.71c - LWTR.71c + LWTR.70m + LWTR.70m 2.53E-8 0 false @@ -351,8 +351,8 @@ - CR.71c - CR.71c + CR.70m + CR.70m 2.53E-8 0 false diff --git a/src/input_xml.F90 b/src/input_xml.F90 index eca7e8ca15..9fc490a33b 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2063,7 +2063,10 @@ contains ! as nuclides internally. ! Get pointer list of XML call get_node_list(node_mat, "macroscopic", node_macro_list) - if (get_list_size(node_macro_list) > 1) then + if (run_CE .and. (get_list_size(node_macro_list) > 0)) then + call fatal_error("Macroscopic can not be used in continuous-energy& + & mode!") + else if (get_list_size(node_macro_list) > 1) then call fatal_error("Only one macroscopic object permitted per material, " & // trim(to_str(mat % id))) else if (get_list_size(node_macro_list) == 1) then diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 index c435686b5d..2a12345108 100644 --- a/src/macroxs_header.F90 +++ b/src/macroxs_header.F90 @@ -3,8 +3,9 @@ module macroxs_header use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI use list_header, only: ListInt use material_header, only: material - use math, only: calc_pn, calc_rn, expand_harmonic + use math, only: calc_pn, calc_rn, expand_harmonic, find_angle use nuclide_header + use random_lcg, only: prn use scattdata_header implicit none @@ -19,8 +20,14 @@ module macroxs_header integer :: order contains - procedure(macroxs_init_), deferred :: init ! initializes object - procedure(macroxs_get_xs_), deferred :: get_xs ! Return xs + procedure(macroxs_init_), deferred :: init ! initializes object + procedure(macroxs_get_xs_), deferred :: get_xs ! Return xs + ! Sample the outgoing energy from a fission event + procedure(macroxs_sample_fission_), deferred :: sample_fission_energy + ! Sample the outgoing energy and angle from a scatter event + procedure(macroxs_sample_scatter_), deferred :: sample_scatter + ! Calculate the material specific MGXS data from the nuclides + procedure(macroxs_calculate_xs_), deferred :: calculate_xs end type MacroXS abstract interface @@ -50,6 +57,33 @@ module macroxs_header real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8) :: xs ! Resultant xs end function macroxs_get_xs_ + + function macroxs_sample_fission_(this, gin, uvw) result(gout) + import MacroXS + class(MacroXS), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + + end function macroxs_sample_fission_ + + subroutine macroxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) + import MacroXS + class(MacroXS), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + end subroutine macroxs_sample_scatter_ + + subroutine macroxs_calculate_xs_(this, gin, uvw, xs) + import MacroXS, MaterialMacroXS + class(MacroXS), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs + end subroutine macroxs_calculate_xs_ end interface type, extends(MacroXS) :: MacroXSIso @@ -64,8 +98,11 @@ module macroxs_header real(8), allocatable :: chi(:,:) ! fission spectra contains - procedure :: init => macroxsiso_init ! inits object - procedure :: get_xs => macroxsiso_get_xs ! Returns xs + procedure :: init => macroxsiso_init ! inits object + procedure :: get_xs => macroxsiso_get_xs ! Returns xs + procedure :: sample_fission_energy => macroxsiso_sample_fission_energy + procedure :: sample_scatter => macroxsiso_sample_scatter + procedure :: calculate_xs => macroxsiso_calculate_xs end type MacroXSIso type, extends(MacroXS) :: MacroXSAngle @@ -84,6 +121,9 @@ module macroxs_header contains procedure :: init => macroxsangle_init ! inits object procedure :: get_xs => macroxsangle_get_xs ! Returns xs + procedure :: sample_fission_energy => macroxsangle_sample_fission_energy + procedure :: sample_scatter => macroxsangle_sample_scatter + procedure :: calculate_xs => macroxsangle_calculate_xs end type MacroXSAngle !=============================================================================== @@ -705,4 +745,116 @@ contains end function macroxsangle_get_xs +!=============================================================================== +! MACROXS_*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission +! event +!=============================================================================== + + function macroxsiso_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXSIso), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout,gin) + end do + + end function macroxsiso_sample_fission_energy + + function macroxsangle_sample_fission_energy(this, gin, uvw) result(gout) + class(MacroXSAngle), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: iazi, ipol + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout,gin,iazi,ipol) + end do + + end function macroxsangle_sample_fission_energy + +!=============================================================================== +! MACROXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter +! event +!=============================================================================== + + subroutine macroxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) + class(MacroXSIso), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + call this % scatter % sample(gin, gout, mu, wgt) + + end subroutine macroxsiso_sample_scatter + + subroutine macroxsangle_sample_scatter(this, uvw, gin, gout, mu, wgt) + class(MacroXSAngle), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + integer :: iazi, ipol ! Angular indices + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + call this % scatter(iazi,ipol) % obj % sample(gin,gout,mu,wgt) + + end subroutine macroxsangle_sample_scatter + +!=============================================================================== +! MACROXS*_CALCULATE_XS determines the multi-group macroscopic cross sections +! for the material the particle is currently traveling through. +!=============================================================================== + + subroutine macroxsiso_calculate_xs(this, gin, uvw, xs) + class(MacroXSIso), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs ! Resultant MacroXS Data + + xs % total = this % total(gin) + xs % elastic = this % scattxs(gin) + xs % absorption = this % absorption(gin) + xs % nu_fission = this % nu_fission(gin) + + end subroutine macroxsiso_calculate_xs + + subroutine macroxsangle_calculate_xs(this, gin, uvw, xs) + class(MacroXSAngle), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs ! Resultant MacroXS Data + + integer :: iazi, ipol + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + xs % total = this % total(gin, iazi, ipol) + xs % elastic = this % scattxs(gin, iazi, ipol) + xs % absorption = this % absorption(gin, iazi, ipol) + xs % nu_fission = this % nu_fission(gin, iazi, ipol) + + end subroutine macroxsangle_calculate_xs + end module macroxs_header diff --git a/src/macroxs_operations.F90 b/src/macroxs_operations.F90 deleted file mode 100644 index 4fc13910ca..0000000000 --- a/src/macroxs_operations.F90 +++ /dev/null @@ -1,243 +0,0 @@ -module macroxs_operations - - use constants - use macroxs_header, only: MacroXS, MacroXSIso, MacroXSAngle, & - expand_harmonic - use material_header, only: Material - use math - use nuclide_header, only: find_angle, MaterialMacroXS, NuclideMicroXS, & - NuclideMG, NuclideMGContainer - use random_lcg, only: prn - use scattdata_header - use search - - implicit none - -contains - -!=============================================================================== -! UPDATE_XS stores the xs to work with -!=============================================================================== - - subroutine calculate_mgxs(this, gin, uvw, xs) - class(MacroXS), intent(in) :: this - integer, intent(in) :: gin ! Incoming neutron group - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - type(MaterialMacroXS), intent(inout) :: xs - - integer :: iazi, ipol - - select type(this) - type is (MacroXSIso) - xs % total = this % total(gin) - xs % elastic = this % scattxs(gin) - xs % absorption = this % absorption(gin) - xs % nu_fission = this % nu_fission(gin) - - type is (MacroXSAngle) - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - xs % total = this % total(gin, iazi, ipol) - xs % elastic = this % scattxs(gin, iazi, ipol) - xs % absorption = this % absorption(gin, iazi, ipol) - xs % nu_fission = this % nu_fission(gin, iazi, ipol) - end select - - end subroutine calculate_mgxs - - -!=============================================================================== -! SAMPLE_FISSION_ENERGY acts as a templating code for macroxs_*_sample_fission_energy -!=============================================================================== - - function sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXS), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - - select type(this) - type is (MacroXSIso) - gout = macroxsiso_sample_fission_energy(this, gin, uvw) - type is (MacroXSAngle) - gout = macroxsangle_sample_fission_energy(this, gin, uvw) - end select - - end function sample_fission_energy - -!=============================================================================== -! MACROXS_*_SAMPLE_FISSION_ENERGY samples the outgoing energy and mu from a scatter event. -! Implemented as % scatter. -!=============================================================================== - - function macroxsiso_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXSIso), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - - xi = prn() - prob = ZERO - gout = 0 - - do while (prob < xi) - gout = gout + 1 - prob = prob + this % chi(gout,gin) - end do - - end function macroxsiso_sample_fission_energy - - function macroxsangle_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXSAngle), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - integer :: iazi, ipol - - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - - xi = prn() - prob = ZERO - gout = 0 - - do while (prob < xi) - gout = gout + 1 - prob = prob + this % chi(gout,gin,iazi,ipol) - end do - - end function macroxsangle_sample_fission_energy - -!=============================================================================== -! SAMPLE_SCATTER acts as a templating code for macroxs_*_sample_scatter -!=============================================================================== - - subroutine sample_scatter(this, uvw, gin, gout, mu, wgt) - class(MacroXS), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight - - integer :: iazi, ipol ! Angular indices - - select type(this) - type is (MacroXSIso) - call macroxs_sample_scatter(this % scatter, gin, gout, mu, wgt) - type is (MacroXSAngle) - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - call macroxs_sample_scatter(this % scatter(iazi,ipol) % obj,gin,gout,mu,wgt) - end select - - end subroutine sample_scatter - -!=============================================================================== -! MACROXS_SAMPLE_SCATTER performs the work with ScattData to sample outgoing -! energy and change in angle. -!=============================================================================== - - subroutine macroxs_sample_scatter(scatt, gin, gout, mu, wgt) - class(ScattData), intent(in) :: scatt ! Scattering Object to Use - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight - - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - integer :: imu - real(8) :: u, f, M - real(8) :: mu0, frac, mu1 - real(8) :: c_k, c_k1, p0, p1 - integer :: k, NP, samples - - xi = prn() - prob = ZERO - gout = 0 - - do while (prob < xi) - gout = gout + 1 - prob = prob + scatt % energy(gout,gin) - end do - - select type (scatt) - type is (ScattDataHistogram) - xi = prn() - if (xi < scatt % data(1,gout,gin)) then - imu = 1 - else - imu = binary_search(scatt % data(:,gout,gin), & - size(scatt % data(:,gout,gin)), xi) - end if - - ! Randomly select a mu in this bin. - mu = prn() * scatt % dmu + scatt % mu(imu) - - type is (ScattDataTabular) - ! determine outgoing cosine bin - NP = size(scatt % data(:,gout,gin)) - xi = prn() - - c_k = scatt % data(1,gout,gin) - do k = 1, NP - 1 - c_k1 = scatt % data(k+1,gout,gin) - if (xi < c_k1) exit - c_k = c_k1 - end do - - ! check to make sure k is <= NP - 1 - k = min(k, NP - 1) - - p0 = scatt % fmu(k,gout,gin) - mu0 = scatt % mu(k) - ! Linear-linear interpolation to find mu value w/in bin. - p1 = scatt % fmu(k+1,gout,gin) - mu1 = scatt % mu(k+1) - - frac = (p1 - p0)/(mu1 - mu0) - - if (frac == ZERO) then - mu = mu0 + (xi - c_k)/p0 - else - mu = mu0 + (sqrt(max(ZERO, p0*p0 + TWO*frac*(xi - c_k))) - p0)/frac - end if - - if (mu <= -ONE) then - mu = -ONE - else if (mu >= ONE) then - mu = ONE - end if - - type is (ScattDataLegendre) - ! Now we can sample mu using the legendre representation of the scattering - ! kernel in data(1:this % order) - - ! Do with rejection sampling - ! Set upper bound (instead of searching for max - though this is inefficient) - M = 4.0_8 - samples = 0 - do - mu = TWO * prn() - ONE - f = scatt % calc_f(gin,gout,mu) - if (f > ZERO) then - u = prn() * M - if (u <= f) then - exit - end if - end if - samples = samples + 1 - if (samples > MAX_SAMPLE) then - ! Exit with an isotropic event. - exit - end if - end do - end select - - wgt = wgt * scatt % mult(gout,gin) - - end subroutine macroxs_sample_scatter - -end module macroxs_operations \ No newline at end of file diff --git a/src/math.F90 b/src/math.F90 index c7ede8d2a5..f49220da76 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -702,4 +702,31 @@ contains end function watt_spectrum + +!=============================================================================== +! find_angle finds the closest angle on the data grid and returns that index +!=============================================================================== + + pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) + real(8), intent(in) :: polar(:) ! Polar angles [0,pi] + real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] + real(8), intent(in) :: uvw(3) ! Direction of motion + integer, intent(inout) :: i_pol ! Closest polar bin + integer, intent(inout) :: i_azi ! Closest azi bin + + real(8) :: my_pol, my_azi, dangle + + ! Convert uvw to polar and azi + + my_pol = acos(uvw(3)) + my_azi = atan2(uvw(2), uvw(1)) + + ! Search for equi-binned angles + dangle = PI / real(size(polar),8) + i_pol = floor(my_pol / dangle + ONE) + dangle = TWO * PI / real(size(azimuthal),8) + i_azi = floor((my_azi + PI) / dangle + ONE) + + end subroutine find_angle + end module math diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 7569d9ea80..9bcce57a75 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -7,9 +7,10 @@ module nuclide_header use endf, only: reaction_name use error, only: fatal_error use list_header, only: ListInt - use math, only: evaluate_legendre + use math, only: evaluate_legendre, find_angle use string use xml_interface + implicit none !=============================================================================== @@ -300,12 +301,9 @@ module nuclide_header ! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed !=============================================================================== - subroutine nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + subroutine nuclidemg_init(this, node_xsdata) class(NuclideMG), intent(inout) :: this ! Working Object type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? type(Node), pointer :: node_legendre_mu character(MAX_LINE_LEN) :: temp_str @@ -403,7 +401,7 @@ module nuclide_header integer :: order_dim ! Call generic data gathering routine - call nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + call nuclidemg_init(this, node_xsdata) ! Load the more specific data if (this % fissionable) then @@ -525,7 +523,7 @@ module nuclide_header integer :: order_dim ! Call generic data gathering routine - call nuclidemg_init(this, node_xsdata, groups, get_kfiss, get_fiss) + call nuclidemg_init(this, node_xsdata) if (this % scatt_type == ANGLE_LEGENDRE) then order_dim = this % order + 1 @@ -1043,13 +1041,13 @@ module nuclide_header if (this % scatt_type == ANGLE_LEGENDRE) then f = evaluate_legendre(this % scatter(gout,gin,:), mu) else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / real(this % order - 1) + dmu = TWO / real(this % order - 1,8) ! Find mu bin algebraically, knowing that the spacing is equal f = (mu + ONE) / dmu + ONE imu = floor(f) ! But save the amount that mu is past the previous index ! so we can use interpolation later. - f = f - real(imu) + f = f - real(imu,8) ! Adjust so interpolation works on the last bin if necessary if (imu == size(this % scatter, dim=3)) then imu = imu - 1 @@ -1060,7 +1058,7 @@ module nuclide_header f = (ONE - r) * this % scatter(gout,gin,imu) + & r * this % scatter(gout,gin,imu+1) else ! (ANGLE_HISTOGRAM) - dmu = TWO / real(this % order) + dmu = TWO / real(this % order,8) ! Find mu bin algebraically, knowing that the spacing is equal imu = floor((mu + ONE) / dmu + ONE) ! Adjust so interpolation works on the last bin if necessary @@ -1097,13 +1095,13 @@ module nuclide_header if (this % scatt_type == ANGLE_LEGENDRE) then f = evaluate_legendre(this % scatter(gout,gin,:,i_azi_,i_pol_), mu) else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / real(this % order - 1) + dmu = TWO / real(this % order - 1,8) ! Find mu bin algebraically, knowing that the spacing is equal f = (mu + ONE) / dmu + ONE imu = floor(f) ! But save the amount that mu is past the previous index ! so we can use interpolation later. - f = f - real(imu) + f = f - real(imu,8) ! Adjust so interpolation works on the last bin if necessary if (imu == size(this % scatter, dim=3)) then imu = imu - 1 @@ -1114,7 +1112,7 @@ module nuclide_header f = (ONE - r) * this % scatter(gout,gin,imu,i_azi_,i_pol_) + & r * this % scatter(gout,gin,imu+1,i_azi_,i_pol_) else ! (ANGLE_HISTOGRAM) - dmu = TWO / real(this % order) + dmu = TWO / real(this % order,8) ! Find mu bin algebraically, knowing that the spacing is equal imu = floor((mu + ONE) / dmu + ONE) ! Adjust so interpolation works on the last bin if necessary @@ -1127,30 +1125,4 @@ module nuclide_header end function nuclideangle_calc_f -!=============================================================================== -! find_angle finds the closest angle on the data grid and returns that index -!=============================================================================== - - pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) - real(8), intent(in) :: polar(:) ! Polar angles [0,pi] - real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] - real(8), intent(in) :: uvw(3) ! Direction of motion - integer, intent(inout) :: i_pol ! Closest polar bin - integer, intent(inout) :: i_azi ! Closest azi bin - - real(8) my_pol, my_azi, dangle - - ! Convert uvw to polar and azi - - my_pol = acos(uvw(3)) - my_azi = atan2(uvw(2), uvw(1)) - - ! Search for equi-binned angles - dangle = PI / real(size(polar),8) - i_pol = floor(my_pol / dangle + ONE) - dangle = TWO * PI / real(size(azimuthal),8) - i_azi = floor((my_azi + PI) / dangle + ONE) - - end subroutine find_angle - end module nuclide_header diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index a0d8eb6e1d..ce296c48e6 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -6,7 +6,6 @@ module physics_mg use error, only: fatal_error, warning use global use macroxs_header, only: MacroXS, MacroXSContainer - use macroxs_operations, only: sample_fission_energy, sample_scatter use material_header, only: Material use math, only: rotate_angle use mesh, only: get_mesh_indices @@ -146,9 +145,9 @@ contains type(Particle), intent(inout) :: p - call sample_scatter(macro_xs(p % material) % obj, & - p % coord(1) % uvw, p % last_g, p % g, & - p % mu, p % wgt) + call macro_xs(p % material) % obj % sample_scatter(p % coord(1) % uvw, & + p % last_g, p % g, & + p % mu, p % wgt) ! Update energy value for downstream compatability (in tallying) p % E = energy_bin_avg(p % g) @@ -256,7 +255,7 @@ contains ! Sample secondary energy distribution for fission reaction and set energy ! in fission bank - bank_array(i) % g = sample_fission_energy(xs, p % g, fission_bank(i) % uvw) + bank_array(i) % g = xs % sample_fission_energy(p % g, fission_bank(i) % uvw) bank_array(i) % E = energy_bin_avg(fission_bank(i) % g) end do diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index b9dcdadd41..e02ba9172f 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -1,7 +1,10 @@ module scattdata_header - use math use constants + use error, only: fatal_error + use math + use random_lcg, only: prn + use search, only: binary_search implicit none @@ -19,6 +22,7 @@ module scattdata_header contains procedure(init_), deferred :: init ! Initializes ScattData procedure(calc_f_), deferred :: calc_f ! Calculates f, given mu + procedure(sample_), deferred :: sample ! sample the scatter event end type ScattData abstract interface @@ -40,12 +44,22 @@ module scattdata_header real(8) :: f ! Return value of f(mu) end function calc_f_ + + subroutine sample_(this, gin, gout, mu, wgt) + import ScattData + class(ScattData), intent(in) :: this ! Scattering Object to Use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + end subroutine sample_ end interface type, extends(ScattData) :: ScattDataLegendre contains procedure :: init => scattdatalegendre_init procedure :: calc_f => scattdatalegendre_calc_f + procedure :: sample => scattdatalegendre_sample end type ScattDataLegendre type, extends(ScattData) :: ScattDataHistogram @@ -54,6 +68,7 @@ module scattdata_header contains procedure :: init => scattdatahistogram_init procedure :: calc_f => scattdatahistogram_calc_f + procedure :: sample => scattdatahistogram_sample end type ScattDataHistogram type, extends(ScattData) :: ScattDataTabular @@ -63,6 +78,7 @@ module scattdata_header contains procedure :: init => scattdatatabular_init procedure :: calc_f => scattdatatabular_calc_f + procedure :: sample => scattdatatabular_sample end type ScattDataTabular !=============================================================================== @@ -290,4 +306,150 @@ contains end function scattdatatabular_calc_f +!=============================================================================== +! SCATTDATA*_SCATTER Samples the outgoing energy and change in angle. +!=============================================================================== + + subroutine scattdatalegendre_sample(this, gin, gout, mu, wgt) + class(ScattDataLegendre), intent(in) :: this ! Scattering object to use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + real(8) :: u, f, M + integer :: samples + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % energy(gout,gin) + end do + + ! Now we can sample mu using the legendre representation of the thisering + ! kernel in data(1:this % order) + + ! Do with rejection sampling + ! Set upper bound (instead of searching for max - though this is inefficient) + M = 4.0_8 + samples = 0 + do + mu = TWO * prn() - ONE + f = this % calc_f(gin,gout,mu) + if (f > ZERO) then + u = prn() * M + if (u <= f) then + exit + end if + end if + samples = samples + 1 + if (samples > MAX_SAMPLE) then + call fatal_error("Maximum number of Legendre expansion samples reached!") + end if + end do + + wgt = wgt * this % mult(gout,gin) + + end subroutine scattdatalegendre_sample + + subroutine scattdatahistogram_sample(this, gin, gout, mu, wgt) + class(ScattDataHistogram), intent(in) :: this ! Scattering object to use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: imu + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % energy(gout,gin) + end do + + xi = prn() + if (xi < this % data(1,gout,gin)) then + imu = 1 + else + imu = binary_search(this % data(:,gout,gin), & + size(this % data(:,gout,gin)), xi) + end if + + ! Randomly select a mu in this bin. + mu = prn() * this % dmu + this % mu(imu) + + wgt = wgt * this % mult(gout,gin) + + end subroutine scattdatahistogram_sample + + subroutine scattdatatabular_sample(this, gin, gout, mu, wgt) + class(ScattDataTabular), intent(in) :: this ! Scattering object to use + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + real(8) :: mu0, frac, mu1 + real(8) :: c_k, c_k1, p0, p1 + integer :: k, NP + + xi = prn() + prob = ZERO + gout = 0 + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % energy(gout,gin) + end do + + ! determine outgoing cosine bin + NP = size(this % data(:,gout,gin)) + xi = prn() + + c_k = this % data(1,gout,gin) + do k = 1, NP - 1 + c_k1 = this % data(k+1,gout,gin) + if (xi < c_k1) exit + c_k = c_k1 + end do + + ! check to make sure k is <= NP - 1 + k = min(k, NP - 1) + + p0 = this % fmu(k,gout,gin) + mu0 = this % mu(k) + ! Linear-linear interpolation to find mu value w/in bin. + p1 = this % fmu(k+1,gout,gin) + mu1 = this % mu(k+1) + + frac = (p1 - p0)/(mu1 - mu0) + + if (frac == ZERO) then + mu = mu0 + (xi - c_k)/p0 + else + mu = mu0 + (sqrt(max(ZERO, p0*p0 + TWO*frac*(xi - c_k))) - p0)/frac + end if + + if (mu <= -ONE) then + mu = -ONE + else if (mu >= ONE) then + mu = ONE + end if + + wgt = wgt * this % mult(gout,gin) + + end subroutine scattdatatabular_sample + end module scattdata_header \ No newline at end of file diff --git a/src/tracking.F90 b/src/tracking.F90 index 98e5483a0a..17fc855591 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -7,7 +7,7 @@ module tracking cross_lattice, check_cell_overlap use geometry_header, only: Universe, BASE_UNIVERSE use global - use macroxs_operations, only: calculate_mgxs + use macroxs_header, only: MacroXS use output, only: write_message use particle_header, only: LocalCoord, Particle use physics, only: collision @@ -92,8 +92,8 @@ contains ! Since the MGXS can be angle dependent, this needs to be done ! After every collision for the MGXS mode if (p % material /= MATERIAL_VOID) then - call calculate_mgxs(macro_xs(p % material) % obj, p % g, & - p % coord(p % n_coord) % uvw, material_xs) + call macro_xs(p % material) % obj % calculate_xs(p % g, & + p % coord(p % n_coord) % uvw, material_xs) else material_xs % total = ZERO material_xs % elastic = ZERO From 391e8b18058df84330a80db7cb2eb9797f6d800e Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 13 Feb 2016 05:18:19 -0500 Subject: [PATCH 74/84] previous commit changed library extension from example problem to 70m from 300K. This puts them back to being 300K and then adds size to the default_xs variable to allow for 5 total characters in the extension.' --- docs/source/usersguide/mgxs_library.rst | 9 ++++-- .../python/pincell_multigroup/build-xml.py | 10 +++--- examples/xml/pincell_multigroup/materials.xml | 4 +-- .../pincell_multigroup/mg_cross_sections.xml | 32 +++++++++---------- src/global.F90 | 4 +-- src/input_xml.F90 | 2 +- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index ae4ee6681e..4cc36f1e89 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -83,10 +83,13 @@ attributes/sub-elements required to describe the meta-data: :name: The name of the microscopic or macroscopic data set. An extension to the - name must be provided (e.g., the ``.70m`` in ``UO2.70m``). This extension, + name must be provided (e.g., the ``.300K`` in ``UO2.300K``). The name and + extension together must be twelve or less characters in length. This + extension must follow a period and be five characters or less in length. similar to the equivalent in the continuous-energy ``cross_sections.xml`` - file is used to denote variants of the particular nuclide or material of - interest (i.e. the ``UO2`` in this example). + file, is used to denote variants of the particular nuclide or material of + interest (i.e. the ``UO2`` data in this example could have been generated + at a temperature of 300K). *Default*: None, this must be provided. diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 7b8926c346..ff75a64d93 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -22,7 +22,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.XSdata('UO2.70m', groups) +uo2_xsdata = openmc.XSdata('UO2.300K', groups) uo2_xsdata.order = 0 uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, 0.5644058]) @@ -45,7 +45,7 @@ uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, 0.0000E+00, 0.0000E+00, 0.0000E+00]) -h2o_xsdata = openmc.XSdata('LWTR.70m', groups) +h2o_xsdata = openmc.XSdata('LWTR.300K', groups) h2o_xsdata.order = 0 h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, 0.718, 1.2544497, 2.650379]) @@ -71,8 +71,8 @@ mg_cross_sections_file.export_to_xml() ############################################################################### # Instantiate some Macroscopic Data -uo2_data = openmc.Macroscopic('UO2', '70m') -h2o_data = openmc.Macroscopic('LWTR', '70m') +uo2_data = openmc.Macroscopic('UO2', '300K') +h2o_data = openmc.Macroscopic('LWTR', '300K') # Instantiate some Materials and register the appropriate Macroscopic objects uo2 = openmc.Material(material_id=1, name='UO2 fuel') @@ -85,7 +85,7 @@ water.add_macroscopic(h2o_data) # Instantiate a MaterialsFile, register all Materials, and export to XML materials_file = openmc.MaterialsFile() -materials_file.default_xs = '70m' +materials_file.default_xs = '300K' materials_file.add_materials([uo2, water]) materials_file.export_to_xml() diff --git a/examples/xml/pincell_multigroup/materials.xml b/examples/xml/pincell_multigroup/materials.xml index c94629665b..6961166541 100644 --- a/examples/xml/pincell_multigroup/materials.xml +++ b/examples/xml/pincell_multigroup/materials.xml @@ -1,7 +1,7 @@ - - 70m + + 300K diff --git a/examples/xml/pincell_multigroup/mg_cross_sections.xml b/examples/xml/pincell_multigroup/mg_cross_sections.xml index d38d2d9c21..3c671a1922 100644 --- a/examples/xml/pincell_multigroup/mg_cross_sections.xml +++ b/examples/xml/pincell_multigroup/mg_cross_sections.xml @@ -11,8 +11,8 @@ --> - UO2.70m - UO2.70m + UO2.300K + UO2.300K 2.53E-8 0 true @@ -67,8 +67,8 @@ - MOX1.70m - MOX1.70m + MOX1.300K + MOX1.300K 2.53E-8 0 true @@ -124,8 +124,8 @@ - MOX2.70m - MOX2.70m + MOX2.300K + MOX2.300K 2.53E-8 0 true @@ -180,8 +180,8 @@ - MOX3.70m - MOX3.70m + MOX3.300K + MOX3.300K 2.53E-8 0 true @@ -236,8 +236,8 @@ - FC.70m - FC.70m + FC.300K + FC.300K 2.53E-8 0 true @@ -286,8 +286,8 @@ - GT.70m - GT.70m + GT.300K + GT.300K 2.53E-8 0 false @@ -318,8 +318,8 @@ - LWTR.70m - LWTR.70m + LWTR.300K + LWTR.300K 2.53E-8 0 false @@ -351,8 +351,8 @@ - CR.70m - CR.70m + CR.300K + CR.300K 2.53E-8 0 false diff --git a/src/global.F90 b/src/global.F90 index 17477ed80b..970f89f9ba 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -79,8 +79,8 @@ module global type(DictCharInt) :: nuclide_dict type(DictCharInt) :: xs_listing_dict - ! Default xs identifier (e.g. 70c) - character(3):: default_xs + ! Default xs identifier (e.g. 70c or 300K) + character(5):: default_xs ! ============================================================================ ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 9fc490a33b..eb504f43a1 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -3072,7 +3072,7 @@ contains ! Append default_xs specifier to nuclide if needed if ((default_xs /= '') .and. (.not. ends_with(sarray(j), 'c'))) then - word = trim(word) // "." // default_xs + word = trim(word) // "." // trim(default_xs) end if ! Search through nuclides From e89b584a7b434c68c91c3550e413f9f9fa9eb4d9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 13 Feb 2016 05:48:36 -0500 Subject: [PATCH 75/84] added in smarter maximal value detection for rejection sampling of scattering angles represented as polynomial legendres --- src/scattdata_header.F90 | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index e02ba9172f..b2c8ba3e3c 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -56,6 +56,8 @@ module scattdata_header end interface type, extends(ScattData) :: ScattDataLegendre + ! Maximal value for rejection sampling from rectangle + real(8), allocatable :: max_val(:,:) contains procedure :: init => scattdatalegendre_init procedure :: calc_f => scattdatalegendre_calc_f @@ -116,15 +118,47 @@ contains subroutine scattdatalegendre_init(this, order, energy, mult, coeffs) class(ScattDataLegendre), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + integer, intent(in) :: order ! Data Order + real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + real(8) :: dmu, mu, f + integer :: imu, Nmu, gout, gin, groups + call scattdata_init(this, order, energy, mult) this % data = coeffs + groups = size(this % energy,dim=1) + + allocate(this % max_val(groups, groups)) + this % max_val = ZERO + ! Step through the polynomial with fixed number of points to identify + ! the maximal value. + Nmu = 1001 + dmu = TWO / real(Nmu,8) + do imu = 1, Nmu + ! Update mu. Do first and last seperate to avoid float errors + if (imu == 1) then + mu = -ONE + else if (imu == Nmu) then + mu = ONE + end if + mu = -ONE + real(imu - 1,8) * dmu + do gin = 1, groups + do gout = 1, groups + ! Calculate probability + f = this % calc_f(gin,gout,mu) + ! If this is a new max, store it. + if (f > this % max_val(gout,gin)) this % max_val(gout,gin) = f + end do + end do + end do + + ! Finally, since we may not have caught the exact max, add 10% margin + this % max_val = this % max_val * 1.1_8 + end subroutine scattdatalegendre_init subroutine scattdatahistogram_init(this, order, energy, mult, coeffs) @@ -145,7 +179,7 @@ contains this % dmu = TWO / real(order,8) this % mu(1) = -ONE do imu = 2, order - this % mu(imu) = -ONE + (imu - 1) * this % dmu + this % mu(imu) = -ONE + real(imu - 1,8) * this % dmu end do ! Best to integrate this histogram so we can avoid rejection sampling @@ -335,12 +369,15 @@ contains ! kernel in data(1:this % order) ! Do with rejection sampling - ! Set upper bound (instead of searching for max - though this is inefficient) - M = 4.0_8 + ! Set maximal value + M = this % max_val(gout,gin) samples = 0 do mu = TWO * prn() - ONE f = this % calc_f(gin,gout,mu) +if (f > M) then +call fatal_error("Legendre exceeds Max Value!!!") +end if if (f > ZERO) then u = prn() * M if (u <= f) then From 2c4917bd3f1958fcd31d53c4f04ca12d94e21c0a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 13 Feb 2016 06:07:19 -0500 Subject: [PATCH 76/84] Updating MG tests which previously failed due to change in rejection sampling algorithm --- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/results_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 1306 +++++++++++----------- 4 files changed, 656 insertions(+), 656 deletions(-) diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 35e2af7c06..35f3e73d40 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.035488E+00 4.058903E-02 +1.045320E+00 5.851680E-02 diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat index dfb1c02d79..1b23005602 100644 --- a/tests/test_mg_max_order/results_true.dat +++ b/tests/test_mg_max_order/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.106635E+00 4.503267E-02 +1.083030E+00 1.855038E-02 diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 26a41ade87..5b60cef222 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.271009E-01 6.377851E-03 +1.380785E-01 5.556526E-03 diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index 4e27ab66b9..0cb47a712d 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,86 +1,86 @@ k-combined: -1.035488E+00 4.058903E-02 +1.045320E+00 5.851680E-02 tally 1: -2.737079E+00 -1.545362E+00 -7.475678E-02 -1.182688E-03 -3.895146E+00 -3.143927E+00 -3.051980E-02 -2.030656E-04 -7.566509E-02 -1.248142E-03 -2.564678E+00 -1.356531E+00 -6.888583E-02 -1.027172E-03 -3.639176E+00 -2.763465E+00 -2.785332E-02 -1.756457E-04 -6.905430E-02 -1.079605E-03 -2.513858E+00 -1.360648E+00 -7.106151E-02 -1.063532E-03 -3.598310E+00 -2.766916E+00 -2.957807E-02 -1.830650E-04 -7.333034E-02 -1.125208E-03 -2.680537E+00 -1.557625E+00 -7.458823E-02 -1.153071E-03 -3.874223E+00 -3.178628E+00 -3.085079E-02 -1.987973E-04 -7.648569E-02 -1.221907E-03 -2.747094E+00 -1.661126E+00 -7.366404E-02 -1.200019E-03 -3.949477E+00 -3.398210E+00 -2.983494E-02 -2.006053E-04 -7.396717E-02 -1.233020E-03 -2.832153E+00 -1.688117E+00 -7.768421E-02 -1.263525E-03 -4.057661E+00 -3.441857E+00 -3.181289E-02 -2.134911E-04 -7.887092E-02 -1.312222E-03 -2.818292E+00 -1.727700E+00 -8.151103E-02 -1.400727E-03 -4.087366E+00 -3.555489E+00 -3.440824E-02 -2.483234E-04 -8.530537E-02 -1.526319E-03 -2.673498E+00 -1.597867E+00 -8.179404E-02 -1.455604E-03 -4.005194E+00 -3.520971E+00 -3.564373E-02 -2.749065E-04 -8.836840E-02 -1.689712E-03 +2.286064E+00 +1.057353E+00 +6.503987E-02 +8.851627E-04 +3.376363E+00 +2.323627E+00 +2.733240E-02 +1.607534E-04 +6.776283E-02 +9.880704E-04 +2.391658E+00 +1.201477E+00 +7.241106E-02 +1.103780E-03 +3.614949E+00 +2.730438E+00 +3.146867E-02 +2.110753E-04 +7.801752E-02 +1.297373E-03 +2.762725E+00 +1.705088E+00 +8.684520E-02 +1.654173E-03 +4.172232E+00 +3.847245E+00 +3.834947E-02 +3.212662E-04 +9.507651E-02 +1.974662E-03 +2.802290E+00 +1.773339E+00 +8.347451E-02 +1.574952E-03 +4.206829E+00 +3.971225E+00 +3.593646E-02 +2.967708E-04 +8.909414E-02 +1.824101E-03 +2.383708E+00 +1.176784E+00 +7.337273E-02 +1.097240E-03 +3.624903E+00 +2.690697E+00 +3.213890E-02 +2.139948E-04 +7.967917E-02 +1.315319E-03 +2.398216E+00 +1.234567E+00 +6.905889E-02 +9.879327E-04 +3.479138E+00 +2.538252E+00 +2.911091E-02 +1.750648E-04 +7.217215E-02 +1.076035E-03 +2.563998E+00 +1.354089E+00 +7.357381E-02 +1.097086E-03 +3.753156E+00 +2.867475E+00 +3.097034E-02 +1.948794E-04 +7.678206E-02 +1.197826E-03 +2.293243E+00 +1.172767E+00 +6.702582E-02 +9.267762E-04 +3.407144E+00 +2.469472E+00 +2.857514E-02 +1.688581E-04 +7.084385E-02 +1.037886E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -171,86 +171,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.694430E+00 -1.482997E+00 -7.661360E-02 -1.219010E-03 -3.956809E+00 -3.231298E+00 -3.211518E-02 -2.179122E-04 -7.962036E-02 -1.339397E-03 -2.572758E+00 -1.418791E+00 -7.213692E-02 -1.094985E-03 -3.692753E+00 -2.869867E+00 -2.991749E-02 -1.926648E-04 -7.417183E-02 -1.184214E-03 -2.477980E+00 -1.312803E+00 -6.912091E-02 -9.790394E-04 -3.581706E+00 -2.674317E+00 -2.863743E-02 -1.680509E-04 -7.099830E-02 -1.032924E-03 -2.845088E+00 -1.688617E+00 -8.173799E-02 -1.368439E-03 -4.131147E+00 -3.544636E+00 -3.438554E-02 -2.417440E-04 -8.524908E-02 -1.485879E-03 -2.793685E+00 -1.647743E+00 -8.194563E-02 -1.421503E-03 -4.186293E+00 -3.695916E+00 -3.501635E-02 -2.621854E-04 -8.681299E-02 -1.611522E-03 -2.638366E+00 -1.500052E+00 -8.011857E-02 -1.356165E-03 -4.000991E+00 -3.395409E+00 -3.487592E-02 -2.544883E-04 -8.646482E-02 -1.564211E-03 -2.842735E+00 -1.690237E+00 -8.154955E-02 -1.356837E-03 -4.156256E+00 -3.570439E+00 -3.435028E-02 -2.398488E-04 -8.516165E-02 -1.474230E-03 -2.196972E+00 -9.871590E-01 -6.781939E-02 -9.725975E-04 -3.352539E+00 -2.320436E+00 -2.976179E-02 -1.937147E-04 -7.378580E-02 -1.190667E-03 +2.604127E+00 +1.442914E+00 +7.142299E-02 +1.083324E-03 +3.786547E+00 +2.990260E+00 +2.935394E-02 +1.905369E-04 +7.277467E-02 +1.171135E-03 +2.457755E+00 +1.228862E+00 +6.655630E-02 +9.411086E-04 +3.528688E+00 +2.561047E+00 +2.709124E-02 +1.640319E-04 +6.716494E-02 +1.008221E-03 +2.450846E+00 +1.295337E+00 +6.779278E-02 +9.992248E-04 +3.519409E+00 +2.693620E+00 +2.793186E-02 +1.714064E-04 +6.924902E-02 +1.053549E-03 +2.469234E+00 +1.300419E+00 +7.347034E-02 +1.175743E-03 +3.675903E+00 +2.880386E+00 +3.155996E-02 +2.200036E-04 +7.824386E-02 +1.352252E-03 +2.576106E+00 +1.365945E+00 +7.241428E-02 +1.090052E-03 +3.719498E+00 +2.861357E+00 +3.008961E-02 +1.906170E-04 +7.459854E-02 +1.171627E-03 +2.503651E+00 +1.290812E+00 +7.432507E-02 +1.132918E-03 +3.702398E+00 +2.813425E+00 +3.186491E-02 +2.091477E-04 +7.899991E-02 +1.285525E-03 +2.395349E+00 +1.202098E+00 +7.095925E-02 +1.051988E-03 +3.559388E+00 +2.628753E+00 +3.041477E-02 +1.959992E-04 +7.540470E-02 +1.204709E-03 +1.910174E+00 +7.331782E-01 +6.366813E-02 +8.166135E-04 +2.966770E+00 +1.762376E+00 +2.893278E-02 +1.712979E-04 +7.173053E-02 +1.052882E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -341,86 +341,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.641273E+00 -1.597870E+00 -7.598644E-02 -1.292899E-03 -3.853049E+00 -3.336280E+00 -3.203862E-02 -2.292746E-04 -7.943056E-02 -1.409235E-03 -2.708082E+00 -1.522839E+00 -7.654337E-02 -1.221093E-03 -3.905027E+00 -3.156770E+00 -3.189847E-02 -2.134574E-04 -7.908310E-02 -1.312015E-03 -2.691233E+00 -1.524379E+00 -8.054050E-02 -1.365756E-03 -3.962250E+00 -3.258368E+00 -3.462881E-02 -2.628049E-04 -8.585218E-02 -1.615329E-03 -3.018386E+00 -1.917223E+00 -8.348614E-02 -1.445746E-03 -4.283272E+00 -3.833787E+00 -3.429972E-02 -2.430307E-04 -8.503630E-02 -1.493787E-03 -2.929994E+00 -1.836911E+00 -8.927512E-02 -1.624433E-03 -4.372984E+00 -4.002348E+00 -3.882367E-02 -3.051257E-04 -9.625215E-02 -1.875454E-03 -3.119790E+00 -2.050856E+00 -9.534078E-02 -1.868390E-03 -4.698804E+00 -4.587809E+00 -4.157799E-02 -3.523492E-04 -1.030807E-01 -2.165713E-03 -2.868621E+00 -1.702964E+00 -8.398565E-02 -1.456555E-03 -4.247485E+00 -3.715607E+00 -3.580655E-02 -2.676357E-04 -8.877207E-02 -1.645022E-03 -2.497455E+00 -1.252375E+00 -6.446362E-02 -8.477811E-04 -3.507541E+00 -2.474088E+00 -2.542963E-02 -1.367733E-04 -6.304548E-02 -8.406768E-04 +2.593479E+00 +1.421618E+00 +7.731733E-02 +1.249860E-03 +3.880469E+00 +3.167768E+00 +3.330331E-02 +2.319171E-04 +8.256599E-02 +1.425478E-03 +2.563470E+00 +1.449702E+00 +7.411043E-02 +1.158986E-03 +3.692974E+00 +2.935486E+00 +3.125554E-02 +2.061246E-04 +7.748913E-02 +1.266944E-03 +2.657580E+00 +1.493736E+00 +7.749682E-02 +1.277831E-03 +3.892576E+00 +3.190262E+00 +3.289903E-02 +2.334764E-04 +8.156370E-02 +1.435062E-03 +2.701357E+00 +1.517431E+00 +8.804410E-02 +1.639744E-03 +4.161224E+00 +3.606273E+00 +3.959674E-02 +3.345554E-04 +9.816875E-02 +2.056343E-03 +2.745200E+00 +1.523378E+00 +7.925308E-02 +1.270874E-03 +3.962649E+00 +3.165021E+00 +3.340000E-02 +2.283904E-04 +8.280570E-02 +1.403801E-03 +2.678775E+00 +1.492394E+00 +8.646776E-02 +1.554919E-03 +4.147456E+00 +3.551060E+00 +3.875994E-02 +3.125295E-04 +9.609415E-02 +1.920962E-03 +2.678888E+00 +1.497390E+00 +7.616647E-02 +1.203778E-03 +3.868905E+00 +3.108718E+00 +3.186093E-02 +2.136540E-04 +7.899003E-02 +1.313223E-03 +2.189117E+00 +9.756340E-01 +6.824988E-02 +9.549688E-04 +3.259136E+00 +2.150849E+00 +2.997262E-02 +1.883650E-04 +7.430850E-02 +1.157785E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -511,86 +511,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.623441E+00 -1.490238E+00 -8.737054E-02 -1.670677E-03 -4.075246E+00 -3.570201E+00 -3.969459E-02 -3.510115E-04 -9.841135E-02 -2.157491E-03 -2.429458E+00 -1.296272E+00 -7.433515E-02 -1.195439E-03 -3.603045E+00 -2.814355E+00 -3.233556E-02 -2.266091E-04 -8.016674E-02 -1.392852E-03 -2.655653E+00 -1.503631E+00 -7.556244E-02 -1.216313E-03 -3.876149E+00 -3.192723E+00 -3.167217E-02 -2.160892E-04 -7.852205E-02 -1.328191E-03 -2.687380E+00 -1.496815E+00 -7.570314E-02 -1.262722E-03 -3.940616E+00 -3.291028E+00 -3.159442E-02 -2.339022E-04 -7.832928E-02 -1.437679E-03 -2.990160E+00 -1.889612E+00 -7.623143E-02 -1.208898E-03 -4.207001E+00 -3.697140E+00 -2.984188E-02 -1.859848E-04 -7.398438E-02 -1.143155E-03 -2.853430E+00 -1.655915E+00 -7.908369E-02 -1.262135E-03 -4.101975E+00 -3.406862E+00 -3.260559E-02 -2.168450E-04 -8.083620E-02 -1.332837E-03 -2.730969E+00 -1.615691E+00 -7.764021E-02 -1.314394E-03 -3.991873E+00 -3.443169E+00 -3.252644E-02 -2.371617E-04 -8.063998E-02 -1.457714E-03 -2.187664E+00 -9.957750E-01 -6.436381E-02 -8.515751E-04 -3.270736E+00 -2.197812E+00 -2.754849E-02 -1.554780E-04 -6.829858E-02 -9.556448E-04 +2.761165E+00 +1.657839E+00 +7.810542E-02 +1.334149E-03 +4.026290E+00 +3.495574E+00 +3.264226E-02 +2.359256E-04 +8.092710E-02 +1.450116E-03 +2.601284E+00 +1.465130E+00 +7.485486E-02 +1.239170E-03 +3.829638E+00 +3.199488E+00 +3.159745E-02 +2.288567E-04 +7.833681E-02 +1.406667E-03 +2.419174E+00 +1.228134E+00 +7.422066E-02 +1.117508E-03 +3.667795E+00 +2.787048E+00 +3.244938E-02 +2.129012E-04 +8.044893E-02 +1.308597E-03 +2.491535E+00 +1.259222E+00 +7.470359E-02 +1.133979E-03 +3.773164E+00 +2.887196E+00 +3.234132E-02 +2.142511E-04 +8.018101E-02 +1.316894E-03 +2.430358E+00 +1.305969E+00 +7.236826E-02 +1.077801E-03 +3.691969E+00 +2.914191E+00 +3.123416E-02 +2.001679E-04 +7.743613E-02 +1.230332E-03 +3.133682E+00 +1.984584E+00 +8.337467E-02 +1.392595E-03 +4.451265E+00 +3.978527E+00 +3.354318E-02 +2.282172E-04 +8.316070E-02 +1.402736E-03 +2.662704E+00 +1.448336E+00 +7.530385E-02 +1.164529E-03 +3.880423E+00 +3.054138E+00 +3.144058E-02 +2.085301E-04 +7.794791E-02 +1.281730E-03 +2.130205E+00 +9.297660E-01 +6.583066E-02 +8.790174E-04 +3.226341E+00 +2.120506E+00 +2.889944E-02 +1.698754E-04 +7.164788E-02 +1.044139E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -681,86 +681,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -3.126226E+00 -2.054101E+00 -9.308386E-02 -1.840170E-03 -4.585435E+00 -4.425166E+00 -3.991071E-02 -3.454637E-04 -9.894716E-02 -2.123391E-03 -2.628975E+00 -1.442927E+00 -7.480586E-02 -1.136055E-03 -3.849243E+00 -3.050079E+00 -3.136784E-02 -1.990547E-04 -7.776755E-02 -1.223489E-03 -2.740162E+00 -1.737335E+00 -7.647229E-02 -1.263465E-03 -4.009845E+00 -3.586955E+00 -3.173845E-02 -2.147512E-04 -7.868637E-02 -1.319968E-03 -2.761943E+00 -1.619005E+00 -7.846740E-02 -1.320872E-03 -4.097351E+00 -3.568014E+00 -3.295230E-02 -2.361898E-04 -8.169577E-02 -1.451740E-03 -2.855074E+00 -1.670686E+00 -7.845369E-02 -1.263464E-03 -4.103374E+00 -3.452249E+00 -3.220431E-02 -2.141592E-04 -7.984135E-02 -1.316329E-03 -2.690178E+00 -1.491926E+00 -7.527503E-02 -1.160972E-03 -3.903606E+00 -3.122977E+00 -3.125741E-02 -2.022968E-04 -7.749378E-02 -1.243417E-03 -2.512911E+00 -1.314036E+00 -7.800028E-02 -1.259212E-03 -3.791186E+00 -2.970061E+00 -3.426379E-02 -2.436930E-04 -8.494722E-02 -1.497858E-03 -2.273876E+00 -1.107297E+00 -7.120819E-02 -1.019386E-03 -3.428794E+00 -2.426375E+00 -3.139941E-02 -1.998412E-04 -7.784582E-02 -1.228323E-03 +2.599461E+00 +1.458035E+00 +7.809884E-02 +1.305214E-03 +3.901359E+00 +3.258238E+00 +3.379142E-02 +2.432493E-04 +8.377612E-02 +1.495131E-03 +2.748044E+00 +1.595569E+00 +8.641555E-02 +1.591494E-03 +4.133038E+00 +3.610482E+00 +3.815976E-02 +3.125423E-04 +9.460617E-02 +1.921040E-03 +2.827693E+00 +1.681951E+00 +9.214026E-02 +1.815952E-03 +4.343252E+00 +3.980138E+00 +4.139309E-02 +3.763771E-04 +1.026223E-01 +2.313401E-03 +2.848302E+00 +1.709266E+00 +8.618471E-02 +1.555247E-03 +4.293029E+00 +3.893924E+00 +3.742129E-02 +2.947160E-04 +9.277535E-02 +1.811471E-03 +3.107129E+00 +1.985180E+00 +9.390982E-02 +1.778566E-03 +4.705512E+00 +4.502266E+00 +4.077729E-02 +3.361217E-04 +1.010956E-01 +2.065971E-03 +3.176743E+00 +2.076916E+00 +9.535836E-02 +1.843238E-03 +4.782883E+00 +4.655802E+00 +4.125628E-02 +3.453802E-04 +1.022831E-01 +2.122878E-03 +3.158364E+00 +2.020031E+00 +9.047734E-02 +1.652565E-03 +4.641857E+00 +4.326900E+00 +3.809128E-02 +2.983406E-04 +9.443638E-02 +1.833749E-03 +2.750064E+00 +1.515295E+00 +7.550745E-02 +1.157933E-03 +4.022702E+00 +3.249004E+00 +3.106532E-02 +2.005988E-04 +7.701755E-02 +1.232980E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -851,86 +851,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.416875E+00 -1.198797E+00 -7.051645E-02 -1.018987E-03 -3.608689E+00 -2.679252E+00 -3.004052E-02 -1.872854E-04 -7.447684E-02 -1.151149E-03 -2.573490E+00 -1.402205E+00 -6.633005E-02 -9.194585E-04 -3.559859E+00 -2.675099E+00 -2.604699E-02 -1.426679E-04 -6.457603E-02 -8.769077E-04 -2.701686E+00 -1.530274E+00 -7.570621E-02 -1.220650E-03 -3.972619E+00 -3.322266E+00 -3.152781E-02 -2.138949E-04 -7.816415E-02 -1.314704E-03 -2.920710E+00 -1.813750E+00 -8.167632E-02 -1.397805E-03 -4.220218E+00 -3.751891E+00 -3.388045E-02 -2.397875E-04 -8.399686E-02 -1.473853E-03 -2.886624E+00 -1.697663E+00 -8.812015E-02 -1.584550E-03 -4.350341E+00 -3.846411E+00 -3.842467E-02 -3.055861E-04 -9.526294E-02 -1.878284E-03 -2.805388E+00 -1.631826E+00 -9.017775E-02 -1.681160E-03 -4.264591E+00 -3.742270E+00 -4.026469E-02 -3.387007E-04 -9.982475E-02 -2.081823E-03 -2.789842E+00 -1.599838E+00 -9.325901E-02 -1.771117E-03 -4.331678E+00 -3.825425E+00 -4.241710E-02 -3.690107E-04 -1.051610E-01 -2.268123E-03 -2.406721E+00 -1.197504E+00 -7.197982E-02 -1.055123E-03 -3.523223E+00 -2.545571E+00 -3.093417E-02 -1.962555E-04 -7.669239E-02 -1.206284E-03 +2.571690E+00 +1.405222E+00 +6.998368E-02 +1.010782E-03 +3.645470E+00 +2.775516E+00 +2.848750E-02 +1.694087E-04 +7.062657E-02 +1.041270E-03 +3.305320E+00 +2.344814E+00 +9.985328E-02 +2.111130E-03 +4.992554E+00 +5.332303E+00 +4.332586E-02 +3.970490E-04 +1.074140E-01 +2.440461E-03 +2.746305E+00 +1.652960E+00 +9.402849E-02 +1.982149E-03 +4.315533E+00 +4.099428E+00 +4.322622E-02 +4.235148E-04 +1.071670E-01 +2.603132E-03 +2.975372E+00 +1.824531E+00 +9.627993E-02 +1.863677E-03 +4.624041E+00 +4.351874E+00 +4.324350E-02 +3.743520E-04 +1.072099E-01 +2.300953E-03 +2.968077E+00 +1.807761E+00 +9.337061E-02 +1.790184E-03 +4.455263E+00 +4.056544E+00 +4.122926E-02 +3.540009E-04 +1.022161E-01 +2.175865E-03 +3.337278E+00 +2.233238E+00 +1.017763E-01 +2.083989E-03 +4.981699E+00 +4.981154E+00 +4.428100E-02 +3.964318E-04 +1.097820E-01 +2.436667E-03 +3.083638E+00 +1.958766E+00 +9.111141E-02 +1.726305E-03 +4.546082E+00 +4.260420E+00 +3.895365E-02 +3.200133E-04 +9.657439E-02 +1.966961E-03 +2.644733E+00 +1.407404E+00 +8.635553E-02 +1.527997E-03 +4.094426E+00 +3.382785E+00 +3.888081E-02 +3.161126E-04 +9.639381E-02 +1.942985E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1021,86 +1021,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.670387E+00 -1.493829E+00 -7.916152E-02 -1.323249E-03 -3.980792E+00 -3.341124E+00 -3.398399E-02 -2.477152E-04 -8.425355E-02 -1.522581E-03 -2.643712E+00 -1.525085E+00 -7.477643E-02 -1.211244E-03 -3.829765E+00 -3.171826E+00 -3.119267E-02 -2.143333E-04 -7.733327E-02 -1.317399E-03 -2.775846E+00 -1.674648E+00 -8.464107E-02 -1.549143E-03 -4.133594E+00 -3.716316E+00 -3.679183E-02 -2.932382E-04 -9.121478E-02 -1.802388E-03 -2.954816E+00 -1.930285E+00 -7.887852E-02 -1.287632E-03 -4.192638E+00 -3.786782E+00 -3.177353E-02 -2.052824E-04 -7.877335E-02 -1.261768E-03 -3.031795E+00 -1.932684E+00 -9.082125E-02 -1.719186E-03 -4.462842E+00 -4.170125E+00 -3.909991E-02 -3.173523E-04 -9.693701E-02 -1.950605E-03 -2.773807E+00 -1.592371E+00 -8.755961E-02 -1.597915E-03 -4.234664E+00 -3.713430E+00 -3.882039E-02 -3.159470E-04 -9.624401E-02 -1.941967E-03 -2.528366E+00 -1.320356E+00 -8.486472E-02 -1.488520E-03 -3.935024E+00 -3.188413E+00 -3.866268E-02 -3.104697E-04 -9.585301E-02 -1.908301E-03 -2.814891E+00 -1.783998E+00 -7.956633E-02 -1.440608E-03 -4.087076E+00 -3.738124E+00 -3.321370E-02 -2.578118E-04 -8.234384E-02 -1.584639E-03 +3.316522E+00 +2.302876E+00 +8.987919E-02 +1.676655E-03 +4.716109E+00 +4.596488E+00 +3.654407E-02 +2.855910E-04 +9.060053E-02 +1.755384E-03 +3.091331E+00 +2.117646E+00 +8.528196E-02 +1.564336E-03 +4.492326E+00 +4.405850E+00 +3.513814E-02 +2.665883E-04 +8.711494E-02 +1.638584E-03 +2.649730E+00 +1.444519E+00 +8.510948E-02 +1.506094E-03 +4.117595E+00 +3.501517E+00 +3.810553E-02 +3.052819E-04 +9.447172E-02 +1.876414E-03 +2.875773E+00 +1.758531E+00 +9.127582E-02 +1.780419E-03 +4.328266E+00 +3.989840E+00 +4.045386E-02 +3.513542E-04 +1.002937E-01 +2.159598E-03 +3.102792E+00 +1.949906E+00 +9.153879E-02 +1.691646E-03 +4.578530E+00 +4.235906E+00 +3.913672E-02 +3.094156E-04 +9.702826E-02 +1.901822E-03 +3.238743E+00 +2.146355E+00 +8.902551E-02 +1.593536E-03 +4.683916E+00 +4.438028E+00 +3.660342E-02 +2.683183E-04 +9.074766E-02 +1.649218E-03 +3.006635E+00 +1.887385E+00 +8.716712E-02 +1.586834E-03 +4.383965E+00 +4.008888E+00 +3.688262E-02 +2.862513E-04 +9.143987E-02 +1.759443E-03 +2.749904E+00 +1.550561E+00 +9.244273E-02 +1.748082E-03 +4.241273E+00 +3.669144E+00 +4.208622E-02 +3.633241E-04 +1.043407E-01 +2.233170E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1191,86 +1191,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.360566E+00 -1.164965E+00 -7.582328E-02 -1.239719E-03 -3.614813E+00 -2.742787E+00 -3.388042E-02 -2.553121E-04 -8.399678E-02 -1.569275E-03 -2.546108E+00 -1.399288E+00 -7.762813E-02 -1.316168E-03 -3.859937E+00 -3.260243E+00 -3.384404E-02 -2.538541E-04 -8.390659E-02 -1.560314E-03 -3.332352E+00 -2.369626E+00 -8.799788E-02 -1.625343E-03 -4.655099E+00 -4.594468E+00 -3.514406E-02 -2.612097E-04 -8.712961E-02 -1.605525E-03 -2.601466E+00 -1.427019E+00 -7.052544E-02 -1.078356E-03 -3.725846E+00 -2.956429E+00 -2.871825E-02 -1.843049E-04 -7.119865E-02 -1.132829E-03 -2.954221E+00 -1.775439E+00 -8.854750E-02 -1.593113E-03 -4.427465E+00 -3.982350E+00 -3.824403E-02 -2.969669E-04 -9.481508E-02 -1.825306E-03 -2.855301E+00 -1.652640E+00 -8.473899E-02 -1.471257E-03 -4.218821E+00 -3.612250E+00 -3.633488E-02 -2.751925E-04 -9.008191E-02 -1.691470E-03 -2.632066E+00 -1.437779E+00 -7.298646E-02 -1.093885E-03 -3.785199E+00 -2.966958E+00 -3.009667E-02 -1.863207E-04 -7.461606E-02 -1.145219E-03 -2.629725E+00 -1.564381E+00 -8.162764E-02 -1.547184E-03 -3.953052E+00 -3.585289E+00 -3.581386E-02 -3.025695E-04 -8.879019E-02 -1.859742E-03 +2.556952E+00 +1.416458E+00 +8.087467E-02 +1.431667E-03 +3.806748E+00 +3.158182E+00 +3.571995E-02 +2.831832E-04 +8.855737E-02 +1.740585E-03 +2.546384E+00 +1.446967E+00 +8.000281E-02 +1.363415E-03 +3.844739E+00 +3.222133E+00 +3.533522E-02 +2.621956E-04 +8.760354E-02 +1.611584E-03 +2.474418E+00 +1.302438E+00 +7.728372E-02 +1.265047E-03 +3.818517E+00 +3.076074E+00 +3.414744E-02 +2.483215E-04 +8.465877E-02 +1.526307E-03 +2.478272E+00 +1.299434E+00 +7.866430E-02 +1.293627E-03 +3.758685E+00 +2.973817E+00 +3.491240E-02 +2.542033E-04 +8.655529E-02 +1.562460E-03 +2.941937E+00 +1.842278E+00 +9.491310E-02 +1.902183E-03 +4.564730E+00 +4.427111E+00 +4.252722E-02 +3.828960E-04 +1.054340E-01 +2.353469E-03 +2.850564E+00 +1.719152E+00 +8.118192E-02 +1.404765E-03 +4.190858E+00 +3.722715E+00 +3.411695E-02 +2.522778E-04 +8.458318E-02 +1.550625E-03 +2.726097E+00 +1.648250E+00 +7.879124E-02 +1.424955E-03 +3.940978E+00 +3.461222E+00 +3.322044E-02 +2.688615E-04 +8.236053E-02 +1.652557E-03 +2.304822E+00 +1.153775E+00 +7.500010E-02 +1.314077E-03 +3.542935E+00 +2.786864E+00 +3.369367E-02 +2.798215E-04 +8.353377E-02 +1.719922E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -2892,15 +2892,15 @@ tally 1: 0.000000E+00 0.000000E+00 tally 2: -4.012713E+01 -3.286443E+02 -4.014931E+01 -3.290078E+02 -5.982856E+00 -7.510508E+00 -5.983297E+00 -7.511618E+00 -1.223283E+02 -3.075680E+03 -1.223283E+02 -3.075680E+03 +4.283244E+01 +3.698890E+02 +4.285612E+01 +3.702981E+02 +6.926001E+00 +9.669342E+00 +6.926497E+00 +9.670727E+00 +1.223563E+02 +3.025594E+03 +1.223563E+02 +3.025594E+03 From 03b433f8f3f8baee2d433279f87391d4393d67c1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 13 Feb 2016 14:06:48 -0500 Subject: [PATCH 77/84] Whoops... left in a debug check from rejection sampling. cleaned it up --- src/scattdata_header.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index b2c8ba3e3c..b04115e570 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -375,9 +375,6 @@ contains do mu = TWO * prn() - ONE f = this % calc_f(gin,gout,mu) -if (f > M) then -call fatal_error("Legendre exceeds Max Value!!!") -end if if (f > ZERO) then u = prn() * M if (u <= f) then From 9cbc1180d03d4ffe019ae4eb991b432057405e04 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 19:51:34 -0500 Subject: [PATCH 78/84] Modified *CROSS_SECTIONS envvar to be OPENMC_*CROSS_SECTIONS, incorporated latest comments from @paulromano. Next is to work on fixing up bank --- docs/source/usersguide/input.rst | 11 ++++++----- docs/source/usersguide/install.rst | 25 ++++++++++++++----------- docs/source/usersguide/mgxs_library.rst | 2 +- openmc/mgxs_library.py | 13 +++++++------ src/bank_header.F90 | 2 +- src/input_xml.F90 | 12 ++++++------ src/relaxng/materials.rnc | 22 +++++++++++----------- 7 files changed, 46 insertions(+), 41 deletions(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index bee60f2218..eb620b650c 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -112,10 +112,11 @@ standard deviation. The ```` element has no attributes and simply indicates the path to an XML cross section listing file (usually named cross_sections.xml). If this -element is absent from the settings.xml file, the :envvar:`CROSS_SECTIONS` -environment variable will be used to find the path to the XML cross section -listing when in continuous-energy mode, and the :envvar:`MG_CROSS_SECTIONS` -environment variable will be used in multi-group mode. +element is absent from the settings.xml file, the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the +path to the XML cross section listing when in continuous-energy mode, and the +:envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in +multi-group mode. ```` Element -------------------- @@ -1728,7 +1729,7 @@ The ```` element accepts the following sub-elements: |inverse-velocity |The flux-weighted inverse velocity where the | | |velocity is in units of centimeters per second. | | |This score type is not used in the | - | |multi-group :ref:`energy_mode`. | + | |multi-group :ref:`energy_mode`. | +----------------------+---------------------------------------------------+ |kappa-fission |The recoverable energy production rate due to | | |fission. The recoverable energy is defined as the | diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index bbb593beb1..2c7ec1b41f 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -355,7 +355,7 @@ Testing Build ------------- If you have ENDF/B-VII.1 cross sections from NNDC_ you can test your build. -Make sure the **CROSS_SECTIONS** environmental variable is set to the +Make sure the **OPENMC_CROSS_SECTIONS** environmental variable is set to the *cross_sections.xml* file in the *data/nndc* directory. There are two ways to run tests. The first is to use the Makefile present in the source directory and run the following: @@ -405,9 +405,10 @@ extract, and set up a confiuration file: cd openmc/data python get_nndc_data.py -At this point, you should set the :envvar:`CROSS_SECTIONS` environment variable -to the absolute path of the file ``openmc/data/nndc/cross_sections.xml``. This -cross section set is used by the test suite. +At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment +variable to the absolute path of the file +``openmc/data/nndc/cross_sections.xml``. This cross section set is used by the +test suite. Using JEFF Cross Sections from OECD/NEA --------------------------------------- @@ -433,8 +434,8 @@ the following steps must be taken: 4. Additionally, you may need to change any occurrences of upper-case "ACE" within the ``cross_sections.xml`` file to lower-case. 5. Either set the :ref:`cross_sections` in a settings.xml file or the - :envvar:`CROSS_SECTIONS` environment variable to the absolute path of the - ``cross_sections.xml`` file. + :envvar:`OPENMC_CROSS_SECTIONS` environment variable to the absolute path of + the ``cross_sections.xml`` file. Using Cross Sections from MCNP ------------------------------ @@ -442,8 +443,9 @@ Using Cross Sections from MCNP To use cross sections distributed with MCNP, change the element in the ``cross_sections.xml`` file in the root directory of the OpenMC distribution to the location of the MCNP cross sections. Then, either set the -:ref:`cross_sections` in a settings.xml file or the :envvar:`CROSS_SECTIONS` -environment variable to the absolute path of the ``cross_sections.xml`` file. +:ref:`cross_sections` in a settings.xml file or the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable to the absolute path of +the ``cross_sections.xml`` file. Using Cross Sections from Serpent --------------------------------- @@ -451,8 +453,9 @@ Using Cross Sections from Serpent To use cross sections distributed with Serpent, change the element in the ``cross_sections_serpent.xml`` file in the root directory of the OpenMC distribution to the location of the Serpent cross sections. Then, either set the -:ref:`cross_sections` in a settings.xml file or the :envvar:`CROSS_SECTIONS` -environment variable to the absolute path of the ``cross_sections_serpent.xml`` +:ref:`cross_sections` in a settings.xml file or the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable to the absolute path of +the ``cross_sections_serpent.xml`` file. Using Multi-Group Cross Sections @@ -462,7 +465,7 @@ Multi-group cross section libraries are generally tailored to the specific calculation to be performed. Therefore, at this point in time, OpenMC is not distributed with any pre-existing multi-group cross section libraries. However, if the user has obtained or generated their own library, the user -should set the :envvar:`MG_CROSS_SECTIONS` environment variable +should set the :envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable to the absolute path of the file library expected to used most frequently. .. _NJOY: http://t2.lanl.gov/nis/codes.shtml diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/usersguide/mgxs_library.rst index 4cc36f1e89..a5d2ec0d06 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/usersguide/mgxs_library.rst @@ -270,7 +270,7 @@ attributes/sub-elements required to describe the meta-data: with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. - *Default*: None, this is required only if :ref:`kappa_fission` tallies are + *Default*: None, this is required only if kappa_fission tallies are requested and the material is fissionable. :chi: diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index ea6407f968..b6dd9f09fe 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -17,6 +17,7 @@ from openmc.clean_xml import * # Supported incoming particle MGXS angular treatment representations _REPRESENTATIONS = ['isotropic', 'angle'] + def ndarray_to_string(arr): """Converts a numpy ndarray in to a join with spaces between entries similar to ' '.join(map(str,arr)) but applied to all sub-dimensions. @@ -48,14 +49,14 @@ def ndarray_to_string(arr): for i in range(shape[0]): text += tab for j in range(shape[1]): - text += '{:.7E} '.format(arr[i,j]) + text += '{:.7E} '.format(arr[i, j]) text += indent elif ndim == 3: for i in range(shape[0]): for j in range(shape[1]): text += tab for k in range(shape[2]): - text += '{:.7E} '.format(arr[i,j,k]) + text += '{:.7E} '.format(arr[i, j, k]) text += indent elif ndim == 4: for i in range(shape[0]): @@ -63,7 +64,7 @@ def ndarray_to_string(arr): for k in range(shape[2]): text += tab for l in range(shape[3]): - text += '{:.7E} '.format(arr[i,j,k,l]) + text += '{:.7E} '.format(arr[i, j, k, l]) text += indent elif ndim == 5: for i in range(shape[0]): @@ -72,7 +73,7 @@ def ndarray_to_string(arr): for l in range(shape[3]): text += tab for m in range(shape[4]): - text += '{:.7E} '.format(arr[i,j,k,l,m]) + text += '{:.7E} '.format(arr[i, j, k, l, m]) text += indent return text @@ -289,7 +290,7 @@ class XSdata(object): check_value('num_points', num_points, Integral) check_greater_than('num_points', num_points, 0) else: - if enable == False: + if not enable: num_points = 1 else: num_points = 33 @@ -563,6 +564,7 @@ class XSdata(object): return element + class MGXSLibraryFile(object): """Multi-Group Cross Sections file used for an OpenMC simulation. Corresponds directly to the MG version of the cross_sections.xml input file. @@ -686,7 +688,6 @@ class MGXSLibraryFile(object): xml_element = xsdata._get_xsdata_xml() self._cross_sections_file.append(xml_element) - def export_to_xml(self, filename='mg_cross_sections.xml'): """Create an mg_cross_sections.xml file that can be used for a simulation. diff --git a/src/bank_header.F90 b/src/bank_header.F90 index ad829341f0..c10a93e569 100644 --- a/src/bank_header.F90 +++ b/src/bank_header.F90 @@ -5,7 +5,7 @@ module bank_header implicit none !=============================================================================== -! BANK* is used for storing fission sites in eigenvalue calculations. Since all +! BANK is used for storing fission sites in eigenvalue calculations. Since all ! the state information of a neutron is not needed, this type allows sites to be ! stored with less memory !=============================================================================== diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 49600939c3..9ef439bb04 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -129,11 +129,11 @@ contains ! No cross_sections.xml file specified in settings.xml, check ! environment variable if (run_CE) then - call get_environment_variable("CROSS_SECTIONS", env_variable) + call get_environment_variable("OPENMC_CROSS_SECTIONS", env_variable) if (len_trim(env_variable) == 0) then call fatal_error("No cross_sections.xml file was specified in & - &settings.xml or in the CROSS_SECTIONS environment variable. & - &OpenMC needs such a file to identify where to & + &settings.xml or in the OPENMC_CROSS_SECTIONS environment & + &variable. OpenMC needs such a file to identify where to & &find ACE cross section libraries. Please consult the user's & &guide at http://mit-crpg.github.io/openmc for information on & &how to set up ACE cross section libraries.") @@ -141,11 +141,11 @@ contains path_cross_sections = trim(env_variable) end if else - call get_environment_variable("MG_CROSS_SECTIONS", env_variable) + call get_environment_variable("OPENMC_MG_CROSS_SECTIONS", env_variable) if (len_trim(env_variable) == 0) then call fatal_error("No cross_sections.xml file was specified in & - &settings.xml or in the MG_CROSS_SECTIONS environment variable. & - &OpenMC needs such a file to identify where to & + &settings.xml or in the OPENMC_MG_CROSS_SECTIONS environment & + &variable. OpenMC needs such a file to identify where to & &find the cross section libraries. Please consult the user's & &guide at http://mit-crpg.github.io/openmc for information on & &how to set up the cross section libraries.") diff --git a/src/relaxng/materials.rnc b/src/relaxng/materials.rnc index aec3fbcbc2..21b36c07e1 100644 --- a/src/relaxng/materials.rnc +++ b/src/relaxng/materials.rnc @@ -13,8 +13,8 @@ element materials { element nuclide { (element name { xsd:string { maxLength = "7" } } | attribute name { xsd:string { maxLength = "7" } }) & - (element xs { xsd:string { maxLength = "3" } } | - attribute xs { xsd:string { maxLength = "3" } })? & + (element xs { xsd:string { maxLength = "5" } } | + attribute xs { xsd:string { maxLength = "5" } })? & (element scattering { ( "data" | "iso-in-lab" ) } | attribute scattering { ( "data" | "iso-in-lab" ) })? & ( @@ -24,17 +24,17 @@ element materials { }* & element macroscopic { - (element name { xsd:string { maxLength = "7" } } | - attribute name { xsd:string { maxLength = "7" } }) & - (element xs { xsd:string { maxLength = "3" } } | - attribute xs { xsd:string { maxLength = "3" } }) + (element name { xsd:string } | + attribute name { xsd:string }) & + (element xs { xsd:string { maxLength = "5" } } | + attribute xs { xsd:string { maxLength = "5" } }) }* & element element { (element name { xsd:string { maxLength = "2" } } | attribute name { xsd:string { maxLength = "2" } }) & - (element xs { xsd:string { maxLength = "3" } } | - attribute xs { xsd:string { maxLength = "3" } })? & + (element xs { xsd:string { maxLength = "5" } } | + attribute xs { xsd:string { maxLength = "5" } })? & (element scattering { ( "data" | "iso-in-lab" ) } | attribute scattering { ( "data" | "iso-in-lab" ) })? & ( @@ -46,10 +46,10 @@ element materials { element sab { (element name { xsd:string { maxLength = "7" } } | attribute name { xsd:string { maxLength = "7" } }) & - (element xs { xsd:string { maxLength = "3" } } | - attribute xs { xsd:string { maxLength = "3" } })? + (element xs { xsd:string { maxLength = "5" } } | + attribute xs { xsd:string { maxLength = "5" } })? }* }+ & - element default_xs { xsd:string { maxLength = "3" } }? + element default_xs { xsd:string { maxLength = "5" } }? } From c0a6582248855736604d0c3054f339d1d4b24622 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 20:18:12 -0500 Subject: [PATCH 79/84] Replacing Bank % g with Bank % E which is cast to an integer. --- .../usersguide/output/particle_restart.rst | 11 +++------ docs/source/usersguide/output/source.rst | 2 +- src/bank_header.F90 | 3 +-- src/constants.F90 | 2 +- src/initialize.F90 | 2 -- src/particle_header.F90 | 23 +++++++++++-------- src/particle_restart_write.F90 | 1 - src/physics_mg.F90 | 4 ++-- src/simulation.F90 | 3 ++- src/source.F90 | 7 +++--- src/tally.F90 | 2 +- src/tracking.F90 | 2 +- 12 files changed, 29 insertions(+), 33 deletions(-) diff --git a/docs/source/usersguide/output/particle_restart.rst b/docs/source/usersguide/output/particle_restart.rst index 1ed6077108..70f00a930f 100644 --- a/docs/source/usersguide/output/particle_restart.rst +++ b/docs/source/usersguide/output/particle_restart.rst @@ -4,7 +4,7 @@ Particle Restart File Format ============================ -The current revision of the particle restart file format is 2. +The current revision of the particle restart file format is 1. **/filetype** (*char[]*) @@ -46,13 +46,8 @@ The current revision of the particle restart file format is 2. **/energy** (*double*) - Energy of the particle in MeV. This is always provided but only used - for continuous-energy mode. - -**/energy_group** (*int*) - - Energy group of the particle. This is always provided but only used - for multi-group mode. + Energy of the particle in MeV for continuous-energy mode, or the energy + group of the particle for multi-group mode. **/xyz** (*double[3]*) diff --git a/docs/source/usersguide/output/source.rst b/docs/source/usersguide/output/source.rst index e8867083c1..53841a5ebc 100644 --- a/docs/source/usersguide/output/source.rst +++ b/docs/source/usersguide/output/source.rst @@ -15,6 +15,6 @@ is that documented here. **/source_bank** (Compound type) Source bank information for each particle. The compound type has fields - ``wgt``, ``xyz``, ``uvw``, ``E``, ``g``, and ``delayed_group``, which + ``wgt``, ``xyz``, ``uvw``, ``E``, and ``delayed_group``, which represent the weight, position, direction, energy, energy group, and delayed_group of the source particle, respectively. diff --git a/src/bank_header.F90 b/src/bank_header.F90 index c10a93e569..97fb1f11fa 100644 --- a/src/bank_header.F90 +++ b/src/bank_header.F90 @@ -14,8 +14,7 @@ module bank_header real(C_DOUBLE) :: wgt ! weight of bank site real(C_DOUBLE) :: xyz(3) ! location of bank particle real(C_DOUBLE) :: uvw(3) ! diretional cosines - real(C_DOUBLE) :: E ! energy - integer(C_INT) :: g ! energy group + real(C_DOUBLE) :: E ! energy / energy group if in MG mode. integer(C_INT) :: delayed_group ! delayed group end type Bank diff --git a/src/constants.F90 b/src/constants.F90 index b93abae2b7..0c6f09cdda 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -12,7 +12,7 @@ module constants ! Revision numbers for binary files integer, parameter :: REVISION_STATEPOINT = 15 - integer, parameter :: REVISION_PARTICLE_RESTART = 2 + integer, parameter :: REVISION_PARTICLE_RESTART = 1 integer, parameter :: REVISION_TRACK = 1 integer, parameter :: REVISION_SUMMARY = 3 diff --git a/src/initialize.F90 b/src/initialize.F90 index d8bbcb0d8c..68426d5686 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -327,8 +327,6 @@ contains c_loc(tmpb(1)%uvw)), coordinates_t, hdf5_err) call h5tinsert_f(hdf5_bank_t, "E", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%E)), H5T_NATIVE_DOUBLE, hdf5_err) - call h5tinsert_f(hdf5_bank_t, "g", h5offsetof(c_loc(tmpb(1)), & - c_loc(tmpb(1)%g)), H5T_NATIVE_INTEGER, hdf5_err) call h5tinsert_f(hdf5_bank_t, "delayed_group", h5offsetof(c_loc(tmpb(1)), & c_loc(tmpb(1)%delayed_group)), H5T_NATIVE_INTEGER, hdf5_err) diff --git a/src/particle_header.F90 b/src/particle_header.F90 index bf820ceb35..c1f02eca24 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -179,10 +179,11 @@ contains ! fission, or simply as a secondary particle. !=============================================================================== - subroutine initialize_from_source(this, src, run_CE) - class(Particle), intent(inout) :: this - type(Bank), intent(in) :: src - logical, intent(in) :: run_CE + subroutine initialize_from_source(this, src, run_CE, energy_bin_avg) + class(Particle), intent(inout) :: this + type(Bank), intent(in) :: src + logical, intent(in) :: run_CE + real(8), allocatable, intent(in) :: energy_bin_avg(:) ! set defaults call this % initialize() @@ -194,12 +195,14 @@ contains this % coord(1) % uvw = src % uvw this % last_xyz = src % xyz this % last_uvw = src % uvw - this % E = src % E - this % last_E = src % E - if (.not. run_CE) then - this % g = src % g - this % last_g = src % g + if (run_CE) then + this % E = src % E + else + this % g = int(src % E) + this % last_g = int(src % E) + this % E = energy_bin_avg(this % g) end if + this % last_E = src % E end subroutine initialize_from_source @@ -229,7 +232,7 @@ contains this % n_secondary = n this % secondary_bank(this % n_secondary) % E = this % E if (.not. run_CE) then - this % secondary_bank(this % n_secondary) % g = this % g + this % secondary_bank(this % n_secondary) % E = real(this % g, 8) end if end subroutine create_secondary diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index e1a280e9fa..d983b3db8a 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -57,7 +57,6 @@ contains call write_dataset(file_id, 'id', p%id) call write_dataset(file_id, 'weight', src%wgt) call write_dataset(file_id, 'energy', src%E) - call write_dataset(file_id, 'energy_group', src%g) call write_dataset(file_id, 'xyz', src%xyz) call write_dataset(file_id, 'uvw', src%uvw) diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index ce296c48e6..6a58540c17 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -255,8 +255,8 @@ contains ! Sample secondary energy distribution for fission reaction and set energy ! in fission bank - bank_array(i) % g = xs % sample_fission_energy(p % g, fission_bank(i) % uvw) - bank_array(i) % E = energy_bin_avg(fission_bank(i) % g) + bank_array(i) % E = & + real(xs % sample_fission_energy(p % g, fission_bank(i) % uvw), 8) end do ! increment number of bank sites diff --git a/src/simulation.F90 b/src/simulation.F90 index 4a419df906..41a28741c3 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -131,7 +131,8 @@ contains integer :: i ! set defaults - call p % initialize_from_source(source_bank(index_source), run_CE) + call p % initialize_from_source(source_bank(index_source), run_CE, & + energy_bin_avg) ! set identifier for particle p % id = work_index(rank) + index_source diff --git a/src/source.F90 b/src/source.F90 index 0a7fa790d5..ad565c95c0 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -192,11 +192,12 @@ contains ! If running in MG, convert site % E to group if (.not. run_CE) then if (site % E <= energy_bins(1)) then - site % g = 1 + site % E = real(1, 8) else if (site % E > energy_bins(energy_groups + 1)) then - site % g = energy_groups + site % E = real(energy_groups, 8) else - site % g = binary_search(energy_bins, energy_groups + 1, site % E) + site % E = real(binary_search(energy_bins, energy_groups + 1, & + site % E), 8) end if end if diff --git a/src/tally.F90 b/src/tally.F90 index e127cf0378..f265bdb274 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1601,7 +1601,7 @@ contains if (t % energyout_matches_groups) then ! determine outgoing energy from fission bank - gout = fission_bank(n_bank - p % n_bank + k) % g + gout = int(fission_bank(n_bank - p % n_bank + k) % E) ! change outgoing energy bin matching_bins(i) = gout diff --git a/src/tracking.F90 b/src/tracking.F90 index 17fc855591..e634112bc6 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -223,7 +223,7 @@ contains if (.not. p % alive) then if (p % n_secondary > 0) then call p % initialize_from_source(p % secondary_bank(p % n_secondary), & - run_CE) + run_CE, energy_bin_avg) p % n_secondary = p % n_secondary - 1 n_event = 0 From ee55476ff025380f6edadc3f1e53d7c49034b4e1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 20:20:25 -0500 Subject: [PATCH 80/84] Aaand environment variables did not match between my machine and travis. Oh travis. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index efdc457a11..acec278ed6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,7 @@ before_script: - git clone --branch=master git://github.com/bhermanmit/nndc_xs nndc_xs - cat nndc_xs/nndc.tar.gza* | tar xzvf - - rm -rf nndc_xs - - export CROSS_SECTIONS=$PWD/nndc/cross_sections.xml + - export OPENMC_CROSS_SECTIONS=$PWD/nndc/cross_sections.xml - cd .. script: From 4212a951d2c379affe82e368ef1f37564ef8e656 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 21:07:51 -0500 Subject: [PATCH 81/84] Updated particle_restart file reversion number in particle_restart.py --- openmc/particle_restart.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/particle_restart.py b/openmc/particle_restart.py index 4aad111325..72bf3ac3de 100644 --- a/openmc/particle_restart.py +++ b/openmc/particle_restart.py @@ -43,11 +43,11 @@ class Particle(object): if 'filetype' not in self._f or self._f[ 'filetype'].value.decode() != 'particle restart': raise IOError('{} is not a particle restart file.'.format(filename)) - if self._f['revision'].value != 2: + if self._f['revision'].value != 1: raise IOError('Particle restart file has a file revision of {} ' 'which is not consistent with the revision this ' 'version of OpenMC expects ({}).'.format( - self._f['revision'].value, 2)) + self._f['revision'].value, 1)) @property def current_batch(self): From 095f3e05103575e0a6139ccdb9ffc338dd147ad5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 21:39:22 -0500 Subject: [PATCH 82/84] Think I fixed the mpi problems --- src/initialize.F90 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index 68426d5686..5b7cc8c063 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -203,15 +203,15 @@ contains integer :: bank_blocks(6) ! Count for each datatype #ifdef MPIF08 - type(MPI_Datatype) :: bank_types(6) + type(MPI_Datatype) :: bank_types(5) type(MPI_Datatype) :: result_types(1) type(MPI_Datatype) :: temp_type #else - integer :: bank_types(6) ! Datatypes + integer :: bank_types(5) ! Datatypes integer :: result_types(1) ! Datatypes integer :: temp_type ! temporary derived type #endif - integer(MPI_ADDRESS_KIND) :: bank_disp(6) ! Displacements + integer(MPI_ADDRESS_KIND) :: bank_disp(5) ! Displacements integer :: result_blocks(1) ! Count for each datatype integer(MPI_ADDRESS_KIND) :: result_disp(1) ! Displacements integer(MPI_ADDRESS_KIND) :: result_base_disp ! Base displacement @@ -245,17 +245,15 @@ contains call MPI_GET_ADDRESS(b % xyz, bank_disp(2), mpi_err) call MPI_GET_ADDRESS(b % uvw, bank_disp(3), mpi_err) call MPI_GET_ADDRESS(b % E, bank_disp(4), mpi_err) - call MPI_GET_ADDRESS(b % g, bank_disp(5), mpi_err) - call MPI_GET_ADDRESS(b % delayed_group, bank_disp(6), mpi_err) + call MPI_GET_ADDRESS(b % delayed_group, bank_disp(5), mpi_err) ! Adjust displacements bank_disp = bank_disp - bank_disp(1) ! Define MPI_BANK for fission sites - bank_blocks = (/ 1, 3, 3, 1, 1, 1 /) - bank_types = (/ MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_REAL8, & - MPI_INTEGER, MPI_INTEGER /) - call MPI_TYPE_CREATE_STRUCT(6, bank_blocks, bank_disp, & + bank_blocks = (/ 1, 3, 3, 1, 1 /) + bank_types = (/ MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_REAL8, MPI_INTEGER /) + call MPI_TYPE_CREATE_STRUCT(5, bank_blocks, bank_disp, & bank_types, MPI_BANK, mpi_err) call MPI_TYPE_COMMIT(MPI_BANK, mpi_err) From 3aa332e8d28452ebb8e8f41289a9222d563b7f68 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 22 Feb 2016 21:43:03 -0500 Subject: [PATCH 83/84] Think I fixed the mpi problems; #2 --- src/initialize.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index 5b7cc8c063..52853f72ff 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -201,7 +201,7 @@ contains subroutine initialize_mpi() - integer :: bank_blocks(6) ! Count for each datatype + integer :: bank_blocks(5) ! Count for each datatype #ifdef MPIF08 type(MPI_Datatype) :: bank_types(5) type(MPI_Datatype) :: result_types(1) From da4de9c4df7216a776849dd581429a95f01e4a28 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 23 Feb 2016 20:43:47 -0500 Subject: [PATCH 84/84] Now check nu_fission data in mgxs_library python api when determining if dataset is fissionable or not. --- openmc/mgxs_library.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index b6dd9f09fe..06b369c68a 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -487,6 +487,8 @@ class XSdata(object): # check we have a numpy list check_type("nu_fission", nu_fission, np.ndarray, expected_iter_type=Real) self._nu_fission = np.copy(nu_fission) + if np.sum(self._nu_fission) > 0.0: + self._fissionable = True def _get_xsdata_xml(self): element = ET.Element("xsdata")