Skip to content

Commit eb03e17

Browse files
committed
implement "pathllib"
replace os.path ... with Path ... in examples, __init__.py, utilities.py, and chemkin_wrapper.py
1 parent 3aba817 commit eb03e17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1965
-1618
lines changed

examples/PFR/plugflow.py

Lines changed: 73 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
# SOFTWARE.
2222

23-
""".. _ref_plug_flow_reactor:
23+
r""".. _ref_plug_flow_reactor:
2424
2525
===========================================
2626
Simulate NO reduction in combustion exhaust
@@ -31,25 +31,29 @@
3131
as well as its resemblance of an exhaust duct or a tailpipe.
3232
3333
The PFR model is a steady-state open reactor because materials are allowed to
34-
move in and out of the reactor. The solutions are obtained along the length of the reactor
35-
as the inlet materials march toward the reactor exit. Typically, the pressure of the PFR
36-
is fixed. However, Chemkin does permit the use of a pressure profile to enforce a certain
37-
pressure gradient in the PFR.
38-
39-
Use the ``PlugFlowReactor_FixedTemperature()`` or ``PlugFlowReactor_EnergyConservation()``
40-
method to create a PFR. Unlike the closed batch reactor model, which is instantiated by a mixture,
34+
move in and out of the reactor. The solutions are obtained along the length of
35+
the reactor as the inlet materials march toward the reactor exit. Typically,
36+
the pressure of the PFR is fixed. However, Chemkin does permit the use of
37+
a pressure profile to enforce a certain pressure gradient in the PFR.
38+
39+
Use the ``PlugFlowReactor_FixedTemperature()`` or
40+
``PlugFlowReactor_EnergyConservation()`` method to create a PFR.
41+
Unlike the closed batch reactor model, which is instantiated by a mixture,
4142
the open reactor model, such as the PFR model, is initiated by a stream, which is
4243
simply a mixture with the addition of the inlet mass/volumetric
43-
flow rate or velocity. You already know how to create a stream if you know how to create
44-
a mixture. You can specify the inlet flow rate using one of these methods:
44+
flow rate or velocity. You already know how to create a stream if you know
45+
how to create a mixture. You can specify the inlet flow rate using one of
46+
these methods:
4547
``velocity()``, ``mass_flowrate()``, ``vol_flowrate()``, or ``sccm()``
4648
(standard cubic centimeters per minute).
4749
4850
This example shows how to use the Chemkin PFR model to study the
4951
reduction of nitric oxide (NO) in the combustion exhaust by using the
50-
CH\ :sub:`4` reburning process. This is achieved by injecting CH\ :sub:`4` into the
51-
hot exhaust gas mixture. As the exhaust gas travels along the tubular reactor, the injected
52-
CH\ :sub:`4` is oxidized by the NO to form N\ :sub:`2`\ , CO, and H\ :sub:`2`. This is why this NO reduction process is called *methane reburning*.
52+
CH\ :sub:`4` reburning process. This is achieved by injecting CH\ :sub:`4` into
53+
the hot exhaust gas mixture. As the exhaust gas travels along the tubular reactor,
54+
the injected CH\ :sub:`4` is oxidized by the NO to form
55+
N\ :sub:`2`\ , CO, and H\ :sub:`2`. This is why this NO reduction process is called
56+
*methane reburning*.
5357
"""
5458

5559
# sphinx_gallery_thumbnail_path = '_static/plot_plug_flow_reactor.png'
@@ -58,7 +62,7 @@
5862
# Import PyChemkin packages and start the logger
5963
# ==============================================
6064

61-
import os
65+
from pathlib import Path
6266
import time
6367

6468
import matplotlib.pyplot as plt # plotting
@@ -73,7 +77,7 @@
7377
from ansys.chemkin.core.logger import logger
7478

7579
# check working directory
76-
current_dir = os.getcwd()
80+
current_dir = str(Path.cwd())
7781
logger.debug("working directory: " + current_dir)
7882
# set interactive mode for plotting the results
7983
# interactive = True: display plot
@@ -84,18 +88,18 @@
8488
########################
8589
# Create a chemistry set
8690
# ======================
87-
# The mechanism to load is the C2 NOx mechanism for the combustion of C1-C2 hydrocarbons.
88-
# The mechanism comes with the standard Ansys Chemkin
91+
# The mechanism to load is the C2 NOx mechanism for the combustion o
92+
# C1-C2 hydrocarbons. The mechanism comes with the standard Ansys Chemkin
8993
# installation in the ``/reaction/data`` directory.
9094

9195
# set mechanism directory (the default Chemkin mechanism data directory)
92-
data_dir = os.path.join(ck.ansys_dir, "reaction", "data")
96+
data_dir = Path(ck.ansys_dir) / "reaction" / "data"
9397
mechanism_dir = data_dir
9498
# create a chemistry set based on the GRI mechanism
9599
MyGasMech = ck.Chemistry(label="C2 NOx")
96100
# set mechanism input files
97101
# including the full file path is recommended
98-
MyGasMech.chemfile = os.path.join(mechanism_dir, "C2_NOx_SRK.inp")
102+
MyGasMech.chemfile = str(mechanism_dir / "C2_NOx_SRK.inp")
99103

100104
######################################
101105
# Preprocess the GRI 3.0 chemistry set
@@ -109,10 +113,10 @@
109113
# =================================
110114
# Create a hot exhaust gas mixture by assigning the mole fractions of the
111115
# species. A stream is simply a mixture with the addition of
112-
# mass/volumetric flow rate or velocity. Here, the gas composition ``exhaust.X`` is given
113-
# by a recipe consisting of the common species in the combustion exhaust, such as
114-
# CO\ :sub:`2` and H\ :sub:`2`O and the CH\ :sub:`4` injected. The inlet velocity
115-
# is given by ``exhaust.velocity = 26.815``.
116+
# mass/volumetric flow rate or velocity. Here, the gas composition ``exhaust.X``
117+
# is given by a recipe consisting of the common species in the combustion exhaust,
118+
# such as CO\ :sub:`2` and H\ :sub:`2`O and the CH\ :sub:`4` injected.
119+
# The inlet velocity is given by ``exhaust.velocity = 26.815``.
116120

117121
# create the inlet (mixture + flow rate)
118122
exhaust = Stream(MyGasMech)
@@ -136,20 +140,20 @@
136140
#####################################
137141
# Create the plug flow reactor object
138142
# ===================================
139-
# Use the ``PlugFlowReactor_FixedTemperature()`` method to create a plug flow reactor.
140-
# The required input parameter of the open reactor models in PyChemkin
141-
# is the stream, while PyChemkin batch reactor models take a mixture
142-
# as the input parameter. In this case, the exhaust stream is used to create a
143-
# PFR named ``tubereactor``.
143+
# Use the ``PlugFlowReactor_FixedTemperature()`` method to create
144+
# a plug flow reactor. The required input parameter of
145+
# the open reactor models in PyChemkin is the stream, while PyChemkin
146+
# batch reactor models take a mixture as the input parameter. In this case,
147+
# the exhaust stream is used to create a PFR named ``tubereactor``.
144148
tubereactor = PlugFlowReactor_FixedTemperature(exhaust)
145149

146150
############################################
147151
# Set up additional reactor model parameters
148152
# ==========================================
149-
# For the PFR, the required reactor parameters are the reactor diameter [cm] or the
150-
# cross-sectional flow area [cm2] and the reactor length [cm].
151-
# The mixture condition and inlet mass flow rate of the inlet are already defined
152-
# by the stream when the ``tubereactor`` PFR is instantiated.
153+
# For the PFR, the required reactor parameters are the reactor diameter [cm]
154+
# or the cross-sectional flow area [cm2] and the reactor length [cm].
155+
# The mixture condition and inlet mass flow rate of the inlet are already
156+
# defined by the stream when the ``tubereactor`` PFR is instantiated.
153157

154158
# set PFR diameter [cm]
155159
tubereactor.diameter = 5.8431
@@ -168,13 +172,14 @@
168172
####################
169173
# Set output options
170174
# ==================
171-
# You can turn on adaptive solution saving to resolve the steep variations in the solution
172-
# profile. Here, additional solution data points are saved for every **100** internal solver steps.
175+
# You can turn on adaptive solution saving to resolve the steep variations
176+
# in the solution profile. Here, additional solution data points are saved
177+
# for every **100** internal solver steps.
173178
#
174179
# .. note::
175-
# By default, distance intervals for both print and save solution are 1/100 of the
176-
# reactor length. In this case, :math:`dt=time/100=0.001`\ . You can change them
177-
# to different values.
180+
# By default, distance intervals for both print and save solution are
181+
# 1/100 of the reactor length. In this case, :math:`dt=time/100=0.001`\ .
182+
# You can change them to different values.
178183

179184
# set distance between saving solution
180185
tubereactor.timestep_for_saving_solution = 0.0005
@@ -219,19 +224,22 @@
219224
# The postprocessing step parses the solution and packages the solution values at each
220225
# time point into a mixture. There are two ways to access the solution profiles:
221226
#
222-
# - The raw solution profiles (value as a function of distance) are available for distance,
223-
# temperature, pressure, volume, and species mass fractions.
227+
# - The raw solution profiles (value as a function of distance) are available
228+
# for distance, temperature, pressure, volume, and species mass fractions.
224229
#
225230
# - The mixtures permit the use of all property and rate utilities to extract
226231
# information such as viscosity, density, and mole fractions.
227232
#
228-
# You can use the ``get_solution_variable_profile()`` method to get the raw solution profiles. You
229-
# can get solution mixtures using either the ``get_solution_mixture_at_index()`` method for the
230-
# solution mixture at the given saved location or the ``get_solution_mixture()`` method for the
231-
# solution mixture at the given distance. (In this case, the mixture is constructed by interpolation.)
233+
# You can use the ``get_solution_variable_profile()`` method to get
234+
# the raw solution profiles. You can get solution mixtures using either the
235+
# ``get_solution_mixture_at_index()`` method for the solution mixture at
236+
# the given saved location or the ``get_solution_mixture()`` method for the
237+
# solution mixture at the given distance.
238+
# (In this case, the mixture is constructed by interpolation.)
232239
#
233-
# You can get the outlet solution by simply grabbing the solution values at the very last point by
234-
# using \ :math:`(outlet solution index) = (number of solutions) - 1`\.
240+
# You can get the outlet solution by simply grabbing the solution values
241+
# at the very last point by using
242+
# \ :math:`(outlet solution index) = (number of solutions) - 1`\.
235243
#
236244

237245
# postprocess the solution profiles
@@ -246,29 +254,29 @@
246254
# get the temperature profile [K]
247255
tempprofile = tubereactor.get_solution_variable_profile("temperature")
248256
# get the CH4 mass fraction profile
249-
YCH4profile = tubereactor.get_solution_variable_profile("CH4")
257+
ch4_y_profile = tubereactor.get_solution_variable_profile("CH4")
250258
# get the CO mass fraction profile
251-
YCOprofile = tubereactor.get_solution_variable_profile("CO")
259+
co_y_profile = tubereactor.get_solution_variable_profile("CO")
252260
# get the H2O mass fraction profile
253-
YH2Oprofile = tubereactor.get_solution_variable_profile("H2O")
261+
h2o_y_profile = tubereactor.get_solution_variable_profile("H2O")
254262
# get the H2 mass fraction profile
255-
YH2profile = tubereactor.get_solution_variable_profile("H2")
263+
h2_y_profile = tubereactor.get_solution_variable_profile("H2")
256264
# get the NO mass fraction profile
257-
YNOprofile = tubereactor.get_solution_variable_profile("NO")
265+
no_y_profile = tubereactor.get_solution_variable_profile("NO")
258266
# get the N2 mass fraction profile
259-
YN2profile = tubereactor.get_solution_variable_profile("N2")
267+
n2_y_profile = tubereactor.get_solution_variable_profile("N2")
260268

261269
# inlet NO mass fraction
262-
YNO_inlet = exhaust.Y[MyGasMech.get_specindex("NO")]
270+
no_y_inlet = exhaust.Y[MyGasMech.get_specindex("NO")]
263271
# outlet grid index
264272
xout_index = solutionpoints - 1
265273
print("At the reactor inlet: x = 0 [xm]")
266-
print(f"The NO mass fraction = {YNO_inlet}.")
274+
print(f"The NO mass fraction = {no_y_inlet}.")
267275
print(f"At the reactor outlet: x = {xprofile[xout_index]} [cm]")
268-
print(f"The NO mass fraction = {YNOprofile[xout_index]}.")
276+
print(f"The NO mass fraction = {no_y_profile[xout_index]}.")
269277
print(
270278
"The NO conversion rate = "
271-
+ f"{(YNO_inlet - YNOprofile[xout_index]) / YNO_inlet * 100.0} %\n."
279+
+ f"{(no_y_inlet - no_y_profile[xout_index]) / no_y_inlet * 100.0} %\n."
272280
)
273281

274282
# more involved postprocessing using mixtures
@@ -297,22 +305,23 @@
297305
# Plot the species and the gas velocity profiles along the tubular reactor.
298306
#
299307
# You can see from the plots that CH\ :sub:`4` is mainly oxidized by NO to form
300-
# N\ :sub:`2` and H\ :sub:`2`\ in the hot exhaust. The gas velocity accelerates because of
301-
# the net increase in total number of moles of gas species due to the chemical reactions.
302-
# You can conduct more in depth analyses of the reaction pathways of the CH\ :sub:`4` reburning
303-
# mechanism by applying other PyChemkin utilities.
308+
# N\ :sub:`2` and H\ :sub:`2`\ in the hot exhaust. The gas velocity accelerates
309+
# because of the net increase in total number of moles of gas species due to
310+
# the chemical reactions. You can conduct more in depth analyses of
311+
# the reaction pathways of the CH\ :sub:`4` reburning mechanism by
312+
# applying other PyChemkin utilities.
304313
plt.subplots(2, 2, sharex="col", figsize=(12, 6))
305314
plt.suptitle("Constant Temperature Plug-Flow Reactor", fontsize=16)
306315
plt.subplot(221)
307-
plt.plot(xprofile, YN2profile, "r-")
316+
plt.plot(xprofile, n2_y_profile, "r-")
308317
plt.ylabel("N2 Mass Fraction")
309318
plt.subplot(222)
310-
plt.plot(xprofile, YH2Oprofile, "b-", label="H2O")
319+
plt.plot(xprofile, h2o_y_profile, "b-", label="H2O")
311320
plt.ylabel("H2O Mass Fraction")
312321
plt.subplot(223)
313-
plt.plot(xprofile, YNOprofile, "g-", label="NO")
314-
plt.plot(xprofile, YCH4profile, "g:", label="CH4")
315-
plt.plot(xprofile, YH2profile, "g--", label="H2")
322+
plt.plot(xprofile, no_y_profile, "g-", label="NO")
323+
plt.plot(xprofile, ch4_y_profile, "g:", label="CH4")
324+
plt.plot(xprofile, h2_y_profile, "g--", label="H2")
316325
plt.legend()
317326
plt.xlabel("distance [cm]")
318327
plt.ylabel("Mass Fraction")

0 commit comments

Comments
 (0)