degadisx 0.1.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.
- degadisx-0.1.0/.gitattributes +1 -0
- degadisx-0.1.0/.gitignore +13 -0
- degadisx-0.1.0/CHANGELOG.md +7 -0
- degadisx-0.1.0/CITATION.cff +21 -0
- degadisx-0.1.0/CONTRIBUTING.md +3 -0
- degadisx-0.1.0/LICENSE +31 -0
- degadisx-0.1.0/PKG-INFO +89 -0
- degadisx-0.1.0/README.md +36 -0
- degadisx-0.1.0/SECURITY.md +3 -0
- degadisx-0.1.0/docs/data-policy.md +10 -0
- degadisx-0.1.0/docs/reproduction.md +21 -0
- degadisx-0.1.0/pyproject.toml +43 -0
- degadisx-0.1.0/src/degadisx/__init__.py +26 -0
- degadisx-0.1.0/src/degadisx/cli.py +84 -0
- degadisx-0.1.0/src/degadisx/core/__init__.py +71 -0
- degadisx-0.1.0/src/degadisx/core/atmosphere.py +352 -0
- degadisx-0.1.0/src/degadisx/core/blanket.py +460 -0
- degadisx-0.1.0/src/degadisx/core/closures.py +140 -0
- degadisx-0.1.0/src/degadisx/core/constants.py +72 -0
- degadisx-0.1.0/src/degadisx/core/crfg.py +215 -0
- degadisx-0.1.0/src/degadisx/core/dose.py +219 -0
- degadisx-0.1.0/src/degadisx/core/downwind.py +437 -0
- degadisx-0.1.0/src/degadisx/core/driver.py +534 -0
- degadisx-0.1.0/src/degadisx/core/entrainment.py +317 -0
- degadisx-0.1.0/src/degadisx/core/fluids.py +136 -0
- degadisx-0.1.0/src/degadisx/core/jetplume.py +1255 -0
- degadisx-0.1.0/src/degadisx/core/numerics.py +237 -0
- degadisx-0.1.0/src/degadisx/core/observer.py +291 -0
- degadisx-0.1.0/src/degadisx/core/rkgst.py +397 -0
- degadisx-0.1.0/src/degadisx/core/steady.py +399 -0
- degadisx-0.1.0/src/degadisx/core/szf.py +132 -0
- degadisx-0.1.0/src/degadisx/core/thermo.py +1057 -0
- degadisx-0.1.0/src/degadisx/core/timesort.py +310 -0
- degadisx-0.1.0/src/degadisx/core/transient.py +499 -0
- degadisx-0.1.0/src/degadisx/io/__init__.py +36 -0
- degadisx-0.1.0/src/degadisx/io/bridge.py +265 -0
- degadisx-0.1.0/src/degadisx/io/inp.py +399 -0
- degadisx-0.1.0/src/degadisx/io/jetdeck.py +143 -0
- degadisx-0.1.0/src/degadisx/io/params.py +163 -0
- degadisx-0.1.0/src/degadisx/io/tr2.py +120 -0
- degadisx-0.1.0/src/degadisx/run.py +335 -0
- degadisx-0.1.0/tests/test_public_smoke.py +18 -0
- degadisx-0.1.0/tools/check_publication.py +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-09-07
|
|
4
|
+
|
|
5
|
+
- First public release of the legacy DEGADIS 2.1 Python reimplementation.
|
|
6
|
+
- Separates the original-model route from non-public DEGALI/LH2 research extensions.
|
|
7
|
+
- Records reproducibility evidence without redistributing EPA reference material or experimental data.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use DEGADISx, please cite it and the original EPA DEGADIS 2.1 report."
|
|
3
|
+
title: "DEGADISx: a Python reimplementation of EPA DEGADIS 2.1"
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
date-released: 2026-09-07
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: Lee
|
|
8
|
+
given-names: Ugwiyeon
|
|
9
|
+
license: MIT
|
|
10
|
+
repository-code: "https://github.com/lyullee/degadisx"
|
|
11
|
+
references:
|
|
12
|
+
- type: report
|
|
13
|
+
authors:
|
|
14
|
+
- family-names: Spicer
|
|
15
|
+
given-names: Thomas O.
|
|
16
|
+
- family-names: Havens
|
|
17
|
+
given-names: Jerry A.
|
|
18
|
+
title: "User’s Guide for the DEGADIS 2.1 Dense Gas Dispersion Model"
|
|
19
|
+
institution: "U.S. Environmental Protection Agency"
|
|
20
|
+
number: "EPA-450/4-89-019"
|
|
21
|
+
year: 1989
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions should preserve the public scope: the legacy DEGADIS 2.1 route only. Do not add proprietary, experimental, or third-party reference inputs/outputs without documented redistribution permission. New numerical changes should state whether they preserve reference behaviour and include a public, synthetic test where possible.
|
degadisx-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 degali contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
DEGADIS 2.1, on which this work is based, was developed by Thomas O. Spicer
|
|
26
|
+
and Jerry A. Havens at the University of Arkansas under US Coast Guard
|
|
27
|
+
contract DT-CG-23-80-C-20029, with subsequent support from the Gas Research
|
|
28
|
+
Institute, the American Petroleum Institute and the US Environmental
|
|
29
|
+
Protection Agency. The original source is in the public domain and is
|
|
30
|
+
distributed by EPA through SCRAM. Copies of it are included under
|
|
31
|
+
reference/fortran for validation purposes.
|
degadisx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: degadisx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python reimplementation of EPA DEGADIS 2.1
|
|
5
|
+
Project-URL: Source, https://github.com/lyullee/degadisx
|
|
6
|
+
Project-URL: Documentation, https://github.com/lyullee/degadisx#readme
|
|
7
|
+
Project-URL: Changelog, https://github.com/lyullee/degadisx/blob/main/CHANGELOG.md
|
|
8
|
+
Author: Ugwiyeon Lee
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026 degali contributors
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
DEGADIS 2.1, on which this work is based, was developed by Thomas O. Spicer
|
|
34
|
+
and Jerry A. Havens at the University of Arkansas under US Coast Guard
|
|
35
|
+
contract DT-CG-23-80-C-20029, with subsequent support from the Gas Research
|
|
36
|
+
Institute, the American Petroleum Institute and the US Environmental
|
|
37
|
+
Protection Agency. The original source is in the public domain and is
|
|
38
|
+
distributed by EPA through SCRAM. Copies of it are included under
|
|
39
|
+
reference/fortran for validation purposes.
|
|
40
|
+
License-File: LICENSE
|
|
41
|
+
Keywords: DEGADIS,consequence modelling,dense gas,dispersion,process safety
|
|
42
|
+
Classifier: Development Status :: 4 - Beta
|
|
43
|
+
Classifier: Intended Audience :: Science/Research
|
|
44
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
45
|
+
Classifier: Programming Language :: Python :: 3
|
|
46
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
47
|
+
Requires-Python: >=3.10
|
|
48
|
+
Requires-Dist: numpy>=1.23
|
|
49
|
+
Requires-Dist: scipy>=1.10
|
|
50
|
+
Provides-Extra: test
|
|
51
|
+
Requires-Dist: pytest>=7; extra == 'test'
|
|
52
|
+
Description-Content-Type: text/markdown
|
|
53
|
+
|
|
54
|
+
# DEGADISx
|
|
55
|
+
|
|
56
|
+
**DEGADISx** is a Python reimplementation of the U.S. EPA **DEGADIS 2.1** dense-gas dispersion model. Its public interface deliberately retains the legacy DEGADIS thermodynamic and numerical route; it is not an LH2 extension and does not contain DEGALI research modules.
|
|
57
|
+
|
|
58
|
+
## Scope
|
|
59
|
+
|
|
60
|
+
DEGADISx provides the original model's ground-level steady and transient routes, pressurised-jet route, deck readers, and bridge from jet touchdown to the ground-level model. It is intended for transparent reproduction, software inspection, and research use. It is not a substitute for site-specific consequence-model selection or safety engineering review.
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install degadisx
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
From a checkout:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install .
|
|
72
|
+
degadisx --help
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Reproduction evidence and data policy
|
|
76
|
+
|
|
77
|
+
The implementation was checked against the EPA DEGADIS 2.1 reference distribution and published EPA benchmark listings. The quantitative audit, its limits, and exact source locations are in [docs/reproduction.md](docs/reproduction.md).
|
|
78
|
+
|
|
79
|
+
This repository deliberately contains **no** third-party Fortran source, EPA input/output decks, experimental measurements, reduced observation data, or PDFs. See [docs/data-policy.md](docs/data-policy.md).
|
|
80
|
+
|
|
81
|
+
## Citation
|
|
82
|
+
|
|
83
|
+
Please cite both this software (see [CITATION.cff](CITATION.cff)) and the original model:
|
|
84
|
+
|
|
85
|
+
> Spicer, T. O., and Havens, J. A. (1989). *User’s Guide for the DEGADIS 2.1 Dense Gas Dispersion Model*. U.S. Environmental Protection Agency, EPA-450/4-89-019.
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
The Python implementation is MIT licensed. DEGADIS is cited as the original model; the original Fortran distribution and source materials are not redistributed here.
|
degadisx-0.1.0/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# DEGADISx
|
|
2
|
+
|
|
3
|
+
**DEGADISx** is a Python reimplementation of the U.S. EPA **DEGADIS 2.1** dense-gas dispersion model. Its public interface deliberately retains the legacy DEGADIS thermodynamic and numerical route; it is not an LH2 extension and does not contain DEGALI research modules.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
DEGADISx provides the original model's ground-level steady and transient routes, pressurised-jet route, deck readers, and bridge from jet touchdown to the ground-level model. It is intended for transparent reproduction, software inspection, and research use. It is not a substitute for site-specific consequence-model selection or safety engineering review.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install degadisx
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
From a checkout:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install .
|
|
19
|
+
degadisx --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Reproduction evidence and data policy
|
|
23
|
+
|
|
24
|
+
The implementation was checked against the EPA DEGADIS 2.1 reference distribution and published EPA benchmark listings. The quantitative audit, its limits, and exact source locations are in [docs/reproduction.md](docs/reproduction.md).
|
|
25
|
+
|
|
26
|
+
This repository deliberately contains **no** third-party Fortran source, EPA input/output decks, experimental measurements, reduced observation data, or PDFs. See [docs/data-policy.md](docs/data-policy.md).
|
|
27
|
+
|
|
28
|
+
## Citation
|
|
29
|
+
|
|
30
|
+
Please cite both this software (see [CITATION.cff](CITATION.cff)) and the original model:
|
|
31
|
+
|
|
32
|
+
> Spicer, T. O., and Havens, J. A. (1989). *User’s Guide for the DEGADIS 2.1 Dense Gas Dispersion Model*. U.S. Environmental Protection Agency, EPA-450/4-89-019.
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
|
|
36
|
+
The Python implementation is MIT licensed. DEGADIS is cited as the original model; the original Fortran distribution and source materials are not redistributed here.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Data and redistribution policy
|
|
2
|
+
|
|
3
|
+
DEGADISx publishes implementation code and a concise reproduction audit only. It does **not** publish or package:
|
|
4
|
+
|
|
5
|
+
- original DEGADIS Fortran source or binaries;
|
|
6
|
+
- EPA example decks or output listings;
|
|
7
|
+
- experimental concentration, meteorological, or source-term data;
|
|
8
|
+
- reduced experimental data, figures derived from them, or third-party PDFs.
|
|
9
|
+
|
|
10
|
+
Where provenance is needed, this repository provides bibliographic citations and source locations rather than copies of the materials. Downstream contributions must follow the same rule unless the contributor has confirmed that redistribution is permitted.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Reproduction audit
|
|
2
|
+
|
|
3
|
+
## What was checked
|
|
4
|
+
|
|
5
|
+
DEGADISx was audited against a locally obtained EPA DEGADIS 2.1 reference distribution and its published benchmark listings. The audit has two distinct layers:
|
|
6
|
+
|
|
7
|
+
1. **Reference executable versus EPA listings.** Five EPA examples were replayed: B9 steady, B9 transient, EX1, EX2, and EX3. The steady and jet/listing cases reproduced all non-timestamp listing lines. The transient B9 listing had eight differences confined to seventh-significant-digit numerical formatting.
|
|
8
|
+
2. **Python implementation versus source-built reference executable.** Input-deck scalars and density-table values matched exactly; scalar thermodynamic and closure checks differed only at floating-point round-off. At driver level, the original adaptive integration and loose tolerance conventions produce documented non-bitwise differences: step sequences were within 6e-10 relative for the DEG1 check, and representative profile/handoff values within 1e-6. Some full-driver concentration outputs differed by up to about 3%, depending on quantity, because the original implementation intentionally retains coarse internal tolerances (including `ADDHEAT` settings).
|
|
9
|
+
|
|
10
|
+
These are reproduction checks, not experimental validation. No claim is made that all outputs are bit-identical or that the software is valid outside the original model's assumptions.
|
|
11
|
+
|
|
12
|
+
## Materials not redistributed
|
|
13
|
+
|
|
14
|
+
The reference Fortran code, EPA example input decks, EPA output listings, compiled executables, and all third-party data were used only in the local audit. They are excluded from this repository and its source/wheel distributions. A user wishing to repeat the independent oracle comparison must obtain the materials from their original rightsholder/source.
|
|
15
|
+
|
|
16
|
+
## Primary sources
|
|
17
|
+
|
|
18
|
+
- Spicer, T. O., and Havens, J. A. (1989). *User’s Guide for the DEGADIS 2.1 Dense Gas Dispersion Model*. U.S. EPA, EPA-450/4-89-019.
|
|
19
|
+
- U.S. EPA Support Center for Regulatory Atmospheric Modeling (SCRAM), historical **DEGADIS 2.1** distribution and example materials. Access path: https://www.epa.gov/scram.
|
|
20
|
+
|
|
21
|
+
The citation is retained for provenance. The source files themselves are not supplied by DEGADISx.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "degadisx"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A Python reimplementation of EPA DEGADIS 2.1"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "Ugwiyeon Lee" }]
|
|
13
|
+
keywords = ["DEGADIS", "dense gas", "dispersion", "consequence modelling", "process safety"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Science/Research",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Scientific/Engineering :: Atmospheric Science",
|
|
20
|
+
]
|
|
21
|
+
dependencies = ["numpy>=1.23", "scipy>=1.10"]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
test = ["pytest>=7"]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
degadisx = "degadisx.cli:main"
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Source = "https://github.com/lyullee/degadisx"
|
|
31
|
+
Documentation = "https://github.com/lyullee/degadisx#readme"
|
|
32
|
+
Changelog = "https://github.com/lyullee/degadisx/blob/main/CHANGELOG.md"
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.targets.wheel]
|
|
35
|
+
packages = ["src/degadisx"]
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.sdist]
|
|
38
|
+
include = ["src", "tests", "tools", "docs", "README.md", "LICENSE", "CHANGELOG.md", "CITATION.cff", "CONTRIBUTING.md", "SECURITY.md", ".gitattributes"]
|
|
39
|
+
exclude = ["**/*.pdf", "**/*.xls", "**/*.xlsx", "**/*.csv", "**/*.dbf", "reference/**"]
|
|
40
|
+
|
|
41
|
+
[tool.pytest.ini_options]
|
|
42
|
+
testpaths = ["tests"]
|
|
43
|
+
pythonpath = ["src"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""DEGADISx: a Python reimplementation of EPA DEGADIS 2.1.
|
|
2
|
+
|
|
3
|
+
DEGADISx is deliberately a *legacy-model* package. It exposes the original
|
|
4
|
+
DEGADIS 2.1 modelling route and its documented numerical conventions; it does
|
|
5
|
+
not include the separate DEGALI liquid-hydrogen research extensions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
|
|
10
|
+
from .run import (
|
|
11
|
+
Receptor,
|
|
12
|
+
SourceResult,
|
|
13
|
+
TransientOutput,
|
|
14
|
+
run_jet,
|
|
15
|
+
run_jet_to_ground,
|
|
16
|
+
run_source,
|
|
17
|
+
run_steady,
|
|
18
|
+
run_transient,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"__version__",
|
|
23
|
+
"Receptor", "SourceResult", "TransientOutput",
|
|
24
|
+
"run_source", "run_steady", "run_transient", "run_jet",
|
|
25
|
+
"run_jet_to_ground",
|
|
26
|
+
]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Command-line interface for the legacy DEGADIS 2.1 route."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from .run import Receptor, run_jet, run_jet_to_ground, run_steady, run_transient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _profile_table(rows: np.ndarray, limit: int = 20) -> str:
|
|
15
|
+
head = f"{'dist (m)':>10} {'mole frac':>11} {'kg/m3':>11} {'T (K)':>8} {'Sz (m)':>8} {'Sy (m)':>8}"
|
|
16
|
+
step = max(1, len(rows) // limit)
|
|
17
|
+
lines = [head, "-" * len(head)]
|
|
18
|
+
for r in rows[::step]:
|
|
19
|
+
lines.append(f"{r[0]:10.4g} {r[2]:11.4g} {r[3]:11.4g} {r[5]:8.1f} {r[7]:8.3g} {r[8]:8.3g}")
|
|
20
|
+
return "\n".join(lines)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _cmd_steady(args) -> int:
|
|
24
|
+
profile, src = run_steady(args.deck, er1=args.er1, er2=args.er2)
|
|
25
|
+
gas = src.case.gas
|
|
26
|
+
print(f"Steady release: {gas.name}, {src.blanket.ess:.4g} kg/s [DEGADIS 2.1 legacy properties]")
|
|
27
|
+
print(f" wind-profile exponent alpha = {src.alpha:.5f}")
|
|
28
|
+
print(f" profile: {len(profile.rows)} points; transition at {profile.transition:.4g} m")
|
|
29
|
+
for name, level in (("upper", gas.ulc), ("lower", gas.llc)):
|
|
30
|
+
d = profile.distance_to(level)
|
|
31
|
+
shown = "not reached" if np.isnan(d) else f"{d:.4g} m"
|
|
32
|
+
print(f" distance to the {name} level of concern ({level * 100:.4g} mol %): {shown}")
|
|
33
|
+
print("\n" + _profile_table(profile.rows))
|
|
34
|
+
return 0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _cmd_transient(args) -> int:
|
|
38
|
+
times = np.array(args.snapshot, dtype=float) if args.snapshot else None
|
|
39
|
+
out = run_transient(args.deck, er1=args.er1, er2=args.er2, times=times)
|
|
40
|
+
print(f"Transient release: {out.source.case.gas.name}, {len(out.field.observers)} observers, {len(out.snapshots)} snapshots")
|
|
41
|
+
for snap in out.snapshots:
|
|
42
|
+
print(f"t={snap.time:.4g} s; extent={snap.column('dist')[-1]:.4g} m; peak={snap.column('yc').max():.5g}")
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _cmd_dose(args) -> int:
|
|
47
|
+
out = run_transient(args.deck, er1=args.er1, er2=args.er2)
|
|
48
|
+
for history in out.dose([Receptor(x=x) for x in args.at]):
|
|
49
|
+
peak, time = history.peak
|
|
50
|
+
print(f"x={history.receptor.x:.4g} m; peak={peak:.5g} at {time:.4g} s; dose={history.dose():.5g}")
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _cmd_jet(args) -> int:
|
|
55
|
+
if args.bridge is None:
|
|
56
|
+
jet, deck = run_jet(args.deck)
|
|
57
|
+
print(f"Jet release: {deck.erate:.4g} kg/s; touchdown={jet.touchdown}")
|
|
58
|
+
return 0
|
|
59
|
+
profile, jet, _src = run_jet_to_ground(args.deck, args.bridge, er1=args.er1, er2=args.er2)
|
|
60
|
+
print(f"Jet release: touchdown at {jet.distance:.5g} m\n" + _profile_table(profile.rows))
|
|
61
|
+
return 0
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def main(argv: list[str] | None = None) -> int:
|
|
65
|
+
parser = argparse.ArgumentParser(prog="degadisx", description="DEGADISx — EPA DEGADIS 2.1 legacy reimplementation")
|
|
66
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
67
|
+
def common(command, help_text):
|
|
68
|
+
command.add_argument("deck", type=Path, help=help_text)
|
|
69
|
+
command.add_argument("--er1", type=Path, help="source-model parameter file")
|
|
70
|
+
command.add_argument("--er2", type=Path, help="downwind parameter file")
|
|
71
|
+
steady = sub.add_parser("steady", help="steady ground-level release"); common(steady, "the .INP input deck"); steady.set_defaults(func=_cmd_steady)
|
|
72
|
+
transient = sub.add_parser("transient", help="unsteady ground-level release"); common(transient, "the .INP input deck"); transient.add_argument("--snapshot", type=float, action="append"); transient.set_defaults(func=_cmd_transient)
|
|
73
|
+
dose = sub.add_parser("dose", help="concentration history at fixed receptors"); common(dose, "the .INP input deck"); dose.add_argument("--at", type=float, action="append", required=True); dose.set_defaults(func=_cmd_dose)
|
|
74
|
+
jet = sub.add_parser("jet", help="pressurised release"); common(jet, "the .INO jet deck"); jet.add_argument("--bridge", type=Path); jet.set_defaults(func=_cmd_jet)
|
|
75
|
+
args = parser.parse_args(argv)
|
|
76
|
+
try:
|
|
77
|
+
return args.func(args)
|
|
78
|
+
except (ValueError, RuntimeError) as exc:
|
|
79
|
+
print(f"degadisx: {exc}", file=sys.stderr)
|
|
80
|
+
return 1
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Physics and numerics of the DEGADIS model."""
|
|
2
|
+
|
|
3
|
+
from .atmosphere import (
|
|
4
|
+
StabilityDefaults,
|
|
5
|
+
absolute_humidity,
|
|
6
|
+
ambient_density,
|
|
7
|
+
fit_alpha,
|
|
8
|
+
friction_velocity,
|
|
9
|
+
psi,
|
|
10
|
+
richardson_star,
|
|
11
|
+
richardson_thermal,
|
|
12
|
+
stability_defaults,
|
|
13
|
+
wind_log,
|
|
14
|
+
wind_power,
|
|
15
|
+
)
|
|
16
|
+
from .blanket import Blanket, BlanketParameters, BlanketResult, BlanketState
|
|
17
|
+
from .crfg import SourceVectors, build_source_vectors
|
|
18
|
+
from .dose import DoseHistory, DoseRun, Receptor, receptor_times
|
|
19
|
+
from .downwind import Downwind, DownwindConstants, DownwindState, series
|
|
20
|
+
from .driver import DriverParameters, SourceRun
|
|
21
|
+
from .entrainment import entrainment_velocity, phi, phi_hat, surface_exchange
|
|
22
|
+
from .jetplume import JetCoefficients, JetPlume, JetResult, JetState, ellipse
|
|
23
|
+
from .observer import (
|
|
24
|
+
Observer,
|
|
25
|
+
ObserverKinematics,
|
|
26
|
+
ObserverState,
|
|
27
|
+
crossing_downwind,
|
|
28
|
+
crossing_upwind,
|
|
29
|
+
release_times,
|
|
30
|
+
)
|
|
31
|
+
from .steady import Profile, SteadyStateRun
|
|
32
|
+
from .szf import LayerState, sigma_z_over_source
|
|
33
|
+
from .thermo import (
|
|
34
|
+
AdiabaticTable,
|
|
35
|
+
AmbientConditions,
|
|
36
|
+
CoolPropBackend,
|
|
37
|
+
GasProperties,
|
|
38
|
+
LegacyBackend,
|
|
39
|
+
MixtureState,
|
|
40
|
+
Thermo,
|
|
41
|
+
make_backend,
|
|
42
|
+
)
|
|
43
|
+
from .timesort import Snapshot, TimeSort, sort_times
|
|
44
|
+
from .transient import ObserverResult, TransientResult, TransientRun
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
# atmosphere
|
|
48
|
+
"StabilityDefaults", "absolute_humidity", "ambient_density", "fit_alpha",
|
|
49
|
+
"friction_velocity", "psi", "richardson_star", "richardson_thermal",
|
|
50
|
+
"stability_defaults", "wind_log", "wind_power",
|
|
51
|
+
# thermodynamics
|
|
52
|
+
"AdiabaticTable", "AmbientConditions", "CoolPropBackend", "GasProperties",
|
|
53
|
+
"LegacyBackend", "MixtureState", "Thermo", "make_backend",
|
|
54
|
+
# closures
|
|
55
|
+
"entrainment_velocity", "phi", "phi_hat", "surface_exchange",
|
|
56
|
+
# source
|
|
57
|
+
"Blanket", "BlanketParameters", "BlanketResult", "BlanketState",
|
|
58
|
+
"DriverParameters", "SourceRun", "SourceVectors", "build_source_vectors",
|
|
59
|
+
"LayerState", "sigma_z_over_source",
|
|
60
|
+
# downwind
|
|
61
|
+
"Downwind", "DownwindConstants", "DownwindState", "series",
|
|
62
|
+
"Profile", "SteadyStateRun",
|
|
63
|
+
# transient
|
|
64
|
+
"Observer", "ObserverKinematics", "ObserverState", "crossing_downwind",
|
|
65
|
+
"crossing_upwind", "release_times",
|
|
66
|
+
"ObserverResult", "TransientResult", "TransientRun",
|
|
67
|
+
"Snapshot", "TimeSort", "sort_times",
|
|
68
|
+
"DoseHistory", "DoseRun", "Receptor", "receptor_times",
|
|
69
|
+
# jet/plume
|
|
70
|
+
"JetCoefficients", "JetPlume", "JetResult", "JetState", "ellipse",
|
|
71
|
+
]
|