diff --git a/docs/source/capi/index.rst b/docs/source/capi/index.rst index f3cdbb840..ae072448d 100644 --- a/docs/source/capi/index.rst +++ b/docs/source/capi/index.rst @@ -4,15 +4,39 @@ C API ===== -.. c:function:: int openmc_find(double* xyz, int rtype) +.. c:function:: void openmc_calculate_voumes() - Return the ID of the cell/material containing a given point + Run a stochastic volume calculation + +.. c:function:: int openmc_cell_set_temperature(int id, double T) + + Set the temperature of a cell. + + :param id: ID of the cell + :type id: int + :param T: Temperature in Kelvin + :type T: double + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: void openmc_finalize() + + Finalize a simulation + +.. c:function:: void openmc_find(double* xyz, int rtype, int* id, int* instance) + + Determine the ID of the cell/material containing a given point :param xyz: Cartesian coordinates :type xyz: double[3] :param rtype: Which ID to return (1=cell, 2=material) :type rtype: int - :rtype: int + :param id: ID of the cell/material found. If a material is requested and the + point is in a void, the ID is 0. If an error occurs, the ID is -1. + :type id: int + :param instance: If a cell is repetaed in the geometry, the instance of the + cell that was found and zero otherwise. + :type instance: int .. c:function:: void openmc_init(int intracomm) @@ -21,9 +45,54 @@ C API :param intracomm: MPI intracommunicator :type intracomm: int -.. c:function:: void openmc_finalize() +.. c:function:: int openmc_load_nuclide(char name[]) - Finalize a simulation + Load data for a nuclide from the HDF5 data library. + + :param name: Name of the nuclide. + :type name: char[] + :return: Return status (negative if an error occurs) + :rtype: int + +.. c:function:: int openmc_material_add_nuclide(int id, char name[], double density) + + Add a nuclide to an existing material. If the nuclide already exists, the + density is overwritten. + + :param id: ID of the material + :type id: int + :param name: Name of the nuclide + :type name: char[] + :param density: Density in atom/b-cm + :type density: double + :return: Return status (negative if an error occurs) + :rtype: int + +.. c:function:: int openmc_material_get_densities(int id, double* ptr) + + Get an array of nuclide densities for a material. + + :param id: ID of the material + :type id: int + :param ptr: Pointer to the array of densities + :type ptr: double* + :return: Length of the array + :rtype: int + +.. c:function:: int openmc_material_set_density(int id, double density) + + Set the density of a material. + + :param id: ID of the material + :type id: int + :param density: Density of the material in atom/b-cm + :type density: double + :return: Return status (negative if an error occurs) + :rtype: int + +.. c:function:: void openmc_plot_geometry() + + Run plotting mode. .. c:function:: void openmc_reset() @@ -32,3 +101,36 @@ C API .. c:function:: void openmc_run() Run a simulation + +.. c:function:: int openmc_set_density(double xyz[3], double density) + + Set the density of a material at a given point. + + :param xyz: Cartesian coordinates + :type xyz: double[3] + :param density: Density of the material to set in atom/b-cm + :type density: double + :return: Return status (negative if an error occurs) + :rtype: int + +.. c:function:: int openmc_set_temperature(double xyz[3], double T) + + Set the density of a cell at a given point. + + :param xyz: Cartesian coordinates + :type xyz: double[3] + :param T: Temperature of the cell to set in Kelvin + :type T: double + :return: Return status (negative if an error occurs) + :rtype: int + +.. c:function:: void openmc_tally_results(int i, double** ptr, int shape_[3]) + + Get a pointer to tally results array. + + :param i: Index in the tallies array + :type i: int + :param ptr: Pointer to the results array + :type ptr: double** + :param shape_: Shape of the results array + :type shape_: int[3] diff --git a/docs/source/pythonapi/capi.rst b/docs/source/pythonapi/capi.rst new file mode 100644 index 000000000..c78c43fd3 --- /dev/null +++ b/docs/source/pythonapi/capi.rst @@ -0,0 +1,10 @@ +--------------------------------------------------- +:data:`openmc.capi` -- Python bindings to the C API +--------------------------------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.capi.OpenMCLibrary diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 5492f362d..bb99dd470 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -47,5 +47,6 @@ Modules mgxs model data + capi examples openmoc diff --git a/openmc/__init__.py b/openmc/__init__.py index 96bcaf6d2..74c991fda 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 +from openmc.capi import lib, OpenMCLibrary __version__ = '0.9.0' diff --git a/openmc/capi.py b/openmc/capi.py index a4ac38c32..2df55abce 100644 --- a/openmc/capi.py +++ b/openmc/capi.py @@ -12,7 +12,20 @@ _double3 = c_double*3 _double_array = POINTER(POINTER(c_double)) -class _OpenMCLibrary(object): +class OpenMCLibrary(object): + """Provides bindings to C functions defined by OpenMC shared library. + + This class is normally not directly instantiated. Instead, when the + :mod:`openmc` package is imported, an instance is automatically created with + the name :data:`openmc.lib`. Calls to the OpenMC can then be made using that + instance, for example: + + .. code-block:: python + + openmc.lib.init() + openmc.lib.run() + + """ def __init__(self, filename): self._dll = CDLL(filename) @@ -22,8 +35,9 @@ class _OpenMCLibrary(object): c_int, c_double] self._dll.openmc_cell_set_temperature.restype = c_int self._dll.openmc_finalize.restype = None - self._dll.openmc_find.argtypes = [POINTER(_double3), c_int] - self._dll.openmc_find.restype = c_int + self._dll.openmc_find.argtypes = [ + POINTER(_double3), c_int, POINTER(c_int), POINTER(c_int)] + self._dll.openmc_find.restype = None self._dll.openmc_init.argtypes = [POINTER(c_int)] self._dll.openmc_init.restype = None self._dll.openmc_load_nuclide.argtypes = [c_char_p] @@ -61,6 +75,7 @@ class _OpenMCLibrary(object): ID of the cell T : float Temperature in K + """ return self._dll.openmc_cell_set_temperature(cell_id, T) @@ -83,16 +98,25 @@ class _OpenMCLibrary(object): int or None ID of the cell or material. If 'material' is requested and no material exists at the given coordinate, None is returned. + int + If the cell at the given point is repeated in the geometry, this + indicates which instance it is, i.e., 0 would be the first instance. """ + # Set second argument to openmc_find if rtype == 'cell': - return self._dll.openmc_find(_double3(*xyz), 1) + r_int = 1 elif rtype == 'material': - uid = self._dll.openmc_find(_double3(*xyz), 2) - return uid if uid != 0 else None + r_int = 2 else: raise ValueError('Unknown return type: {}'.format(rtype)) + # Call openmc_find + uid = c_int() + instance = c_int() + self._dll.openmc_find(_double3(*xyz), r_int, byref(uid), byref(instance)) + return (uid.value if uid != 0 else None), instance.value + def init(self, intracomm=None): """Initialize OpenMC @@ -278,7 +302,7 @@ else: filename = pkg_resources.resource_filename( __name__, '_libopenmc.{}'.format(suffix)) try: - lib = _OpenMCLibrary(filename) + lib = OpenMCLibrary(filename) except OSError: warn("OpenMC shared library is not available from the Python API. This " "means you will not be able to use openmc.lib to make in-memory " diff --git a/src/api.F90 b/src/api.F90 index a7a7e3ab4..c0ee84594 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -24,10 +24,10 @@ module openmc_api public :: openmc_finalize public :: openmc_find public :: openmc_init + public :: openmc_load_nuclide public :: openmc_material_add_nuclide public :: openmc_material_get_densities public :: openmc_material_set_density - public :: openmc_load_nuclide public :: openmc_plot_geometry public :: openmc_reset public :: openmc_run @@ -66,10 +66,11 @@ contains ! OPENMC_FIND determines the ID or a cell or material at a given point in space !=============================================================================== - function openmc_find(xyz, rtype) result(id) bind(C) + subroutine openmc_find(xyz, rtype, id, instance) bind(C) real(C_DOUBLE), intent(in) :: xyz(3) ! Cartesian point integer(C_INT), intent(in), value :: rtype ! 1 for cell, 2 for material - integer(C_INT) :: id + integer(C_INT), intent(out) :: id + integer(C_INT), intent(out) :: instance logical :: found type(Particle) :: p @@ -80,6 +81,7 @@ contains call find_cell(p, found) id = -1 + instance = -1 if (found) then if (rtype == 1) then id = cells(p % coord(p % n_coord) % cell) % id @@ -90,8 +92,9 @@ contains id = materials(p % material) % id end if end if + instance = p % cell_instance end if - end function openmc_find + end subroutine openmc_find !=============================================================================== ! OPENMC_LOAD_NUCLIDE loads a nuclide from the cross section library