HP Forums
(HP-65) Prog. No. 04198A Reverse Osmosis - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Software Libraries (/forum-10.html)
+--- Forum: HP-65/67/97 Software Library (/forum-12.html)
+--- Thread: (HP-65) Prog. No. 04198A Reverse Osmosis (/thread-20238.html)



(HP-65) Prog. No. 04198A Reverse Osmosis - SlideRule - 07-28-2023 05:03 PM

Extract from Aircraft Industry Wastewater Recycling, EPA-600/2-78-130 (1978/06), Appendix D: Calculator Program for Computing Reverse Osmosis Unit Product and Concentrate Concentrations, pgs 69-71

     "The general problem of calculating concentrate concentration and permeate concentration in an unit employing feedback is best solved by a reiterative technique. Such calculation is time consuming unless a computer or programmable calculator is available. This appendix contains a 99-step program devised for use on a Hewlett-Packard HP-65 calculator, that reiterates the necessary calculations until two successive results differ by less than one part in 1000".

Program Description Description, Equations, Variables
Calculation Steps
Operating Limits and Warnings
Sample Problem
Reference
Program {listing}

[attachment=12365]
BEST!
SlideRule


RE: (HP-65) Prog. No. 04198A Reverse Osmosis - Thomas Klemm - 07-29-2023 01:32 PM

Quote:This appendix contains a 99-step program devised for use on a Hewlett-Packard HP-65 calculator, that reiterates the necessary calculations until two successive results differ by less than one part in 1000.

Looking at the equations, I wondered why they used fixed-point iteration when a purely algebraic solution is possible:

\(
\begin{align}
C_c &= \frac{Q_f C_f - Q_p C_p}{Q_c} \\
\\
C_m &= \frac{Q_f C_f + C_c(2 Q_l + Q_c)}{Q_f + 2Q_l + Q_c} \\
&= \frac{Q_f C_f + \frac{Q_f C_f - Q_p C_p}{Q_c}(2 Q_l + Q_c)}{Q_f + 2Q_l + Q_c} \\
\\
C_p &= (1 - R) \times C_m \\
&= (1 - R) \times \frac{Q_f C_f + \frac{Q_f C_f - Q_p C_p}{Q_c}(2 Q_l + Q_c)}{Q_f + 2Q_l + Q_c} \\
\end{align}
\)

WolframAlpha gives:
Code:
C_1 = (2 C_0 Q_0 (Q_2 + Q_3) (R - 1))/((Q_2 + 2 Q_3) (Q_1 (R - 1) - Q_2) - Q_0 Q_2)
and Q_0 Q_2!=(Q_2 + 2 Q_3) (Q_1 (R - 1) - Q_2)
and Q_2 (Q_0 + Q_2 + 2 Q_3)!=0

From this we can write a function in Python:
Code:
def osmosis(Q_f, Q_p, Q_c, Q_l, C_f, R):
    return (2 * C_f * Q_f * (Q_c + Q_l) * (R - 1)) / (
        ((R - 1) * Q_p - Q_c) * (2 * Q_l + Q_c) - Q_f * Q_c
    )

Calling it with the given input values returns the correct result for \(C_p\):

osmosis(
Q_f = 3.0,
Q_p = 2.0,
Q_c = 1.0,
Q_l = 5.0,
C_f = 200,
R = 0.8
)

78.26086956521739


This function can be disassembled with:
Code:
from dis import dis
dis(osmosis)

The result is:
Code:
  9           0 LOAD_CONST               1 (2)
              2 LOAD_FAST                4 (C_f)
              4 BINARY_MULTIPLY
              6 LOAD_FAST                0 (Q_f)
              8 BINARY_MULTIPLY
             10 LOAD_FAST                2 (Q_c)
             12 LOAD_FAST                3 (Q_l)
             14 BINARY_ADD
             16 BINARY_MULTIPLY
             18 LOAD_FAST                5 (R)
             20 LOAD_CONST               2 (1)
             22 BINARY_SUBTRACT
             24 BINARY_MULTIPLY
             26 LOAD_FAST                5 (R)
             28 LOAD_CONST               2 (1)
             30 BINARY_SUBTRACT
             32 LOAD_FAST                1 (Q_p)
             34 BINARY_MULTIPLY
             36 LOAD_FAST                2 (Q_c)
             38 BINARY_SUBTRACT
             40 LOAD_CONST               1 (2)
             42 LOAD_FAST                3 (Q_l)
             44 BINARY_MULTIPLY
             46 LOAD_FAST                2 (Q_c)
             48 BINARY_ADD
             50 BINARY_MULTIPLY
             52 LOAD_FAST                0 (Q_f)
             54 LOAD_FAST                2 (Q_c)
             56 BINARY_MULTIPLY
             58 BINARY_SUBTRACT
             60 BINARY_TRUE_DIVIDE
             62 RETURN_VALUE

After a bit of find and replace we end up with the following program for the HP-42S:
Code:
00 { 54-Byte Prgm }
01 LBL "OSMOSIS"
02 STO 00 # Q_f
03 STOP
04 STO 01 # Q_p
05 STOP
06 STO 02 # Q_c
07 STOP
08 STO 03 # Q_l
09 STOP
10 STO 04 # C_f
11 STOP
12 STO 05 # R
13 2
14 RCL 04 # C_f
15 ×
16 RCL 00 # Q_f
17 ×
18 RCL 02 # Q_c
19 RCL 03 # Q_l
20 +
21 ×
22 RCL 05 # R
23 1
24 -
25 ×
26 LASTX # R - 1
27 RCL 01 # Q_p
28 ×
29 RCL 02 # Q_c
30 -
31 2
32 RCL 03 # Q_l
33 ×
34 RCL 02 # Q_c
35 +
36 ×
37 RCL 00 # Q_f
38 RCL 02 # Q_c
39 ×
40 -
41 ÷
42 END

You may have noticed that I rearranged the expression in the Python function a bit.
This avoids stack overflow and allows me to use LASTX instead of evaluating \(R - 1\) a second time.

Example

3 XEQ "OSMOSIS"
2 R/S
1 R/S
5 R/S
200 R/S
0.8 R/S

78.2609