mirror of https://github.com/Nonannet/pyladoc.git
rendering tests updated
This commit is contained in:
parent
b6b673a65e
commit
f6c80eb047
|
@ -0,0 +1,176 @@
|
||||||
|
import pyladoc
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import pandas as pd
|
||||||
|
import document_validation
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
VALIDATE_HTML_CODE_ONLINE = False
|
||||||
|
WRITE_RESULT_FILES = True
|
||||||
|
|
||||||
|
|
||||||
|
def mason_saxena_k_mixture(x_h2):
|
||||||
|
"""
|
||||||
|
Calculate the thermal conductivity of a H2/CO2 gas mixture using the Mason and Saxena mixing rule.
|
||||||
|
|
||||||
|
The mixture thermal conductivity is computed as:
|
||||||
|
k_mix = Σ_i [ X_i * k_i / (Σ_j X_j * φ_ij) ]
|
||||||
|
with:
|
||||||
|
φ_ij = 1/√8 * (1 + M_i/M_j)^(-0.5) * [ 1 + ( (k_i/k_j)**0.5 * (M_j/M_i)**0.25 ) ]^2
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
x_h2 (float or array-like): Mole fraction of H2 (from 0 to 1). The CO2 mole fraction is 1 - x_h2.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float or array-like: Thermal conductivity of the mixture in W/m·K.
|
||||||
|
"""
|
||||||
|
# Pure gas properties (at room temperature, approx.)
|
||||||
|
k_h2 = 0.1805 # Thermal conductivity of H2 in W/mK
|
||||||
|
k_co2 = 0.0166 # Thermal conductivity of CO2 in W/mK
|
||||||
|
|
||||||
|
M_h2 = 2.016 # Molar mass of H2 in g/mol
|
||||||
|
M_co2 = 44.01 # Molar mass of CO2 in g/mol
|
||||||
|
|
||||||
|
# Define the phi_ij function according to Mason and Saxena.
|
||||||
|
def phi(k_i, k_j, M_i, M_j):
|
||||||
|
return (1 / np.sqrt(8)) * (1 + M_i / M_j) ** (-0.5) * (1 + ((k_i / k_j) ** 0.5 * (M_j / M_i) ** 0.25))**2
|
||||||
|
|
||||||
|
# Compute phi terms for the two species.
|
||||||
|
# For i = j the phi terms should be 1.
|
||||||
|
phi_h2_h2 = phi(k_h2, k_h2, M_h2, M_h2) # Should be 1
|
||||||
|
phi_h2_co2 = phi(k_h2, k_co2, M_h2, M_co2)
|
||||||
|
phi_co2_h2 = phi(k_co2, k_h2, M_co2, M_h2)
|
||||||
|
phi_co2_co2 = phi(k_co2, k_co2, M_co2, M_co2) # Should be 1
|
||||||
|
|
||||||
|
# Ensure we can perform vectorized operations.
|
||||||
|
x_h2 = np.array(x_h2)
|
||||||
|
x_co2 = 1 - x_h2
|
||||||
|
|
||||||
|
# Use the Mason-Saxena mixing rule:
|
||||||
|
# k_mix = X_H2 * k_H2 / (X_H2*φ_H2_H2 + X_CO2*φ_H2_CO2) +
|
||||||
|
# X_CO2 * k_CO2 / (X_CO2*φ_CO2_CO2 + X_H2*φ_CO2_H2)
|
||||||
|
k_mix = (x_h2 * k_h2 / (x_h2 * phi_h2_h2 + x_co2 * phi_h2_co2)) + \
|
||||||
|
(x_co2 * k_co2 / (x_co2 * phi_co2_co2 + x_h2 * phi_co2_h2))
|
||||||
|
|
||||||
|
return k_mix
|
||||||
|
|
||||||
|
|
||||||
|
def make_document():
|
||||||
|
doc = pyladoc.DocumentWriter()
|
||||||
|
|
||||||
|
doc.add_markdown("""
|
||||||
|
# Thermal Conductivity of Mixtures
|
||||||
|
|
||||||
|
The determination of the thermal conductivity of gas mixtures is a central aspect of modeling
|
||||||
|
transport phenomena, particularly in high-temperature and high-pressure processes. Among the
|
||||||
|
most established approaches is the empirical equation introduced by Wassiljewa, which was
|
||||||
|
subsequently refined by Mason and Saxena to improve its applicability to multicomponent systems.
|
||||||
|
This model offers a reliable means of estimating the thermal conductivity of gas mixtures based
|
||||||
|
on the properties of the pure components and their molar interactions.
|
||||||
|
|
||||||
|
The thermal conductivity of a gas mixture, denoted by $$\\lambda_{\\text{mix}}$$, can expressed as
|
||||||
|
shown in equation @eq:lambda_mixture.
|
||||||
|
|
||||||
|
$$
|
||||||
|
\\label{eq:lambda_mixture}
|
||||||
|
\\lambda_{\text{mix}} = \\sum_{i=1}^{n} \\frac{x_i \\lambda_i}{\\sum_{j=1}^{n} x_j \\Phi_{ij}}
|
||||||
|
$$
|
||||||
|
|
||||||
|
In this equation, $$x_i$$ represents the molar fraction of component $$i$$ within the mixture,
|
||||||
|
while $$\\lambda_i$$ denotes the thermal conductivity of the pure substance $$i$$. The denominator
|
||||||
|
contains the interaction parameter $$\\Phi_{ij}$$, which describes the influence of component
|
||||||
|
$$j$$ on the transport properties of component $$i$$.
|
||||||
|
|
||||||
|
The interaction parameter $$\\Phi_{ij}$$ is given by the relation shown in equation @eq:interaction_parameter.
|
||||||
|
|
||||||
|
$$
|
||||||
|
\\label{eq:interaction_parameter}
|
||||||
|
\\Phi_{ij} = \\frac{1}{\\sqrt{8}} \\left(1 + \\frac{M_i}{M_j} \\right)^{-1/2} \\left[ 1 + \\left( \\frac{\\lambda_i}{\\lambda_j} \\right)^{1/2} \\left( \\frac{M_j}{M_i} \\right)^{1/4} \\right]^2
|
||||||
|
$$
|
||||||
|
|
||||||
|
Here, $$M_i$$ and $$M_j$$ are the molar masses of the components $$i$$ and $$j$$, respectively.
|
||||||
|
Molar masses and thermal conductivity of the pure substances are listed in table @table:gas_probs.
|
||||||
|
The structure of this expression illustrates the nonlinear dependence of the interaction term on
|
||||||
|
both the molar mass ratio and the square root of the conductivity ratio of the involved species.
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Table
|
||||||
|
data = {
|
||||||
|
"Gas": ["H2", "O2", "N2", "CO2", "CH4", "Ar", "He"],
|
||||||
|
"Molar mass in g/mol": ["2.016", "32.00", "28.02", "44.01", "16.04", "39.95", "4.0026"],
|
||||||
|
"Thermal conductivity in W/m/K": ["0.1805", "0.0263", "0.0258", "0.0166", "0.0341", "0.0177", "0.1513"]
|
||||||
|
}
|
||||||
|
df = pd.DataFrame(data)
|
||||||
|
doc.add_table(df.style.hide(axis="index"), 'Properties of some gases', 'gas_probs')
|
||||||
|
|
||||||
|
doc.add_markdown("""
|
||||||
|
This formulation acknowledges that the transport properties of a gas mixture are not a simple
|
||||||
|
linear combination of the individual conductivities. Rather, they are governed by intermolecular
|
||||||
|
interactions, which affect the energy exchange and diffusion behavior of each component. These
|
||||||
|
interactions are particularly significant at elevated pressures or in cases where the gas components
|
||||||
|
exhibit widely differing molecular masses or transport properties.
|
||||||
|
|
||||||
|
The equation proposed by Wassiljewa and refined by Mason and Saxena assumes that binary interactions
|
||||||
|
dominate the behavior of the mixture, while higher-order (three-body or more) interactions are
|
||||||
|
neglected. It also presumes that the gases approximate ideal behavior, although in practical
|
||||||
|
applications, moderate deviations from ideality are tolerated without significant loss of accuracy.
|
||||||
|
In figure @fig:mixture the resulting thermal conductivity of an H2/CO2-mixture is shown.""")
|
||||||
|
|
||||||
|
# Figure
|
||||||
|
x_h2_values = np.linspace(0, 1, 100)
|
||||||
|
k_mixture_values = mason_saxena_k_mixture(x_h2_values)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
ax.set_xlabel("H2 molar fraction / %")
|
||||||
|
ax.set_ylabel("Thermal Conductivity / (W/m·K)")
|
||||||
|
ax.plot(x_h2_values * 100, k_mixture_values, color='black')
|
||||||
|
|
||||||
|
doc.add_diagram(fig, 'Thermal Conductivity of H2/CO2 mixtures', 'mixture')
|
||||||
|
|
||||||
|
doc.add_markdown("""
|
||||||
|
In engineering practice, the accurate determination of $$\\lambda_{\\text{mix}}$$ is essential
|
||||||
|
for the prediction of heat transfer in systems such as membrane modules, chemical reactors, and
|
||||||
|
combustion chambers. In the context of membrane-based gas separation, for instance, the thermal
|
||||||
|
conductivity of the gas mixture influences the local temperature distribution, which in turn affects
|
||||||
|
both the permeation behavior and the structural stability of the membrane.
|
||||||
|
|
||||||
|
It is important to note that the calculated mixture conductivity reflects only the gas phase
|
||||||
|
behavior. In porous systems such as carbon membranes, additional effects must be considered.
|
||||||
|
These include the solid-phase thermal conduction through the membrane matrix, radiative transport
|
||||||
|
in pore channels at high temperatures, and transport in the Knudsen regime for narrow pores.
|
||||||
|
To account for these complexities, models based on effective medium theory, such as those of
|
||||||
|
Maxwell-Eucken or Bruggeman, are frequently employed. These models combine the conductivities of
|
||||||
|
individual phases (gas and solid) with geometrical factors that reflect the morphology of the
|
||||||
|
porous structure.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Expanded by more or less sensible AI jabbering; based on: [doi:10.14279/depositonce-7390](https://doi.org/10.14279/depositonce-7390)
|
||||||
|
""")
|
||||||
|
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
def test_html_render():
|
||||||
|
doc = make_document()
|
||||||
|
html_code = doc.to_html()
|
||||||
|
|
||||||
|
document_validation.validate_html(html_code, VALIDATE_HTML_CODE_ONLINE)
|
||||||
|
|
||||||
|
if WRITE_RESULT_FILES:
|
||||||
|
with open('tests/out/test_html_render1.html', 'w', encoding='utf-8') as f:
|
||||||
|
f.write(pyladoc.inject_to_template(html_code, internal_template='templates/test_template.html'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_latex_render():
|
||||||
|
doc = make_document()
|
||||||
|
|
||||||
|
if WRITE_RESULT_FILES:
|
||||||
|
with open('tests/out/test_html_render1.tex', 'w', encoding='utf-8') as f:
|
||||||
|
f.write(doc.to_latex())
|
||||||
|
|
||||||
|
assert doc.to_pdf('tests/out/test_latex_render1.pdf', font_family='serif')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_html_render()
|
||||||
|
test_latex_render()
|
|
@ -8,9 +8,9 @@ WRITE_RESULT_FILES = True
|
||||||
|
|
||||||
|
|
||||||
def make_document():
|
def make_document():
|
||||||
dw = pyladoc.DocumentWriter()
|
doc = pyladoc.DocumentWriter()
|
||||||
|
|
||||||
dw.add_markdown("""
|
doc.add_markdown("""
|
||||||
# Special characters
|
# Special characters
|
||||||
|
|
||||||
ö ä ü Ö Ä Ü ß @ ∆
|
ö ä ü Ö Ä Ü ß @ ∆
|
||||||
|
@ -20,9 +20,9 @@ def make_document():
|
||||||
£ ¥ $ €
|
£ ¥ $ €
|
||||||
|
|
||||||
Œ
|
Œ
|
||||||
|
|
||||||
# Link
|
# Link
|
||||||
|
|
||||||
This is a hyperlink: [nonan.net](https://www.nonan.net)
|
This is a hyperlink: [nonan.net](https://www.nonan.net)
|
||||||
|
|
||||||
# Table
|
# Table
|
||||||
|
@ -42,15 +42,15 @@ def make_document():
|
||||||
| 3 | KL3202 | PT100 2 Temperatureingänge (3-Leiter)
|
| 3 | KL3202 | PT100 2 Temperatureingänge (3-Leiter)
|
||||||
| 1 | KL2404 | 4 Digitalausgänge
|
| 1 | KL2404 | 4 Digitalausgänge
|
||||||
| 2 | KL9010 | Endklemme
|
| 2 | KL9010 | Endklemme
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Equations
|
# Equations
|
||||||
|
|
||||||
This line represents a reference to the equation @eq:test1.
|
This line represents a reference to the equation @eq:test1.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
dw.add_equation(r'y = a + b * \sum_{i=0}^{\infty} a_i x^i', 'test1')
|
doc.add_equation(r'y = a + b * \sum_{i=0}^{\infty} a_i x^i', 'test1')
|
||||||
|
|
||||||
# Figure
|
# Figure
|
||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
|
@ -65,7 +65,7 @@ def make_document():
|
||||||
ax.set_title('Fruit supply by kind and color')
|
ax.set_title('Fruit supply by kind and color')
|
||||||
ax.legend(title='Fruit color')
|
ax.legend(title='Fruit color')
|
||||||
|
|
||||||
dw.add_diagram(fig, 'Bar chart with individual bar colors')
|
doc.add_diagram(fig, 'Bar chart with individual bar colors')
|
||||||
|
|
||||||
# Table
|
# Table
|
||||||
mydataset = {
|
mydataset = {
|
||||||
|
@ -79,9 +79,9 @@ def make_document():
|
||||||
}
|
}
|
||||||
df = pd.DataFrame(mydataset)
|
df = pd.DataFrame(mydataset)
|
||||||
|
|
||||||
dw.add_table(df.style.hide(axis="index"), 'This is a example table', 'example1')
|
doc.add_table(df.style.hide(axis="index"), 'This is a example table', 'example1')
|
||||||
|
|
||||||
return dw
|
return doc
|
||||||
|
|
||||||
|
|
||||||
def test_html_render():
|
def test_html_render():
|
||||||
|
@ -91,7 +91,7 @@ def test_html_render():
|
||||||
document_validation.validate_html(html_code, VALIDATE_HTML_CODE_ONLINE)
|
document_validation.validate_html(html_code, VALIDATE_HTML_CODE_ONLINE)
|
||||||
|
|
||||||
if WRITE_RESULT_FILES:
|
if WRITE_RESULT_FILES:
|
||||||
with open('tests/out/test_html_render.html', 'w', encoding='utf-8') as f:
|
with open('tests/out/test_html_render2.html', 'w', encoding='utf-8') as f:
|
||||||
f.write(pyladoc.inject_to_template(html_code, internal_template='templates/test_template.html'))
|
f.write(pyladoc.inject_to_template(html_code, internal_template='templates/test_template.html'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ def test_latex_render():
|
||||||
|
|
||||||
# print(doc.to_latex())
|
# print(doc.to_latex())
|
||||||
|
|
||||||
assert doc.to_pdf('tests/out/test_latex_render.pdf', font_family='serif')
|
assert doc.to_pdf('tests/out/test_latex_render2.pdf', font_family='serif')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue