From e9a2c3e501b347a22a950ff13b122b0de7ff3b34 Mon Sep 17 00:00:00 2001 From: daklauss Date: Sun, 6 Oct 2024 19:35:45 +0200 Subject: [PATCH] Large commit, sry for mess reworked def unit operation, initial condition for non circular system --- CADETPythonSimulator/componentsystem.py | 75 +++++- CADETPythonSimulator/residual.py | 27 ++- CADETPythonSimulator/solver.py | 6 +- CADETPythonSimulator/system.py | 48 ++-- CADETPythonSimulator/unit_operation.py | 298 ++++++++++++++++++------ tests/test_system.py | 1 + tests/test_unit_operation.py | 10 +- 7 files changed, 344 insertions(+), 121 deletions(-) diff --git a/CADETPythonSimulator/componentsystem.py b/CADETPythonSimulator/componentsystem.py index 28375e0..9c041c2 100644 --- a/CADETPythonSimulator/componentsystem.py +++ b/CADETPythonSimulator/componentsystem.py @@ -26,6 +26,8 @@ class CPSSpecies(Structure): Density of the species. molecular_volume : float The molecular volume of the species + specific_cake_resistance : float + The specific cake resistance of the species """ @@ -35,6 +37,8 @@ class CPSSpecies(Structure): density = UnsignedFloat() molecular_volume = UnsignedFloat() viscosity = UnsignedFloat() + pure_density = UnsignedFloat() + specific_cake_resistance = UnsignedFloat() class CPSComponent(Component): @@ -65,6 +69,10 @@ class CPSComponent(Component): Molecular volume of component (including species). viscosity : list Viscosity of component(including species) + pure_density : list + pure_density of component(including species) + specific_cake_resistance : list + specific_cake_resistance of component(including species) See Also -------- @@ -80,7 +88,9 @@ def __init__(self, molecular_weight=None, density=None, molecular_volume=None, - viscosity=None): + viscosity=None, + pure_density=None, + specific_cake_resistance=None): """Construct CPSComponent.""" self.name = name self._species = [] @@ -92,7 +102,9 @@ def __init__(self, molecular_weight, density, molecular_volume, - viscosity + viscosity, + pure_density, + specific_cake_resistance ) elif isinstance(species, str): self.add_species( @@ -101,7 +113,9 @@ def __init__(self, molecular_weight, density, molecular_volume, - viscosity + viscosity, + pure_density, + specific_cake_resistance ) elif isinstance(species, list): if charge is None: @@ -114,6 +128,10 @@ def __init__(self, molecular_volume = len(species) * [None] if viscosity is None: viscosity = len(species) * [None] + if pure_density is None: + pure_density = len(species) * [None] + if specific_cake_resistance is None: + specific_cake_resistance = len(species) * [None] for i, spec in enumerate(species): self.add_species( spec, @@ -121,7 +139,9 @@ def __init__(self, molecular_weight[i], density[i], molecular_volume[i], - viscosity[i] + viscosity[i], + pure_density[i], + specific_cake_resistance[i] ) else: raise CADETPythonSimError("Could not determine number of species") @@ -152,6 +172,16 @@ def viscosity(self): """List of float or None: The viscosity of the subspecies.""" return [spec.viscosity for spec in self.species] + @property + def pure_density(self): + """List of float or None: Density of the subspecies.""" + return [spec.pure_density for spec in self.species] + + @property + def specific_cake_resistance(self): + """List of float or None: specific cake resistance of the subspecies.""" + return [spec.specific_cake_resistance for spec in self.species] + class CPSComponentSystem(ComponentSystem): """ Component System Class. @@ -187,6 +217,8 @@ class CPSComponentSystem(ComponentSystem): Molecular volume of all component species. viscosity : list Viscosity of all component species. + pure_density : list + Pure density of all component species. See Also -------- @@ -203,7 +235,9 @@ def __init__( molecular_weights=None, densities=None, molecular_volume=None, - viscosities=None + viscosities=None, + pure_densities=None, + specific_cake_resistances=None ): """ Initialize the ComponentSystem object. @@ -225,6 +259,10 @@ def __init__( The molecular volume of each component. viscosities : list, None viscosity of each component. + pure_densities : list, None + pure densities of each component. + specific_cake_resistances : list, None. + specific cake resistance of each component Raises ------ @@ -257,6 +295,11 @@ def __init__( molecular_volume = n_comp * [None] if viscosities is None: viscosities = n_comp * [None] + if pure_densities is None: + pure_densities = n_comp * [None] + if specific_cake_resistances is None: + specific_cake_resistances = n_comp * [None] + for i, comp in enumerate(components): self.add_component( @@ -265,7 +308,9 @@ def __init__( molecular_weight=molecular_weights[i], density=densities[i], molecular_volume=molecular_volume[i], - viscosity=viscosities[i] + viscosity=viscosities[i], + pure_density=pure_densities[i], + specific_cake_resistance=specific_cake_resistances[i] ) @wraps(CPSComponent.__init__) @@ -320,3 +365,21 @@ def viscosities(self): viscosities +=comp.viscosity return viscosities + + @property + def pure_densities(self): + """list: List of species density if pure.""" + pure_densities = [] + for comp in self.components: + pure_densities += comp.pure_density + + return pure_densities + + @property + def specific_cake_resistances(self): + """list: List of species cake resistance if pure.""" + specific_cake_resistances = [] + for comp in self.components: + specific_cake_resistances += comp.specific_cake_resistance + + return specific_cake_resistances diff --git a/CADETPythonSimulator/residual.py b/CADETPythonSimulator/residual.py index 1adcfab..bcb97a2 100644 --- a/CADETPythonSimulator/residual.py +++ b/CADETPythonSimulator/residual.py @@ -63,7 +63,7 @@ def calculate_residual_concentration_cstr( Q_out : float Volume leaving the Unit c_in : np.ndarray - Initial concentration + Incomming concentration """ if V < 0: @@ -78,30 +78,33 @@ def calculate_residual_visc_cstr(): return 0 def calculate_residual_cake_vol_def( - V_dot_f: float, + V: float, rejection: np.ndarray, - molar_volume: np.ndarray, + densities: np.ndarray, + molecular_weights: np.ndarray, c_in: np.ndarray, - V_dot_C: float + V_C: float ) -> float: """ Residual equation for the Cake Volume. Parameters ---------- - V_dot_f : float - Flowrate of incoming feed + V : float + Volume of liquid pressured into the filter rejection : np.ndarray Rejection of the filter - molar_volume : np.ndarray - Volume of suspended material + densities : np.ndarray + densities of suspended material + molecular_weights : np.ndarray + molecular weights of the components c_in : np.array Incoming Concentration - V_dot_C : float - Change of Cake Volume + V_C : float + Cake Volume """ - return -V_dot_C + np.sum(rejection * molar_volume * c_in * V_dot_f) + return -V_C + V * np.sum(rejection * c_in * molecular_weights / densities) def calculate_residual_press_easy_def( V_dot_Perm: float, @@ -138,7 +141,7 @@ def calculate_residual_press_easy_def( """ hyd_resistance = (Rm + alpha*V_C/A) * mu - return -V_dot_Perm + deltap * A *hyd_resistance + return deltap * A - V_dot_Perm* hyd_resistance def calculate_residual_visc_def(): """Calculate the residual of the Viscosity equation of the CSTR.""" diff --git a/CADETPythonSimulator/solver.py b/CADETPythonSimulator/solver.py index 576cca4..1119b38 100644 --- a/CADETPythonSimulator/solver.py +++ b/CADETPythonSimulator/solver.py @@ -87,9 +87,7 @@ def _compute_residual( Array to save the calculated residual """ - self._system.y = y - self._system.y_dot = y_dot - self._system.compute_residual(t) + self._system.compute_residual(t, y, y_dot) r[...] = self._system.r def initialize_solution_recorder(self) -> NoReturn: @@ -157,7 +155,7 @@ def write_solution( def solve(self) -> NoReturn: """Simulate the system.""" - self.initialize_system() + # self.initialize_system() self.initialize_solution_recorder() for section in self.sections: diff --git a/CADETPythonSimulator/system.py b/CADETPythonSimulator/system.py index 467459c..3f6e348 100644 --- a/CADETPythonSimulator/system.py +++ b/CADETPythonSimulator/system.py @@ -152,6 +152,22 @@ def y(self, y: np.ndarray) -> NoReturn: unit_operation.y = y[start_index:end_index] start_index = end_index + @property + def y_init(self) -> np.ndarray: + """np.ndarray: State array flattened into one dimension.""" + return np.concatenate([ + unit_operation.y_init for unit_operation in self.unit_operations.values() + ]) + + @y_init.setter + def y_init(self, y_init: np.ndarray) -> NoReturn: + """Setter for state in From of y_init array.""" + start_index = 0 + for unit_operation in self.unit_operations.values(): + end_index = start_index + unit_operation.n_dof + unit_operation.y_init = y_init[start_index:end_index] + start_index = end_index + @property def state_derivatives(self) -> dict[str, dict[str, State]]: """dict: State derivative array block of the system, indexed by name.""" @@ -237,7 +253,6 @@ def update_system_connectivity(self, connections: list) -> NoReturn: """ self._compute_connectivity_matrix(connections) self.set_rates() - self.couple_unit_operations() def set_rates(self) -> NoReturn: """ @@ -251,6 +266,8 @@ def set_rates(self) -> NoReturn: def compute_residual( self, t: float, + y: np.ndarray, + y_dot: np.ndarray ) -> NoReturn: """ Compute the residual for the differential-algebraic equations system. @@ -259,8 +276,15 @@ def compute_residual( ---------- t : float Current time point. + y : np.ndarray + initial state + y_dot : np.ndarray + initial state derivative """ + self.y = y + self.y_dot = y_dot + self.r = y self.couple_unit_operations() for unit_operation in self.unit_operations.values(): unit_operation.compute_residual(t) @@ -382,20 +406,6 @@ def _compute_connectivity_matrix(self, connections: list) -> np.ndarray: self._connectivity = connections_matrix - def compute_residual_for_initial_values(self, y_dot: np.ndarray) -> np.ndarray: - """ - Compute the residual for calculating the initial values. - - Parameters - ---------- - y_dot: np.ndarray - derivative array to calculate - - """ - self.y_dot = y_dot - self.compute_residual(self.t_zero) - return self.r - def initialize_initial_values(self, t0: float): """ Calculate initial values and set them up. @@ -405,14 +415,12 @@ def initialize_initial_values(self, t0: float): """ self.t_zero = t0 + self.set_rates() + self.couple_unit_operations() for unit_operation in self.unit_operations.values(): unit_operation.initialize_initial_values(t0) + self.couple_unit_operations() - y_dot = self.y_dot - - y_dot = scipyopt.fsolve(self.compute_residual_for_initial_values, y_dot) - - self.y_dot = y_dot class FlowSystem(SystemBase): """ diff --git a/CADETPythonSimulator/unit_operation.py b/CADETPythonSimulator/unit_operation.py index 824ac31..3621ce6 100644 --- a/CADETPythonSimulator/unit_operation.py +++ b/CADETPythonSimulator/unit_operation.py @@ -142,6 +142,22 @@ def y_dot(self, y_dot: np.ndarray) -> NoReturn: state_derivative.s_flat = y_dot[start_index:end_index] start_index = end_index + @property + def y_init(self) -> np.ndarray: + """np.ndarray: State derivative array flattened into one dimension.""" + return np.concatenate([ + state_derivative.s_flat + for state_derivative in self.state_derivatives.values() + ]) + + @y_init.setter + def y_init(self, y_init: np.ndarray) -> NoReturn: + start_index = 0 + for state_derivative in self.state_derivatives.values(): + end_index = start_index + state_derivative.n_dof + state_derivative.s_flat = y_init[start_index:end_index] + start_index = end_index + @property def residuals(self) -> dict[str, State]: """list: Residual array blocks of the unit operation.""" @@ -508,6 +524,10 @@ def __str__(self) -> str: """Return string represenation of the unit operation.""" return self.name + def compute_residual_for_initial_values(self, t_zero: float): + """Calculate Residual for initial values.""" + self.compute_residual(t_zero) + class Inlet(UnitOperationBase): """ @@ -561,6 +581,8 @@ def initialize_initial_values(self, t_zero: float): Time to initialize the values """ + t_poly = np.array([1, t_zero, t_zero**2, t_zero**3]) + self.states['outlet']['c'] = self.c_poly @ t_poly t_poly = np.array([0, 1, 2*t_zero, 3*t_zero**2]) self.state_derivatives['outlet']['c'] = self.c_poly @ t_poly @@ -587,7 +609,7 @@ def compute_residual( Time at which to evaluate the residual. """ - self.residuals['inlet']['c'] = np.zeros(self.states['inlet']['c'].shape) + self.residuals['inlet']['c'] -= self.states['inlet']['c'] class Cstr(UnitOperationBase): @@ -628,7 +650,7 @@ def compute_residual( V_dot = self.state_derivatives['bulk']['Volume'] # Handle inlet DOFs, which are simply copied to the residual - self.residuals['inlet']['c'] = c_in + self.residuals['inlet']['c'] -= c_in # Handle bulk/outlet DOFs Q_in = self.Q_in[0] @@ -686,32 +708,37 @@ class DeadEndFiltration(UnitOperationBase): cake = { 'dimensions': (), - 'entries': {'c': 'n_comp', - 'pressure': 1, - 'cakevolume': 1, - 'permeate': 1 - }, + 'entries': { + 'c': 'n_comp', + 'n_feed': 'n_comp', + 'cakevolume': 'n_comp', + 'n_cake': 'n_comp', + 'permeatevolume': 1, + 'n_permeate': 'n_comp', + 'c_permeate': 'n_comp', + 'pressure': 1 + }, 'n_inlet_ports': 1, } - permeate = { + permeate_tank = { 'dimensions': (), - 'entries': {'c': 'n_comp', 'Volume': 1}, + 'entries': { + 'c': 'n_comp', + 'tankvolume': 1 + }, 'n_outlet_ports': 1, } - _state_structures = ['cake', 'permeate'] + + _state_structures = ['cake', 'permeate_tank'] membrane_area = UnsignedFloat() membrane_resistance = UnsignedFloat() - specific_cake_resistance = UnsignedFloat() - solution_viscosity = UnsignedFloat() rejection_model = Typed(ty=RejectionBase) viscosity_model = Typed(ty=ViscosityBase) _parameters = [ 'membrane_area', 'membrane_resistance', - 'specific_cake_resistance', - 'solution_viscosity', 'rejection_model', 'viscosity_model' ] @@ -724,31 +751,43 @@ def compute_residual( Q_in = self.Q_in[0] Q_out = self.Q_out[0] - c_in = self.states['cake']['c'] - # c_in_dot = self.state_derivatives['cake']['c'] + c_feed = self.states['cake']['c'] + c_feed_dot = self.state_derivatives['cake']['c'] + + n_feed = self.states['cake']['n_feed'] + n_feed_dot = self.state_derivatives['cake']['n_feed'] - V_C = self.states['cake']['cakevolume'] - V_dot_C = self.state_derivatives['cake']['cakevolume'] + n_cake = self.states['cake']['n_cake'] + n_cake_dot = self.state_derivatives['cake']['n_cake'] - # V_p = self.states['cake']['permeate'] - Q_p = self.state_derivatives['cake']['cakevolume'] + cake_vol = self.states['cake']['cakevolume'] + cake_vol_dot = self.state_derivatives['cake']['cakevolume'] - c = self.states['permeate']['c'] - c_dot = self.state_derivatives['permeate']['c'] + c_permeate = self.states['cake']['c_permeate'] + c_permeate_dot = self.state_derivatives['cake']['c_permeate'] - V = self.states['permeate']['Volume'] - V_dot = self.state_derivatives['permeate']['Volume'] + n_permeate = self.states['cake']['n_permeate'] + n_permeate_dot = self.state_derivatives['cake']['n_permeate'] + + permeate_vol = self.states['cake']['permeatevolume'] + permeate_vol_dot = self.state_derivatives['cake']['permeatevolume'] deltap = self.states['cake']['pressure'] + c_tank = self.states['permeate_tank']['c'] + c_tank_dot = self.state_derivatives['permeate_tank']['c'] + + tankvolume = self.states['permeate_tank']['tankvolume'] + tankvolume_dot = self.state_derivatives['permeate_tank']['tankvolume'] + # parameters - molecular_weights = self.component_system.molecular_weights - molar_volume = self.component_system.molecular_volumes - viscosities = self.component_system.viscosities + molecular_weights = np.array(self.component_system.molecular_weights) + densities = np.array(self.component_system.pure_densities) + viscosities = np.array(self.component_system.viscosities) membrane_area = self.parameters['membrane_area'] membrane_resistance = self.parameters['membrane_resistance'] - specific_cake_resistance = self.parameters['specific_cake_resistance'] - solution_viscosity = self.parameters['solution_viscosity'] + specific_cake_resistance =\ + np.array(self.component_system.specific_cake_resistances) rejection = np.array( [ @@ -756,61 +795,172 @@ def compute_residual( for mw in molecular_weights ] ) - # Handle viscosities - c_part = c*molar_volume - c_liquid = 1 - np.sum(c_part) - c_part = np.append(c_part, c_liquid) + # Coupling residual equation + self.residuals['cake']['c'] -= c_feed - viscosities.append(solution_viscosity) - viscosity = self.viscosity_model.get_mixture_viscosity(viscosities, c_part) + # Number of Feed - # 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, - rejection, - molar_volume, - c_in, - V_dot_C - ) + self.residuals['cake']['n_feed'] = n_feed_dot - Q_in * c_feed - self.residuals['cake']['pressure'] = calculate_residual_press_easy_def( - Q_p, - V_C, - deltap, - membrane_area, - viscosity, - membrane_resistance, - specific_cake_resistance - ) + # Number of cake - self.residuals['cake']['permeate'] = calculate_residual_volume_cstr( - V_C, - V_dot_C, - Q_in, - Q_p - ) + self.residuals['cake']['n_cake'] = n_cake_dot - rejection * n_feed_dot - new_c_in = (1 - rejection) * c_in + # Number of Permeate - self.residuals['permeate']['c'] = calculate_residual_concentration_cstr( - c, - c_dot, - V, - V_dot, - Q_p, - Q_out, - new_c_in - ) + self.residuals['cake']['n_permeate'] =\ + n_permeate_dot - (1 - rejection) * n_feed_dot + + # Cakevolume + + self.residuals['cake']['cakevolume'] =\ + cake_vol_dot - n_cake_dot * molecular_weights / densities + + # Permeate flow - self.residuals['permeate']['Volume'] = calculate_residual_volume_cstr( - V, - V_dot, - Q_p, - Q_out + self.residuals['cake']['permeatevolume'] =\ + permeate_vol_dot - np.sum(n_permeate_dot * molecular_weights / densities) + + # Concentration Permeate + + self.residuals['cake']['c_permeate'] =\ + c_permeate - n_permeate_dot / permeate_vol_dot + + # Pressure equation + + cakresistance = \ + np.sum(specific_cake_resistance * densities * cake_vol/membrane_area) + + viscositiy = \ + np.exp(np.sum(n_permeate_dot* np.log(viscosities)) / np.sum(n_permeate_dot)) + + self.residuals['cake']['pressure'] = \ + viscositiy * permeate_vol_dot * (membrane_resistance + cakresistance)\ + / membrane_area - deltap + + # Tank equations + + self.residuals['permeate_tank']['c'] = calculate_residual_concentration_cstr( + c=c_tank, + c_dot=c_tank_dot, + V=tankvolume, + V_dot=tankvolume_dot, + Q_in=permeate_vol_dot, + Q_out=Q_out, + c_in=c_permeate ) + self.residuals['permeate_tank']['tankvolume'] =\ + tankvolume_dot - permeate_vol_dot + Q_out + + + @property + def y_init(self) -> np.ndarray: + """np.ndarray: State derivative array flattened into one dimension.""" + ret = [] + for state, state_derivative in self.state_derivatives.items(): + if state != "cake": + ret.append(state_derivative.s_flat) + else: + for entry in state_derivative.entries.keys(): + if entry != "pressure": + ret.append(state_derivative[entry]) + else: + ret.append(self.states[state][entry]) + return np.concatenate(ret, axis=None) + + @y_init.setter + def y_init(self, y_init: np.ndarray) -> NoReturn: + start_index = 0 + for state, state_derivative in self.state_derivatives.items(): + end_index = start_index + state_derivative.n_dof + if state != "cake": + state_derivative.s_flat = y_init[start_index:end_index] + else: + sub_start_index = start_index + for entry, dim in state_derivative.entries.items(): + sub_end_index = sub_start_index + dim + if state != "pressure": + self.state_derivatives[state][entry] =\ + y_init[sub_start_index:sub_end_index] + else: + self.states[state][entry] =\ + y_init[sub_start_index:sub_end_index] + sub_start_index = sub_end_index + start_index = end_index + + def initialize_initial_values(self, t_zero: float): + """Initialize the values.""" + molecular_weights = np.array(self.component_system.molecular_weights) + densities = np.array(self.component_system.pure_densities) + viscosities = np.array(self.component_system.viscosities) + membrane_area = self.parameters['membrane_area'] + membrane_resistance = self.parameters['membrane_resistance'] + specific_cake_resistance =\ + np.array(self.component_system.specific_cake_resistances) + + Q_in = self.Q_in[0] + Q_out = self.Q_out[0] + c_feed = self.states['cake']['c'] + + n_feed_dot = Q_in * c_feed + self.state_derivatives['cake']['n_feed'] = n_feed_dot + + rejection = np.array( + [ + self.rejection_model.get_rejection(mw)\ + for mw in molecular_weights + ] + ) + + n_cake_dot = rejection * n_feed_dot + self.state_derivatives['cake']['n_cake'] = n_cake_dot + + cake_vol = self.states['cake']['cakevolume'] + + cake_vol_dot = molecular_weights * n_cake_dot / densities + + self.state_derivatives['cake']['cakevolume'] = cake_vol_dot + + + n_permeate_dot = (1 - rejection) * n_feed_dot + self.state_derivatives['cake']['n_permeate'] = n_permeate_dot + + c_permeate_dot = self.state_derivatives['cake']['c_permeate'] + + permeate_vol_dot = np.sum(n_permeate_dot * molecular_weights / densities) + self.state_derivatives['cake']['permeatevolume'] = permeate_vol_dot + + c_permeate = n_permeate_dot / permeate_vol_dot + self.states['cake']['c_permeate'] = c_permeate + + + cakresistance = \ + np.sum(specific_cake_resistance * densities * cake_vol/membrane_area) + + viscositiy = \ + np.exp(np.sum(n_permeate_dot* np.log(viscosities)) / np.sum(n_permeate_dot)) + + self.states['cake']['pressure'] = \ + viscositiy * permeate_vol_dot * (membrane_resistance + cakresistance)\ + / membrane_area + + c_tank = self.states['permeate_tank']['c'] + + tankvolume = self.states['permeate_tank']['tankvolume'] + tankvolume_dot = permeate_vol_dot - Q_out + self.state_derivatives['permeate_tank']['tankvolume'] = tankvolume_dot + + if tankvolume == 0: + raise CADETPythonSimError("""Initialize error + Volume of Permeate tank can't be initialized with 0""") + c_tank_dot =\ + (permeate_vol_dot * c_permeate - Q_out * c_tank -c_tank*tankvolume_dot)\ + /tankvolume + self.state_derivatives['permeate_tank']['c'] = c_tank_dot + + class CrossFlowFiltration(UnitOperationBase): """ diff --git a/tests/test_system.py b/tests/test_system.py index 1edc386..623eaf4 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -133,6 +133,7 @@ def test_coupling( system.y_dot = y_dot system.update_system_connectivity(connections) + system.couple_unit_operations() np.testing.assert_almost_equal(system.y, expected_state) @pytest.mark.parametrize( diff --git a/tests/test_unit_operation.py b/tests/test_unit_operation.py index d213d03..5b7ef9a 100644 --- a/tests/test_unit_operation.py +++ b/tests/test_unit_operation.py @@ -442,7 +442,7 @@ def test_get_outlet_state(self, unit_operation: UnitOperationBase, expected: dic ], { 'inlet': { - 'c': np.array([7, 8]) + 'c': np.array([-7, -8]) }, 'bulk': { 'c': np.array([-11, -7]), @@ -486,14 +486,14 @@ def test_get_outlet_state(self, unit_operation: UnitOperationBase, expected: dic ], { 'cake': { - 'c': np.array([0.5, 0.5]), - 'pressure': 1, + 'c': np.array([-0.5, -0.5]), + 'pressure': 2, 'cakevolume': 0, - 'permeate': 1, + 'permeate': 0, }, 'permeate': { 'c': np.array([1.5, 1.5]), - 'Volume': 1, + 'Volume': 2, } } ),