Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/source/io_formats/geometry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,11 @@ Each ``<dagmc_universe>`` element can have the following attributes or sub-eleme

*Default*: None

:length_multiplier:
Coordinate scaling factor applied when loading a DAGMC geometry model.

*Default*: 1.0

:cell:
Zero or more ``<cell>`` sub-elements may appear to override properties of
individual DAGMC volumes. Each ``<cell>`` element supports the following
Expand Down
9 changes: 6 additions & 3 deletions include/openmc/dagmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ class DAGUniverse : public Universe {
//! \param[in] filename Name of the DAGMC file
//! \param[in] auto_geom_ids Whether or not to automatically assign cell and
//! surface IDs \param[in] auto_mat_ids Whether or not to automatically assign
//! material IDs
//! material IDs \param[in] length_multiplier Multiplicative factor applied to
//! geometry coordinates
explicit DAGUniverse(const std::string& filename, bool auto_geom_ids = false,
bool auto_mat_ids = false);
bool auto_mat_ids = false, double length_multiplier = 1.0);

//! Alternative DAGMC universe constructor for external DAGMC instance
explicit DAGUniverse(std::shared_ptr<moab::DagMC> external_dagmc_ptr,
const std::string& filename = "", bool auto_geom_ids = false,
bool auto_mat_ids = false);
bool auto_mat_ids = false, double length_multiplier = 1.0);

//! Initialize the DAGMC accel. data structures, indices, material
//! assignments, etc.
Expand Down Expand Up @@ -209,6 +210,8 @@ class DAGUniverse : public Universe {
//!< universe
bool adjust_material_ids_; //!< Indicates whether or not to automatically
//!< generate new material IDs for the universe
double length_multiplier_ {
1.0}; //!< Multiplicative factor applied to geometry coordinates
bool has_graveyard_; //!< Indicates if the DAGMC geometry has a "graveyard"
//!< volume
};
Expand Down
35 changes: 30 additions & 5 deletions openmc/dagmc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Iterable, Mapping
from numbers import Integral
from numbers import Integral, Real

import h5py
import lxml.etree as ET
Expand Down Expand Up @@ -36,6 +36,8 @@ class DAGMCUniverse(openmc.UniverseBase):
auto_mat_ids : bool
Set IDs automatically on initialization (True) or report overlaps in ID
space between OpenMC and UWUW materials (False)
length_multiplier : float
Coordinate scaling factor applied when loading a DAGMC geometry model.
Attributes
----------
id : int
Expand All @@ -50,6 +52,8 @@ class DAGMCUniverse(openmc.UniverseBase):
auto_mat_ids : bool
Set IDs automatically on initialization (True) or report overlaps in ID
space between OpenMC and UWUW materials (False)
length_multiplier : float
Coordinate scaling factor applied when loading a DAGMC geometry model.
bounding_box : openmc.BoundingBox
Lower-left and upper-right coordinates of an axis-aligned bounding box
of the universe.
Expand Down Expand Up @@ -79,23 +83,30 @@ def __init__(self,
universe_id=None,
name='',
auto_geom_ids=False,
auto_mat_ids=False):
auto_mat_ids=False,
length_multiplier: float = 1.0):
super().__init__(universe_id, name)
# Initialize class attributes
self.filename = filename
self.auto_geom_ids = auto_geom_ids
self.auto_mat_ids = auto_mat_ids
self.length_multiplier = length_multiplier

def __repr__(self):
string = super().__repr__()
string += '{: <16}=\t{}\n'.format('\tGeom', 'DAGMC')
string += '{: <16}=\t{}\n'.format('\tFile', self.filename)
if self.length_multiplier != 1.0:
string += '{: <16}=\t{}\n'.format(
'\tLength multiplier', self.length_multiplier
)
return string

@property
def bounding_box(self):
with h5py.File(self.filename) as dagmc_file:
coords = dagmc_file['tstt']['nodes']['coordinates'][()]
coords *= self.length_multiplier
lower_left_corner = coords.min(axis=0)
upper_right_corner = coords.max(axis=0)
return openmc.BoundingBox(lower_left_corner, upper_right_corner)
Expand Down Expand Up @@ -175,6 +186,16 @@ def auto_mat_ids(self, val):
cv.check_type('DAGMC automatic material ids', val, bool)
self._auto_mat_ids = val

@property
def length_multiplier(self):
return self._length_multiplier

@length_multiplier.setter
def length_multiplier(self, length_multiplier):
cv.check_type('DAGMC universe length multiplier', length_multiplier, Real)
Comment thread
ssgudala-bwxt marked this conversation as resolved.
Resolved
cv.check_greater_than('DAGMC universe length multiplier', length_multiplier, 0.0)
self._length_multiplier = length_multiplier

@property
def material_names(self):
material_tags_ascii = []
Expand Down Expand Up @@ -254,6 +275,8 @@ def create_xml_subelement(self, xml_element, memo=None):
dagmc_element.set('auto_geom_ids', 'true')
if self.auto_mat_ids:
dagmc_element.set('auto_mat_ids', 'true')
if self.length_multiplier != 1.0:
dagmc_element.set('length_multiplier', str(self.length_multiplier))
dagmc_element.set('filename', str(self.filename))
if self.cells:
for cell in self.cells.values():
Expand Down Expand Up @@ -374,8 +397,9 @@ def from_hdf5(cls, group):
id = int(group.name.split('/')[-1].lstrip('universe '))
fname = group['filename'][()].decode()
name = group['name'][()].decode() if 'name' in group else None
length_multiplier = float(group.attrs.get('length_multiplier', 1.0))

out = cls(fname, universe_id=id, name=name)
out = cls(fname, universe_id=id, name=name, length_multiplier=length_multiplier)

out.auto_geom_ids = bool(group.attrs['auto_geom_ids'])
out.auto_mat_ids = bool(group.attrs['auto_mat_ids'])
Expand All @@ -402,8 +426,9 @@ def from_xml_element(cls, elem, mats=None):
"""
id = int(get_text(elem, 'id'))
fname = get_text(elem, 'filename')
length_multiplier = float(get_text(elem, 'length_multiplier', 1.0))

out = cls(fname, universe_id=id)
out = cls(fname, universe_id=id, length_multiplier=length_multiplier)

name = get_text(elem, 'name')
if name is not None:
Expand Down Expand Up @@ -467,7 +492,7 @@ def _partial_deepcopy(self):
its cells, as they are copied within the clone function. This should
only to be used within the openmc.UniverseBase.clone() context.
"""
clone = openmc.DAGMCUniverse(name=self.name, filename=self.filename)
clone = openmc.DAGMCUniverse(name=self.name, filename=self.filename, length_multiplier=self.length_multiplier)
clone.volume = self.volume
clone.auto_geom_ids = self.auto_geom_ids
clone.auto_mat_ids = self.auto_mat_ids
Expand Down
40 changes: 35 additions & 5 deletions src/dagmc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "openmc/dagmc.h"

#include <array>
#include <cassert>

#include "openmc/constants.h"
Expand Down Expand Up @@ -80,6 +81,10 @@ DAGUniverse::DAGUniverse(pugi::xml_node node)
adjust_material_ids_ = get_node_value_bool(node, "auto_mat_ids");
}

if (check_for_node(node, "length_multiplier")) {
length_multiplier_ = std::stod(get_node_value(node, "length_multiplier"));
}

// Get material assignment overrides from nested DAGMC cell elements.
if (node.child("cell")) {
for (pugi::xml_node cell_node : node.children("cell")) {
Expand Down Expand Up @@ -153,19 +158,21 @@ DAGUniverse::DAGUniverse(pugi::xml_node node)
initialize(material_overrides, temperature_overrides, density_overrides);
}

DAGUniverse::DAGUniverse(
const std::string& filename, bool auto_geom_ids, bool auto_mat_ids)
DAGUniverse::DAGUniverse(const std::string& filename, bool auto_geom_ids,
bool auto_mat_ids, double length_multiplier)
: filename_(filename), adjust_geometry_ids_(auto_geom_ids),
adjust_material_ids_(auto_mat_ids)
adjust_material_ids_(auto_mat_ids), length_multiplier_(length_multiplier)
{
set_id();
initialize();
}

DAGUniverse::DAGUniverse(std::shared_ptr<moab::DagMC> dagmc_ptr,
const std::string& filename, bool auto_geom_ids, bool auto_mat_ids)
const std::string& filename, bool auto_geom_ids, bool auto_mat_ids,
double length_multiplier)
: dagmc_instance_(dagmc_ptr), filename_(filename),
adjust_geometry_ids_(auto_geom_ids), adjust_material_ids_(auto_mat_ids)
adjust_geometry_ids_(auto_geom_ids), adjust_material_ids_(auto_mat_ids),
length_multiplier_(length_multiplier)
{
MaterialOverrides material_overrides;
TemperatureOverrides temperature_overrides;
Expand Down Expand Up @@ -225,6 +232,28 @@ void DAGUniverse::init_dagmc()
moab::ErrorCode rval = dagmc_instance_->load_file(filename_.c_str());
MB_CHK_ERR_CONT(rval);

if (length_multiplier_ != 1.0) {
moab::Range verts;
rval =
dagmc_instance_->moab_instance()->get_entities_by_dimension(0, 0, verts);
MB_CHK_ERR_CONT(rval);

for (auto vert : verts) {
std::array<double, 3> coord;
rval =
dagmc_instance_->moab_instance()->get_coords(&vert, 1, coord.data());
MB_CHK_ERR_CONT(rval);

for (auto& c : coord) {
c *= length_multiplier_;
}

rval =
dagmc_instance_->moab_instance()->set_coords(&vert, 1, coord.data());
MB_CHK_ERR_CONT(rval);
}
}

// initialize acceleration data structures
rval = dagmc_instance_->init_OBBTree();
MB_CHK_ERR_CONT(rval);
Expand Down Expand Up @@ -579,6 +608,7 @@ void DAGUniverse::to_hdf5(hid_t universes_group) const
group, "auto_geom_ids", static_cast<int>(adjust_geometry_ids_));
write_attribute(
group, "auto_mat_ids", static_cast<int>(adjust_material_ids_));
write_attribute(group, "length_multiplier", length_multiplier_);

close_group(group);
}
Expand Down
17 changes: 17 additions & 0 deletions tests/unit_tests/test_universe.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,21 +222,38 @@ def test_clone():
dagmc_u.volume = 1.
dagmc_u.auto_geom_ids = True
dagmc_u.auto_mat_ids = True
dagmc_u.length_multiplier = 0.5
dagmc_u1 = dagmc_u.clone()
assert dagmc_u1.name == dagmc_u.name
assert dagmc_u1.volume == dagmc_u.volume
assert dagmc_u1.auto_geom_ids == dagmc_u.auto_geom_ids
assert dagmc_u1.auto_mat_ids == dagmc_u.auto_mat_ids
assert dagmc_u1.length_multiplier == dagmc_u.length_multiplier

# Change attributes, check the clone remained intact
dagmc_u.name = "another name"
dagmc_u.auto_geom_ids = False
dagmc_u.auto_mat_ids = False
dagmc_u.length_multiplier = 2.0
dagmc_u.volume = 2.
assert dagmc_u1.name != dagmc_u.name
assert dagmc_u1.volume != dagmc_u.volume
assert dagmc_u1.auto_geom_ids != dagmc_u.auto_geom_ids
assert dagmc_u1.auto_mat_ids != dagmc_u.auto_mat_ids
assert dagmc_u1.length_multiplier != dagmc_u.length_multiplier


def test_dagmc_length_multiplier_xml_roundtrip():
dagmc_u = openmc.DAGMCUniverse(filename="dagmc.h5m", universe_id=100, length_multiplier=0.1)
root = ET.Element('geometry')
dagmc_u.create_xml_subelement(root)
dagmc_elem = root.find('dagmc_universe')
assert dagmc_elem.get('length_multiplier') == '0.1'
dagmc_u_roundtrip = openmc.DAGMCUniverse.from_xml_element(dagmc_elem)
assert dagmc_u_roundtrip.length_multiplier == 0.1
default_elem = ET.fromstring('<dagmc_universe id="100" filename="dagmc.h5m"/>')
default_univ = openmc.DAGMCUniverse.from_xml_element(default_elem)
assert default_univ.length_multiplier == 1.0


def test_create_xml(cell_with_lattice):
Expand Down
Loading