@@ -37,10 +37,10 @@ class DAGMCUniverse(openmc.UniverseBase):
3737 Set IDs automatically on initialization (True) or report overlaps in ID
3838 space between OpenMC and UWUW materials (False)
3939 material_overrides : dict, optional
40- A dictionary of material overrides. The keys are material name strings
41- and the values are Iterables of openmc.Material objects. If a material
42- name is found in the DAGMC file, the material will be replaced with the
43- openmc.Material object in the value .
40+ A dictionary of material overrides. Keys are cell IDs (or
41+ :class:` openmc.DAGMCCell` objects), and values are
42+ :class:`openmc.Material` objects or iterables of
43+ :class:` openmc.Material` objects .
4444
4545 Attributes
4646 ----------
@@ -130,6 +130,8 @@ def filename(self, val: cv.PathLike):
130130
131131 @property
132132 def material_overrides (self ):
133+ if self .cells :
134+ return self ._get_cell_material_overrides ()
133135 return self ._material_overrides
134136
135137 @material_overrides .setter
@@ -201,7 +203,11 @@ def add_material_override(self, key, overrides=None):
201203 if key not in self .cells :
202204 raise ValueError (f"Cell ID '{ key } ' not found in DAGMC universe" )
203205
204- self ._material_overrides [key ] = overrides
206+ self ._material_overrides [key ] = list (overrides )
207+ if len (overrides ) == 1 :
208+ self .cells [key ].fill = overrides [0 ]
209+ else :
210+ self .cells [key ].fill = list (overrides )
205211
206212 @property
207213 def auto_geom_ids (self ):
@@ -281,6 +287,21 @@ def n_cells(self):
281287 def n_surfaces (self ):
282288 return self ._n_geom_elements ('surface' )
283289
290+ def _get_cell_material_overrides (self ):
291+ overrides = {}
292+ for cell in self .cells .values ():
293+ if cell .fill_type == 'material' :
294+ overrides [cell .id ] = [cell .fill ]
295+ elif cell .fill_type == 'distribmat' :
296+ overrides [cell .id ] = list (cell .fill )
297+ elif cell .fill_type == 'void' :
298+ overrides [cell .id ] = [None ]
299+ else :
300+ raise ValueError (
301+ "Only material fills are supported for DAGMC cell "
302+ "overrides." )
303+ return overrides
304+
284305 def create_xml_subelement (self , xml_element , memo = None ):
285306 if memo is None :
286307 memo = set ()
@@ -290,12 +311,6 @@ def create_xml_subelement(self, xml_element, memo=None):
290311
291312 memo .add (self )
292313
293- # Ensure that the material overrides are up-to-date
294- for cell in self .cells .values ():
295- if cell .fill is None :
296- continue
297- self .add_material_override (cell , cell .fill )
298-
299314 # Set xml element values
300315 dagmc_element = ET .Element ('dagmc_universe' )
301316 dagmc_element .set ('id' , str (self .id ))
@@ -307,17 +322,11 @@ def create_xml_subelement(self, xml_element, memo=None):
307322 if self .auto_mat_ids :
308323 dagmc_element .set ('auto_mat_ids' , 'true' )
309324 dagmc_element .set ('filename' , str (self .filename ))
310- if self ._material_overrides :
311- mat_element = ET .Element ('material_overrides' )
312- for key in self ._material_overrides :
313- cell_overrides = ET .Element ('cell_override' )
314- cell_overrides .set ("id" , str (key ))
315- material_element = ET .Element ('material_ids' )
316- material_element .text = ' ' .join (
317- str (t .id ) for t in self ._material_overrides [key ])
318- cell_overrides .append (material_element )
319- mat_element .append (cell_overrides )
320- dagmc_element .append (mat_element )
325+ if self .cells :
326+ self ._material_overrides = self ._get_cell_material_overrides ()
327+ for cell in self .cells .values ():
328+ cell_element = cell .create_xml_subelement (xml_element , memo )
329+ dagmc_element .append (cell_element )
321330 xml_element .append (dagmc_element )
322331
323332 def bounding_region (
@@ -442,7 +451,7 @@ def from_hdf5(cls, group):
442451 return out
443452
444453 @classmethod
445- def from_xml_element (cls , elem , mats = None ):
454+ def from_xml_element (cls , elem , mats = None ):
446455 """Generate DAGMC universe from XML element
447456
448457 Parameters
@@ -471,21 +480,59 @@ def from_xml_element(cls, elem, mats = None):
471480 out .auto_geom_ids = bool (get_text (elem , "auto_geom_ids" ))
472481 out .auto_mat_ids = bool (get_text (elem , "auto_mat_ids" ))
473482
474- el_mat_override = elem .find ('material_overrides' )
475- if el_mat_override is not None :
476- if mats is None :
477- raise ValueError ("Material overrides found in DAGMC universe "
478- "but no materials were provided to populate "
479- "the mapping." )
480- out ._material_overrides = {}
481- for elem in el_mat_override .findall ('cell_override' ):
482- cell_id = int (get_text (elem , 'id' ))
483- mat_ids = get_elem_list (elem , "material_ids" , str ) or []
484- mat_objs = [mats [mat_id ] for mat_id in mat_ids ]
485- out ._material_overrides [cell_id ] = mat_objs
483+ if elem .find ('material_overrides' ) is not None :
484+ raise ValueError (
485+ "DAGMCUniverse <material_overrides> is no longer supported. "
486+ "Use nested <cell> elements under <dagmc_universe> instead." )
487+
488+ if elem .find ('cell' ) is not None :
489+ out ._parse_cell_overrides (elem , mats )
486490
487491 return out
488492
493+ def _parse_cell_overrides (self , elem , mats ):
494+ if mats is None :
495+ raise ValueError ("DAGMC cell overrides found in DAGMC universe but "
496+ "no materials were provided to populate the "
497+ "mapping." )
498+
499+ self ._material_overrides = {}
500+ for cell_elem in elem .findall ('cell' ):
501+ cell_id = int (get_text (cell_elem , 'id' ))
502+ name = get_text (cell_elem , 'name' )
503+
504+ if get_text (cell_elem , 'region' ) is not None :
505+ raise ValueError ("DAGMC cell overrides cannot include a region." )
506+ if get_text (cell_elem , 'fill' ) is not None :
507+ raise ValueError ("DAGMC cell overrides currently only support "
508+ "material fills." )
509+ if get_text (cell_elem , 'universe' ) is not None :
510+ raise ValueError ("DAGMC cell overrides cannot specify a "
511+ "universe." )
512+ for tag in ('temperature' , 'density' , 'translation' , 'rotation' , 'volume' ):
513+ if get_text (cell_elem , tag ) is not None :
514+ raise ValueError (
515+ "DAGMC cell overrides currently only support material "
516+ f"fills (found unsupported '{ tag } ' for cell { cell_id } )." )
517+
518+ mat_ids = get_elem_list (cell_elem , 'material' , str )
519+ if mat_ids is None :
520+ raise ValueError (
521+ f"DAGMC cell { cell_id } must specify a material override." )
522+
523+ mat_objs = [mats [mat_id ] for mat_id in mat_ids ]
524+ if len (mat_objs ) == 1 :
525+ fill = mat_objs [0 ]
526+ else :
527+ fill = mat_objs
528+
529+ if cell_id in self .cells :
530+ raise ValueError (
531+ f"Duplicate DAGMC cell override specified for cell { cell_id } ." )
532+ self .add_cell (openmc .DAGMCCell (
533+ cell_id = cell_id , name = name or '' , fill = fill ))
534+ self ._material_overrides [cell_id ] = mat_objs
535+
489536 def _partial_deepcopy (self ):
490537 """Clone all of the openmc.DAGMCUniverse object's attributes except for
491538 its cells, as they are copied within the clone function. This should
@@ -625,7 +672,15 @@ def plot(self, *args, **kwargs):
625672 raise TypeError ("plot is not available for DAGMC cells." )
626673
627674 def create_xml_subelement (self , xml_element , memo = None ):
628- raise TypeError ("create_xml_subelement is not available for DAGMC cells." )
675+ if self .fill_type not in ('void' , 'material' , 'distribmat' ):
676+ raise TypeError ("DAGMC cell overrides currently only support "
677+ "material fills." )
678+ if any (getattr (self , attr ) is not None for attr in (
679+ 'temperature' , 'density' , 'translation' , 'rotation' , 'volume'
680+ )):
681+ raise TypeError ("DAGMC cell overrides currently only support "
682+ "material fills." )
683+ return super ().create_xml_subelement (xml_element , memo )
629684
630685 @classmethod
631686 def from_xml_element (cls , elem , surfaces , materials , get_universe ):
0 commit comments