Skip to content

Commit aade215

Browse files
authored
Merge pull request #22 from pathsim/feature/extended-process
Feature/extended process
2 parents 5b43c59 + 68181b8 commit aade215

10 files changed

Lines changed: 121 additions & 722 deletions

docs/source/examples/cstr_reaction.ipynb

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,7 @@
2727
"execution_count": null,
2828
"metadata": {},
2929
"outputs": [],
30-
"source": [
31-
"import matplotlib.pyplot as plt\n",
32-
"\n",
33-
"from pathsim import Simulation, Connection\n",
34-
"from pathsim.blocks import Source, Scope\n",
35-
"\n",
36-
"from pathsim_chem.process import CSTR"
37-
]
30+
"source": "import matplotlib.pyplot as plt\n\nplt.style.use('../pathsim_docs.mplstyle')\n\nfrom pathsim import Simulation, Connection\nfrom pathsim.blocks import Source, Scope\n\nfrom pathsim_chem.process import CSTR"
3831
},
3932
{
4033
"cell_type": "markdown",
@@ -48,7 +41,7 @@
4841
"execution_count": null,
4942
"metadata": {},
5043
"outputs": [],
51-
"source": "cstr = CSTR(\n V=1.0, # reactor volume [m³]\n F=0.05, # volumetric flow rate [m³/s] -> tau = 20 s\n k0=1e6, # pre-exponential factor [1/s]\n Ea=40000.0, # activation energy [J/mol]\n n=1.0, # first-order reaction\n dH_rxn=-40000.0, # exothermic [J/mol]\n rho=1000.0, # density [kg/m³]\n Cp=4184.0, # heat capacity [J/(kg·K)]\n UA=800.0, # cooling jacket [W/K]\n C_A0=0.0, # start empty\n T0=300.0, # initial temperature [K]\n)"
44+
"source": "reactor = CSTR(\n V=1.0, # reactor volume [m³]\n F=0.05, # volumetric flow rate [m³/s] -> tau = 20 s\n k0=1e6, # pre-exponential factor [1/s]\n Ea=40000.0, # activation energy [J/mol]\n n=1.0, # first-order reaction\n dH_rxn=-40000.0, # exothermic [J/mol]\n rho=1000.0, # density [kg/m³]\n Cp=4184.0, # heat capacity [J/(kg·K)]\n UA=800.0, # cooling jacket [W/K]\n C_A0=0.0, # start empty\n T0=300.0, # initial temperature [K]\n)"
5245
},
5346
{
5447
"cell_type": "markdown",
@@ -60,33 +53,14 @@
6053
"execution_count": null,
6154
"metadata": {},
6255
"outputs": [],
63-
"source": "# Constant feed and coolant conditions\nC_feed = Source(func=lambda t: 1000.0) # feed concentration [mol/m³]\nT_feed = Source(func=lambda t: 320.0) # feed temperature [K]\nT_cool = Source(func=lambda t: 290.0) # coolant temperature [K]\n\nscp = Scope(labels=[\"C_A [mol/m³]\", \"T [K]\"])\n\nsim = Simulation(\n blocks=[C_feed, T_feed, T_cool, cstr, scp],\n connections=[\n Connection(C_feed, cstr), # C_in -> port 0\n Connection(T_feed, cstr[1]), # T_in -> port 1\n Connection(T_cool, cstr[2]), # T_c -> port 2\n Connection(cstr, scp), # C_out -> scope port 0\n Connection(cstr[1], scp[1]), # T_out -> scope port 1\n ],\n dt=0.1,\n)\n\nsim.run(200)"
56+
"source": "# Constant feed and coolant conditions\nsrc_c = Source(lambda t: 1000.0) # feed concentration [mol/m³]\nsrc_t = Source(lambda t: 320.0) # feed temperature [K]\nsrc_tc = Source(lambda t: 290.0) # coolant temperature [K]\n\nsco = Scope(labels=[\"C_A [mol/m³]\", \"T [K]\"])\n\nsim = Simulation(\n [src_c, src_t, src_tc, reactor, sco],\n [\n Connection(src_c, reactor), # C_in\n Connection(src_t, reactor[1]), # T_in\n Connection(src_tc, reactor[2]), # T_c\n Connection(reactor, sco), # C_out\n Connection(reactor[1], sco[1]), # T_out\n ],\n dt=0.1,\n log=True,\n)\n\nsim.run(200)"
6457
},
6558
{
6659
"cell_type": "code",
6760
"execution_count": null,
6861
"metadata": {},
6962
"outputs": [],
70-
"source": [
71-
"time, signals = scp.read()\n",
72-
"\n",
73-
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))\n",
74-
"\n",
75-
"ax1.plot(time, signals[0])\n",
76-
"ax1.set_xlabel(\"Time [s]\")\n",
77-
"ax1.set_ylabel(\"Concentration [mol/m³]\")\n",
78-
"ax1.set_title(\"Outlet Concentration\")\n",
79-
"ax1.grid(True, alpha=0.3)\n",
80-
"\n",
81-
"ax2.plot(time, signals[1])\n",
82-
"ax2.set_xlabel(\"Time [s]\")\n",
83-
"ax2.set_ylabel(\"Temperature [K]\")\n",
84-
"ax2.set_title(\"Reactor Temperature\")\n",
85-
"ax2.grid(True, alpha=0.3)\n",
86-
"\n",
87-
"plt.tight_layout()\n",
88-
"plt.show()"
89-
]
63+
"source": "sco.plot(lw=1.5)\nplt.show()"
9064
},
9165
{
9266
"cell_type": "markdown",

docs/source/examples/equation_of_state.ipynb

Lines changed: 7 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,7 @@
2323
"execution_count": null,
2424
"metadata": {},
2525
"outputs": [],
26-
"source": [
27-
"import matplotlib.pyplot as plt\n",
28-
"\n",
29-
"from pathsim import Simulation, Connection\n",
30-
"from pathsim.blocks import Source, Constant, Scope\n",
31-
"\n",
32-
"from pathsim_chem.thermodynamics import PengRobinson, RedlichKwongSoave"
33-
]
26+
"source": "import matplotlib.pyplot as plt\n\nplt.style.use('../pathsim_docs.mplstyle')\n\nfrom pathsim import Simulation, Connection\nfrom pathsim.blocks import Source, Constant, Scope\n\nfrom pathsim_chem.thermodynamics import PengRobinson, RedlichKwongSoave"
3427
},
3528
{
3629
"cell_type": "markdown",
@@ -46,23 +39,7 @@
4639
"execution_count": null,
4740
"metadata": {},
4841
"outputs": [],
49-
"source": [
50-
"# Critical properties of methane\n",
51-
"Tc, Pc, omega = 190.6, 4.6e6, 0.011\n",
52-
"\n",
53-
"# EoS blocks\n",
54-
"pr = PengRobinson(Tc=Tc, Pc=Pc, omega=omega)\n",
55-
"rks = RedlichKwongSoave(Tc=Tc, Pc=Pc, omega=omega)\n",
56-
"\n",
57-
"# Fixed temperature, logarithmic pressure sweep\n",
58-
"import numpy as np\n",
59-
"T_const = Constant(250) # 250 K (above Tc, supercritical)\n",
60-
"P_src = Source(func=lambda t: 10**(4 + t * 0.035)) # 10 kPa to ~30 MPa over 100s\n",
61-
"\n",
62-
"# Scopes: record Z from both EoS (output port 1)\n",
63-
"scp_pr = Scope(labels=[\"Z_PR\"])\n",
64-
"scp_rks = Scope(labels=[\"Z_RKS\"])"
65-
]
42+
"source": "import numpy as np\n\n# Critical properties of methane\nTc, Pc, omega = 190.6, 4.6e6, 0.011\n\n# EoS blocks\npr = PengRobinson(Tc=Tc, Pc=Pc, omega=omega)\nrks = RedlichKwongSoave(Tc=Tc, Pc=Pc, omega=omega)\n\n# Fixed temperature, logarithmic pressure sweep\nsrc_t = Constant(250) # 250 K (above Tc, supercritical)\nsrc_p = Source(lambda t: 10**(4 + t * 0.035)) # 10 kPa to ~30 MPa over 100s\n\n# Scopes: record Z from both EoS (output port 1)\nsco_pr = Scope(labels=[\"Z_PR\"])\nsco_rks = Scope(labels=[\"Z_RKS\"])"
6643
},
6744
{
6845
"cell_type": "markdown",
@@ -78,46 +55,14 @@
7855
"execution_count": null,
7956
"metadata": {},
8057
"outputs": [],
81-
"source": [
82-
"sim = Simulation(\n",
83-
" blocks=[T_const, P_src, pr, rks, scp_pr, scp_rks],\n",
84-
" connections=[\n",
85-
" # Temperature -> both EoS (input port 0)\n",
86-
" Connection(T_const, pr, rks),\n",
87-
" # Pressure -> both EoS (input port 1)\n",
88-
" Connection(P_src, pr[1], rks[1]),\n",
89-
" # Z output (port 1) -> scopes\n",
90-
" Connection(pr[1], scp_pr),\n",
91-
" Connection(rks[1], scp_rks),\n",
92-
" ],\n",
93-
" dt=1.0,\n",
94-
")\n",
95-
"\n",
96-
"sim.run(100)"
97-
]
58+
"source": "sim = Simulation(\n [src_t, src_p, pr, rks, sco_pr, sco_rks],\n [\n Connection(src_t, pr, rks), # T -> both EoS\n Connection(src_p, pr[1], rks[1]), # P -> both EoS\n Connection(pr[1], sco_pr), # Z_PR\n Connection(rks[1], sco_rks), # Z_RKS\n ],\n dt=1.0,\n log=True,\n)\n\nsim.run(100)"
9859
},
9960
{
10061
"cell_type": "code",
10162
"execution_count": null,
10263
"metadata": {},
10364
"outputs": [],
104-
"source": [
105-
"time, Z_pr = scp_pr.read()\n",
106-
"_, Z_rks = scp_rks.read()\n",
107-
"P_vals = 10**(4 + time * 0.035) / 1e6 # MPa\n",
108-
"\n",
109-
"fig, ax = plt.subplots(figsize=(7, 5))\n",
110-
"ax.semilogx(P_vals, Z_pr[0], label=\"Peng-Robinson\")\n",
111-
"ax.semilogx(P_vals, Z_rks[0], \"--\", label=\"Soave-Redlich-Kwong\")\n",
112-
"ax.axhline(1.0, color=\"gray\", linestyle=\"-.\", alpha=0.5, label=\"Ideal gas\")\n",
113-
"ax.set_xlabel(\"Pressure [MPa]\")\n",
114-
"ax.set_ylabel(\"Compressibility Factor Z\")\n",
115-
"ax.set_title(\"Methane at T = 250 K\")\n",
116-
"ax.legend()\n",
117-
"ax.grid(True, alpha=0.3)\n",
118-
"plt.tight_layout()\n",
119-
"plt.show()"
120-
]
65+
"source": "time, [Z_pr] = sco_pr.read()\n_, [Z_rks] = sco_rks.read()\nP_vals = 10**(4 + time * 0.035) / 1e6 # MPa\n\nfig, ax = plt.subplots(figsize=(7, 5))\nax.semilogx(P_vals, Z_pr, label=\"Peng-Robinson\")\nax.semilogx(P_vals, Z_rks, \"--\", label=\"Soave-Redlich-Kwong\")\nax.axhline(1.0, color=\"gray\", linestyle=\"-.\", alpha=0.5, label=\"Ideal gas\")\nax.set_xlabel(\"Pressure [MPa]\")\nax.set_ylabel(\"Compressibility Factor Z\")\nax.set_title(\"Methane at T = 250 K\")\nax.legend()\nax.grid(True, alpha=0.3)\nplt.tight_layout()\nplt.show()"
12166
},
12267
{
12368
"cell_type": "markdown",
@@ -140,52 +85,14 @@
14085
"execution_count": null,
14186
"metadata": {},
14287
"outputs": [],
143-
"source": [
144-
"pr_mix = PengRobinson(\n",
145-
" Tc=[190.6, 305.3],\n",
146-
" Pc=[4.6e6, 4.872e6],\n",
147-
" omega=[0.011, 0.099],\n",
148-
" x=[0.7, 0.3],\n",
149-
")\n",
150-
"\n",
151-
"T_const2 = Constant(300)\n",
152-
"P_src2 = Source(func=lambda t: 10**(4 + t * 0.035))\n",
153-
"scp_mix = Scope(labels=[\"Z_mixture\"])\n",
154-
"\n",
155-
"sim_mix = Simulation(\n",
156-
" blocks=[T_const2, P_src2, pr_mix, scp_mix],\n",
157-
" connections=[\n",
158-
" Connection(T_const2, pr_mix),\n",
159-
" Connection(P_src2, pr_mix[1]),\n",
160-
" Connection(pr_mix[1], scp_mix),\n",
161-
" ],\n",
162-
" dt=1.0,\n",
163-
")\n",
164-
"\n",
165-
"sim_mix.run(100)"
166-
]
88+
"source": "pr_mix = PengRobinson(\n Tc=[190.6, 305.3],\n Pc=[4.6e6, 4.872e6],\n omega=[0.011, 0.099],\n x=[0.7, 0.3],\n)\n\nsrc_t2 = Constant(300)\nsrc_p2 = Source(lambda t: 10**(4 + t * 0.035))\nsco_mix = Scope(labels=[\"Z_mixture\"])\n\nsim_mix = Simulation(\n [src_t2, src_p2, pr_mix, sco_mix],\n [\n Connection(src_t2, pr_mix),\n Connection(src_p2, pr_mix[1]),\n Connection(pr_mix[1], sco_mix),\n ],\n dt=1.0,\n log=True,\n)\n\nsim_mix.run(100)"
16789
},
16890
{
16991
"cell_type": "code",
17092
"execution_count": null,
17193
"metadata": {},
17294
"outputs": [],
173-
"source": [
174-
"time_m, Z_mix = scp_mix.read()\n",
175-
"P_mix = 10**(4 + time_m * 0.035) / 1e6\n",
176-
"\n",
177-
"fig, ax = plt.subplots(figsize=(7, 5))\n",
178-
"ax.semilogx(P_vals, Z_pr[0], label=\"Pure CH₄ (250 K)\")\n",
179-
"ax.semilogx(P_mix, Z_mix[0], \"--\", label=\"70/30 CH₄-C₂H₆ (300 K)\")\n",
180-
"ax.axhline(1.0, color=\"gray\", linestyle=\"-.\", alpha=0.5)\n",
181-
"ax.set_xlabel(\"Pressure [MPa]\")\n",
182-
"ax.set_ylabel(\"Compressibility Factor Z\")\n",
183-
"ax.set_title(\"Peng-Robinson: Pure vs Mixture\")\n",
184-
"ax.legend()\n",
185-
"ax.grid(True, alpha=0.3)\n",
186-
"plt.tight_layout()\n",
187-
"plt.show()"
188-
]
95+
"source": "time_m, [Z_mix] = sco_mix.read()\nP_mix = 10**(4 + time_m * 0.035) / 1e6\n\nfig, ax = plt.subplots(figsize=(7, 5))\nax.semilogx(P_vals, Z_pr, label=\"Pure CH₄ (250 K)\")\nax.semilogx(P_mix, Z_mix, \"--\", label=\"70/30 CH₄-C₂H₆ (300 K)\")\nax.axhline(1.0, color=\"gray\", linestyle=\"-.\", alpha=0.5)\nax.set_xlabel(\"Pressure [MPa]\")\nax.set_ylabel(\"Compressibility Factor Z\")\nax.set_title(\"Peng-Robinson: Pure vs Mixture\")\nax.legend()\nax.grid(True, alpha=0.3)\nplt.tight_layout()\nplt.show()"
18996
},
19097
{
19198
"cell_type": "markdown",
@@ -208,4 +115,4 @@
208115
},
209116
"nbformat": 4,
210117
"nbformat_minor": 4
211-
}
118+
}

0 commit comments

Comments
 (0)