Repository: openmc-dev/openmc

Issue:
Expose the set_contained option through the C-API
In Cardinal, we're setting the temperatures of pebbles (which are filled with many cells representing TRISOs, etc.) by calling `cell->set_temperature(T, instance, true /* set_contained */)`. Unfortunately, the `runtime_error`s thrown by OpenMC in this function do not get routed through MOOSE, so if OpenMC encounters an error, all that shows up on the MOOSE side is an unhelpful `MPI_Abort`. 

For instance, if we try to set a temperature of `0` to an OpenMC cell, but don't have data at that temperature, we get this error message:

```
Time Step 1, time = 1, dt = 1
Sending temperature to OpenMC...
application called MPI_Abort(MPI_COMM_WORLD, 1) - process 0
[unset]: write_line error; fd=-1 buf=:cmd=abort exitcode=1
```

even though OpenMC internally is throwing an exception with a helpful message:

*in Cell::set_temperature*:
```
      throw std::runtime_error{"Temperature is below minimum temperature at "
        "which data is available."};
```

Because the `openmc_cell_set_temperature` function _does_ catch this exception and saves the error message, I'd like to use `openmc_cell_set_temperature`. *But*, the interface right now does not let you control the `set_contained` parameter.

### Desired Change

Allow `openmc_cell_set_temperature` to control the `set_contained` parameter so that we can catch exceptions for cell temperatures in MOOSE.


Discussion:

Resolving patch:
diff --git a/openmc/lib/cell.py b/openmc/lib/cell.py
--- a/openmc/lib/cell.py
+++ b/openmc/lib/cell.py
@@ -1,7 +1,7 @@
 import sys
 
 from collections.abc import Mapping, Iterable
-from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
+from ctypes import c_int, c_int32, c_double, c_char_p, POINTER, c_bool
 from weakref import WeakValueDictionary
 
 import numpy as np
@@ -43,7 +43,7 @@
 _dll.openmc_cell_set_id.restype = c_int
 _dll.openmc_cell_set_id.errcheck = _error_handler
 _dll.openmc_cell_set_temperature.argtypes = [
-    c_int32, c_double, POINTER(c_int32)]
+    c_int32, c_double, POINTER(c_int32), c_bool]
 _dll.openmc_cell_set_temperature.restype = c_int
 _dll.openmc_cell_set_temperature.errcheck = _error_handler
 _dll.openmc_get_cell_index.argtypes = [c_int32, POINTER(c_int32)]
@@ -171,7 +171,7 @@ def get_temperature(self, instance=None):
         _dll.openmc_cell_get_temperature(self._index, instance, T)
         return T.value
 
-    def set_temperature(self, T, instance=None):
+    def set_temperature(self, T, instance=None, set_contained=False):
         """Set the temperature of a cell
 
         Parameters
@@ -180,13 +180,16 @@ def set_temperature(self, T, instance=None):
             Temperature in K
         instance : int or None
             Which instance of the cell
+        set_contained: bool
+            If cell is not filled by a material, whether to set the temperature of
+            all filled cells
 
         """
 
         if instance is not None:
             instance = c_int32(instance)
 
-        _dll.openmc_cell_set_temperature(self._index, T, instance)
+        _dll.openmc_cell_set_temperature(self._index, T, instance, set_contained)
 
     @property
     def bounding_box(self):


Test patch: