diff --git a/idaes/core/scaling/custom_scaler_base.py b/idaes/core/scaling/custom_scaler_base.py index 0d47673805..8e94cc7c5a 100644 --- a/idaes/core/scaling/custom_scaler_base.py +++ b/idaes/core/scaling/custom_scaler_base.py @@ -554,8 +554,7 @@ def propagate_state_scaling( def call_submodel_scaler_method( self, - model, - submodel: str, + submodel, method: str, submodel_scalers: ComponentMap = None, overwrite: bool = False, @@ -567,8 +566,7 @@ def call_submodel_scaler_method( default scaler for the submodel is used. Args: - model: parent model of submodel - submodel: local name of submodel to be scaled as str + submodel: submodel to be scaled submodel_scalers: user provided ComponentMap of Scalers to use for submodels method: name of method to call from submodel (as string) overwrite: whether to overwrite existing scaling factors @@ -576,39 +574,32 @@ def call_submodel_scaler_method( Returns: None """ - # Get actual submodel object from name - # For this method, we have to use the component name as the Scaler is written - # before the model is constructed. - sm_obj = model.find_component(submodel) - if submodel_scalers is None: submodel_scalers = {} # Iterate over indices of submodel - for smdata in sm_obj.values(): + for smdata in submodel.values(): # Get Scaler for submodel - if sm_obj in submodel_scalers: - scaler = submodel_scalers[sm_obj] + if submodel in submodel_scalers: + scaler = submodel_scalers[submodel] if callable(scaler): # Check to see if Scaler is callable - this implies it is a class and not an instance # Call the class to create an instance scaler = scaler() - _log.debug(f"Using user-defined Scaler for {model}.{submodel}.") + _log.debug(f"Using user-defined Scaler for {submodel}.") else: try: scaler = smdata.default_scaler - _log.debug(f"Using default Scaler for {model}.{submodel}.") + _log.debug(f"Using default Scaler for {submodel}.") except AttributeError: _log.debug( - f"No default Scaler set for {model}.{submodel}. Cannot call {method}." + f"No default Scaler set for {submodel}. Cannot call {method}." ) return if scaler is not None: scaler = scaler() else: - _log.debug( - f"No Scaler found for {model}.{submodel}. Cannot call {method}." - ) + _log.debug(f"No Scaler found for {submodel}. Cannot call {method}.") # If a Scaler is found, call desired method if scaler is not None: @@ -616,6 +607,6 @@ def call_submodel_scaler_method( smeth = getattr(scaler, method) except AttributeError: raise AttributeError( - f"Scaler for {model}.{submodel} does not have a method named {method}." + f"Scaler for {submodel} does not have a method named {method}." ) smeth(smdata, overwrite=overwrite) diff --git a/idaes/core/scaling/tests/test_custom_scaler_base.py b/idaes/core/scaling/tests/test_custom_scaler_base.py index e3e9637807..6cd6697e60 100644 --- a/idaes/core/scaling/tests/test_custom_scaler_base.py +++ b/idaes/core/scaling/tests/test_custom_scaler_base.py @@ -608,15 +608,12 @@ def test_call_submodel_scaler_method_no_scaler(self, caplog): m.b = Block([1, 2, 3]) sb = CustomScalerBase() - sb.call_submodel_scaler_method(m, "b", method="dummy_method", overwrite=True) + sb.call_submodel_scaler_method(m.b, method="dummy_method", overwrite=True) for bd in m.b.values(): assert not hasattr(bd, "_dummy_scaler_test") - assert ( - "No default Scaler set for unknown.b. Cannot call dummy_method." - in caplog.text - ) + assert "No default Scaler set for b. Cannot call dummy_method." in caplog.text @pytest.mark.unit def test_call_submodel_scaler_method_default_scaler(self, caplog): @@ -629,12 +626,12 @@ def test_call_submodel_scaler_method_default_scaler(self, caplog): bd.default_scaler = DummyScaler sb = CustomScalerBase() - sb.call_submodel_scaler_method(m, "b", method="dummy_method", overwrite=True) + sb.call_submodel_scaler_method(m.b, method="dummy_method", overwrite=True) for bd in m.b.values(): assert bd._dummy_scaler_test - assert "Using default Scaler for unknown.b." in caplog.text + assert "Using default Scaler for b." in caplog.text @pytest.mark.unit def test_call_submodel_scaler_method_user_scaler(self, caplog): @@ -649,8 +646,7 @@ def test_call_submodel_scaler_method_user_scaler(self, caplog): sb = CustomScalerBase() sb.call_submodel_scaler_method( - m, - "b", + m.b, method="dummy_method", submodel_scalers=scaler_map, overwrite=False, @@ -659,7 +655,7 @@ def test_call_submodel_scaler_method_user_scaler(self, caplog): for bd in m.b.values(): assert not bd._dummy_scaler_test - assert "Using user-defined Scaler for unknown.b." in caplog.text + assert "Using user-defined Scaler for b." in caplog.text @pytest.mark.unit def test_call_submodel_scaler_method_user_scaler_class(self, caplog): @@ -674,8 +670,7 @@ def test_call_submodel_scaler_method_user_scaler_class(self, caplog): sb = CustomScalerBase() sb.call_submodel_scaler_method( - m, - "b", + m.b, method="dummy_method", submodel_scalers=scaler_map, overwrite=False, @@ -684,27 +679,4 @@ def test_call_submodel_scaler_method_user_scaler_class(self, caplog): for bd in m.b.values(): assert not bd._dummy_scaler_test - assert "Using user-defined Scaler for unknown.b." in caplog.text - - @pytest.mark.unit - def test_call_submodel_scaler_method_invalid_method(self): - # Dummy up a nested model - m = ConcreteModel() - m.b = Block([1, 2, 3]) - - scaler_map = ComponentMap() - scaler_map[m.b] = DummyScaler() - - sb = CustomScalerBase() - - with pytest.raises( - AttributeError, - match="Scaler for unknown.b does not have a method named foo.", - ): - sb.call_submodel_scaler_method( - m, - "b", - method="foo", - submodel_scalers=scaler_map, - overwrite=False, - ) + assert "Using user-defined Scaler for b." in caplog.text diff --git a/idaes/models/unit_models/equilibrium_reactor.py b/idaes/models/unit_models/equilibrium_reactor.py index a8a92c96ae..5c915fb8ba 100644 --- a/idaes/models/unit_models/equilibrium_reactor.py +++ b/idaes/models/unit_models/equilibrium_reactor.py @@ -76,8 +76,7 @@ def variable_scaling_routine( """ # Call scaling methods for sub-models self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_in", + submodel=model.control_volume.properties_in, method="variable_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, @@ -89,15 +88,13 @@ def variable_scaling_routine( ) self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_out", + submodel=model.control_volume.properties_out, method="variable_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, ) self.call_submodel_scaler_method( - model=model, - submodel="control_volume.reactions", + submodel=model.control_volume.reactions, method="variable_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, @@ -121,6 +118,8 @@ def variable_scaling_routine( for t in model.flowsheet().time: h_in = 0 for p in model.control_volume.properties_in.phase_list: + # The expression for enthalpy flow might include multiple terms, + # so we will sum over all the terms provided h_in += sum( self.get_expression_nominal_values( model.control_volume.properties_in[ @@ -130,7 +129,7 @@ def variable_scaling_routine( ) # Scale for heat is general one order of magnitude less than enthalpy flow self.set_variable_scaling_factor( - model.control_volume.heat[t], 1 / (0.1 * h_in) + model.control_volume.heat[t], abs(1 / (0.1 * h_in)) ) def constraint_scaling_routine( @@ -152,22 +151,19 @@ def constraint_scaling_routine( """ # Call scaling methods for sub-models self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_in", + submodel=model.control_volume.properties_in, method="constraint_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, ) self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_out", + submodel=model.control_volume.properties_out, method="constraint_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, ) self.call_submodel_scaler_method( - model=model, - submodel="control_volume.reactions", + submodel=model.control_volume.reactions, method="constraint_scaling_routine", submodel_scalers=submodel_scalers, overwrite=overwrite, diff --git a/idaes/models/unit_models/gibbs_reactor.py b/idaes/models/unit_models/gibbs_reactor.py index 26d1c56458..d9aa799f7c 100644 --- a/idaes/models/unit_models/gibbs_reactor.py +++ b/idaes/models/unit_models/gibbs_reactor.py @@ -86,16 +86,14 @@ def variable_scaling_routine( # Step 1b: Call Scalers for state blocks # Inlet properties self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_in", + submodel=model.control_volume.properties_in, submodel_scalers=submodel_scalers, method="variable_scaling_routine", overwrite=overwrite, ) # Outlet properties self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_out", + submodel=model.control_volume.properties_out, submodel_scalers=submodel_scalers, method="variable_scaling_routine", overwrite=overwrite, @@ -152,16 +150,14 @@ def constraint_scaling_routine( # Step 1: Call Scalers for state blocks # Inlet properties self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_in", + submodel=model.control_volume.properties_in, submodel_scalers=submodel_scalers, method="constraint_scaling_routine", overwrite=overwrite, ) # Outlet properties self.call_submodel_scaler_method( - model=model, - submodel="control_volume.properties_out", + submodel=model.control_volume.properties_out, submodel_scalers=submodel_scalers, method="constraint_scaling_routine", overwrite=overwrite, diff --git a/idaes/models/unit_models/tests/test_gibbs.py b/idaes/models/unit_models/tests/test_gibbs.py index b74e4517d3..726cd083c0 100644 --- a/idaes/models/unit_models/tests/test_gibbs.py +++ b/idaes/models/unit_models/tests/test_gibbs.py @@ -636,8 +636,8 @@ def model(self): scaler.scale_model( m.fs.unit, submodel_scalers={ - "control_volume.properties_in": PropertyScaler, - "control_volume.properties_out": PropertyScaler, + m.fs.unit.control_volume.properties_in: PropertyScaler, + m.fs.unit.control_volume.properties_out: PropertyScaler, }, )