Specify temperature from a field (structured mesh only)#3734
Specify temperature from a field (structured mesh only)#3734JoffreyDorville wants to merge 95 commits into
Conversation
paulromano
left a comment
There was a problem hiding this comment.
A few initial thoughts:
- I see that this currently only works in history-based mode. You'll need to extend event-based mode as well (see
process_advance_particle_eventsin event.cpp) - It looks like
next_eventcould just be returned fromevent_advance()rather than stored as a new attribute on the particle. - @pshriwise talked about the notion that we may want mesh boundary crossings to be a generic concept (there may be other reasons to stop particles at mesh boundaries). If we were to generalize the event handling, it would involve something like a vector of meshes against which we would check distances to and if any of them are the closest, the "cross mesh" event would be activated. I'm not sure it's worth it to do that as part of this PR though, or even what other meshes we would potentially want to use this way. Curious to hear thoughts from anyone on where it might come in handy.
|
One case where it is potentialy useful to transport particles to nearest mesh boundary is when using weight windows and rouletting particles when crossing mesh surfaces. We can also potentially replace #3107 with adding a "timelike" mesh to stop particles at. |
|
Thanks for your comments @paulromano!
|
…nd spherical meshes
…icle construction
… point is on the lower boundary
paulromano
left a comment
There was a problem hiding this comment.
A few initial comments; more to come!
| if mesh_memo and self.temperature_field.mesh.id in mesh_memo: | ||
| return |
There was a problem hiding this comment.
If the mesh used for the temperature field was used for something else and already written to XML, this would result in <values> never being written. Even if the mesh is shared, the values still need to be written.
|
|
||
| """ | ||
| def __init__(self, mesh, values): | ||
| super().__init__(mesh, values) |
There was a problem hiding this comment.
It would be good to have some validation here to check for cases that are not yet supported (unstructured mesh and, if I'm not mistaken, cylindrical/spherical mesh). Additionally, there could be some basic checks for consistency (number of values matches number of mesh elements, temperature values are positive).
| return | ||
|
|
||
| # add mesh ID to this element | ||
| element = ET.SubElement(root, "temperature_field") |
There was a problem hiding this comment.
You should update docs/source/io_formats/settings.rst with any new XML elements.
| extern "C" int openmc_temperature_field_set_temperature( | ||
| int32_t index, double temperature) |
There was a problem hiding this comment.
This should be declared in capi.h
| //! \param[in] r Position of the particle | ||
| //! \return Temperature in Kelvin | ||
| double get_temperature(int bin); |
There was a problem hiding this comment.
Mismatch between Doxygen comment and actual arguments (r vs bin)
| from abc import ABC | ||
|
|
||
|
|
||
| class ScalarField(ABC): |
There was a problem hiding this comment.
I see that ScalarField inherit from ABC but right now it doesn't have any abstract methods. Were you planning on making this class have a defined interface that subclasses would have to implement?
Also, right now these classes don't really have much "behavior" (methods), which calls into question if they are needed as classes in the first place, but I understand that they are likely to be expanded in the future. Can you elaborate on what you see these classes providing beyond what we could achieve with built-in type? i.e., why should it not just be:
settings.temperature_field = (mesh, values)
Description
This PR introduces a new way to specify temperature using a field based on a spatial mesh. The motivation for this work is to simplify data transfer (and workflow) when working with multi-physics framework (e.g., Cardinal). It is limited to structured mesh now as a way to get started, but the objective is to add more complexity (support to unstructured mesh via the XDG library) with follow-up PRs.
This work is still in progress (draft PR).
I am planning to:
Do not hesitate to start a conversation here if you are interested in this feature and want to share any ideas!
More details on the implementation
This feature relies on a minimal interface with the mesh class (via the methods get_bin() and distance_to_next_boundary()) which is expected to simplify the connection with unstructured mesh classes once XDG functionalities are available in OpenMC.
In this PR, the temperature field is defined as the association of a spatial mesh and a list of temperature values corresponding to each mesh cell. The temperature in each mesh cell is considered constant in the entire volume of the mesh cell. Now, every time a particle is advancing, OpenMC also checks the distance to the next boundary associated with the mesh of the temperature field. The temperature associated with the particle is updated in three different scenarios (first time the particle is in the transport loop, after crossing a geometric cell boundary, and after crossing a boundary from the mesh of the temperature field) and will take precedence over any temperature value defined for the cell, material, or globally.
Checklist