simjsr 0.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
simjsr-0.0.0/PKG-INFO ADDED
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.3
2
+ Name: simjsr
3
+ Version: 0.0.0
4
+ Author: Andreas V. Copan
5
+ Author-email: Andreas V. Copan <avcopan@uga.edu>
6
+ Requires-Dist: cantera>=3.2.0
7
+ Requires-Python: >=3.12
@@ -0,0 +1,78 @@
1
+ [project]
2
+ name = "simjsr"
3
+ version = "0.0.0"
4
+ authors = [{name = "Andreas V. Copan", email = "avcopan@uga.edu"}]
5
+ requires-python = ">= 3.12"
6
+ dependencies = [
7
+ "cantera>=3.2.0",
8
+ ]
9
+
10
+ [build-system]
11
+ build-backend = "uv_build"
12
+ requires = ["uv_build<0.12"]
13
+
14
+ # Ruff configurations
15
+ [tool.ruff]
16
+ exclude = [
17
+ "docs",
18
+ "**/*.ipynb",
19
+ ]
20
+
21
+ [tool.ruff.lint]
22
+ select = ["ALL"]
23
+ ignore = [
24
+ "COM812", # missing trailing comma (handled by format)
25
+ "RUF022", # `__all__` is not sorted
26
+ "TID252", # relative import
27
+ "D203", # confict: incorrect blank line before class (uses D211 instead)
28
+ "D213", # conflict: multi-line summary second line (uses D212 instead)
29
+ ]
30
+
31
+ [tool.ruff.lint.per-file-ignores]
32
+ "tests/**.py" = ["S101"]
33
+
34
+ [tool.ruff.lint.pydocstyle]
35
+ convention = "google"
36
+
37
+ # Ty configurations
38
+ [tool.ty.environment]
39
+ python = ".pixi/envs/dev/bin/python"
40
+
41
+ [tool.ty.src]
42
+ include = [
43
+ "src",
44
+ "tests",
45
+ ]
46
+
47
+ # Import-linter configurations
48
+ [tool.importlinter]
49
+ root_package = "simjsr"
50
+
51
+ [[tool.importlinter.contracts]]
52
+ name = "Module Layering"
53
+ type = "layers"
54
+ containers = "simjsr"
55
+ layers = [
56
+ "convert | run",
57
+ ]
58
+
59
+ # Pytest configurations
60
+ [tool.pytest.ini_options]
61
+ testpaths = ["tests", "src"]
62
+ addopts = [
63
+ "--doctest-modules",
64
+ "--cov=simjsr",
65
+ "--cov-report=term-missing",
66
+ "--cov-report=html",
67
+ ]
68
+ doctest_optionflags = "NORMALIZE_WHITESPACE"
69
+
70
+ # Pytest-cov configurations
71
+ [tool.coverage.run]
72
+ branch = true
73
+ source = ["simjsr"]
74
+
75
+ [tool.coverage.report]
76
+ show_missing = true
77
+ skip_covered = true
78
+ fail_under = 80
@@ -0,0 +1,7 @@
1
+ """simrun."""
2
+
3
+ __version__ = "0.0.0"
4
+
5
+ from . import convert, run
6
+
7
+ __all__ = ["convert", "run"]
@@ -0,0 +1,19 @@
1
+ """Convert mechanism files to Cantera YAML format."""
2
+
3
+ from pathlib import Path
4
+
5
+ from cantera.ck2yaml import Parser
6
+
7
+
8
+ def from_chemkin(
9
+ mech_file: str | Path,
10
+ thermo_file: str | Path | None = None,
11
+ out_file: str | Path | None = None,
12
+ ) -> str:
13
+ """Convert Chemkin mechanism and thermo files to Cantera YAML format."""
14
+ out_file = str(out_file or Path(mech_file).with_suffix(".yaml"))
15
+
16
+ Parser.convert_mech(
17
+ input_file=mech_file, thermo_file=thermo_file, out_name=out_file
18
+ )
19
+ return str(out_file)
@@ -0,0 +1,58 @@
1
+ """Reactors."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ import cantera as ct
6
+ from cantera import Reactor, Solution
7
+
8
+
9
+ @dataclass
10
+ class Config:
11
+ """Configuration for a jet-stirred reactor simulation.
12
+
13
+ Attributes:
14
+ temperature: Temperature (K)
15
+ pressure: Pressure (atm)
16
+ residence_time: Residence time (s)
17
+ volume: Volume (cm^3)
18
+ concentrations: Starting concentrations
19
+ """
20
+
21
+ temperature: float
22
+ pressure: float
23
+ residence_time: float
24
+ concentrations: dict[str, float]
25
+ volume: float = 1.0
26
+
27
+
28
+ def single(model: Solution, config: Config) -> Reactor:
29
+ """Run a single jet-stirred reactor simulation.
30
+
31
+ Args:
32
+ model: Chemical kinetics model
33
+ config: Configuration for the simulation
34
+
35
+ Returns:
36
+ Reactor at steady state
37
+ """
38
+ # Use concentrations from the previous iteration to speed up convergence
39
+ model.TPX = config.temperature, config.pressure * ct.one_atm, config.concentrations
40
+
41
+ # Set up JSR: inlet -> flow control -> reactor -> pressure control -> exhaust
42
+ volume_m3 = config.volume * (1e-2) ** 3
43
+ reactor = ct.IdealGasReactor(model, energy="off", volume=volume_m3, clone=True)
44
+ exhaust = ct.Reservoir(model, clone=True)
45
+ inlet = ct.Reservoir(model, clone=True)
46
+ ct.PressureController(
47
+ upstream=reactor,
48
+ downstream=exhaust,
49
+ K=1e-3,
50
+ primary=ct.MassFlowController(
51
+ upstream=inlet,
52
+ downstream=reactor,
53
+ mdot=reactor.mass / config.residence_time,
54
+ ),
55
+ )
56
+ reactor_net = ct.ReactorNet([reactor])
57
+ reactor_net.advance_to_steady_state(max_steps=100000)
58
+ return reactor