11from itertools import product
22from pathlib import Path
3+ from math import sqrt
4+ import random
35
46import pytest
57import numpy as np
@@ -334,13 +336,10 @@ def test_umesh_source_independent(run_in_tmpdir, request, void_model, library):
334336 n_elements = 12_000
335337 model .settings .source = openmc .MeshSource (uscd_mesh , n_elements * [ind_source ])
336338 model .export_to_model_xml ()
337- try :
338- openmc .lib .init ()
339+ with openmc .lib .run_in_memory ():
339340 openmc .lib .simulation_init ()
340341 sites = openmc .lib .sample_external_source (10 )
341342 openmc .lib .statepoint_write ('statepoint.h5' )
342- finally :
343- openmc .lib .finalize ()
344343
345344 with openmc .StatePoint ('statepoint.h5' ) as sp :
346345 uscd_mesh = sp .meshes [uscd_mesh .id ]
@@ -351,51 +350,53 @@ def test_umesh_source_independent(run_in_tmpdir, request, void_model, library):
351350 assert site .r in bounding_box
352351
353352
354- def test_mesh_source_file (run_in_tmpdir ):
355- # Creating a source file with a single particle
356- source_particle = openmc .SourceParticle (time = 10.0 )
357- openmc .write_source_file ([source_particle ], 'source.h5' )
358- file_source = openmc .FileSource ('source.h5' )
353+ def test_mesh_source_constraints (run_in_tmpdir ):
354+ """Test application of constraints to underlying mesh element sources"""
359355
356+ # Create simple model with two cells
357+ m1 = openmc .Material ()
358+ m1 .add_nuclide ('H1' , 1.0 )
359+ m2 = m1 .clone ()
360+ sph = openmc .Sphere (r = 100 , boundary_type = 'vacuum' )
361+ box1 = openmc .model .RectangularParallelepiped (- 1 , 0 , - 1 , 1 , - 1 , 1 )
362+ box2 = openmc .model .RectangularParallelepiped (0 , 2 , - 1 , 1 , - 1 , 1 )
363+ cell1 = openmc .Cell (fill = m1 , region = - box1 )
364+ cell2 = openmc .Cell (fill = m2 , region = - box2 )
365+ outer = openmc .Cell (region = - sph & (+ box1 | + box2 ))
360366 model = openmc .Model ()
367+ model .geometry = openmc .Geometry ([cell1 , cell2 , outer ])
361368
362- rect_prism = openmc .model .RectangularParallelepiped (
363- - 5.0 , 5.0 , - 5.0 , 5.0 , - 5.0 , 5.0 , boundary_type = 'vacuum' )
364-
365- mat = openmc .Material ()
366- mat .add_nuclide ('H1' , 1.0 )
367-
368- model .geometry = openmc .Geometry ([openmc .Cell (fill = mat , region = - rect_prism )])
369- model .settings .particles = 1000
370- model .settings .batches = 10
371- model .settings .run_mode = 'fixed source'
372-
369+ # Define a mesh covering the two cells: the first mesh element contains
370+ # cell1 (-1 < x < 0) and the second element contains cells2 (0 < x < 2)
373371 mesh = openmc .RegularMesh ()
374- mesh .lower_left = (- 1 , - 2 , - 3 )
375- mesh .upper_right = (2 , 3 , 4 )
376- mesh .dimension = (1 , 1 , 1 )
372+ mesh .lower_left = (- 3. , - 1. , - 1. )
373+ mesh .upper_right = (3. , 1. , 1. )
374+ mesh .dimension = (2 , 1 , 1 )
377375
378- model .settings .source = openmc .MeshSource (mesh , [file_source ])
376+ # Define a mesh source with a randomly chosen probability
377+ p = random .random ()
378+ src1 = openmc .IndependentSource (strength = p , constraints = {'domains' : [cell1 ]})
379+ src2 = openmc .IndependentSource (strength = 1 - p , constraints = {'domains' : [cell2 ]})
380+ model .settings .source = openmc .MeshSource (mesh , [src1 , src2 ])
379381
382+ # Finish settings and export
383+ model .settings .particles = 100
384+ model .settings .batches = 1
380385 model .export_to_model_xml ()
381386
382- openmc .lib .init ()
383- openmc .lib .simulation_init ()
384- sites = openmc .lib .sample_external_source (10 )
385- openmc .lib .simulation_finalize ()
386- openmc .lib .finalize ()
387+ with openmc .lib .run_in_memory ():
388+ # Sample sites from the source
389+ sites = openmc .lib .sample_external_source (N := 1000 )
387390
388- # The mesh bounds do not contain the point of the lone source site in the
389- # file source, so it should not appear in the set of source sites produced
390- # from the mesh source. Additionally, the source should be located within
391- # the mesh
392- bbox = mesh .bounding_box
393- for site in sites :
394- assert site .r != (0 , 0 , 0 )
395- assert site .E == source_particle .E
396- assert site .u == source_particle .u
397- assert site .time == source_particle .time
398- assert site .r in bbox
391+ # Check that all sites are either in cell1 or cell2
392+ xs = np .array ([s .r [0 ] for s in sites ])
393+ assert (xs >= - 1.0 ).all ()
394+ assert (xs <= 2.0 ).all ()
395+
396+ # Check that the correct percentage of the sites are in cell1
397+ sigma = sqrt (p * (1 - p )/ N )
398+ frac = xs [(- 1.0 <= xs ) & (xs <= 0.0 )].size / N
399+ assert frac == pytest .approx (p , abs = 5 * sigma )
399400
400401
401402@pytest .mark .parametrize ("mesh_type" , ('rectangular' , 'cylindrical' , 'spherical' ))
0 commit comments