diff --git a/docs/source/pythonapi/capi.rst b/docs/source/pythonapi/capi.rst index c78c43fd3..af00363cc 100644 --- a/docs/source/pythonapi/capi.rst +++ b/docs/source/pythonapi/capi.rst @@ -2,6 +2,13 @@ :data:`openmc.capi` -- Python bindings to the C API --------------------------------------------------- +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.capi.lib_context + .. autosummary:: :toctree: generated :nosignatures: diff --git a/openmc/__init__.py b/openmc/__init__.py index 74c991fda..a0fe26491 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -27,6 +27,6 @@ from openmc.particle_restart import * from openmc.mixin import * from openmc.plotter import * from openmc.search import * -from openmc.capi import lib, OpenMCLibrary +from openmc.capi import * __version__ = '0.9.0' diff --git a/openmc/capi.py b/openmc/capi.py index a194e2d26..bb9241d7d 100644 --- a/openmc/capi.py +++ b/openmc/capi.py @@ -1,3 +1,4 @@ +from contextlib import contextmanager from ctypes import CDLL, c_int, c_int32, c_double, c_char_p, POINTER import sys from warnings import warn @@ -7,6 +8,8 @@ from numpy.ctypeslib import as_array import pkg_resources +__all__ = ['OpenMCLibrary', 'lib', 'lib_context'] + _int3 = c_int*3 _double3 = c_double*3 _double_array = POINTER(POINTER(c_double)) @@ -80,7 +83,6 @@ class OpenMCLibrary(object): else: return self._dll.openmc_cell_set_temperature(cell_id, T, None) - def finalize(self): """Finalize simulation and free memory""" return self._dll.openmc_finalize() @@ -124,7 +126,7 @@ class OpenMCLibrary(object): Parameters ---------- - intracomm : int or None + intracomm : mpi4py.MPI.Intracomm or None MPI intracommunicator """ @@ -258,6 +260,32 @@ class OpenMCLibrary(object): .format(key)) +@contextmanager +def lib_context(intracomm=None): + """Provides context manager for calling OpenMC shared library functions. + + This function is intended to be used in a 'with' statement and ensures that + OpenMC is properly initialized/finalized. At the completion of the 'with' + block, all memory that was allocated during the block is freed. For + example:: + + with openmc.lib_context() as lib: + for i in range(n_iters): + lib.reset() + do_stuff() + lib.run() + + Parameters + ---------- + intracomm : mpi4py.MPI.Intracomm or None + MPI intracommunicator + + """ + lib.init(comm) + yield lib + lib.finalize() + + # Determine shared-library suffix if sys.platform == 'darwin': suffix = 'dylib'