From 08d55249aee4bc5ba99e4acf59474631d8157d92 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 25 Jan 2019 10:50:22 -0600 Subject: [PATCH] Move some material-related C API functions to C++ --- src/material.cpp | 69 ++++++++++++++++++++++++ src/material_header.F90 | 115 ---------------------------------------- 2 files changed, 69 insertions(+), 115 deletions(-) diff --git a/src/material.cpp b/src/material.cpp index a732d9191b..05e7dc57ce 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -891,6 +891,19 @@ read_materials(pugi::xml_node* node) // C API //============================================================================== +extern "C" int +openmc_get_material_index(int32_t id, int32_t* index) +{ + auto it = model::material_map.find(id); + if (it == model::material_map.end()) { + set_errmsg("No material exists with ID=" + std::to_string(id) + "."); + return OPENMC_E_INVALID_ID; + } else { + *index = it->second; + return 0; + } +} + extern "C" int openmc_material_add_nuclide(int32_t index, const char* name, double density) { @@ -938,6 +951,50 @@ openmc_material_add_nuclide(int32_t index, const char* name, double density) return err; } +extern "C" int +openmc_material_get_densities(int32_t index, int** nuclides, double** densities, int* n) +{ + if (index >= 1 && index <= model::materials.size()) { + auto& mat = model::materials[index - 1]; + if (!mat->nuclide_.empty()) { + *nuclides = mat->nuclide_.data(); + *densities = mat->atom_density_.data(); + *n = mat->nuclide_.size(); + return 0; + } else { + set_errmsg("Material atom density array has not been allocated."); + return OPENMC_E_ALLOCATE; + } + } else { + set_errmsg("Index in materials array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } +} + +extern "C" int +openmc_material_get_fissionable(int32_t index, bool* fissionable) +{ + if (index >= 1 && index <= model::materials.size()) { + *fissionable = model::materials[index - 1]->fissionable_; + return 0; + } else { + set_errmsg("Index in materials array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } +} + +extern "C" int +openmc_material_get_id(int32_t index, int32_t* id) +{ + if (index >= 1 && index <= model::materials.size()) { + *id = model::materials[index - 1]->id_; + return 0; + } else { + set_errmsg("Index in materials array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } +} + extern "C" int openmc_material_get_volume(int32_t index, double* volume) { @@ -1005,6 +1062,18 @@ openmc_material_set_densities(int32_t index, int n, const char** name, const dou } } +extern "C" int +openmc_material_set_id(int32_t index, int32_t id) +{ + if (index >= 1 && index <= model::materials.size()) { + model::materials[index - 1]->id_ = id; + model::material_map[id] = index - 1; + } else { + set_errmsg("Index in materials array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } +} + extern "C" int openmc_material_set_volume(int32_t index, double volume) { diff --git a/src/material_header.F90 b/src/material_header.F90 index 42ef35c63d..84eda36df9 100644 --- a/src/material_header.F90 +++ b/src/material_header.F90 @@ -17,11 +17,7 @@ module material_header private public :: free_memory_material public :: openmc_extend_materials - public :: openmc_get_material_index - public :: openmc_material_get_id - public :: openmc_material_get_densities public :: openmc_material_get_volume - public :: openmc_material_set_id public :: material_pointer interface @@ -52,13 +48,6 @@ module material_header logical(C_BOOL) :: fissionable end function material_fissionable_c - subroutine material_set_fissionable_c(mat_ptr, fissionable) & - bind(C, name='material_set_fissionable') - import C_PTR, C_BOOL - type(C_PTR), intent(in), value :: mat_ptr - logical(C_BOOL), intent(in), value :: fissionable - end subroutine material_set_fissionable_c - subroutine extend_materials_c(n) bind(C) import C_INT32_T integer(C_INT32_T), intent(in), value :: n @@ -113,7 +102,6 @@ module material_header procedure :: id => material_id procedure :: set_id => material_set_id procedure :: fissionable => material_fissionable - procedure :: set_fissionable => material_set_fissionable procedure :: init_nuclide_index => material_init_nuclide_index procedure :: calculate_xs => material_calculate_xs end type Material @@ -146,12 +134,6 @@ contains fissionable = material_fissionable_c(this % ptr) end function material_fissionable - subroutine material_set_fissionable(this, fissionable) - class(Material),intent(in) :: this - logical, intent(in) :: fissionable - call material_set_fissionable_c(this % ptr, logical(fissionable, C_BOOL)) - end subroutine material_set_fissionable - !=============================================================================== ! INIT_NUCLIDE_INDEX creates a mapping from indices in the global nuclides(:) ! array to the Material % nuclides array @@ -251,103 +233,6 @@ contains err = 0 end function openmc_extend_materials - function openmc_get_material_index(id, index) result(err) bind(C) - ! Returns the index in the materials array of a material with a given ID - integer(C_INT32_T), value :: id - integer(C_INT32_T), intent(out) :: index - integer(C_INT) :: err - - if (allocated(materials)) then - if (material_dict % has(id)) then - index = material_dict % get(id) - err = 0 - else - err = E_INVALID_ID - call set_errmsg("No material exists with ID=" // trim(to_str(id)) // ".") - end if - else - err = E_ALLOCATE - call set_errmsg("Memory has not been allocated for materials.") - end if - end function openmc_get_material_index - - - function openmc_material_get_densities(index, nuclides, densities, n) & - result(err) bind(C) - ! returns an array of nuclide densities in a material - integer(C_INT32_T), value :: index - type(C_PTR), intent(out) :: nuclides - type(C_PTR), intent(out) :: densities - integer(C_INT), intent(out) :: n - integer(C_INT) :: err - - if (index >= 1 .and. index <= size(materials)) then - associate (m => materials(index)) - if (allocated(m % atom_density)) then - nuclides = C_LOC(m % nuclide(1)) - densities = C_LOC(m % atom_density(1)) - n = size(m % atom_density) - err = 0 - else - err = E_ALLOCATE - call set_errmsg("Material atom density array has not been allocated.") - end if - end associate - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in materials array is out of bounds.") - end if - end function openmc_material_get_densities - - - function openmc_material_get_id(index, id) result(err) bind(C) - ! returns the ID of a material - integer(C_INT32_T), value :: index - integer(C_INT32_T), intent(out) :: id - integer(C_INT) :: err - - if (index >= 1 .and. index <= size(materials)) then - id = materials(index) % id() - err = 0 - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in materials array is out of bounds.") - end if - end function openmc_material_get_id - - - function openmc_material_get_fissionable(index, fissionable) result(err) bind(C) - ! returns whether a material is fissionable - integer(C_INT32_T), value :: index - logical(C_BOOL), intent(out) :: fissionable - integer(C_INT) :: err - - if (index >= 1 .and. index <= size(materials)) then - fissionable = materials(index) % fissionable() - err = 0 - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in materials array is out of bounds.") - end if - end function openmc_material_get_fissionable - - - function openmc_material_set_id(index, id) result(err) bind(C) - ! Set the ID of a material - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), value, intent(in) :: id - integer(C_INT) :: err - - if (index >= 1 .and. index <= n_materials) then - call materials(index) % set_id(id, index) - call material_dict % set(id, index) - err = 0 - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in materials array is out of bounds.") - end if - end function openmc_material_set_id - !=============================================================================== ! Fortran compatibility !===============================================================================