|
15 | 15 | from CADETPythonSimulator.exception import NotInitializedError, CADETPythonSimError
|
16 | 16 | from CADETPythonSimulator.state import State, state_factory
|
17 | 17 | from CADETPythonSimulator.residual import (
|
18 |
| - calculate_residual_volume_cstr, calculate_residual_concentration_cstr, calculate_residuals_visc_cstr |
| 18 | + calculate_residual_volume_cstr, |
| 19 | + calculate_residual_concentration_cstr, |
| 20 | + calculate_residual_visc_cstr, |
| 21 | + calculate_residual_press_easy_def, |
| 22 | + calculate_residual_cake_vol_def, |
| 23 | + calculate_residual_visc_def |
19 | 24 | )
|
20 | 25 | from CADETPythonSimulator.rejection import RejectionBase
|
21 | 26 | from CADETPythonSimulator.cake_compressibility import CakeCompressibilityBase
|
@@ -595,73 +600,121 @@ class DeadEndFiltration(UnitOperationBase):
|
595 | 600 | Model for cake compressibility.
|
596 | 601 |
|
597 | 602 | """
|
598 |
| - retentate = { |
| 603 | + cake = { |
599 | 604 | 'dimensions': (),
|
600 |
| - 'entries': {'c': 'n_comp', 'viscosity': 1, 'Rc': 1, 'mc': 'n_comp'}, |
| 605 | + 'entries': {'c': 'n_comp', |
| 606 | + 'viscosity': 1, |
| 607 | + 'pressure': 1, |
| 608 | + 'cakevolume': 1, |
| 609 | + 'permeate': 1 |
| 610 | + }, |
601 | 611 | 'n_inlet_ports': 1,
|
602 | 612 | }
|
603 | 613 | permeate = {
|
604 | 614 | 'dimensions': (),
|
605 | 615 | 'entries': {'c': 'n_comp', 'viscosity': 1, 'Volume': 1},
|
606 | 616 | 'n_outlet_ports': 1,
|
607 | 617 | }
|
608 |
| - _state_structures = ['retentate', 'permeate'] |
609 |
| - |
610 |
| - rejection_model = Typed(ty=RejectionBase) |
611 |
| - cake_compressibility_model = Typed(ty=CakeCompressibilityBase) |
| 618 | + _state_structures = ['cake', 'permeate'] |
612 | 619 |
|
613 | 620 | membrane_area = UnsignedFloat()
|
614 | 621 | membrane_resistance = UnsignedFloat()
|
| 622 | + specific_cake_resistance = UnsignedFloat() |
| 623 | + rejection = Typed(ty=RejectionBase) |
615 | 624 |
|
616 | 625 | _parameters = [
|
617 | 626 | 'membrane_area',
|
618 | 627 | 'membrane_resistance',
|
| 628 | + 'specific_cake_resistance', |
| 629 | + 'rejection' |
619 | 630 | ]
|
620 | 631 |
|
621 |
| - def delta_p(self): |
622 |
| - raise NotImplementedError() |
| 632 | + def compute_residual( |
| 633 | + self, |
| 634 | + t: float, |
| 635 | + ) -> NoReturn: |
623 | 636 |
|
624 |
| - def specific_cake_resistance(self, delta_p: float) -> float: |
625 |
| - """ |
626 |
| - Compute specific resistance as a function of delta_p. |
| 637 | + Q_in = self.Q_in[0] |
| 638 | + Q_out = self.Q_out[0] |
627 | 639 |
|
628 |
| - Parameters |
629 |
| - ---------- |
630 |
| - delta_p : float |
631 |
| - Pressure difference. |
| 640 | + c_in = self.states['cake']['c'] |
| 641 | + c_in_dot = self.state_derivatives['cake']['c'] |
632 | 642 |
|
633 |
| - Returns |
634 |
| - ------- |
635 |
| - float |
636 |
| - Specific cake resistance. |
| 643 | + V_C = self.states['cake']['cakevolume'] |
| 644 | + V_dot_C = self.state_derivatives['cake']['cakevolume'] |
637 | 645 |
|
638 |
| - """ |
639 |
| - raise self.cake_compressibility_model.specific_cake_resistance(delta_p) |
| 646 | + V_p = self.states['cake']['permeate'] |
| 647 | + Q_p = self.state_derivatives['cake']['cakevolume'] |
640 | 648 |
|
641 |
| - def compute_residual( |
642 |
| - self, |
643 |
| - t: float, |
644 |
| - y: np.ndarray, |
645 |
| - y_dot: np.ndarray, |
646 |
| - residual: np.ndarray |
647 |
| - ) -> NoReturn: |
648 |
| - # 0, 1, 2 |
649 |
| - # y = Vp, Rc, mc |
650 |
| - # TODO: Needs to be extended to include c_in / c_out |
651 |
| - # y = [*c_i_in], viscosity_in, Vp, Rc, mc, [*c_i_out], viscosity_out |
| 649 | + viscosity_in = self.states['cake']['viscosity'] |
| 650 | + |
| 651 | + c = self.states['permeate']['c'] |
| 652 | + c_dot = self.state_derivatives['permeate']['c'] |
652 | 653 |
|
653 |
| - c_in = y[0: self.n_comp] |
654 |
| - viscosity_in = y[self.n_comp] |
| 654 | + V = self.states['permeate']['Volume'] |
| 655 | + V_dot = self.state_derivatives['permeate']['Volume'] |
655 | 656 |
|
656 |
| - densities = self.component_system.densities |
| 657 | + deltap = self.states['cake']['pressure'] |
657 | 658 |
|
658 |
| - residual[self.n_dof_coupling + 0] = ((self.membrane_area*self.delta_p(t)/viscosity_in)/(self.membrane_resistance+y[1])) - y_dot[0] |
659 |
| - residual[self.n_dof_coupling + 1] = (1/self.membrane_area) * (y_dot[2] * self.specific_cake_resistance(self.p(t))) - y_dot[1] |
| 659 | + #parameters |
| 660 | + molecular_weights = self.component_system.molecular_weights |
| 661 | + molar_volume = self.component_system.molecular_volumes |
| 662 | + membrane_area = self.parameters['membrane_area'] |
| 663 | + membrane_resistance = self.parameters['membrane_resistance'] |
| 664 | + specific_cake_resistance = self.parameters['specific_cake_resistance'] |
660 | 665 |
|
661 |
| - residual[self.n_dof_coupling + 2] = ((self.c(t) * y_dot[0]) / (1-self.c(t)/self.density)) - y_dot[2] |
| 666 | + rejection = np.array( |
| 667 | + [self.rejection.get_rejection(mw) for mw in molecular_weights]) |
662 | 668 |
|
663 |
| - self.residuals['retentate'] |
664 |
| - self.residuals['permeate'] |
| 669 | + # Handle inlet DOFs, which are simply copied to the residual |
| 670 | + self.residuals['cake']['c'] = c_in |
| 671 | + self.residuals['cake']['cakevolume'] = calculate_residual_cake_vol_def( |
| 672 | + Q_in, |
| 673 | + rejection, |
| 674 | + molar_volume, |
| 675 | + c_in, |
| 676 | + V_dot_C |
| 677 | + ) |
| 678 | + |
| 679 | + self.residuals['cake']['pressure'] = calculate_residual_press_easy_def( |
| 680 | + Q_p, |
| 681 | + V_C, |
| 682 | + deltap, |
| 683 | + membrane_area, |
| 684 | + viscosity_in, |
| 685 | + membrane_resistance, |
| 686 | + specific_cake_resistance |
| 687 | + ) |
| 688 | + |
| 689 | + self.residuals['cake']['permeate'] = calculate_residual_volume_cstr( |
| 690 | + V_C, |
| 691 | + V_dot_C, |
| 692 | + Q_in, |
| 693 | + Q_p |
| 694 | + ) |
| 695 | + |
| 696 | + self.residuals['cake']['viscosity'] = calculate_residual_visc_def() |
| 697 | + |
| 698 | + new_c_in = (1-rejection)*c_in |
| 699 | + |
| 700 | + self.residuals['permeate']['c'] = calculate_residual_concentration_cstr( |
| 701 | + c, |
| 702 | + c_dot, |
| 703 | + V, |
| 704 | + V_dot, |
| 705 | + Q_p, |
| 706 | + Q_out, |
| 707 | + new_c_in |
| 708 | + ) |
| 709 | + |
| 710 | + self.residuals['permeate']['Volume'] = calculate_residual_volume_cstr( |
| 711 | + V, |
| 712 | + V_dot, |
| 713 | + Q_p, |
| 714 | + Q_out |
| 715 | + ) |
| 716 | + |
| 717 | + self.residuals['permeate']['viscosity'] = calculate_residual_visc_cstr() |
665 | 718 |
|
666 | 719 |
|
667 | 720 |
|
|
0 commit comments