Skip to content

Commit

Permalink
Merge pull request CambridgeNuclear#103 from Mikolaj-A-Kowalski/colou…
Browse files Browse the repository at this point in the history
…r-mat

User defined colours for plotting materials
  • Loading branch information
valeriaRaffuzzi authored Jan 25, 2024
2 parents 16ee2a7 + 76e1251 commit f6b61a6
Show file tree
Hide file tree
Showing 7 changed files with 550 additions and 431 deletions.
2 changes: 2 additions & 0 deletions InputFiles/c5g7_mox
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ viz {
centre (0.0 0.0 0.0);
//width (25.0 25.0);
axis z;
offset -17;
res (500 500);
}
}
Expand All @@ -119,6 +120,7 @@ nuclearData {

water {
temp 75675;
rgb (0 0 139); // Colour of water is dark blue
moder { 1001.03 h-h2o.42; }
composition {
1001.03 6.700E-002;
Expand Down
90 changes: 60 additions & 30 deletions NuclearData/materialMenu_mod.f90
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
!!
!! Material Menu is a module (Singleton) that contains global definitions of diffrent materials
!! Material Menu is a module (Singleton) that contains global definitions of different materials
!!
!! It exists to make it easier for all databases to refer to the same materials by the same
!! name and index. This is necessary to avoid confusion resulting from diffrent materials with the
!! same name or index in diffrent databases.
!! name and index. This is necessary to avoid confusion resulting from different materials with the
!! same name or index in different databases.
!!
!! Public Members:
!! materialDefs -> array of material definitions of type materialItem
!! nameMap -> Map that maps material name to matIdx
!! colourMap -> Map that maps matIdx to 24bit colour (to use for visualisation)
!!
!! Interface:
!! init -> Load material definitions from a dictionary
Expand All @@ -21,8 +22,10 @@
module materialMenu_mod

use numPrecision
use universalVariables, only : NOT_FOUND, VOID_MAT, OUTSIDE_MAT
use universalVariables, only : NOT_FOUND, VOID_MAT, OUTSIDE_MAT, UNDEF_MAT
use genericProcedures, only : fatalError, charToInt, numToChar
use colours_func, only : rgb24bit
use intMap_class, only : intMap
use charMap_class, only : charMap
use dictionary_class, only : dictionary

Expand All @@ -33,9 +36,9 @@ module materialMenu_mod
!! Information about a single nuclide
!!
!! Based somewhat on MCNP conventions.
!! Atomic and Mass number identify cleary a nuclide species
!! Atomic and Mass number identify clearly a nuclide species
!! Evaluation number T allows to refer to multiple states/evaluations of the same nuclide species
!! E.G. at a Diffrent temperature as in MCNP Library.
!! E.G. at a Different temperature as in MCNP Library.
!!
!! Public members:
!! Z -> Atomic number
Expand Down Expand Up @@ -83,6 +86,7 @@ module materialMenu_mod
!! 5010.03 2.0E-005;
!! }
!! xsFile /home/uberMoffTarkin/XS/mat1.xs;
!! #rgb (255 0 0); # // RGB colour to be used in visualisation
!! }
!!
!! NOTE: the moder dictionary is optional, necessary only if S(a,b) thermal scattering
Expand All @@ -102,9 +106,16 @@ module materialMenu_mod
procedure :: display => display_materialItem
end type materialItem

!! MODULE COMPONENTS
!! Parameters
integer(shortInt), parameter :: COL_OUTSIDE = int(z'ffffff', shortInt)
integer(shortInt), parameter :: COL_VOID = int(z'000000', shortInt)
integer(shortInt), parameter :: COL_UNDEF = int(z'00ff00', shortInt)


!! MODULE COMPONENTS
type(materialItem),dimension(:),allocatable,target,public :: materialDefs
type(charMap),target,public :: nameMap
type(charMap), target, public :: nameMap
type(intMap), public :: colourMap

public :: init
public :: kill
Expand All @@ -131,7 +142,7 @@ subroutine init(dict)
integer(shortInt) :: i
character(nameLen) :: temp

! Clean whatever may be alrady present
! Clean whatever may be already present
call kill()

! Load all material names
Expand All @@ -142,17 +153,20 @@ subroutine init(dict)

! Load definitions
do i=1,size(matNames)
call materialDefs(i) % init(matNames(i), dict % getDictPtr(matNames(i)))
materialDefs(i) % matIdx = i
call materialDefs(i) % init(matNames(i), i, dict % getDictPtr(matNames(i)))
call nameMap % add(matNames(i), i)
end do

! Add special Material keywords to thedictionary
! Add special Material keywords to the dictionary
temp = 'void'
call nameMap % add(temp, VOID_MAT)
temp = 'outside'
call nameMap % add(temp, OUTSIDE_MAT)

!! Load colours for the special materials
call colourMap % add(VOID_MAT, COL_VOID)
call colourMap % add(OUTSIDE_MAT, COL_OUTSIDE)
call colourMap % add(UNDEF_MAT, COL_UNDEF)

end subroutine init

Expand Down Expand Up @@ -204,7 +218,7 @@ end subroutine display
!! Result:
!! nameLen long character with material name
!!
!! Erorrs:
!! Error:
!! If idx is -ve or larger then number of defined materials
!! Empty string '' is returned as its name
!!
Expand Down Expand Up @@ -250,25 +264,30 @@ end function matIdx
!!
!! Args:
!! name [in] -> character with material name
!! idx [in] -> material index
!! dict [in] -> dictionary with material definition
!!
!! Errors:
!! FatalError if dictionary does not contain valid material definition.
!!
subroutine init_materialItem(self, name, dict)
class(materialItem), intent(inout) :: self
character(nameLen),intent(in) :: name
class(dictionary), intent(in) :: dict
character(nameLen),dimension(:),allocatable :: keys, moderKeys
integer(shortInt) :: i
class(dictionary),pointer :: compDict, moderDict
logical(defBool) :: hasSab
subroutine init_materialItem(self, name, idx, dict)
class(materialItem), intent(inout) :: self
character(nameLen), intent(in) :: name
integer(shortInt), intent(in) :: idx
class(dictionary), intent(in) :: dict
character(nameLen), dimension(:), allocatable :: keys, moderKeys
integer(shortInt), dimension(:), allocatable :: temp
integer(shortInt) :: i
class(dictionary),pointer :: compDict, moderDict
logical(defBool) :: hasSab
character(100), parameter :: Here = 'init_materialItem (materialMenu_mod.f90)'

! Return to initial state
call self % kill()

! Load easy components c
self % name = name
self % matIdx = idx
call dict % get(self % T,'temp')

! Get composition dictionary and load composition
Expand Down Expand Up @@ -300,6 +319,17 @@ subroutine init_materialItem(self, name, dict)
call self % nuclides(i) % init(keys(i))
end do

! Add colour info if present
if(dict % isPresent('rgb')) then
call dict % get(temp, 'rgb')

if (size(temp) /= 3) then
call fatalError(Here, "'rgb' keyword must have 3 values")
end if

call colourMap % add(idx, rgb24bit(temp(1), temp(2), temp(3)))
end if

! Save dictionary
self % extraInfo = dict

Expand Down Expand Up @@ -392,7 +422,7 @@ function isNucDefinition(key) result(isIt)
za = verify(key(1:L),'0123456789')
tt = verify(key(1:L),'0123456789', back = .true.)

! Verify that the location of the dot is consistant
! Verify that the location of the dot is consistent
isIt = dot == za .and. dot == tt

end function isNucDefinition
Expand Down Expand Up @@ -437,7 +467,7 @@ end subroutine init_nuclideInfo
!! None
!!
!! Result:
!! Character in format ZZAAA.TT that dscribes nuclide definition
!! Character in format ZZAAA.TT that describes nuclide definition
!!
!! Errors:
!! None
Expand All @@ -461,17 +491,17 @@ end function toChar_nuclideInfo
!! Get pointer to a material definition under matIdx
!!
!! Args:
!! matIdx [in] -> Index of the material
!! idx [in] -> Index of the material
!!
!! Result:
!! Pointer to a materialItem with the definition
!!
!! Errors:
!! FatalError if matIdx does not correspond to any defined material
!! FatalError if idx does not correspond to any defined material
!! FatalError if material definitions were not loaded
!!
function getMatPtr(matIdx) result(ptr)
integer(shortInt), intent(in) :: matIdx
function getMatPtr(idx) result(ptr)
integer(shortInt), intent(in) :: idx
type(materialItem), pointer :: ptr
character(100), parameter :: Here = 'getMatPtr (materialMenu_mod.f90)'

Expand All @@ -481,13 +511,13 @@ function getMatPtr(matIdx) result(ptr)
end if

! Verify matIdx
if( matIdx <= 0 .or. matIdx > nMat()) then
call fatalError(Here,"matIdx: "//numToChar(matIdx)// &
if( idx <= 0 .or. idx > nMat()) then
call fatalError(Here,"matIdx: "//numToChar(idx)// &
" does not correspond to any defined material")
end if

! Attach pointer
ptr => materialDefs(matIdx)
ptr => materialDefs(idx)

end function getMatPtr

Expand Down
6 changes: 4 additions & 2 deletions SharedModules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ add_sources( ./genericProcedures.f90
./timer_mod.f90
./charLib_func.f90
./openmp_func.f90
./errors_mod.f90)
./errors_mod.f90
./colours_func.f90)

add_unit_tests( ./Tests/grid_test.f90
./Tests/energyGrid_test.f90
Expand All @@ -21,4 +22,5 @@ add_unit_tests( ./Tests/grid_test.f90
./Tests/hashFunctions_test.f90
./Tests/timer_test.f90
./Tests/conversions_test.f90
./Tests/charLib_test.f90)
./Tests/charLib_test.f90
./Tests/colours_test.f90)
26 changes: 26 additions & 0 deletions SharedModules/Tests/colours_test.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module colours_test
use numPrecision
use colours_func, only : rgb24bit
use pFUnit_mod

implicit none

contains


@Test
subroutine testColourConversions()

! Test by comparison with some hex values
@assertEqual(int(z"123456"), rgb24bit(18, 52, 86))

@assertEqual(int(z"000000"), rgb24bit(0, 0, 0))
@assertEqual(int(z"ffffff"), rgb24bit(255, 255, 255))

@assertEqual(int(z"ff0000"), rgb24bit(255, 0, 0))
@assertEqual(int(z"00ff00"), rgb24bit(0, 255, 0))
@assertEqual(int(z"0000ff"), rgb24bit(0, 0, 255))

end subroutine testColourConversions

end module colours_test
48 changes: 48 additions & 0 deletions SharedModules/colours_func.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
!!
!! Contains function to deal with colours
!!
module colours_func
use numPrecision
use genericProcedures, only: numToChar
use errors_mod, only: fatalError
implicit none

public :: rgb24bit

contains


!!
!! Return integer with 24bit colour value from r,g,b components
!!
!! Args:
!! r [in] -> red component in [0-255] range
!! g [in] -> green component in [0-255] range
!! b [in] -> blue component in [0-255] range
!!
function rgb24bit(r, g, b) result(col)
integer(shortInt), intent(in) :: r
integer(shortInt), intent(in) :: g
integer(shortInt), intent(in) :: b
integer(shortInt) :: col
character(100), parameter :: Here = "rgb24bit (colours_func.f90)"

! Check that the values are in the correct range
if (r < 0 .or. r > 255) then
call fatalError(Here, "Red value is out of [0-255] range: " // numToChar(r))
end if
if (g < 0 .or. g > 255) then
call fatalError(Here, "Green value is out of [0-255] range: " // numToChar(g))
end if
if (b < 0 .or. b > 255) then
call fatalError(Here, "Blue value is out of [0-255] range: " // numToChar(b))
end if

! Compute the 24 bit colour
! Note inversion, blue is the least significant bits
col = b + 256 * g + 256 * 256 * r

end function rgb24bit


end module colours_func
Loading

0 comments on commit f6b61a6

Please sign in to comment.