Add material volumes to XML and Material type

This commit is contained in:
Paul Romano 2018-07-23 09:50:18 -05:00
parent e4232536df
commit 8106329fe8
12 changed files with 146 additions and 29 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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")

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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
//==============================================================================

View file

@ -25,6 +25,7 @@ class Material
{
public:
int32_t id; //!< Unique ID
double volume_ {-1.0}; //!< Volume in [cm^3]
Material() {};

View file

@ -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
!===============================================================================

View file

@ -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 })? &

View file

@ -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>

View file

@ -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)