-
Notifications
You must be signed in to change notification settings - Fork 25
Temperature and density fields #173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Temperature and density fields #173
Conversation
Added in the BEAVRS model with the D-bank partially inserted. Also fixed a flaw in the geometry where the outermost cell was defined such that there could be a rare particle lost between it and the geometry boundary.
Field which have values that are piecewise constant. Endowed with a distance calculation. Added a simple version which allows a lattice to be specified.
Can overlay temperature and density fields on the geometry. Supports both surface and delta tracking.
|
I have also added a new map to allow tallying on a given field definition. Currently this is limited to pieceConstantFields until we unify the interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was a lot!!!! The nuclear data bit seemed to make sense but I have to admit it will be good to give it another look post revisions.
There are a couple of bigger issues that I wrote in specific comments, but in general it looks good! It was a massive effort so well done.
| real(defReal) :: time ! Particle time point | ||
|
|
||
| ! Information passed from geometry | ||
| real(defReal) :: T = -INF ! Local temperature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use a consistent undefined value in between places: it is -INF here but, for example, -ONE in fissionSource_class.f90 (line 227)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I should define a 'NO_TEMPERATURE' and 'NO_DENSITY' I think.
| in different materials, or uniformly across all materials. | ||
|
|
||
| - shape: (x y z) array of integers, stating the numbers of x, y and z | ||
| elements of the field. For a 2D field, one of the entries has to be 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought only z was allowed to be 0
| - names of each material: a map, named after every material present in the materials list. | ||
| The entries of the map are the values that the field takes in that material in that | ||
| element of the field. The order is: increasing x, increasing y and then increasing z. | ||
| - default: the value taken by the field when a point is either outside of the field or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should probably be a default for each material.
In the case of density, the default could be set to 1.0 for all materials but this wouldn't be possible for the temperature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may need to think about a way of doing this in cases where there are many materials. The most obvious use case that I see at the moment is that there are ~2 materials one would care to modify (fuel, coolant). The others would not have any modifications, i.e., they would use the default input values, corresponding to setting a default of a negative number, which does not perform any modification. Maybe there is a question of how to make this as userfriendly as possible, e.g., the default default is 'do nothing'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think I understand better now. You mean for each material specified in the field definition. This does make sense; the default option was made for anything that doesn't correspond to what's in the map (either in space or material). There is maybe quite a multiplicity of options to consider...
| if (dict % isPresent('path')) then | ||
| call dict % get(path, 'path') | ||
| call self % init_file(path) | ||
| else | ||
| call self % init_dict(dict) | ||
| end if | ||
|
|
||
| end subroutine init | ||
|
|
||
| !! | ||
| !! Initialise field from a file | ||
| !! | ||
| !! Args: | ||
| !! file [in] -> Path to a file containing the field definition | ||
| !! | ||
| subroutine init_file(self, path) | ||
| class(pieceConstantField), intent(inout) :: self | ||
| character(pathLen), intent(in) :: path | ||
| type(dictionary) :: dict | ||
|
|
||
| call fileToDict(dict, path) | ||
| call self % init(dict) | ||
|
|
||
| end subroutine init_file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (dict % isPresent('path')) then | |
| call dict % get(path, 'path') | |
| call self % init_file(path) | |
| else | |
| call self % init_dict(dict) | |
| end if | |
| end subroutine init | |
| !! | |
| !! Initialise field from a file | |
| !! | |
| !! Args: | |
| !! file [in] -> Path to a file containing the field definition | |
| !! | |
| subroutine init_file(self, path) | |
| class(pieceConstantField), intent(inout) :: self | |
| character(pathLen), intent(in) :: path | |
| type(dictionary) :: dict | |
| call fileToDict(dict, path) | |
| call self % init(dict) | |
| end subroutine init_file | |
| if (dict % isPresent('path')) then | |
| call dict % get(path, 'path') | |
| call fileToDict(dict, path) | |
| end if | |
| call self % init_dict(dict) | |
| end subroutine init |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And then you remove init_file, you have init public and init_dict private
| !! T -> temperature of the cross section | ||
| !! rho -> density scaling of the cross section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should T and rho have been added to cacheSingleXS?
| ! Procedures implemented by a specific CE Neutron Database | ||
| procedure(updateMajorantXS), deferred :: updateMajorantXS | ||
| procedure(updateTotalMatXS), deferred :: updateTrackMatXS | ||
| procedure(updateTrackMatXS), deferred :: updateTrackMatXS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How could we have survived with this massive typo?
|
|
||
|
|
||
| ! This check is really awful - can we do something better? | ||
| else if (fieldDist < dist .and. abs(fieldDist - dist) > 10*NUDGE) then ! Stays within the same cell, but crosses field boundary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you just do
else if (maxDist < dist .and. maxDist >= fieldDist)?
in this case you're not crossing any geometrical boundary but a field boundary.
| !! Returns nucIdx <= if material is not fissile | ||
| !! | ||
| function sampleFission(self, E, rand) result(nucIdx) | ||
| function sampleFission(self, E, temp, rho, rand) result(nucIdx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all these sampling functions are not used to be honest...
Using the pieceConstantField, I have added the capability to super-impose temperature and density-scaling fields on the geometry. Both surface and delta tracking agree with each other for temperature and density changes, and they agree with reference calculations without imposed fields.
The distance calculations are done inside move. They work well for the most part, with one uncomfortable bit: fuzziness needed to be added to ensure that distance to the field does not take precedence over distance to the boundary. If there are any better suggestions for this it would be great.
This necessitated make the initMajorant function part of the nuclearDatabase, allowing it to be called in the physicsPackages which can receive the relevant field information from geometry.
I have updated the docs and added an integration test to geometry for obtaining values from the fields and distance calculations.