surfaceFilter when using dagmc geometry

Hello,

I am modelling a fusion reactor using DAGMC geometries. Up until now I have been using meshes for tallying which has worked great.

I am now looking to tally using surfaceFilters so I can evaluate the effectiveness of different shields. Is there a way to use a dagmc geometry to define the surface for the surfaceFilter? If not, is there a way to superimpose a surface on top of the existing DAGMC geometry which won’t affect the geometry or the neutronics paths, but will allow me to tally the surface? For example if I could create a cylindrical surface in the middle of my DAGMC geometry to tally it.

I hope that makes sense.
Thank you!

Interesting question @maarten! I haven’t actually tried this myself, but you should be able to specify the surface by ID on a SurfaceFilter. You’d have to use Cubit or the like to inspect the DAGMC model to determine the surface ID though I’m afraid.

Alternatively, I think you could super impose a CSG surface, yes. Your DAGMC model would be in a universe that fills the cells on either side of that superimposed surface. It’s a creative idea!

I did just do a run with a surface filter applied using valid DAGMC surface IDs to convince myself. Everything seemed to work just fine. Do let me know if you run into any issues though!

Hi @pshriwise, thanks for the reply!

Sadly I don’t have access to cubit so I won’t be able to get the surface IDs from that, otherwise that would have been great (for anyone else looking to do a similar thing).

Regarding the CSG surface. I have been playing around with the concept a bit but can’t really get it to work. How would it related to my dagmcUniverse? When I do it, the surface ends up cutting my dagmc geometry depending on the region I’ve defined. I guess my issue is defining a surface that doesn’t actually affect the overall geometry at all? Once you haev the surface defined then setting the surfaceFilter shouldn’t be an issue.

This is what I’m trying to do at the moment, but I know it’s wrong because it removes everything inside of the cylinder surface (since the region is -self.cylinder). Probably I’m doing something silly when defining the surface.

‘’'python

    # Create universe for CAD
    dag_universe = openmc.DAGMCUniverse(h5m_filename, auto_geom_ids=True) 
    self.cad_bounding_box = dag_universe.bounding_box
    
    # Define surrounding empty space, "graveyard"   
    graveyard = openmc.Sphere(r=10000, surface_id=9999, boundary_type='vacuum')

    # Create the cell that contains everything and fill it with the dagmc_universe
    containment_cell = openmc.Cell(cell_id=9999, region=region, fill=dag_universe)

    ### Create cylindrical surfaces for tallying ###
    radius = 100
    self.cylinder = openmc.ZCylinder(x0=0, y0=0, r=radius, 
        boundary_type='transmission')
    cylinder_cell = openmc.Cell(name='cylinder_surface_filter')

    # Create geometry object and export 
    geometry = openmc.Geometry(root=[containment_cell, cylinder_cell])

‘’’

You may be on the right track, @maarten. But I’ll need more lines of code to tell for sure. I can mock up what I had in mind though. If you have a dagmc universe:

dag_universe = openmc.DAGMCUniverse(h5m_filename, auto_geom_ids=True)

Then you should be able to create a new universe with a CSG surface inserted like so:

# defaults for x and y are zero, and the default boundary condition is transmission
radius = 100
cylinder = openmc.ZCylinder(r=radius)

# create two cells that are filled with the DAGMC universe, 
# one with a region that is the inside of the cylinder and
# another with a region that is the outside of the cylinder
inside_cyl = openmc.Cell(region=-cylinder, fill=dag_universe)
outside_cyl = openmc.Cell(region=+cylinder, fill=dag_universe)

# create a new universe that contains both of these cells
inner_universe = openmc.Universe([inside_cyl, outside_cyl])

# put this new universe into the containing cell
containment_cell = openmc.Sphere(r=10000, boundary_type='vacuum')

geometry = openmc.Geometry(root=[containment_cell])

That should represent your original DAGMC geometry with a CSG surface inserted that you can tally on. There will be a little bit of extra overhead as particles will always stop on that new surface where they wouldn’t before, but it shouldn’t be significant. Do let me know if you observe otherwise though.

I hope this helps!

-Patrick

Hi,

That’s really good, thank you.

Now that I see your example, silly enough, it made me realise that I’ve already done something similar (couldn’t see the forest for the trees?). I normally only model an angular section of a fusion reactor since I assume that it is symmetrical all the way around. When I do this I take two planes and only use the slice of the dagmc-universe that is between them. So your method should definitely work, I just need to add the extra regions.

This is how I normally do it:

‘’’

    dag_universe = openmc.DAGMCUniverse(h5m_filename, auto_geom_ids=True) 
    self.cad_bounding_box = dag_universe.bounding_box
    
    # Define surrounding empty space, "graveyard"   
    graveyard = openmc.Sphere(r=10000, surface_id=9999, boundary_type='vacuum')

    # Add reflective surfaces on planes where we model the section of the reactor
    # Only if we want to simulate a toroidal section of the reactor   
    self.angles_rad = np.deg2rad(self.input_file['section_angles'])
    reflective_1 = openmc.Plane(
        a=np.sin(self.angles_rad[0]), 
        b=-np.cos(self.angles_rad[0]), 
        c=0.0, 
        d=0.0, 
        surface_id=9991, 
        boundary_type='reflective')
    reflective_2 = openmc.Plane(
        a=np.sin(self.angles_rad[1]), 
        b=-np.cos(self.angles_rad[1]), 
        c=0.0, 
        d=0.0, 
        surface_id=9992, 
        boundary_type='reflective')

    region = -graveyard & -reflective_1 & +reflective_2
    
    # Create the cell that contains everything and fill it with the dagmc_universe
    containment_cell = openmc.Cell(cell_id=9999, region=region, fill=dag_universe)

    # Create geometry object and export 
    geometry = openmc.Geometry(root=[containment_cell])
    geometry.export_to_xml(path=self.input_file['save_dir'])

‘’’

Thank you for the help!

1 Like