From bf77cc11620ed6f37f36a9f08585c7be59fb5c05 Mon Sep 17 00:00:00 2001 From: daklauss Date: Wed, 31 Jul 2024 17:33:09 +0200 Subject: [PATCH] Added tests to the residual calculation of DEF CAKEVOLUME and PRESSURE DROP Adjusted tests for unit_operation to the new CPSComponentsystem --- CADETPythonSimulator/residual.py | 14 +-- CADETPythonSimulator/unit_operation.py | 14 ++- tests/test_residual.py | 130 ++++++++++++++++++++++--- tests/test_unit_operation.py | 4 +- 4 files changed, 135 insertions(+), 27 deletions(-) diff --git a/CADETPythonSimulator/residual.py b/CADETPythonSimulator/residual.py index 8fc2318..52c97c8 100644 --- a/CADETPythonSimulator/residual.py +++ b/CADETPythonSimulator/residual.py @@ -79,7 +79,7 @@ def calculate_residual_visc_cstr(): def calculate_residual_cake_vol_def( V_dot_f : float, - eff : np.ndarray, + rejection : np.ndarray, molar_volume : np.ndarray, c_in : np.ndarray, V_dot_C : float @@ -90,16 +90,16 @@ def calculate_residual_cake_vol_def( Parameters ---------- V_dot_f : float - flowrate of incoming feed - eff : float - efficency of the filter + Flowrate of incoming feed + rejection : float + Rejection of the filter gamma : float - portion of suspended material + Portion of suspended material V_dot_C : float - change of Cake Volume + Change of Cake Volume """ - return -V_dot_C + np.sum(eff * molar_volume * c_in * V_dot_f) + return -V_dot_C + np.sum(rejection * molar_volume * c_in * V_dot_f) def calculate_residual_press_easy_def( diff --git a/CADETPythonSimulator/unit_operation.py b/CADETPythonSimulator/unit_operation.py index 6013593..1a2a1bd 100644 --- a/CADETPythonSimulator/unit_operation.py +++ b/CADETPythonSimulator/unit_operation.py @@ -11,6 +11,7 @@ ) from CADETProcess.dynamicEvents import Section +from CADETPythonSimulator.componentsystem import CPSComponentSystem from CADETPythonSimulator.exception import NotInitializedError, CADETPythonSimError from CADETPythonSimulator.state import State, state_factory from CADETPythonSimulator.residual import ( @@ -40,7 +41,7 @@ class UnitOperationBase(Structure): """ name = String() - component_system = Typed(ty=ComponentSystem) + component_system = Typed(ty=CPSComponentSystem) _state_structures = [] _parameters = [] @@ -657,17 +658,20 @@ def compute_residual( deltap = self.states['cake']['pressure'] #parameters - efficency = self.parameters['efficency'] - molar_volume = self.parameters['molar_volume'] + molecular_weights = self.component_system.molecular_weights + molar_volume = self.component_system.molecular_volumes membrane_area = self.parameters['membrane_area'] membrane_resistance = self.parameters['membrane_resistance'] specific_cake_resistance = self.parameters['specific_cake_resistance'] + rejection = np.array( + [self.rejection.get_rejection(mw) for mw in molecular_weights]) + # Handle inlet DOFs, which are simply copied to the residual self.residuals['cake']['c'] = c_in self.residuals['cake']['cakevolume'] = calculate_residual_cake_vol_def( Q_in, - efficency, + rejection, molar_volume, c_in, V_dot_C @@ -692,7 +696,7 @@ def compute_residual( self.residuals['cake']['viscosity'] = calculate_residual_visc_def() - new_c_in = (1-efficency)*c_in + new_c_in = (1-rejection)*c_in self.residuals['permeate']['c'] = calculate_residual_concentration_cstr( c, diff --git a/tests/test_residual.py b/tests/test_residual.py index 640bd82..643288d 100644 --- a/tests/test_residual.py +++ b/tests/test_residual.py @@ -11,7 +11,7 @@ # random number test -TestCaseConc_level1 = { +TestCaseCSTRConc_level1 = { "values" : { "c" : np.array([1, 2, 3]), "c_dot" : np.array([4, 5, 6]), @@ -25,7 +25,7 @@ } # flow in and out are equal, concentrations to -TestCaseConc_equal = { +TestCaseCSTRConc_equal = { "values" : { "c" : np.array([0.1,]), "c_dot" : np.array([0,]), @@ -39,7 +39,7 @@ } # flow in and out are equal, but concentrations going into the unit is not -TestCaseConc_diffcin = { +TestCaseCSTRConc_diffcin = { "values" : { "c" : np.array([0.1,]), "c_dot" : np.array([0,]), @@ -53,7 +53,7 @@ } #flow in and out are not equal, concentrantions going in are -TestCaseConc_diffvol = { +TestCaseCSTRConc_diffvol = { "values" : { "c" : np.array([0.1,]), "c_dot" : np.array([0,]), @@ -67,7 +67,7 @@ } #flow in and out are not, equal, concentrations aren't equal too -TestCaseConc_diffvolc = { +TestCaseCSTRConc_diffvolc = { "values" : { "c" : np.array([0.1,]), "c_dot" : np.array([0.2,]), @@ -84,11 +84,11 @@ @pytest.mark.parametrize( "parameters", [ - TestCaseConc_level1, - TestCaseConc_equal, - TestCaseConc_diffcin, - TestCaseConc_diffvol, - TestCaseConc_diffvolc + TestCaseCSTRConc_level1, + TestCaseCSTRConc_equal, + TestCaseCSTRConc_diffcin, + TestCaseCSTRConc_diffvol, + TestCaseCSTRConc_diffvolc ] ) class TestResidualConcCSTR(): @@ -181,15 +181,119 @@ def test_calculation_cstr(self, parameters): parameters["expected"] ) +# Testcase 1: Membrane rejects all +TestCaseDEFCake_rejects_all = { + "values" : { + "V_dot_f" : 1.0, + "rejection" : np.array([1, 1]), + "molar_volume" : np.array([1, 1]), + "c_in" : np.array([0.5, 0.5]), + "V_dot_C" : 1.0 + }, + "expected" : 0 +} +# Testcase 2: Membrane rejects nothing +TestCaseDEFCake_rejects_not = { + "values" : { + "V_dot_f" : 1.0, + "rejection" : np.array([0, 0]), + "molar_volume" : np.array([1, 1]), + "c_in" : np.array([0.5, 0.5]), + "V_dot_C" : 0.0 + }, + "expected" : 0 +} + +# Testcase 3: Membrane rejects only Component 2 +TestCaseDEFCake_rejects_2 = { + "values" : { + "V_dot_f" : 1.0, + "rejection" : np.array([0, 1]), + "molar_volume" : np.array([1, 1]), + "c_in" : np.array([0.5, 0.5]), + "V_dot_C" : 0.5 + }, + "expected" : 0 +} -class TestResidualCakeDEF(): +# Testcase 4: Component 2 is larger then 1 +TestCaseDEFCake_C2_le_C1 = { + "values" : { + "V_dot_f" : 1.0, + "rejection" : np.array([1, 1]), + "molar_volume" : np.array([0.5, 1]), + "c_in" : np.array([0.5, 0.5]), + "V_dot_C" : 0.75 + }, + "expected" : 0 +} + +@pytest.mark.parametrize( + "parameters", + [ + TestCaseDEFCake_rejects_all, + TestCaseDEFCake_rejects_not, + TestCaseDEFCake_rejects_2, + TestCaseDEFCake_C2_le_C1 + ] +) + +class TestResidualCakeVolDEF(): def test_calculation_def(self, parameters): - param_vec_volume = parameters["values"].values() + param_vec_cake_vol = parameters["values"].values() - np.testing.assert_equal(1,1) + np.testing.assert_equal(calculate_residual_cake_vol_def(*param_vec_cake_vol), + parameters["expected"] + ) + +# Case 1 : Equally large hyraulic resistance +TestCaseDEFPressureDrop = { + "values" : { + "V_dot_P" : 1, + "V_C" : 1, + "deltap" : 0.5, + "A" : 1, + "mu" : 1, + "Rm" : 1, + "alpha" : 1, + }, + "expected" : 0 +} + +# Case 2 : No cake yet +TestCaseDEFPressureDrop_no_cake = { + "values" : { + "V_dot_P" : 0.5, + "V_C" : 0, + "deltap" : 0.5, + "A" : 1, + "mu" : 1, + "Rm" : 1, + "alpha" : 1, + }, + "expected" : 0 +} + +@pytest.mark.parametrize( + "parameters", + [ + TestCaseDEFPressureDrop, + TestCaseDEFPressureDrop_no_cake + ] +) + + +class TestResidualPressureDropDEF(): + def test_calculation_def(self, parameters): + + param_vec_pressure = parameters["values"].values() + + np.testing.assert_equal(calculate_residual_press_easy_def(*param_vec_pressure), + parameters["expected"] + ) TestCaseConcError = { diff --git a/tests/test_unit_operation.py b/tests/test_unit_operation.py index fc592d3..eaeec36 100644 --- a/tests/test_unit_operation.py +++ b/tests/test_unit_operation.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from CADETProcess.processModel import ComponentSystem +from CADETPythonSimulator.componentsystem import CPSComponentSystem from CADETPythonSimulator.unit_operation import ( UnitOperationBase, @@ -15,7 +15,7 @@ # %% Unit Operation Fixtures -class TwoComponentFixture(ComponentSystem): +class TwoComponentFixture(CPSComponentSystem): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)