mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Add material volumes to XML and Material type
This commit is contained in:
parent
e4232536df
commit
8106329fe8
12 changed files with 146 additions and 29 deletions
|
|
@ -50,6 +50,12 @@ Each ``material`` element can have the following attributes or sub-elements:
|
|||
|
||||
*Default*: ""
|
||||
|
||||
:depletable:
|
||||
Boolean value indicating whether the material is depletable.
|
||||
|
||||
:volume:
|
||||
Volume of the material in cm^3.
|
||||
|
||||
:temperature:
|
||||
An element with no attributes which is used to set the default temperature
|
||||
of the material in Kelvin.
|
||||
|
|
|
|||
|
|
@ -56,9 +56,11 @@ extern "C" {
|
|||
int openmc_material_add_nuclide(int32_t index, const char name[], double density);
|
||||
int openmc_material_get_densities(int32_t index, int** nuclides, double** densities, int* n);
|
||||
int openmc_material_get_id(int32_t index, int32_t* id);
|
||||
int openmc_material_get_volume(int32_t index, double* volume);
|
||||
int openmc_material_set_density(int32_t index, double density);
|
||||
int openmc_material_set_densities(int32_t index, int n, const char** name, const double* density);
|
||||
int openmc_material_set_id(int32_t index, int32_t id);
|
||||
int openmc_material_set_volume(int32_t index, double volume);
|
||||
int openmc_material_filter_get_bins(int32_t index, int32_t** bins, int32_t* n);
|
||||
int openmc_material_filter_set_bins(int32_t index, int32_t n, const int32_t* bins);
|
||||
int openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh);
|
||||
|
|
|
|||
|
|
@ -284,6 +284,8 @@ class Material(IDManagerMixin):
|
|||
# Create the Material
|
||||
material = cls(mat_id, name)
|
||||
material.depletable = bool(group.attrs['depletable'])
|
||||
if 'volume' in group.attrs:
|
||||
material.volume = group.attrs['volume']
|
||||
|
||||
# Read the names of the S(a,b) tables for this Material and add them
|
||||
if 'sab_names' in group:
|
||||
|
|
@ -833,6 +835,9 @@ class Material(IDManagerMixin):
|
|||
if self._depletable:
|
||||
element.set("depletable", "true")
|
||||
|
||||
if self._volume:
|
||||
element.set("volume", str(self._volume))
|
||||
|
||||
# Create temperature XML subelement
|
||||
if self.temperature is not None:
|
||||
subelement = ET.SubElement(element, "temperature")
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n)
|
|||
*n = 1;
|
||||
}
|
||||
} else {
|
||||
strcpy(openmc_err_msg, "Index in cells array is out of bounds.");
|
||||
set_errmsg("Index in cells array is out of bounds.");
|
||||
return OPENMC_E_OUT_OF_BOUNDS;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -517,7 +517,7 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n,
|
|||
//TODO: off-by-one
|
||||
c.material.push_back(i_mat - 1);
|
||||
} else {
|
||||
strcpy(openmc_err_msg, "Index in materials array is out of bounds.");
|
||||
set_errmsg("Index in materials array is out of bounds.");
|
||||
return OPENMC_E_OUT_OF_BOUNDS;
|
||||
}
|
||||
}
|
||||
|
|
@ -528,7 +528,7 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n,
|
|||
c.type = FILL_LATTICE;
|
||||
}
|
||||
} else {
|
||||
strcpy(openmc_err_msg, "Index in cells array is out of bounds.");
|
||||
set_errmsg("Index in cells array is out of bounds.");
|
||||
return OPENMC_E_OUT_OF_BOUNDS;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
31
src/error.h
31
src/error.h
|
|
@ -5,6 +5,7 @@
|
|||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "openmc.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
|
|
@ -14,20 +15,38 @@ extern "C" void warning_from_c(const char* message, int message_len);
|
|||
extern "C" void write_message_from_c(const char* message, int message_len,
|
||||
int level);
|
||||
|
||||
inline
|
||||
void fatal_error(const char *message)
|
||||
inline void
|
||||
set_errmsg(const char* message)
|
||||
{
|
||||
fatal_error_from_c(message, strlen(message));
|
||||
std::strcpy(openmc_err_msg, message);
|
||||
}
|
||||
|
||||
inline void
|
||||
set_errmsg(const std::string& message)
|
||||
{
|
||||
std::strcpy(openmc_err_msg, message.c_str());
|
||||
}
|
||||
|
||||
inline void
|
||||
set_errmsg(const std::stringstream& message)
|
||||
{
|
||||
std::strcpy(openmc_err_msg, message.str().c_str());
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal_error(const std::string &message)
|
||||
void fatal_error(const char* message)
|
||||
{
|
||||
fatal_error_from_c(message, std::strlen(message));
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal_error(const std::string& message)
|
||||
{
|
||||
fatal_error_from_c(message.c_str(), message.length());
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal_error(const std::stringstream &message)
|
||||
void fatal_error(const std::stringstream& message)
|
||||
{
|
||||
fatal_error(message.str());
|
||||
}
|
||||
|
|
@ -47,7 +66,7 @@ void warning(const std::stringstream& message)
|
|||
inline
|
||||
void write_message(const char* message, int level)
|
||||
{
|
||||
write_message_from_c(message, strlen(message), level);
|
||||
write_message_from_c(message, std::strlen(message), level);
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
|||
|
|
@ -1534,9 +1534,7 @@ contains
|
|||
|
||||
! Check if material is depletable
|
||||
if (check_for_node(node_mat, "depletable")) then
|
||||
call get_node_value(node_mat, "depletable", temp_str)
|
||||
if (to_lower(temp_str) == "true" .or. temp_str == "1") &
|
||||
mat % depletable = .true.
|
||||
call get_node_value(node_mat, "depletable", mat % depletable)
|
||||
end if
|
||||
|
||||
! Copy material name
|
||||
|
|
|
|||
|
|
@ -20,13 +20,17 @@ std::unordered_map<int32_t, int32_t> material_map;
|
|||
// Material implementation
|
||||
//==============================================================================
|
||||
|
||||
Material::Material(pugi::xml_node material_node)
|
||||
Material::Material(pugi::xml_node node)
|
||||
{
|
||||
if (check_for_node(material_node, "id")) {
|
||||
id = std::stoi(get_node_value(material_node, "id"));
|
||||
if (check_for_node(node, "id")) {
|
||||
id = std::stoi(get_node_value(node, "id"));
|
||||
} else {
|
||||
fatal_error("Must specify id of material in materials XML file.");
|
||||
}
|
||||
|
||||
if (check_for_node(node, "volume")) {
|
||||
volume_ = std::stod(get_node_value(node, "volume"));
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -56,6 +60,48 @@ read_materials(pugi::xml_node* node)
|
|||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// C API
|
||||
//==============================================================================
|
||||
|
||||
extern "C" int
|
||||
openmc_material_get_volume(int32_t index, double* volume)
|
||||
{
|
||||
if (index >= 1 && index <= global_materials.size()) {
|
||||
Material* m = global_materials[index - 1];
|
||||
if (m->volume_ >= 0.0) {
|
||||
*volume = m->volume_;
|
||||
return 0;
|
||||
} else {
|
||||
std::stringstream msg;
|
||||
msg << "Volume for material with ID=" << m->id << " not set.";
|
||||
set_errmsg(msg);
|
||||
return OPENMC_E_UNASSIGNED;
|
||||
}
|
||||
} 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)
|
||||
{
|
||||
if (index >= 1 && index <= global_materials.size()) {
|
||||
Material* m = global_materials[index - 1];
|
||||
if (volume >= 0.0) {
|
||||
m->volume_ = volume;
|
||||
return 0;
|
||||
} else {
|
||||
set_errmsg("Volume must be non-negative");
|
||||
return OPENMC_E_INVALID_ARGUMENT;
|
||||
}
|
||||
} else {
|
||||
set_errmsg("Index in materials array is out of bounds.");
|
||||
return OPENMC_E_OUT_OF_BOUNDS;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Fortran compatibility functions
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class Material
|
|||
{
|
||||
public:
|
||||
int32_t id; //!< Unique ID
|
||||
double volume_ {-1.0}; //!< Volume in [cm^3]
|
||||
|
||||
Material() {};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ module material_header
|
|||
public :: openmc_material_add_nuclide
|
||||
public :: openmc_material_get_id
|
||||
public :: openmc_material_get_densities
|
||||
public :: openmc_material_get_volume
|
||||
public :: openmc_material_set_density
|
||||
public :: openmc_material_set_densities
|
||||
public :: openmc_material_set_id
|
||||
|
|
@ -51,9 +52,16 @@ module material_header
|
|||
end subroutine material_set_id_c
|
||||
|
||||
subroutine extend_materials_c(n) bind(C)
|
||||
import C_INT32_t
|
||||
import C_INT32_T
|
||||
integer(C_INT32_T), intent(in), value :: n
|
||||
end subroutine extend_materials_c
|
||||
|
||||
function openmc_material_get_volume(index, volume) result(err) bind(C)
|
||||
import C_INT32_T, C_DOUBLE, C_INT
|
||||
integer(C_INT32_T), value :: index
|
||||
real(C_DOUBLE), intent(out) :: volume
|
||||
integer(C_INT) :: err
|
||||
end function openmc_material_get_volume
|
||||
end interface
|
||||
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
element materials {
|
||||
element material {
|
||||
(element id { xsd:int } | attribute id { xsd:int }) &
|
||||
(element name { xsd:string { maxLength="52" } } |
|
||||
attribute name { xsd:string { maxLength="52" } })? &
|
||||
|
||||
element temperature { xsd:double }? &
|
||||
(element name { xsd:string } | attribute name { xsd:string })? &
|
||||
|
||||
(element depletable { xsd:boolean } | attribute depletable { xsd:boolean })? &
|
||||
|
||||
(element volume { xsd:double } | attribute volume { xsd:double })? &
|
||||
|
||||
(element temperature { xsd:double } | attribute temperature { xsd:double })? &
|
||||
|
||||
element density {
|
||||
(element value { xsd:double } | attribute value { xsd:double })? &
|
||||
|
|
|
|||
|
|
@ -15,21 +15,42 @@
|
|||
<optional>
|
||||
<choice>
|
||||
<element name="name">
|
||||
<data type="string">
|
||||
<param name="maxLength">52</param>
|
||||
</data>
|
||||
<data type="string"/>
|
||||
</element>
|
||||
<attribute name="name">
|
||||
<data type="string">
|
||||
<param name="maxLength">52</param>
|
||||
</data>
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="temperature">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<choice>
|
||||
<element name="depletable">
|
||||
<data type="boolean"/>
|
||||
</element>
|
||||
<attribute name="depletable">
|
||||
<data type="boolean"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="volume">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="volume">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="temperature">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="temperature">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<element name="density">
|
||||
<interleave>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module summary
|
|||
use error, only: write_message
|
||||
use geometry_header
|
||||
use hdf5_interface
|
||||
use material_header, only: Material, n_materials
|
||||
use material_header, only: Material, n_materials, openmc_material_get_volume
|
||||
use mesh_header, only: RegularMesh
|
||||
use message_passing
|
||||
use mgxs_interface
|
||||
|
|
@ -315,8 +315,10 @@ contains
|
|||
integer :: j
|
||||
integer :: k
|
||||
integer :: n
|
||||
integer :: err
|
||||
character(20), allocatable :: nuc_names(:)
|
||||
character(20), allocatable :: macro_names(:)
|
||||
real(8) :: volume
|
||||
real(8), allocatable :: nuc_densities(:)
|
||||
integer :: num_nuclides
|
||||
integer :: num_macros
|
||||
|
|
@ -341,6 +343,11 @@ contains
|
|||
call write_attribute(material_group, "depletable", 0)
|
||||
end if
|
||||
|
||||
err = openmc_material_get_volume(i, volume)
|
||||
if (err == 0 .and. volume > ZERO) then
|
||||
call write_attribute(material_group, "volume", volume)
|
||||
end if
|
||||
|
||||
! Write name for this material
|
||||
call write_dataset(material_group, "name", m % name)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue