diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 0af2d517..6d5d0c22 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -18,7 +18,8 @@ MontePy Changelog * Allow multiple universe fills to accept 2D MNCP lattices (:issue:`719`). * Make `LatticeType.RECTANGULAR` and `LatticeType.HEXAHEDRAL` synonymous (:issue:`808`). * Allow setting ``cell.fill.universes`` with a numpy array of universe IDs (:issue:`736`). - +* Added Boundary condition type to the representation of a ``montepy.Surface`` (e.g., ``repr(surf)``) (:issue:`682`). +* Changed default importance value from 0.0 to 1.0 to match MCNP defaults. (:issue:`735`) **Bugs Fixed** * Fixed bug where lines that were the allowed length was raising a ``LineOverRunWarning`` when read by MontePy (:issue:`517`). @@ -42,9 +43,8 @@ MontePy Changelog 1.1.3 -------------- -**Features Added** -* Added Boundary condition type to the representation of a ``montepy.Surface`` (e.g., ``repr(surf)``) (:issue:`682`). + **Documentation** diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 58d9e820..e07f372c 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -609,10 +609,10 @@ For example: >>> for particle in sorted(problem.mode): ... print(particle, cell.importance[particle]) - neutron 0.0 - photon 0.0 + neutron 1.0 + photon 1.0 >>> print(cell.importance[montepy.Particle.NEUTRON]) - 0.0 + 1.0 There's also a lot of convenient ways to do bulk modifications. There is the :func:`~montepy.data_inputs.importance.Importance.all` property that lets you set the importance for all particles in the problem at once. @@ -629,7 +629,10 @@ For example: neutron 2.0 photon 2.0 -This will set the importances for the neutron and photon. +This will set the importances for the neutron and photon. + +You can also delete an importance to reset it to the default value (1.0). +For example: ``del cell.importance.neutron``. There is also the method: :func:`~montepy.cells.Cells.set_equal_importance`. This method sets all of the cells for all particles in the problem to the same importance. diff --git a/montepy/cell.py b/montepy/cell.py index d1294a84..429b32d7 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -227,10 +227,17 @@ def importance(self): Each particle's importance is a property of Importance. e.g., ``cell.importance.photon = 1.0``. + Deleting an importance resets it to the default value (1.0). + e.g., ``del cell.importance.neutron``. + Returns ------- Importance the importance for the Cell. + + .. versionchanged:: 1.2.0 + + Default importance value changed from 0.0 to 1.0 to match MCNP defaults. """ return self._importance diff --git a/montepy/data_inputs/importance.py b/montepy/data_inputs/importance.py index 3993b797..61e91826 100644 --- a/montepy/data_inputs/importance.py +++ b/montepy/data_inputs/importance.py @@ -42,6 +42,8 @@ class Importance(CellModifierInput): the value syntax tree from the key-value pair in a cell """ + _DEFAULT_IMP = 1.0 + def __init__( self, input: InitInput = None, @@ -52,6 +54,7 @@ def __init__( self._particle_importances = {} self._real_tree = {} self._part_combos = [] + self._explicitly_set = False super().__init__(input, in_cell_block, key, value) if self.in_cell_block: if key: @@ -62,6 +65,7 @@ def __init__( raise ValueError( f"Cell importance must be a number ≥ 0. {val.value} was given" ) + self._explicitly_set = True self._part_combos.append(self.particle_classifiers) for particle in self.particle_classifiers: self._particle_importances[particle] = value @@ -76,6 +80,7 @@ def __init__( raise MalformedInputError( input, f"Importances must be ≥ 0 value: {node} given" ) + self._explicitly_set = True self._part_combos.append(self.particle_classifiers) for particle in self.particle_classifiers: self._particle_importances[particle] = copy.deepcopy(self._tree) @@ -95,7 +100,7 @@ def _generate_default_cell_tree(self, particle=None): particles.particles = self._problem.mode.particles classifier.particles = particles list_node = syntax_node.ListNode("imp data") - list_node.append(self._generate_default_node(float, 0.0)) + list_node.append(self._generate_default_node(float, self._DEFAULT_IMP)) tree = syntax_node.SyntaxNode( "Importance", { @@ -125,8 +130,17 @@ def _has_classifier(): @property def has_information(self): - if self.in_cell_block: + has_info = [] + for part in self: + has_info.append( + not math.isclose( + self[part], self._DEFAULT_IMP, rel_tol=rel_tol, abs_tol=abs_tol + ) + ) + if any(has_info): return True + if self.in_cell_block: + return self.set_in_cell_block def merge(self, other): if not isinstance(other, type(self)): @@ -163,7 +177,7 @@ def __getitem__(self, particle): val = self._particle_importances[particle]["data"][0] return val.value except KeyError: - return 0.0 + return self._DEFAULT_IMP def __setitem__(self, particle, value): if not isinstance(particle, Particle): @@ -175,6 +189,7 @@ def __setitem__(self, particle, value): raise ValueError("importance must be ≥ 0") if particle not in self._particle_importances: self._generate_default_cell_tree(particle) + self._explicitly_set = True self._particle_importances[particle]["data"][0].value = value def __delitem__(self, particle): @@ -213,6 +228,7 @@ def push_to_cells(self): value = self._particle_importances[particle]["data"][i] # force generating the default tree cell.importance[particle] = value.value + cell.importance._explicitly_set = True # replace default ValueNode with actual valueNode tree = cell.importance._particle_importances[particle] tree.nodes["classifier"] = copy.deepcopy( @@ -284,6 +300,7 @@ def all(self, value): if value < 0.0: raise ValueError("Importance must be ≥ 0.0") if self._problem: + self._explicitly_set = True for particle in self._problem.mode: self._particle_importances[particle]["data"][0].value = value @@ -506,7 +523,7 @@ def __create_particle_imp_doc(particle_type): Returns ------- float - the importance for the particle type. If not set, defaults to 0. + the importance for the particle type. If not set, defaults to 1.0. """ diff --git a/pyproject.toml b/pyproject.toml index 5a8f71bf..e9506a34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,8 @@ authors = [ {name = "Brenna Carbno", email="brenna.carbno@inl.gov"}, {name = "Benjaminas Marcinkevicius", email="BenjaminasDev@outlook.com"}, {name = "Paul Ferney", email="Paul.Ferney@inl.gov"}, - {name = "Digvijay Yeware", email="yewaredigvijay@gmail.com"} + {name = "Digvijay Yeware", email="yewaredigvijay@gmail.com"}, + {name = "Harsh Dayal", email="harshdayal13@gmail.com"}, ] keywords = ["MCNP", "neutronics", "imcnp", "input file", "monte carlo", "radiation transport"] license = "MIT" diff --git a/tests/test_importance.py b/tests/test_importance.py index 57ae99d1..6210691e 100644 --- a/tests/test_importance.py +++ b/tests/test_importance.py @@ -28,7 +28,7 @@ def create_cell_from_input(self, in_str, block=block_type.BlockType.CELL): "neutron": 1.0, "photon": 1.0, "all": None, - "alpha_particle": 0.0, + "alpha_particle": 1.0, "in_cell_block": True, }, None, @@ -40,7 +40,7 @@ def create_cell_from_input(self, in_str, block=block_type.BlockType.CELL): ), ( "1 0 -1", - {"neutron": 0.0}, + {"neutron": 1.0}, None, ), # default neutron importance when nothing is set # Error cases @@ -267,9 +267,9 @@ def test_importance_deleter(self, cell_with_importance): """ cell = cell_with_importance del cell.importance.neutron - assert cell.importance.neutron == pytest.approx(0.0) + assert cell.importance.neutron == pytest.approx(1.0) del cell.importance[Particle.PHOTON] - assert cell.importance.photon == pytest.approx(0.0) + assert cell.importance.photon == pytest.approx(1.0) with pytest.raises(TypeError): del cell.importance[""] @@ -312,3 +312,8 @@ def test_default_importance_not_implemented(self): prob.print_in_data_block["imp"] = True with pytest.raises(NotImplementedError): prob.write_problem(io.StringIO()) + + def test_default_cell_importance(self): + """Test that new cells have default importance of 1.0 (Issue #735)""" + cell = montepy.Cell() + assert cell.importance.neutron == 1.0 diff --git a/tests/test_integration.py b/tests/test_integration.py index b90c9e93..041b1eaf 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1121,10 +1121,8 @@ def test_alternate_encoding(): _SKIP_LINES = { - # skip lines of added implied importances - "tests/inputs/test_universe_data.imcnp": {5: 1, 14: 1, 15: 1}, - # I don't care about the edge case of shortcuts in a material def. - "tests/inputs/test_complement_edge.imcnp": {37: 0, 38: 0, 39: 0}, + "tests\\inputs\\test_complement_edge.imcnp": {38: 0, 39: 0}, + "tests\\inputs\\test_interp_edge.imcnp": {1: 0}, } @@ -1169,10 +1167,6 @@ def test_read_write_cycle(file): continue else: gold_line = next(gold_fh_iter) - # edge case override for not fixing #527. - if str(file) == "tests/inputs/test_interp_edge.imcnp" and i == 1: - assert new_line == "10214 0 (1 2I 4 )" - continue try: assert new_line == gold_line.rstrip().expandtabs(8) except AssertionError as e: