diff --git a/Tallies/TallyMaps/CMakeLists.txt b/Tallies/TallyMaps/CMakeLists.txt index 35383328a..0ac9ee1d0 100644 --- a/Tallies/TallyMaps/CMakeLists.txt +++ b/Tallies/TallyMaps/CMakeLists.txt @@ -1,31 +1,31 @@ # Add Source Files to the global list add_sources(./tallyMap_inter.f90 - ./tallyMap1D_inter.f90 - ./tallyMap1DFactory_func.f90 ./tallyMapFactory_func.f90 - ./tallyMapSlot_class.f90 - ./testMap_class.f90 - ./energyMap_class.f90 - ./spaceMap_class.f90 - ./materialMap_class.f90 - ./homogMatMap_class.f90 ./multiMap_class.f90 - ./weightMap_class.f90 - ./sphericalMap_class.f90 - ./cellMap_class.f90 - ./cylindricalMap_class.f90 - ./collNumMap_class.f90 - # ./matXsMap_class.f90 + ./cylindricalMap_class.f90 + ./Maps1D/tallyMap1D_inter.f90 + ./Maps1D/tallyMap1DFactory_func.f90 + ./Maps1D/testMap_class.f90 + ./Maps1D/energyMap_class.f90 + ./Maps1D/spaceMap_class.f90 + ./Maps1D/materialMap_class.f90 + ./Maps1D/homogMatMap_class.f90 + ./Maps1D/weightMap_class.f90 + ./Maps1D/cellMap_class.f90 + ./Maps1D/radialMap_class.f90 + ./Maps1D/collNumMap_class.f90 + ./Maps1D/directionMap_class.f90 ) -add_unit_tests(./Tests/materialMap_test.f90 - ./Tests/energyMap_test.f90 - ./Tests/weightMap_test.f90 - ./Tests/spaceMap_test.f90 - ./Tests/testMap_test.f90 - ./Tests/multiMap_test.f90 - ./Tests/homogMatMap_test.f90 - ./Tests/sphericalMap_test.f90 - ./Tests/cellMap_test.f90 +add_unit_tests(./Tests/multiMap_test.f90 ./Tests/cylindricalMap_test.f90 - ./Tests/collNumMap_test.f90) + ./Maps1D/Tests/materialMap_test.f90 + ./Maps1D/Tests/energyMap_test.f90 + ./Maps1D/Tests/weightMap_test.f90 + ./Maps1D/Tests/spaceMap_test.f90 + ./Maps1D/Tests/testMap_test.f90 + ./Maps1D/Tests/homogMatMap_test.f90 + ./Maps1D/Tests/radialMap_test.f90 + ./Maps1D/Tests/cellMap_test.f90 + ./Maps1D/Tests/collNumMap_test.f90 + ./Maps1D/Tests/directionMap_test.f90) diff --git a/Tallies/TallyMaps/Tests/cellMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/cellMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/cellMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/cellMap_test.f90 diff --git a/Tallies/TallyMaps/Tests/collNumMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/collNumMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/collNumMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/collNumMap_test.f90 diff --git a/Tallies/TallyMaps/Maps1D/Tests/directionMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/directionMap_test.f90 new file mode 100644 index 000000000..f09c43e9d --- /dev/null +++ b/Tallies/TallyMaps/Maps1D/Tests/directionMap_test.f90 @@ -0,0 +1,155 @@ +module directionMap_test + use numPrecision + use pFUnit_mod + use particle_class, only : particleState + use dictionary_class, only : dictionary + use outputFile_class, only : outputFile + + use directionMap_class, only : directionMap + + implicit none + + +@testCase + type, extends(TestCase) :: test_directionMap + private + type(directionMap) :: map1 + type(directionMap) :: map2 + + contains + procedure :: setUp + procedure :: tearDown + + end type test_directionMap + +contains + + !! + !! Sets up test_directionMap object + !! + subroutine setUp(this) + class(test_directionMap), intent(inout) :: this + type(dictionary) :: tempDict + + ! Build map with yz plane + call tempDict % init(2) + call tempDict % store('plane','yz') + call tempDict % store('N', 4) + + call this % map1 % init(tempDict) + call tempDict % kill() + + ! Build map with default plane + call tempDict % init(3) + call tempDict % store('N', 9) + call tempDict % store('min', 90) + call tempDict % store('max', 180) + + call this % map2 % init(tempDict) + call tempDict % kill() + + end subroutine setUp + + !! + !! Kills test_directionMap objects + !! + subroutine tearDown(this) + class(test_directionMap), intent(inout) :: this + + call this % map1 % kill() + call this % map2 % kill() + + end subroutine tearDown + +!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +!! PROPER TESTS BEGIN HERE +!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> + + !! + !! Test first map + !! +@Test + subroutine testMap1(this) + class(test_directionMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: x = [0.44_defReal, 15.8_defReal, 83.2_defReal, 999.1_defReal] + real(defReal),dimension(4),parameter :: phi = [100.1_defReal, 20.84_defReal, 333.9_defReal, 264.8_defReal]*PI/180.0_defReal + integer(shortInt),dimension(4),parameter :: RES_IDX = [4, 3, 2, 1] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % dir(1) = x + states(:) % dir(2) = cos(phi) + states(:) % dir(3) = sin(phi) + + idx = this % map1 % map(states) + + @assertEqual(RES_IDX, idx) + + end subroutine testMap1 + + !! + !! Test second + !! +@Test + subroutine testMap2(this) + class(test_directionMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: z = [0.44_defReal, 15.8_defReal, 83.2_defReal, 999.1_defReal] + real(defReal),dimension(4),parameter :: phi = [170.1_defReal, 90.84_defReal, 133.9_defReal, 264.8_defReal]*PI/180.0_defReal + integer(shortInt),dimension(4),parameter :: RES_IDX = [9, 1, 5, 0] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % dir(1) = cos(phi) + states(:) % dir(2) = sin(phi) + states(:) % dir(3) = z + + idx = this % map2 % map(states) + + @assertEqual(RES_IDX, idx) + + end subroutine testMap2 + + !! + !! Test bin number retrival + !! +@Test + subroutine testBinNumber(this) + class(test_directionMap), intent(inout) :: this + + ! Test that map is 1D + @assertEqual(4, this % map1 % bins(0),'All bins') + @assertEqual(4, this % map1 % bins(1),'1st dimension') + @assertEqual(0, this % map2 % bins(2),'2nd dimension') + @assertEqual(9, this % map2 % bins(1),'1st dimension') + + ! Get dimensionality + @assertEqual(1, this % map1 % dimensions()) + @assertEqual(1, this % map2 % dimensions()) + + end subroutine testBinNumber + + !! + !! Test correctness of print subroutine + !! Does not check that values are correct, but that call sequence is without errors + !! +@Test + subroutine testPrint(this) + class(test_directionMap), intent(inout) :: this + type(outputFile) :: out + + call out % init('dummyPrinter', fatalErrors = .false.) + + call this % map2 % print(out) + @assertTrue(out % isValid(),'Radial map case') + call out % reset() + + call this % map1 % print(out) + @assertTrue(out % isValid(),'Unstruct map case') + call out % reset() + + end subroutine testPrint + + +end module directionMap_test diff --git a/Tallies/TallyMaps/Tests/energyMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/energyMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/energyMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/energyMap_test.f90 diff --git a/Tallies/TallyMaps/Tests/homogMatMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/homogMatMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/homogMatMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/homogMatMap_test.f90 diff --git a/Tallies/TallyMaps/Tests/materialMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/materialMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/materialMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/materialMap_test.f90 diff --git a/Tallies/TallyMaps/Maps1D/Tests/radialMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/radialMap_test.f90 new file mode 100644 index 000000000..dedd16637 --- /dev/null +++ b/Tallies/TallyMaps/Maps1D/Tests/radialMap_test.f90 @@ -0,0 +1,331 @@ +module radialMap_test + + use numPrecision + use pFUnit_mod + use particle_class, only : particleState + use dictionary_class, only : dictionary + use outputFile_class, only : outputFile + + use radialMap_class, only : radialMap + + implicit none + + +@testCase + type, extends(TestCase) :: test_radialMap + private + type(radialMap) :: map_cyl_linear + type(radialMap) :: map_cyl_equivol + type(radialMap) :: map_cyl_unstruct + type(radialMap) :: map_sph_from_zero + type(radialMap) :: map_sph_from_min + type(radialMap) :: map_sph_equivol + + contains + procedure :: setUp + procedure :: tearDown + end type test_radialMap + +contains + + !! + !! Sets up test_radialMap object we can use in a number of tests + !! + subroutine setUp(this) + class(test_radialMap), intent(inout) :: this + type(dictionary) :: tempDict + + ! Build cylindrical map with linear bins + call tempDict % init(4) + call tempDict % store('axis','x') + call tempDict % store('grid','lin') + call tempDict % store('max', 8.0_defReal) + call tempDict % store('N', 4) + + call this % map_cyl_linear % init(tempDict) + call tempDict % kill() + + ! Build cylindrical map with different orientation & minimum radius + call tempDict % init(5) + call tempDict % store('axis','z') + call tempDict % store('grid','equivolume') + call tempDict % store('min', 2.0_defReal) + call tempDict % store('max', 10.0_defReal) + call tempDict % store('N', 5) + + call this % map_cyl_equivol % init(tempDict) + call tempDict % kill() + + ! Build cylindrical map with different origin & unstruct bins + call tempDict % init(4) + call tempDict % store('axis','z') + call tempDict % store('origin',[ONE, ONE, ZERO]) + call tempDict % store('grid','unstruct') + call tempDict % store('bins', [1.5_defReal, 2.3_defReal, 3.8_defReal, 8.0_defReal]) + + call this % map_cyl_unstruct % init(tempDict) + call tempDict % kill() + + ! Build spherical map with default origin & minimum radius + call tempDict % init(3) + call tempDict % store('grid','lin') + call tempDict % store('max', 10.0_defReal) + call tempDict % store('N', 20) + + call this % map_sph_from_zero % init(tempDict) + call tempDict % kill() + + ! Build spherical map with diffrent origin & minimum radius + call tempDict % init(5) + call tempDict % store('origin', [ONE, ONE, ONE]) + call tempDict % store('grid', 'lin') + call tempDict % store('min', 5.0_defReal) + call tempDict % store('max', 10.0_defReal) + call tempDict % store('N', 5) + + call this % map_sph_from_min % init(tempDict) + call tempDict % kill() + + ! Build spherical map with equivolume bins + call tempDict % init(4) + call tempDict % store('grid', 'equivolume') + call tempDict % store('min', 2.0_defReal) + call tempDict % store('max', 20.0_defReal) + call tempDict % store('N', 8) + + call this % map_sph_equivol % init(tempDict) + call tempDict % kill() + + end subroutine setUp + + !! + !! Kills test_radialMap object we can use in a number of tests + !! + subroutine tearDown(this) + class(test_radialMap), intent(inout) :: this + + call this % map_cyl_linear % kill() + call this % map_cyl_equivol % kill() + call this % map_cyl_unstruct % kill() + call this % map_sph_from_zero % kill() + call this % map_sph_from_min % kill() + call this % map_sph_equivol % kill() + + end subroutine tearDown + +!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +!! PROPER TESTS BEGIN HERE +!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> + + !! + !! Test cylindrical map with different orientation & minimum radius + !! +@Test + subroutine testCylLinear(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [0.4_defReal, 5.38_defReal, 7.9_defReal, 9.1_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.0_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4),parameter :: z = [1.0_defReal, 39.8_defReal, 0.05_defReal, -12.2_defReal] + integer(shortInt),dimension(4),parameter :: RES_IDX = [1, 3, 4, 0] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = z + states(:) % r(2) = r * cos(phi) + states(:) % r(3) = r * sin(phi) + + idx = this % map_cyl_linear % map(states) + + @assertEqual(RES_IDX, idx) + + end subroutine testCylLinear + + !! + !! Test cylindrical map with equivolume bins + !! +@Test + subroutine testCylEquivol(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [1.82_defReal, 4.68_defReal, 7.9_defReal, 9.01_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.0_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4), parameter :: z = [1.0_defReal, 39.8_defReal, 0.05_defReal, -12.2_defReal] + integer(shortInt),dimension(4),parameter :: RES_IDX = [0, 1, 4, 5] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = r * cos(phi) + states(:) % r(2) = r * sin(phi) + states(:) % r(3) = z + + idx = this % map_cyl_equivol % map(states) + @assertEqual(RES_IDX, idx) + + end subroutine testCylEquivol + + !! + !! Test cylindrical map with different origin & unstruct bins + !! +@Test + subroutine testCylUnstruct(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [1.52_defReal, 5.5_defReal, 8.9_defReal, 2.88_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.0_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4), parameter :: z = [1.0_defReal, 39.8_defReal, 0.05_defReal, -12.2_defReal] + integer(shortInt),dimension(4),parameter :: RES_IDX = [1, 3, 0, 2] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = r * cos(phi) + states(:) % r(2) = r * sin(phi) + states(:) % r(3) = z + + ! Shift the origin + states(:) % r(1) = states(:) % r(1) + ONE + states(:) % r(2) = states(:) % r(2) + ONE + states(:) % r(3) = states(:) % r(3) + + idx = this % map_cyl_unstruct % map(states) + @assertEqual(RES_IDX, idx) + + end subroutine testCylUnstruct + + !! + !! Test spherical map with default-initialised grid + !! +@Test + subroutine testSphFromOrigin(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [0.4_defReal, 3.58_defReal, 8.9_defReal, 11.0_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] + integer(shortInt),dimension(4),parameter :: RES_IDX = [1, 8, 18, 0] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = r * cos(phi) * sin(tht) + states(:) % r(2) = r * sin(phi) * sin(tht) + states(:) % r(3) = r * cos(tht) + + idx = this % map_sph_from_zero % map(states) + @assertEqual(RES_IDX, idx) + + end subroutine testSphFromOrigin + + !! + !! Test spherical map with grid with shifted origin & minimum radius + !! +@Test + subroutine testSphFromMin(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [1.5_defReal, 5.5_defReal, 8.9_defReal, 11.0_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] + integer(shortInt),dimension(4),parameter :: RES_IDX = [0, 1, 4, 0] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = r * cos(phi) * sin(tht) + states(:) % r(2) = r * sin(phi) * sin(tht) + states(:) % r(3) = r * cos(tht) + + ! Shift the origin + states(:) % r(1) = states(:) % r(1) + ONE + states(:) % r(2) = states(:) % r(2) + ONE + states(:) % r(3) = states(:) % r(3) + ONE + + idx = this % map_sph_from_min % map(states) + @assertEqual(RES_IDX, idx) + + end subroutine testSphFromMin + + !! + !! Test spherical map with grid with equivolume bins + !! +@Test + subroutine testSphEquivol(this) + class(test_radialMap), intent(inout) :: this + real(defReal),dimension(4),parameter :: r = [1.5_defReal, 5.5_defReal, 18.9_defReal, 11.0_defReal] + real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] + real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] + integer(shortInt),dimension(4),parameter :: RES_IDX = [0, 1, 7, 2] + integer(shortInt),dimension(4) :: idx + type(particleState),dimension(4) :: states + + ! Initialise states + states(:) % r(1) = r * cos(phi) * sin(tht) + states(:) % r(2) = r * sin(phi) * sin(tht) + states(:) % r(3) = r * cos(tht) + + idx = this % map_sph_equivol % map(states) + @assertEqual(RES_IDX, idx) + + end subroutine testSphEquivol + + !! + !! Test bin number retrival + !! +@Test + subroutine testBinNumber(this) + class(test_radialMap), intent(inout) :: this + + ! Test that map is 1D + @assertEqual(4, this % map_cyl_linear % bins(0),'All bins') + @assertEqual(4, this % map_cyl_linear % bins(1),'1st dimension') + @assertEqual(0, this % map_cyl_linear % bins(2),'2nd dimension') + @assertEqual(3, this % map_cyl_unstruct % bins(1),'1st dimension') + @assertEqual(5, this % map_cyl_equivol % bins(1),'1st dimension') + @assertEqual(20, this % map_sph_from_zero % bins(1),'1st Dimension') + @assertEqual(20, this % map_sph_from_zero % bins(0),'All bins') + @assertEqual(0, this % map_sph_from_min % bins(2),'Invalid Dimension') + + ! Get dimensionality + @assertEqual(1, this % map_cyl_linear % dimensions()) + @assertEqual(1, this % map_cyl_unstruct % dimensions()) + @assertEqual(1, this % map_sph_from_min % dimensions()) + + end subroutine testBinNumber + + !! + !! Test correctness of print subroutine + !! Does not check that values are correct, but that call sequence is without errors + !! +@Test + subroutine testPrint(this) + class(test_radialMap), intent(inout) :: this + type(outputFile) :: out + + call out % init('dummyPrinter', fatalErrors = .false.) + + call this % map_cyl_linear % print(out) + @assertTrue(out % isValid(),'Linear map case (cylindrical)') + call out % reset() + + call this % map_cyl_equivol % print(out) + @assertTrue(out % isValid(),'Equivolume map case (cylindrical)') + call out % reset() + + call this % map_cyl_unstruct % print(out) + @assertTrue(out % isValid(),'Unstruct map case (cylindrical)') + call out % reset() + + call this % map_sph_from_zero % print(out) + @assertTrue(out % isValid(),'Linear map case from zero (spherical)') + call out % reset() + + call this % map_sph_from_min % print(out) + @assertTrue(out % isValid(),'Linear map case from minimum radius (spherical)') + call out % reset() + + call this % map_sph_equivol % print(out) + @assertTrue(out % isValid(),'Equivolume map case (spherical)') + call out % reset() + + end subroutine testPrint + + +end module radialMap_test diff --git a/Tallies/TallyMaps/Tests/spaceMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/spaceMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/spaceMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/spaceMap_test.f90 diff --git a/Tallies/TallyMaps/Tests/testMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/testMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/testMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/testMap_test.f90 diff --git a/Tallies/TallyMaps/Tests/weightMap_test.f90 b/Tallies/TallyMaps/Maps1D/Tests/weightMap_test.f90 similarity index 100% rename from Tallies/TallyMaps/Tests/weightMap_test.f90 rename to Tallies/TallyMaps/Maps1D/Tests/weightMap_test.f90 diff --git a/Tallies/TallyMaps/cellMap_class.f90 b/Tallies/TallyMaps/Maps1D/cellMap_class.f90 similarity index 99% rename from Tallies/TallyMaps/cellMap_class.f90 rename to Tallies/TallyMaps/Maps1D/cellMap_class.f90 index 293f5a8e7..d8934bdff 100644 --- a/Tallies/TallyMaps/cellMap_class.f90 +++ b/Tallies/TallyMaps/Maps1D/cellMap_class.f90 @@ -7,6 +7,7 @@ module cellMap_class use particle_class, only : particleState use outputFile_class, only : outputFile use tallyMap1D_inter, only : tallyMap1D, kill_super => kill + ! Geometry use geometryStd_class, only : geometryStd, geometryStd_CptrCast use geometry_inter, only : geometry diff --git a/Tallies/TallyMaps/collNumMap_class.f90 b/Tallies/TallyMaps/Maps1D/collNumMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/collNumMap_class.f90 rename to Tallies/TallyMaps/Maps1D/collNumMap_class.f90 diff --git a/Tallies/TallyMaps/Maps1D/directionMap_class.f90 b/Tallies/TallyMaps/Maps1D/directionMap_class.f90 new file mode 100644 index 000000000..a1ce82ed9 --- /dev/null +++ b/Tallies/TallyMaps/Maps1D/directionMap_class.f90 @@ -0,0 +1,222 @@ +module directionMap_class + + use numPrecision + use universalVariables, only : valueOutsideArray, X_AXIS, Y_AXIS, Z_AXIS + use genericProcedures, only : fatalError, dotProduct, numToChar + use dictionary_class, only : dictionary + use grid_class, only : grid + use particle_class, only : particleState + use outputFile_class, only : outputFile + use tallyMap1D_inter, only : tallyMap1D, kill_super => kill + + implicit none + private + + !! + !! Maps the particle direction in linear bins in the range -180 -> 180 degrees (default) + !! or boundaries defined by the user + !! + !! The angle is calculated using as a reference the positive direction of the + !! axis x in the 'xy' and 'xz' cases, or y in the 'yz' case + !! + !! NOTE: the map is built in radians for convenience when using the function atan2, but + !! the user input and the results are in degrees for easy of interpretation + !! + !! Interface: + !! tallyMap1D interface + !! + !! NOTE: + !! Behaviour of points exactly at the boundary of bins is undefined. + !! Particle can end-up in either of the two + !! + !! Sample Dictionary Input: + !! directionMap { + !! type directionMap; + !! #plane xz;# // Optional. Default xy + !! N 10; + !! #min 60;# // Optional. Default -180 + !! #max 120;# // Optional. Default 180 + !! } + !! + type, public, extends (tallyMap1D) :: directionMap + private + type(grid) :: bounds + integer(shortInt) :: N = 0 + integer(shortInt) :: DIM1 = 0 + integer(shortInt) :: DIM2 = 0 + + contains + ! Superclass + procedure :: init + procedure :: bins + procedure :: getAxisName + procedure :: map + procedure :: print + procedure :: kill + + end type directionMap + +contains + + !! + !! Initialise tallyMap from a dictionary + !! + !! See tallyMap for specification. + !! + subroutine init(self, dict) + class(directionMap), intent(inout) :: self + class(dictionary), intent(in) :: dict + character(nameLen) :: type + real(defReal) :: min, max + character(100), parameter :: Here = 'init (directionMap_class.f90)' + + ! Check orientation of the cylinder + if (dict % isPresent('plane')) then + call dict % get(type, 'plane') + else + type = 'xy' + end if + + select case(type) + case('yz') + self % DIM1 = Y_AXIS + self % DIM2 = Z_AXIS + + case('xz') + self % DIM1 = X_AXIS + self % DIM2 = Z_AXIS + + case('xy') + self % DIM1 = X_AXIS + self % DIM2 = Y_AXIS + + case default + call fatalError(Here, 'Keyword orientation must be xy, yz or xz. It is: '//type) + + end select + + ! Get grid details + call dict % get(self % N, 'N') + call dict % getOrDefault(min, 'min', -180.0_defReal) + call dict % getOrDefault(max, 'max', 180.0_defReal) + + ! Check boundaries + if (min < -180.0_defReal .or. min > 180.0_defReal) then + call fatalError(Here, 'Minimum angle must be between -180 and 180 degrees. It is: '//type) + end if + + if (max < -180.0_defReal .or. max > 180.0_defReal) then + call fatalError(Here, 'Maximum angle must be between -180 and 180 degrees. It is: '//type) + end if + + ! Build map in radians + min = min*PI/180.0_defReal + max = max*PI/180.0_defReal + call self % bounds % init(min, max, self % N, 'lin') + + end subroutine init + + !! + !! Return total number of bins in this division along Dimension D + !! + !! See tallyMap for specification. + !! + elemental function bins(self, D) result(N) + class(directionMap), intent(in) :: self + integer(shortInt), intent(in) :: D + integer(shortInt) :: N + + if (D == 1 .or. D == 0) then + N = self % N + else + N = 0 + end if + + end function bins + + !! + !! Return string that describes variable used to divide event space + !! + !! See tallyMap for specification + !! + function getAxisName(self) result(name) + class(directionMap), intent(in) :: self + character(nameLen) :: name + + name = 'directionMap' + + end function getAxisName + + !! + !! Map particle to a single bin. Return 0 for particle out of division + !! + !! See tallyMap for specification. + !! + elemental function map(self, state) result(idx) + class(directionMap), intent(in) :: self + class(particleState), intent(in) :: state + integer(shortInt) :: idx + real(defReal) :: x, y, theta + + ! Map the angle + x = state % dir(self % DIM1) + y = state % dir(self % DIM2) + + ! Returns angle in radians in the range -PI to PI + theta = atan2(y,x) + + ! Search in the grid return 0 if index is out-of-bounds + idx = self % bounds % search(theta) + + ! Should never happen + if (idx == valueOutsideArray) then + idx = 0 + return + end if + + end function map + + !! + !! Add information about division axis to the output file + !! + !! See tallyMap for specification. + !! + subroutine print(self,out) + class(directionMap), intent(in) :: self + class(outputFile), intent(inout) :: out + character(nameLen) :: name + integer(shortInt) :: i + + ! Print grid bins + name = trim(self % getAxisName()) //'AngularBounds' + + call out % startArray(name, [2,self % N]) + + do i = 1, self % N + ! Print lower bin boundary in degrees + call out % addValue(self % bounds % bin(i)/PI*180.0_defReal) + + ! Print upper bin boundary in degrees + call out % addValue(self % bounds % bin(i + 1)/PI*180.0_defReal) + end do + + call out % endArray() + + end subroutine print + + !! + !! Return to uninitialised state + !! + elemental subroutine kill(self) + class(directionMap), intent(inout) :: self + + call kill_super(self) + + call self % bounds % kill() + self % N = 0 + self % DIM1 = 0 + self % DIM2 = 0 + + end subroutine kill + +end module directionMap_class diff --git a/Tallies/TallyMaps/energyMap_class.f90 b/Tallies/TallyMaps/Maps1D/energyMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/energyMap_class.f90 rename to Tallies/TallyMaps/Maps1D/energyMap_class.f90 diff --git a/Tallies/TallyMaps/homogMatMap_class.f90 b/Tallies/TallyMaps/Maps1D/homogMatMap_class.f90 similarity index 98% rename from Tallies/TallyMaps/homogMatMap_class.f90 rename to Tallies/TallyMaps/Maps1D/homogMatMap_class.f90 index d6eb97fa4..b0476d8f0 100644 --- a/Tallies/TallyMaps/homogMatMap_class.f90 +++ b/Tallies/TallyMaps/Maps1D/homogMatMap_class.f90 @@ -193,7 +193,7 @@ elemental function map(self,state) result(idx) integer(shortInt) :: idx, isThere do idx = 1,size(self % binMap) - isThere = self % binMap(idx) % getOrDefault( state % matIdx, self % default) + isThere = self % binMap(idx) % getOrDefault(state % matIdx, self % default) if (isThere == 1) return end do diff --git a/Tallies/TallyMaps/materialMap_class.f90 b/Tallies/TallyMaps/Maps1D/materialMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/materialMap_class.f90 rename to Tallies/TallyMaps/Maps1D/materialMap_class.f90 diff --git a/Tallies/TallyMaps/Maps1D/radialMap_class.f90 b/Tallies/TallyMaps/Maps1D/radialMap_class.f90 new file mode 100644 index 000000000..5477f67bb --- /dev/null +++ b/Tallies/TallyMaps/Maps1D/radialMap_class.f90 @@ -0,0 +1,269 @@ +module radialMap_class + + use numPrecision + use universalVariables, only : valueOutsideArray, X_AXIS, Y_AXIS, Z_AXIS + use genericProcedures, only : fatalError, dotProduct, numToChar + use dictionary_class, only : dictionary + use grid_class, only : grid + use particle_class, only : particleState + use outputFile_class, only : outputFile + use tallyMap1D_inter, only : tallyMap1D, kill_super => kill + + implicit none + private + + !! + !! Divides space into a radial mesh in cylindrical or spherical co-ordinates + !! + !! Interface: + !! tallyMap1D interface + !! + !! NOTE: + !! Behaviour of points exactly at the boundary of bins is undefined. + !! particle can end-up in either of the two + !! + !! Sample Dictionary Input: + !! radialMap { + !! type radialMap; + !! axis x; // Optional. Default is 'xyz' (spherical map) + !! #origin (1.0 0.0 0.0);# // Optional. Default (0.0 0.0 0.0) + !! grid lin; + !! #min 2.0;# // Optional. Default 0.0 + !! max 10.0; + !! N 10; + !! } + !! + type, public, extends (tallyMap1D) :: radialMap + private + integer(shortInt), dimension(:), allocatable :: axis + real(defReal), dimension(3) :: origin + type(grid) :: bounds + integer(shortInt) :: N = 0 + + contains + ! Superclass + procedure :: init + procedure :: bins + procedure :: getAxisName + procedure :: map + procedure :: print + procedure :: kill + + end type radialMap + +contains + + !! + !! Initialise tallyMap from a dictionary + !! + !! See tallyMap for specification. + !! + subroutine init(self, dict) + class(radialMap), intent(inout) :: self + class(dictionary), intent(in) :: dict + real(defReal), dimension(:), allocatable :: temp, grid + character(nameLen) :: type + real(defReal) :: min, max, vol, exp + integer(shortInt) :: i + logical(defBool) :: spherical + character(100), parameter :: Here = 'init (radialMap_class.f90)' + + ! Check if the map is cylindrical or spherical, and orientation of the cylinder + call dict % getOrDefault(type, 'axis', 'xyz') + spherical = .false. + + select case(type) + case('x') + allocate(self % axis(2)) + self % axis = [Y_AXIS, Z_AXIS] + + case('y') + allocate(self % axis(2)) + self % axis = [X_AXIS, Z_AXIS] + + case('z') + allocate(self % axis(2)) + self % axis = [X_AXIS, Y_AXIS] + + case('xyz') + allocate(self % axis(3)) + self % axis = [X_AXIS, Y_AXIS, Z_AXIS] + spherical = .true. + + case default + call fatalError(Here, 'Keyword orientation must be x, y, z or xyz for spherical. It is: '//type) + + end select + + ! Check & load origin + call dict % getOrDefault(temp, 'origin', [ZERO, ZERO, ZERO]) + + if (size(temp) /= 3) then + call fatalError(Here, 'Expected 3 values for origin. Got: ' // numToChar(size(temp))) + end if + + self % origin = temp + + ! Load radial grid information + if (.not. dict % isPresent('grid')) call fatalError(Here, 'Keyword grid must be present') + call dict % get(type, 'grid') + + ! Check type of radial grid bins + select case(type) + + case('lin') + + call dict % getOrDefault(min, 'min', ZERO) + call dict % get(max, 'max') + call dict % get(self % N, 'N') + + ! Check that minimum radius is ok + if (min < ZERO) then + call fatalError(Here, 'Minumum radius must be +ve. It is: '//numToChar(min)) + end if + + ! Build grid + call self % bounds % init(min, max, self % N, type) + + case('unstruct') + + call dict % get(grid,'bins') + + ! Initialise + self % N = size(grid) - 1 + call self % bounds % init(grid) + + case('equivolume') + + call dict % getOrDefault(min, 'min', ZERO) + call dict % get(max, 'max') + call dict % get(self % N, 'N') + + ! Check that minimum radius is OK + if (min < ZERO) then + call fatalError(Here, 'Minumum radius must be +ve. It is: '//numToChar(min)) + end if + + ! Get exponent for spherical or cylindrical mesh + if (spherical) then + exp = 3.0_defReal + else + exp = 2.0_defReal + end if + + ! Allocate grid and initialise grid boundaries + allocate(grid(self % N + 1)) + grid(1) = min + grid(self % N + 1) = max + + ! Calculate volume + vol = (max**exp - min**exp)/self % N + + ! Calculate grid boundaries + do i = 2,self % N + grid(i) = (vol + grid(i-1)**exp)**(ONE/exp) + end do + + call self % bounds % init(grid) + + case default + call fatalError(Here, "'grid' can take only values of: lin, unstruct, equivolume") + + end select + + end subroutine init + + !! + !! Return total number of bins in this division along dimension D + !! + !! See tallyMap for specification. + !! + elemental function bins(self, D) result(N) + class(radialMap), intent(in) :: self + integer(shortInt), intent(in) :: D + integer(shortInt) :: N + + if (D == 1 .or. D == 0) then + N = self % N + else + N = 0 + end if + + end function bins + + !! + !! Return string that describes variable used to divide event space + !! + !! See tallyMap for specification + !! + function getAxisName(self) result(name) + class(radialMap), intent(in) :: self + character(nameLen) :: name + + name = 'radialMap' + + end function getAxisName + + !! + !! Map particle to a single bin. Return 0 for particle out of division + !! + !! See tallyMap for specification. + !! + elemental function map(self, state) result(idx) + class(radialMap), intent(in) :: self + class(particleState), intent(in) :: state + integer(shortInt) :: idx + real(defReal) :: r + + ! Calculate the distance from the origin + r = norm2(state % r(self % axis) - self % origin(self % axis)) + + ! Search and return 0 if r is out-of-bounds + idx = self % bounds % search(r) + if (idx == valueOutsideArray) idx = 0 + + end function map + + !! + !! Add information about division axis to the output file + !! + !! See tallyMap for specification. + !! + subroutine print(self,out) + class(radialMap), intent(in) :: self + class(outputFile), intent(inout) :: out + character(nameLen) :: name + integer(shortInt) :: i + + ! Name the array + name = trim(self % getAxisName()) //'RadialBounds' + + call out % startArray(name, [2,self % N]) + do i = 1, self % N + ! Print lower bin boundary + call out % addValue(self % bounds % bin(i)) + + ! Print upper bin boundar + call out % addValue(self % bounds % bin(i + 1)) + + end do + call out % endArray() + + end subroutine print + + !! + !! Return to uninitialised state + !! + elemental subroutine kill(self) + class(radialMap), intent(inout) :: self + + call kill_super(self) + + call self % bounds % kill() + self % origin = ZERO + self % axis = 0 + self % N = 0 + + end subroutine kill + +end module radialMap_class diff --git a/Tallies/TallyMaps/spaceMap_class.f90 b/Tallies/TallyMaps/Maps1D/spaceMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/spaceMap_class.f90 rename to Tallies/TallyMaps/Maps1D/spaceMap_class.f90 diff --git a/Tallies/TallyMaps/tallyMap1DFactory_func.f90 b/Tallies/TallyMaps/Maps1D/tallyMap1DFactory_func.f90 similarity index 80% rename from Tallies/TallyMaps/tallyMap1DFactory_func.f90 rename to Tallies/TallyMaps/Maps1D/tallyMap1DFactory_func.f90 index aab438ea3..c64ae1209 100644 --- a/Tallies/TallyMaps/tallyMap1DFactory_func.f90 +++ b/Tallies/TallyMaps/Maps1D/tallyMap1DFactory_func.f90 @@ -25,15 +25,16 @@ module tallyMap1DFactory_func use tallyMap1D_inter, only : tallyMap1D ! TallyMap implementations - use energyMap_class, only : energyMap - use spaceMap_class, only : spaceMap - use materialMap_class, only : materialMap - use homogMatMap_class, only : homogMatMap - use weightMap_class, only : weightMap - use cellMap_class, only : cellMap - use testMap_class, only : testMap - use collNumMap_class, only : collNumMap -! use matXsMap_class, only : matXsMap + use energyMap_class, only : energyMap + use spaceMap_class, only : spaceMap + use materialMap_class, only : materialMap + use homogMatMap_class, only : homogMatMap + use weightMap_class, only : weightMap + use cellMap_class, only : cellMap + use testMap_class, only : testMap + use collNumMap_class, only : collNumMap + use radialMap_class, only : radialMap + use directionMap_class, only : directionMap implicit none private @@ -45,14 +46,16 @@ module tallyMap1DFactory_func ! It is printed if type was unrecognised ! NOTE: ! For now it is necessary to adjust trailing blanks so all enteries have the same length - character(nameLen),dimension(*),parameter, public :: AVALIBLE_tallyMaps1D = [ 'energyMap ',& - 'spaceMap ',& - 'materialMap',& - 'homogMatMap',& - 'weightMap ',& - 'cellMap ',& - 'testMap ',& - 'collNumMap '] + character(nameLen),dimension(*),parameter, public :: AVALIBLE_tallyMaps1D = [ 'energyMap ',& + 'spaceMap ',& + 'materialMap ',& + 'homogMatMap ',& + 'weightMap ',& + 'cellMap ',& + 'collNumMap ',& + 'radialMap ',& + 'directionMap',& + 'testMap '] contains @@ -100,12 +103,18 @@ subroutine new_tallyMap1D(new, dict) case('cellMap') allocate(cellMap :: new) - case('testMap') - allocate(testMap :: new) - case('collNumMap') allocate(collNumMap :: new) + case('radialMap') + allocate(radialMap :: new) + + case('directionMap') + allocate(directionMap :: new) + + case('testMap') + allocate(testMap :: new) + case default print *, AVALIBLE_tallyMaps1D call fatalError(Here,'Unrecognised type of tallyMap1D : ' // trim(type)) diff --git a/Tallies/TallyMaps/tallyMap1D_inter.f90 b/Tallies/TallyMaps/Maps1D/tallyMap1D_inter.f90 similarity index 100% rename from Tallies/TallyMaps/tallyMap1D_inter.f90 rename to Tallies/TallyMaps/Maps1D/tallyMap1D_inter.f90 diff --git a/Tallies/TallyMaps/testMap_class.f90 b/Tallies/TallyMaps/Maps1D/testMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/testMap_class.f90 rename to Tallies/TallyMaps/Maps1D/testMap_class.f90 diff --git a/Tallies/TallyMaps/weightMap_class.f90 b/Tallies/TallyMaps/Maps1D/weightMap_class.f90 similarity index 100% rename from Tallies/TallyMaps/weightMap_class.f90 rename to Tallies/TallyMaps/Maps1D/weightMap_class.f90 diff --git a/Tallies/TallyMaps/Tests/cylindricalMap_test.f90 b/Tallies/TallyMaps/Tests/cylindricalMap_test.f90 index 2de328219..d73ec4dd4 100644 --- a/Tallies/TallyMaps/Tests/cylindricalMap_test.f90 +++ b/Tallies/TallyMaps/Tests/cylindricalMap_test.f90 @@ -44,7 +44,7 @@ subroutine setUp(this) ! Build map with different origin & unstruct bins call tempDict % init(3) - call tempDict % store('origin',[ONE, ONE]) + call tempDict % store('origin',[ONE, ONE, TWO]) call tempDict % store('rGrid','unstruct') call tempDict % store('bins', [1.5_defReal, 2.3_defReal, 3.8_defReal, 8.0_defReal]) @@ -179,7 +179,7 @@ end subroutine testBinNumber !! !! Test correctness of print subroutine - !! Does not checks that values are correct, but that calls sequance is without errors + !! Does not check that values are correct, but that call sequence is without errors !! @Test subroutine testPrint(this) diff --git a/Tallies/TallyMaps/Tests/sphericalMap_test.f90 b/Tallies/TallyMaps/Tests/sphericalMap_test.f90 deleted file mode 100644 index 22daeaa5a..000000000 --- a/Tallies/TallyMaps/Tests/sphericalMap_test.f90 +++ /dev/null @@ -1,236 +0,0 @@ -module sphericalMap_test - use numPrecision - use pFUnit_mod - use particle_class, only : particleState - use dictionary_class, only : dictionary - use outputFile_class, only : outputFile - - use sphericalMap_class, only : sphericalMap - - implicit none - - -@testCase - type, extends(TestCase) :: test_sphericalMap - private - type(sphericalMap) :: map_lin_from_zero - type(sphericalMap) :: map_lin_from_min - type(sphericalMap) :: map_unstruct - type(sphericalMap) :: map_equivol - - contains - procedure :: setUp - procedure :: tearDown - end type test_sphericalMap - -contains - - !! - !! Sets up test_sphericalMap object we can use in a number of tests - !! - subroutine setUp(this) - class(test_sphericalMap), intent(inout) :: this - type(dictionary) :: tempDict - - ! Build map with default origin & minimum radius - call tempDict % init(4) - call tempDict % store('grid','lin') - call tempDict % store('Rmax', 10.0_defReal) - call tempDict % store('N', 20) - - call this % map_lin_from_zero % init(tempDict) - call tempDict % kill() - - ! Build map with diffrent origin & minimum radius - call tempDict % init(5) - call tempDict % store('origin', [ONE, ONE, ONE]) - call tempDict % store('grid', 'lin') - call tempDict % store('Rmin', 5.0_defReal) - call tempDict % store('Rmax', 10.0_defReal) - call tempDict % store('N', 5) - - call this % map_lin_from_min % init(tempDict) - call tempDict % kill() - - ! Build map with unstruct bins - call tempDict % init(2) - call tempDict % store('grid', 'unstruct') - call tempDict % store('bins', [4.0_defReal, 5.8_defReal, 7.3_defReal, 10.5_defReal, 15.0_defReal]) - - call this % map_unstruct % init(tempDict) - call tempDict % kill() - - ! Build map with equivolume bins - call tempDict % init(4) - call tempDict % store('grid', 'equivolume') - call tempDict % store('Rmin', 2.0_defReal) - call tempDict % store('Rmax', 20.0_defReal) - call tempDict % store('N', 8) - - call this % map_equivol % init(tempDict) - call tempDict % kill() - - end subroutine setUp - - !! - !! Kills test_sphericalMap object we can use in a number of tests - !! - subroutine tearDown(this) - class(test_sphericalMap), intent(inout) :: this - - call this % map_lin_from_zero % kill() - call this % map_lin_from_min % kill() - call this % map_unstruct % kill() - call this % map_equivol % kill() - - end subroutine tearDown - -!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> -!! PROPER TESTS BEGIN HERE -!!<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> - - !! - !! Test default-initialised grid - !! -@Test - subroutine testFromOrigin(this) - class(test_sphericalMap), intent(inout) :: this - real(defReal),dimension(4),parameter :: r = [0.4_defReal, 3.58_defReal, 8.9_defReal, 11.0_defReal] - real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] - real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] - integer(shortInt),dimension(4),parameter :: RES_IDX = [1, 8, 18, 0] - integer(shortInt),dimension(4) :: idx - type(particleState),dimension(4) :: states - - ! Initialise states - states(:) % r(1) = r * cos(phi) * sin(tht) - states(:) % r(2) = r * sin(phi) * sin(tht) - states(:) % r(3) = r * cos(tht) - - idx = this % map_lin_from_zero % map(states) - @assertEqual(RES_IDX, idx) - - end subroutine testFromOrigin - - !! - !! Test grid with shifted origin & minimum radius - !! -@Test - subroutine testFromMin(this) - class(test_sphericalMap), intent(inout) :: this - real(defReal),dimension(4),parameter :: r = [1.5_defReal, 5.5_defReal, 8.9_defReal, 11.0_defReal] - real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] - real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] - integer(shortInt),dimension(4),parameter :: RES_IDX = [0, 1, 4, 0] - integer(shortInt),dimension(4) :: idx - type(particleState),dimension(4) :: states - - ! Initialise states - states(:) % r(1) = r * cos(phi) * sin(tht) - states(:) % r(2) = r * sin(phi) * sin(tht) - states(:) % r(3) = r * cos(tht) - - ! Shift the origin - states(:) % r(1) = states(:) % r(1) + ONE - states(:) % r(2) = states(:) % r(2) + ONE - states(:) % r(3) = states(:) % r(3) + ONE - - idx = this % map_lin_from_min % map(states) - @assertEqual(RES_IDX, idx) - - end subroutine testFromMin - - !! - !! Test grid with unstruct bins - !! -@Test - subroutine testUnstruct(this) - class(test_sphericalMap), intent(inout) :: this - real(defReal),dimension(4),parameter :: r = [4.5_defReal, 15.5_defReal, 8.9_defReal, 11.0_defReal] - real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] - real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] - integer(shortInt),dimension(4),parameter :: RES_IDX = [1, 0, 3, 4] - integer(shortInt),dimension(4) :: idx - type(particleState),dimension(4) :: states - - ! Initialise states - states(:) % r(1) = r * cos(phi) * sin(tht) - states(:) % r(2) = r * sin(phi) * sin(tht) - states(:) % r(3) = r * cos(tht) - - idx = this % map_unstruct % map(states) - @assertEqual(RES_IDX, idx) - - end subroutine testUnstruct - - !! - !! Test grid with equivolume bins - !! -@Test - subroutine testEquiVol(this) - class(test_sphericalMap), intent(inout) :: this - real(defReal),dimension(4),parameter :: r = [1.5_defReal, 5.5_defReal, 18.9_defReal, 11.0_defReal] - real(defReal), dimension(4),parameter :: phi = [1.4_defReal, 3.98_defReal, 0.5_defReal, PI/2] - real(defReal), dimension(4), parameter :: tht = [ZERO, PI/2, PI/4, -PI/2] - integer(shortInt),dimension(4),parameter :: RES_IDX = [0, 1, 7, 2] - integer(shortInt),dimension(4) :: idx - type(particleState),dimension(4) :: states - - ! Initialise states - states(:) % r(1) = r * cos(phi) * sin(tht) - states(:) % r(2) = r * sin(phi) * sin(tht) - states(:) % r(3) = r * cos(tht) - - idx = this % map_equivol % map(states) - @assertEqual(RES_IDX, idx) - - end subroutine testEquiVol - - !! - !! Test bin number retrival - !! -@Test - subroutine testBinNumber(this) - class(test_sphericalMap), intent(inout) :: this - - @assertEqual(20, this % map_lin_from_zero % bins(1),'1st Dimension') - @assertEqual(4, this % map_unstruct % bins(1),'1st Dimension') - @assertEqual(20, this % map_lin_from_zero % bins(0),'All bins') - @assertEqual(0, this % map_lin_from_zero % bins(-3),'Invalid Dimension') - - ! Get dimensionality - @assertEqual(1, this % map_lin_from_zero % dimensions()) - - end subroutine testBinNumber - - !! - !! Test correctness of print subroutine - !! Does not checks that values are correct, but that calls sequance is without errors - !! -@Test - subroutine testPrint(this) - class(test_sphericalMap), intent(inout) :: this - type(outputFile) :: out - - call out % init('dummyPrinter', fatalErrors = .false.) - - call this % map_lin_from_zero % print(out) - @assertTrue(out % isValid(),'Default-initialised map case') - call out % reset() - - call this % map_lin_from_min % print(out) - @assertTrue(out % isValid(),'Map with minimum R') - call out % reset() - - call this % map_unstruct % print(out) - @assertTrue(out % isValid(),'Map with unstruct bins') - call out % reset() - - call this % map_equivol % print(out) - @assertTrue(out % isValid(),'Map with equivolume bins') - call out % reset() - - end subroutine testPrint - - -end module sphericalMap_test diff --git a/Tallies/TallyMaps/cylindricalMap_class.f90 b/Tallies/TallyMaps/cylindricalMap_class.f90 index b8d8eb757..7d326b64d 100644 --- a/Tallies/TallyMaps/cylindricalMap_class.f90 +++ b/Tallies/TallyMaps/cylindricalMap_class.f90 @@ -27,7 +27,7 @@ module cylindricalMap_class !! cylindricalMap { !! type cylindricalMap; !! #orientation x;# // Optional. Defeult z - !! #origin (1.0 0.0);# // Optional. Default (0 0). Order is xy, xz or yz. + !! #origin (1.0 0.0 0.0);# // Optional. Default (0 0 0) !! rGrid lin; !! #Rmin 2.0;# // Optional. Default 0.0 !! Rmax 10.0; @@ -51,7 +51,7 @@ module cylindricalMap_class type(grid) :: rBounds type(grid) :: axBounds type(grid) :: azBounds - integer(shortInt) :: rN = 0 + integer(shortInt) :: rN = 0 integer(shortInt) :: axN = 0 integer(shortInt) :: azN = 0 integer(shortInt) :: DIM1 = 0 @@ -66,6 +66,7 @@ module cylindricalMap_class procedure :: map procedure :: print procedure :: kill + end type cylindricalMap contains @@ -84,14 +85,6 @@ subroutine init(self, dict) integer(shortInt) :: i character(100), parameter :: Here = 'init (cylindricalMap_class.f90)' - ! Check & load origin - call dict % getOrDefault(temp, 'origin', [ZERO, ZERO]) - - if (size(temp) /= 2) then - call fatalError(Here, 'Expected 2 values for origin. Got: ' // numToChar(size(temp))) - end if - self % origin = temp - ! Check orientation of the cylinder if (dict % isPresent('orientation')) then call dict % get(type, 'orientation') @@ -120,6 +113,15 @@ subroutine init(self, dict) end select + ! Check & load origin + call dict % getOrDefault(temp, 'origin', [ZERO, ZERO, ZERO]) + + if (size(temp) /= 3) then + call fatalError(Here, 'Expected 3 values for origin. Got: ' // numToChar(size(temp))) + end if + + self % origin = temp([self % DIM1, self % DIM2]) + ! Load radial grid information if (.not. dict % isPresent('rGrid')) call fatalError(Here, 'Keyword rGrid must be present') call dict % get(type, 'rGrid') @@ -376,10 +378,10 @@ subroutine print(self,out) call out % startArray(name, [2,self % azN]) do i = 1, self % azN ! Print lower bin boundary - call out % addValue(self % azBounds % bin(i) + PI) + call out % addValue(self % azBounds % bin(i)) ! Print upper bin boundar - call out % addValue(self % azBounds % bin(i + 1) + PI) + call out % addValue(self % azBounds % bin(i + 1)) end do call out % endArray() diff --git a/Tallies/TallyMaps/matXsMapOLD_class.f90 b/Tallies/TallyMaps/matXsMapOLD_class.f90 deleted file mode 100644 index 990977fbc..000000000 --- a/Tallies/TallyMaps/matXsMapOLD_class.f90 +++ /dev/null @@ -1,186 +0,0 @@ -module matXsMap_class - - use numPrecision - use universalVariables - use genericProcedures, only : fatalError - use dictionary_class, only : dictionary - use grid_class, only : grid - use particle_class, only : particle - use outputFile_class, only : outputFile - use tallyMap_inter, only : tallyMap - - use nuclearDataRegistry_mod, only : getMatIdx - use nuclearData_inter, only : nuclearData - use transportNuclearData_inter, only : transportNuclearData - - implicit none - private - - !! - !! Constructor - !! - interface matXsMap - module procedure matXsMap_fromDict - end interface - - !! - !! Very weird map that creates bins depending on value of total XS in a specific material - !! Unfortunatly cannot detect upper and lower bound. Need to be provided manually. - !! I wander if there is any practical use for it. - !! - type, public,extends(tallyMap) :: matXsMap - private - type(grid) :: binBounds ! Bin grid - integer(shortInt) :: N ! Number of Bins - integer(shortInt) :: matIdx ! Material Index of querry material - - contains - ! Superclass interface implementaction - procedure :: bins ! Return number of bins - procedure :: map ! Map particle to a bin - procedure :: getAxisName ! Return character describing variable of devision - procedure :: print ! Print values associated with bins to outputfile - - ! Class specific procedures - procedure :: init - end type matXsMap - -contains - - !! - !! Initialise from min and max value, number of bins and extrapolation - !! - subroutine init(self, mini, maxi, N, type, matName) - class(matXsMap), intent(inout) :: self - real(defReal), intent(in) :: mini - real(defReal), intent(in) :: maxi - integer(shortInt),intent(in) :: N - character(nameLen), intent(in) :: type - character(nameLen), intent(in) :: matName - - self % N = N - call self % binBounds % init(mini, maxi, N, type) - - self % matIdx = getMatIdx(matName) - - end subroutine init - - - !! - !! Return total number of bins in this division - !! - pure function bins(self) result(N) - class(matXsMap), intent(in) :: self - integer(shortInt) :: N - - N = self % N - - end function bins - - !! - !! Map particle to a single bin. Return 0 for particle out of division - !! - function map(self,p) result(idx) - class(matXsMap), intent(in) :: self - class(particle), intent(in) :: p - integer(shortInt) :: idx - real(defReal) :: SigmaTot - character(100),parameter :: Here = 'map (matXsMap_class.f90)' - - ! Obtain XS - associate (xsData => p % xsData) - select type(xsData) - class is (transportNuclearData) - SigmaTot = xsData % getTotalMatXS(p, self % matIdx) - - class default - call fatalError(Here,'Dynamic type of XS data attached to particle is not transportNuclearData') - - end select - end associate - - idx = self % binBounds % search(SigmaTot) - if (idx == valueOutsideArray) idx = 0 - - end function map - - !! - !! Return string that describes variable used to divide event space - !! - function getAxisName(self) result(name) - class(matXsMap), intent(in) :: self - character(nameLen) :: name - - name = 'matXs' - - end function getAxisName - - !! - !! Add information about division axis to the output file - !! - subroutine print(self,out) - class(matXsMap), intent(in) :: self - class(outputFile), intent(inout) :: out - character(nameLen) :: name - integer(shortInt) :: i - - ! Name the array - name = trim(self % getAxisName()) //'Bounds' - - call out % startArray(name,[self % N,2]) - do i=1,self % N - ! Print lower bin boundary - call out % addValue(self % binBounds % bin(i)) - end do - - do i=1,self % N - ! Print upper bin boundar - call out % addValue(self % binBounds % bin(i+1)) - end do - - call out % endArray() - - end subroutine print - - !! - !! Return instance of matXsMap from dictionary - !! - function matXsMap_fromDict(dict) result(new) - class(dictionary), intent(in) :: dict - type(matXsMap) :: new - character(nameLen) :: str, matName - real(defReal) :: mini, maxi - real(defReal),dimension(:),allocatable :: bins - integer(shortInt) :: N - character(100), parameter :: Here = 'matXsMap_fromDict (matXsMap_class.f90)' - - if(.not.dict % isPresent('grid')) call fatalError(Here,"Keyword 'grid' must be present") - if(.not.dict % isPresent('mat')) call fatalError(Here,"Keyword 'mat' must be present") - - ! Read material name - call dict % get(matName,'mat') - - - - ! Read grid definition keyword - call dict % get(str,'grid') - - ! Choose approperiate definition - select case(str) - case('lin','log') - ! Read settings - call dict % get(mini,'min') - call dict % get(maxi,'max') - call dict % get(N,'N') - - ! Initialise - call new % init(mini, maxi, N, str, matName) - - case default - call fatalError(Here,"'grid' keyword must be: lin or log") - - end select - - end function matXsMap_fromDict - -end module matXsMap_class diff --git a/Tallies/TallyMaps/sphericalMap_class.f90 b/Tallies/TallyMaps/sphericalMap_class.f90 deleted file mode 100644 index 8a6d9dfff..000000000 --- a/Tallies/TallyMaps/sphericalMap_class.f90 +++ /dev/null @@ -1,242 +0,0 @@ -module sphericalMap_class - - use numPrecision - use universalVariables, only : valueOutsideArray - use genericProcedures, only : fatalError, dotProduct, numToChar - use dictionary_class, only : dictionary - use grid_class, only : grid - use particle_class, only : particleState - use outputFile_class, only : outputFile - use tallyMap_inter, only : tallyMap, kill_super => kill - - implicit none - private - - - !! - !! Divides space into a mesh in spherical co-ordinates - !! - !! TODO: - !! Implement polar & azimuthal subdivision - !! - !! Interface: - !! tallyMap interface - !! - !! NOTE: - !! Behaviour of points exactly at the boundary of bins is undefined. - !! particle can end-up in either of the two - !! - !! Sample Dictionary Input: - !! sphericalMap { - !! type sphericalMap; - !! #origin (1.0 0.0 0.0);# // Optional. Default (0 0 0) - !! grid lin; - !! #Rmin 2.0;# // Optional. Default 0.0 - !! Rmax 10.0; - !! N 10; - !! } - !! - !! - type, public, extends (tallyMap) :: sphericalMap - private - real(defReal), dimension(3) :: origin = ZERO - type(grid) :: rBounds - integer(shortInt) :: N = 0 - contains - ! Superclass - procedure :: init - procedure :: bins - procedure :: dimensions - procedure :: getAxisName - procedure :: map - procedure :: print - procedure :: kill - end type sphericalMap - -contains - - !! - !! Initialise tallyMap from a dictionary - !! - !! See tallyMap for specification. - !! - subroutine init(self, dict) - class(sphericalMap), intent(inout) :: self - class(dictionary), intent(in) :: dict - real(defReal), dimension(:), allocatable :: temp, grid - character(nameLen) :: type - real(defReal) :: Rmin, Rmax, vol - integer(shortInt) :: i - character(100), parameter :: Here = 'init (sphericalmap_class.f90)' - - ! Check & load origin - call dict % getOrDefault(temp, 'origin', [ZERO, ZERO, ZERO]) - - if (size(temp) /= 3) then - call fatalError(Here, 'Expected 3 values for origin. Got: ' // numToChar(size(temp))) - end if - self % origin = temp - - ! Load grid information - if (.not.dict % isPresent('grid')) call fatalError(Here, 'Keyword grid must be present') - call dict % get(type, 'grid') - - select case(type) - case('lin') - call dict % getOrDefault(Rmin, 'Rmin', ZERO) - call dict % get(Rmax, 'Rmax') - call dict % get(self % N, 'N') - - ! Check that minimum radius is OK - if (Rmin < ZERO) then - call fatalError(Here, 'Minumum radius must be +ve is:'//numToChar(Rmin)) - end if - - ! Build grid - call self % rBounds % init(Rmin, Rmax, self % N, type) - - case('unstruct') - - call dict % get(grid,'bins') - - ! Initialise - self % N = size(grid) - 1 - call self % rBounds % init(grid) - - case('equivolume') - - call dict % getOrDefault(Rmin, 'Rmin', ZERO) - call dict % get(Rmax, 'Rmax') - call dict % get(self % N, 'N') - - ! Check that minimum radius is OK - if (Rmin < ZERO) then - call fatalError(Here, 'Minumum radius must be +ve is:'//numToChar(Rmin)) - end if - - ! Calculate volume - vol = (Rmax**3 - Rmin**3) /self % N - - allocate(grid(self % N + 1)) - ! Calculate grid boundaries - grid(1) = Rmin - grid(self % N + 1) = Rmax - do i = 2,self % N - grid(i) = (vol + grid(i-1)**3)**(ONE/3.0_defReal) - end do - - call self % rBounds % init(grid) - - case default - call fatalError(Here, "'grid' can take only values of: lin, unstruct and equivolume") - - end select - - end subroutine init - - !! - !! Return total number of bins in this division along Dimension D - !! - !! See tallyMap for specification. - !! - elemental function bins(self, D) result(N) - class(sphericalMap), intent(in) :: self - integer(shortInt), intent(in) :: D - integer(shortInt) :: N - - if (D == 1 .or. D == 0) then - N = self % N - else - N = 0 - end if - - end function bins - - !! - !! Return number of dimensions - !! - !! See tallyMap for specification. - !! - elemental function dimensions(self) result(D) - class(sphericalMap), intent(in) :: self - integer(shortInt) :: D - - D = 1 - - end function dimensions - - !! - !! Return string that describes variable used to divide event space - !! - !! See tallyMap for specification - !! - function getAxisName(self) result(name) - class(sphericalMap), intent(in) :: self - character(nameLen) :: name - - name ='sphericalMap' - - end function getAxisName - - !! - !! Map particle to a single bin. Return 0 for particle out of division - !! - !! See tallyMap for specification. - !! - elemental function map(self, state) result(idx) - class(sphericalMap), intent(in) :: self - class(particleState), intent(in) :: state - integer(shortInt) :: idx - real(defReal) :: r - - ! Calculate the distance from the origin - r = norm2(state % r - self % origin) - - ! Search and return 0 if r is out-of-bounds - idx = self % rBounds % search(r) - if (idx == valueOutsideArray) idx = 0 - - end function map - - !! - !! Add information about division axis to the output file - !! - !! See tallyMap for specification. - !! - subroutine print(self,out) - class(sphericalMap), intent(in) :: self - class(outputFile), intent(inout) :: out - character(nameLen) :: name - integer(shortInt) :: i - - ! Name the array - name = trim(self % getAxisName()) //'Bounds' - - call out % startArray(name, [2,self % N]) - do i = 1, self % N - ! Print lower bin boundary - call out % addValue(self % rBounds % bin(i)) - - ! Print upper bin boundar - call out % addValue(self % rBounds % bin(i + 1)) - - end do - call out % endArray() - - end subroutine print - - !! - !! Return to uninitialised state - !! - elemental subroutine kill(self) - class(sphericalMap), intent(inout) :: self - - call kill_super(self) - - self % origin = ZERO - call self % rBounds % kill() - self % N = 0 - - end subroutine kill - -end module sphericalMap_class diff --git a/Tallies/TallyMaps/tallyMapFactory_func.f90 b/Tallies/TallyMaps/tallyMapFactory_func.f90 index 5eb67f6f2..33d5108fb 100644 --- a/Tallies/TallyMaps/tallyMapFactory_func.f90 +++ b/Tallies/TallyMaps/tallyMapFactory_func.f90 @@ -20,7 +20,6 @@ module tallyMapFactory_func ! TallyMap implementations use multiMap_class, only : multiMap - use sphericalMap_class, only : sphericalMap use cylindricalMap_class, only : cylindricalMap implicit none @@ -33,7 +32,6 @@ module tallyMapFactory_func ! NOTE: ! For now it is necessary to adjust trailing blanks so all enteries have the same length character(nameLen),dimension(*),parameter :: AVALIBLE_tallyMaps = [ 'multiMap ', & - 'sphericalMap ', & 'cylindricalMap'] @@ -72,9 +70,6 @@ subroutine new_tallyMap(new, dict) case('multiMap') allocate( multiMap :: new) - case('sphericalMap') - allocate( sphericalMap :: new) - case('cylindricalMap') allocate( cylindricalMap :: new) diff --git a/Tallies/TallyMaps/tallyMapSlot_class.f90 b/Tallies/TallyMaps/tallyMapSlot_class.f90 deleted file mode 100644 index 3c3910bf8..000000000 --- a/Tallies/TallyMaps/tallyMapSlot_class.f90 +++ /dev/null @@ -1,163 +0,0 @@ -module tallyMapSlot_class - - use numPrecision - use particle_class, only : particleState - use outputFile_class, only : outputFile - use dictionary_class, only : dictionary - use tallyMap_inter, only : tallyMap, kill_super => kill - use tallyMapFactory_func, only : new_tallyMap - - implicit none - private - - !! - !! Container for polymorphic instances of tallyMaps - !! - !! tallyMapSlot is itself a tallyMap. Init functions uses tallyMapFactory - !! to build any type of tallyMap as specified in the provided dictionary - !! - !! Private Members: - !! slot -> allocatable tallyMap content - !! - !! Interface: - !! tallyMap interface - !! moveAllocFrom -> moves allocation of allocatable class(tallyMap) into the slot - !! - type, public,extends(tallyMap) :: tallyMapSlot - private - class(tallyMap),allocatable :: slot - contains - ! Superclass interface implementaction - procedure :: init - procedure :: dimensions - procedure :: bins - procedure :: map - procedure :: getAxisName - procedure :: print - procedure :: kill - - ! Class specific procedures - procedure :: moveAllocFrom - - end type tallyMapSlot - -contains - - !! - !! Shortcut to factory. - !! Builds object in a factory from a dictionary and stores it in a slot - !! - !! See tallyMap for specification - !! - subroutine init(self, dict) - class(tallyMapSlot), intent(inout) :: self - class(dictionary), intent(in) :: dict - - call self % kill() - call new_tallyMap(self % slot, dict) - - end subroutine init - - !! - !! Return total number of bins in this division - !! - !! See tallyMap for specification - !! - elemental function bins(self, D) result(N) - class(tallyMapSlot), intent(in) :: self - integer(shortInt),intent(in) :: D - integer(shortInt) :: N - - N = self % slot % bins(D) - - end function bins - - !! - !! Return number of dimensions - !! - !! See tallyMap for specification - !! - elemental function dimensions(self) result(D) - class(tallyMapSlot), intent(in) :: self - integer(shortInt) :: D - - D = self % slot % dimensions() - - end function dimensions - - - !! - !! Map particle to a single bin. Return 0 for particle out of division - !! - !! See tallyMap for specification - !! - elemental function map(self,state) result(idx) - class(tallyMapSlot), intent(in) :: self - class(particleState), intent(in) :: state - integer(shortInt) :: idx - - idx = self % slot % map(state) - - end function map - - !! - !! Return string that describes variable used to divide event space - !! - !! See tallyMap for specification - !! - function getAxisName(self) result(name) - class(tallyMapSlot), intent(in) :: self - character(nameLen) :: name - - name = self % slot % getAxisName() - - end function getAxisName - - !! - !! Add information about division axis to the output file - !! - !! See tallyMap for specification - !! - subroutine print(self,out) - class(tallyMapSlot), intent(in) :: self - class(outpuTFile), intent(inout) :: out - - call self % slot % print(out) - - end subroutine print - - !! - !! Move allocation from allocatable RHS into slot - !! - !! Args: - !! RHS [inout] -> allocatable tallyMap to load into the slot - !! - !! Errors: - !! None - !! - !! NOTE: - !! RHS is deallocated on exit - !! - subroutine moveAllocFrom(LHS,RHS) - class(tallyMapSlot), intent(inout) :: LHS - class(tallyMap), allocatable, intent(inout) :: RHS - - call LHS % kill() - call move_alloc(RHS, LHS % slot) - - end subroutine moveAllocFrom - - !! - !! Deallocate content of the slot - !! - elemental subroutine kill(self) - class(tallyMapSlot), intent(inout) :: self - - call kill_super(self) - - if(allocated(self % slot)) deallocate(self % slot) - - end subroutine kill - - -end module tallyMapSlot_class diff --git a/docs/User Manual.rst b/docs/User Manual.rst index ac7575ed0..fba5d5a6f 100644 --- a/docs/User Manual.rst +++ b/docs/User Manual.rst @@ -1123,6 +1123,27 @@ Example: :: map { type cellMap; cells (1 5 3 2 4 100); undefBin T; } +* collNumMap (1D map), filters the particles tallied over number of collisions they underwent + + - collNumbers: list of collision numbers (integers) to be used as map bins + +Examples: :: + + map1 { type collNumMap; collNumbers ( 0 1 2 3 4 5 10 20); } + +* directionMap (1D map), angular map for the particle's direction with a linear grid + + - axis (*optional*, default = ``xy``): ``xy``, ``yz``, ``xz`` define the plane + of the direction to map + - N: number of bins + - min (*optional*, default = -180): grid lower limit [degrees] + - max (*optional*, default = 180): grid upper limit [degrees] + +Examples: :: + + map1 { type directionMap; axis xz; min 0.0; max 90.0; N 6; } + map2 { type directionMap; N 36; } + * energyMap (1D map), defines an energy group structure - grid: ``log`` for logarithmically spaced bins or ``lin`` for linearly spaced bins @@ -1177,23 +1198,33 @@ Example: :: map { type materialMap; materials (fuel water cladding reflector fuelGd); undefBin T; } -* multiMap, ensemble of multiple 1D maps +* radialMap, spherical or cylindrical radial map - - maps: list of the names of the maps that will compose the ``multiMap``. This - is followed by dictionaries that define the requested maps + - axis (*optional*, default = ``xyz``): ``x``, ``y``, ``z``, is the normal of + the cylindrical plane, or ``xyz`` to indicate spherical coordinates + - origin (*optional*, default = (0.0 0.0 0.0)): (x y z) vector with the origin + of the radial map. If the map is cylindrical, only the two coordinates perpendicular + to the cylinder's normal matter + - grid: ``lin`` for linearly spaced bins or ``equivolume`` -Example: :: + + min (*optional*, default = 0.0): minimum radius [cm] + + max: maximum radius [cm] + + N: number of radial bins - map { type multiMap; maps (map1 map2 map10); - map1 { <1D map definition> } - map2 { <1D map definition> } - map10 { <1D map definition> } - } + - grid: ``unstruct`` for unstructured grids, to be manually defined + + + bins: array with the explicit definition of the spherical bin boundaries + to be used + +Examples: :: + + map1 { type radialMap; axis xyz; origin (2.0 1.0 0.0); grid lin; min 3.0; max 10.0; N 14; } + map2 { type radialMap; axis z; grid equivolume; max 20.0; N 10; } + map3 { type radialMap; grid unstruct; bins (1.0 2.0 2.5 3.0 5.0); } * spaceMap (1D map), geometric cartesian map - axis: ``x``, ``y`` or ``z`` - - grid: ``lin`` for linearly spaced bins + min: bottom coordinate [cm] @@ -1209,27 +1240,23 @@ Examples: :: map1 { type spaceMap; axis x; grid lin; min -50.0; max 50.0; N 100; } map2 { type spaceMap; axis z; grid unstruct; bins (0.0 0.2 0.3 0.5 0.7 0.8 1.0); } -* sphericalMap, geometric spherical map - - - origin (*optional*, default = (0.0 0.0 .0.)): (x y z) vector with the origin - of the spherical map +* weightMap (1D map), divides weight into number of discrete bins - - grid: ``lin`` for linearly spaced bins or ``equivolume`` for spherical shells + - grid: ``log`` for logarithmically spaced bins or ``lin`` for linearly spaced bins - + Rmin (*optional*, default = 0.0): minimum radius [cm] - + Rmax: maximum radius [cm] - + N: number of radial bins + + min: bottom weight + + max: top weight + + N: number of bins - grid: ``unstruct`` for unstructured grids, to be manually defined - + bins: array with the explicit definition of the spherical bin boundaries - to be used + + bins: array with the explicit definition of the weight bin boundaries to be used Examples: :: - map1 { type sphericalMap; origin (2.0 1.0 0.0); grid lin; Rmin 3.0; Rmax 10.0; N 14; } - map2 { type sphericalMap; grid equivolume; Rmax 20.0; N 10; } - map3 { type sphericalMap; grid unstruct; bins (1.0 2.0 2.5 3.0 5.0); } + map1 { type weightMap; grid log; min 1.0e-3; max 100.0; N 100; } + map2 { type weightMap; grid lin; min 0.1; max 2.0; N 20; } + map3 { type weightMap; bins (0.0 0.2 0.4 0.6 0.8 1.0 2.0 5.0 10.0); } * cylindricalMap, geometric cylindrical map; other than the radial discretisation, one could add axial and azimuthal discretisation @@ -1261,31 +1288,18 @@ Example: :: map1 { type cylindricalMap; orientation y; origin (7.0 0.0); rGrid lin; Rmax 5.0; rN 10; } map2 { type cylindricalMap; rGrid unstruct; bins (2.0 3.0 4.5 5.0); axGrid lin; axMin 0.0; axMax 6.0 axN 24; azimuthalN 8; } -* collNumMap (1D map), filters the particles tallied over number of collisions they underwent - - - collNumbers: list of collision numbers (integers) to be used as map bins - -Examples: :: - - map1 { type collNumMap; collNumbers ( 0 1 2 3 4 5 10 20); } - -* weightMap (1D map), divides weight into number of discrete bins - - - grid: ``log`` for logarithmically spaced bins or ``lin`` for linearly spaced bins - - + min: bottom weight - + max: top weight - + N: number of bins - - - grid: ``unstruct`` for unstructured grids, to be manually defined +* multiMap, ensemble of multiple 1D maps - + bins: array with the explicit definition of the weight bin boundaries to be used + - maps: list of the names of the maps that will compose the ``multiMap``. This + is followed by dictionaries that define the requested maps -Examples: :: +Example: :: - map1 { type weightMap; grid log; min 1.0e-3; max 100.0; N 100; } - map2 { type weightMap; grid lin; min 0.1; max 2.0; N 20; } - map3 { type weightMap; bins (0.0 0.2 0.4 0.6 0.8 1.0 2.0 5.0 10.0); } + map { type multiMap; maps (map1 map2 map10); + map1 { <1D map definition> } + map2 { <1D map definition> } + map10 { <1D map definition> } + } Tally Filters #############