Upload folder using huggingface_hub
Browse files- .gitattributes +2 -0
- .gitignore +37 -0
- README.md +42 -3
- Run.py +1612 -0
- dynamics.png +3 -0
- requirements.txt +9 -0
- spectra.png +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
dynamics.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
spectra.png filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Large data and model files (exceed GitHub's 100MB limit or kept out of repo)
|
| 2 |
+
# See README for how to obtain these.
|
| 3 |
+
spectraV1_225_50_50_250000_5e_06_0_005_1_0_1_0.npz
|
| 4 |
+
Boltzmann3_macro_values_Adapt_FullExp.pkl
|
| 5 |
+
DSMC3ModelsExp/DSMC3LearnModelFull6.pt
|
| 6 |
+
|
| 7 |
+
# Python
|
| 8 |
+
__pycache__/
|
| 9 |
+
*.py[cod]
|
| 10 |
+
*$py.class
|
| 11 |
+
*.so
|
| 12 |
+
.Python
|
| 13 |
+
*.egg-info/
|
| 14 |
+
.eggs/
|
| 15 |
+
dist/
|
| 16 |
+
build/
|
| 17 |
+
|
| 18 |
+
# Virtual envs
|
| 19 |
+
.env
|
| 20 |
+
.venv
|
| 21 |
+
venv/
|
| 22 |
+
env/
|
| 23 |
+
|
| 24 |
+
# IDE / OS
|
| 25 |
+
.idea/
|
| 26 |
+
.vscode/
|
| 27 |
+
.DS_Store
|
| 28 |
+
*.swp
|
| 29 |
+
*~
|
| 30 |
+
|
| 31 |
+
# Jupyter
|
| 32 |
+
.ipynb_checkpoints/
|
| 33 |
+
*.ipynb_checkpoints
|
| 34 |
+
|
| 35 |
+
# Optional: uncomment to also ignore generated outputs
|
| 36 |
+
# spectra.png
|
| 37 |
+
# dynamics.png
|
README.md
CHANGED
|
@@ -1,3 +1,42 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Learning the Optimal Linear Hydrodynamic Closure
|
| 2 |
+
|
| 3 |
+
Code for generating spectral and time-evolution comparisons used in the paper *Learning the Optimal Linear Hydrodynamic Closure*. The main entry point is `Run.py`.
|
| 4 |
+
|
| 5 |
+
## Setup
|
| 6 |
+
|
| 7 |
+
Create a fresh environment and install the dependencies:
|
| 8 |
+
|
| 9 |
+
```bash
|
| 10 |
+
conda create -n nc-code python=3.11
|
| 11 |
+
conda activate nc-code
|
| 12 |
+
pip install -r requirements.txt
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
If you prefer, you can use `venv` instead of Conda.
|
| 16 |
+
|
| 17 |
+
## Required Files
|
| 18 |
+
|
| 19 |
+
Before running `Run.py`, make sure these files are present:
|
| 20 |
+
|
| 21 |
+
- `spectraV1_225_50_50_250000_5e_06_0_005_1_0_1_0.npz`
|
| 22 |
+
- `Boltzmann3_macro_values_Adapt_FullExp.pkl`
|
| 23 |
+
- `DSMC3ModelsExp/DSMC3LearnModelFull6.pt`
|
| 24 |
+
|
| 25 |
+
## Run
|
| 26 |
+
|
| 27 |
+
Run from the repository root:
|
| 28 |
+
|
| 29 |
+
```bash
|
| 30 |
+
python Run.py
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
The script loads the precomputed data and trained model, then writes:
|
| 34 |
+
|
| 35 |
+
- `spectra.png`
|
| 36 |
+
- `dynamics.png`
|
| 37 |
+
|
| 38 |
+
## Notes
|
| 39 |
+
|
| 40 |
+
- `Run.py` uses relative paths, so run it from the repository root.
|
| 41 |
+
- JAX is set to CPU mode in the script.
|
| 42 |
+
- `jax` and `torch` may need platform-specific installation steps on some systems.
|
Run.py
ADDED
|
@@ -0,0 +1,1612 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import jax
|
| 2 |
+
import jax.numpy as np
|
| 3 |
+
jax.config.update("jax_platform_name", "cpu")
|
| 4 |
+
jax.config.update("jax_enable_x64", True)
|
| 5 |
+
import scipy
|
| 6 |
+
import scipy.special as special
|
| 7 |
+
import scipy.signal as signal
|
| 8 |
+
import matplotlib.pyplot as plt
|
| 9 |
+
import copy
|
| 10 |
+
import numpy.f2py
|
| 11 |
+
import os
|
| 12 |
+
import copy
|
| 13 |
+
|
| 14 |
+
from IPython.display import clear_output
|
| 15 |
+
|
| 16 |
+
with np.load(r"./spectraV1_225_50_50_250000_5e_06_0_005_1_0_1_0.npz", allow_pickle = True) as load:
|
| 17 |
+
densitiesF = load["densitiesF"]
|
| 18 |
+
parameters = load["parameters"].item()
|
| 19 |
+
try:
|
| 20 |
+
velocitiesF = load["velocitiesF"]
|
| 21 |
+
has_velocitiesF = True
|
| 22 |
+
except:
|
| 23 |
+
has_velocitiesF = False
|
| 24 |
+
|
| 25 |
+
for key in parameters.keys():
|
| 26 |
+
exec( key + "=parameters['"+key+"']" )
|
| 27 |
+
Boltz = 1.380622e-23
|
| 28 |
+
|
| 29 |
+
print("total_Time", total_Time)
|
| 30 |
+
for key in parameters.keys():
|
| 31 |
+
exec( key + "=parameters['"+key+"']" )
|
| 32 |
+
|
| 33 |
+
import scipy.special as special
|
| 34 |
+
import scipy.signal as signal
|
| 35 |
+
|
| 36 |
+
time_ratio = 0.05
|
| 37 |
+
domain_T = total_Time*(1-time_ratio)
|
| 38 |
+
cutoff_time_step = int(densitiesF.shape[0]*time_ratio)
|
| 39 |
+
spectra = np.sqrt(2*np.pi)**3/domain_LX/domain_LY/domain_LZ*np.sqrt(2*np.pi)/domain_T*np.abs( delta_x*delta_t*np.fft.fftn(densitiesF[cutoff_time_step:], axes=(-2, -1))/np.sqrt(2*np.pi)/np.sqrt(2*np.pi) )**2
|
| 40 |
+
kx_freq = 2*np.pi*np.fft.fftfreq(spectra.shape[1], d=delta_x)
|
| 41 |
+
omega_freq = 2*np.pi*np.fft.fftfreq(spectra.shape[0], d=delta_t)
|
| 42 |
+
|
| 43 |
+
tau_BGK = viscosity_coef/(density_0/molecule_mass*Boltz*Temp_0)
|
| 44 |
+
time_scale = 10*tau_BGK# non-dim tau_BGK = 0.1
|
| 45 |
+
|
| 46 |
+
kx_freq = 2*np.pi*np.fft.fftfreq(spectra.shape[1], d=delta_x)
|
| 47 |
+
omega_freq = 2*np.pi*np.fft.fftfreq(spectra.shape[0], d=delta_t)
|
| 48 |
+
|
| 49 |
+
space_scale = time_scale*np.sqrt(Boltz*Temp_0/molecule_mass) # Non-dim
|
| 50 |
+
|
| 51 |
+
k_titla_freq = kx_freq*space_scale
|
| 52 |
+
omega_titla_freq = omega_freq*time_scale
|
| 53 |
+
'''
|
| 54 |
+
k_number=11
|
| 55 |
+
omega_plot = np.fft.fftshift(omega_freq)/(kx_freq[k_number]*speed_of_sound)
|
| 56 |
+
omega_spacing = np.mean( omega_plot[1:]-omega_plot[:-1] )
|
| 57 |
+
plot_spectra = np.fft.fftshift( spectra[:,k_number])/space_scale**3/time_scale
|
| 58 |
+
|
| 59 |
+
b, a = signal.butter(1, 20, fs = 1/omega_spacing)
|
| 60 |
+
filtered_spectra = signal.filtfilt(b, a, plot_spectra)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def CE_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k):
|
| 64 |
+
m = molecule_mass
|
| 65 |
+
mu1 = 0
|
| 66 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 67 |
+
mu2 = -4/3*Kn
|
| 68 |
+
mu3 = 0
|
| 69 |
+
kap1 = 0
|
| 70 |
+
kap2 = 0
|
| 71 |
+
kap3 = -15/4*Kn
|
| 72 |
+
kabs = np.abs(k)
|
| 73 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 74 |
+
tau2 = kabs**2*mu2
|
| 75 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 76 |
+
tau4 = 2/3*kabs**2*kap1
|
| 77 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 78 |
+
tau6 = 2/3*kabs**2*kap3
|
| 79 |
+
omega = omega_freq
|
| 80 |
+
Neff = num_effect
|
| 81 |
+
rho0 = density_0
|
| 82 |
+
L = delta_x
|
| 83 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 84 |
+
return spec
|
| 85 |
+
#m = molecule_mass*num_effect/(4*np.pi**2*wavelength**3)
|
| 86 |
+
#spec = -((complex(0,1)*m*(-4*k**2-20*k**4*Kn**2-23*complex(0,1)*k**2*Kn*omega_freq+6*omega_freq**2))/(density_0*(15*complex(0,1)*k**4*Kn-10*k**2*omega_freq-20*k**4*Kn**2*omega_freq-23*complex(0,1)*k**2*Kn*omega_freq**2+6*omega_freq**3)))
|
| 87 |
+
#return 2*np.real(spec)
|
| 88 |
+
|
| 89 |
+
def TH_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k, mask = -1):
|
| 90 |
+
m = molecule_mass
|
| 91 |
+
mu1 = 0
|
| 92 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 93 |
+
mu2 = -4/3*Kn
|
| 94 |
+
mu3 = 0
|
| 95 |
+
kap1 = 0
|
| 96 |
+
kap2 = 0
|
| 97 |
+
kap3 = -15/4*Kn
|
| 98 |
+
kabs = np.abs(k)
|
| 99 |
+
print(kabs)
|
| 100 |
+
tau1 = -0.910858854965221635639183580413607*kabs-0.0681031747662745635208073664825305*kabs**2
|
| 101 |
+
tau2 = -0.137647159761080650249789096758410*kabs**2+0.00258989586650062128792005410176610*kabs**3
|
| 102 |
+
tau3 = -0.980736834542179305331651160476348*kabs+0.002878781203443508188808986885745442*kabs**3
|
| 103 |
+
tau4 = 0.00270043719488066581208735095210*kabs**2-0.000956430940350492874510704526398*kabs**3+0.0000398354558076273539332410866928*kabs**4
|
| 104 |
+
#tau4 = 2/3*kabs**2*kap1
|
| 105 |
+
tau5 = -0.677006693600986515897927777975082*kabs-0.02720695551116714037510321445687466*kabs**2
|
| 106 |
+
tau6 = -0.248523533056964259160237397019776*kabs**2+0.00978711916205478871774188307120469*kabs**3
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
if mask == 0:
|
| 110 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 111 |
+
elif mask == 1:
|
| 112 |
+
tau2 = kabs**2*mu2
|
| 113 |
+
elif mask == 2:
|
| 114 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 115 |
+
elif mask == 3:
|
| 116 |
+
tau4 = 2/3*kabs**2*kap1
|
| 117 |
+
elif mask == 4:
|
| 118 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 119 |
+
elif mask == 5:
|
| 120 |
+
tau6 = 2/3*kabs**2*kap3
|
| 121 |
+
omega = omega_freq
|
| 122 |
+
Neff = num_effect
|
| 123 |
+
rho0 = density_0
|
| 124 |
+
L = delta_x
|
| 125 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 126 |
+
return spec
|
| 127 |
+
|
| 128 |
+
def THBGK_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k, mask = -1):
|
| 129 |
+
m = molecule_mass
|
| 130 |
+
mu1 = 0
|
| 131 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 132 |
+
mu2 = -4/3*Kn
|
| 133 |
+
mu3 = 0
|
| 134 |
+
kap1 = 0
|
| 135 |
+
kap2 = 0
|
| 136 |
+
kap3 = -15/4*Kn
|
| 137 |
+
kabs = np.abs(k)
|
| 138 |
+
print(kabs)
|
| 139 |
+
#tau1 = -0.910858854965221635639183580413607*kabs-0.0681031747662745635208073664825305*kabs**2
|
| 140 |
+
tau1 = -0.9858867248408030*kabs-0.04701941111476196*kabs**2
|
| 141 |
+
#tau2 = -0.137647159761080650249789096758410*kabs**2+0.00258989586650062128792005410176610*kabs**3
|
| 142 |
+
tau2 = -0.129198118429724*kabs**2+0.00400848955369925*kabs**3
|
| 143 |
+
#tau3 = -0.980736834542179305331651160476348*kabs+0.002878781203443508188808986885745442*kabs**3
|
| 144 |
+
tau3 = -1.002964233770220*kabs-0.0000911571759799050*kabs**3
|
| 145 |
+
#tau4 = 0.00270043719488066581208735095210*kabs**2-0.000956430940350492874510704526398*kabs**3+0.0000398354558076273539332410866928*kabs**4
|
| 146 |
+
tau4 = -0.0084451424529939*kabs**2-0.00060032464997635*kabs**3+0.000017125859875981*kabs**4
|
| 147 |
+
#tau4 = 2/3*kabs**2*kap1
|
| 148 |
+
#tau5 = -0.677006693600986515897927777975082*kabs-0.02720695551116714037510321445687466*kabs**2
|
| 149 |
+
tau5 = -0.677965329349480*kabs-0.002348308957845470*kabs**2
|
| 150 |
+
#tau6 = -0.248523533056964259160237397019776*kabs**2+0.00978711916205478871774188307120469*kabs**3
|
| 151 |
+
tau6 = -0.185259190536085*kabs**2+0.0068634125525231*kabs**3
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
if mask == 0:
|
| 155 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 156 |
+
elif mask == 1:
|
| 157 |
+
tau2 = kabs**2*mu2
|
| 158 |
+
elif mask == 2:
|
| 159 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 160 |
+
elif mask == 3:
|
| 161 |
+
tau4 = 2/3*kabs**2*kap1
|
| 162 |
+
elif mask == 4:
|
| 163 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 164 |
+
elif mask == 5:
|
| 165 |
+
tau6 = 2/3*kabs**2*kap3
|
| 166 |
+
omega = omega_freq
|
| 167 |
+
Neff = num_effect
|
| 168 |
+
rho0 = density_0
|
| 169 |
+
L = delta_x
|
| 170 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 171 |
+
return spec
|
| 172 |
+
def MW_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k):
|
| 173 |
+
m = molecule_mass
|
| 174 |
+
mu1 = 0
|
| 175 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 176 |
+
mu2 = -4/3*Kn
|
| 177 |
+
mu3 = 0
|
| 178 |
+
kap1 = 0
|
| 179 |
+
kap2 = 0
|
| 180 |
+
kap3 = -15/4*Kn
|
| 181 |
+
kabs = np.abs(k)
|
| 182 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 183 |
+
tau2 = kabs**2*mu2
|
| 184 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 185 |
+
tau4 = 2/3*kabs**2*kap1
|
| 186 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 187 |
+
tau6 = 2/3*kabs**2*kap3
|
| 188 |
+
omega = omega_freq
|
| 189 |
+
Neff = num_effect
|
| 190 |
+
rho0 = density_0
|
| 191 |
+
L = delta_x
|
| 192 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 193 |
+
return spec
|
| 194 |
+
#m = molecule_mass*num_effect/(4*np.pi**2*wavelength**3)
|
| 195 |
+
#spec = -((complex(0,1)*m*(-4*k**2-20*k**4*Kn**2-23*complex(0,1)*k**2*Kn*omega_freq+6*omega_freq**2))/(density_0*(15*complex(0,1)*k**4*Kn-10*k**2*omega_freq-20*k**4*Kn**2*omega_freq-23*complex(0,1)*k**2*Kn*omega_freq**2+6*omega_freq**3)))
|
| 196 |
+
#return 2*np.real(spec)
|
| 197 |
+
|
| 198 |
+
plt.title("k = "+ str(k_titla_freq[k_number]))
|
| 199 |
+
plt.plot(omega_plot , filtered_spectra, label = "DSMC")
|
| 200 |
+
plt.plot( np.fft.fftshift(omega_freq)/(kx_freq[k_number]*speed_of_sound) , np.fft.fftshift( CE_spectra(space_scale,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_titla_freq,num_effect,k_titla_freq[k_number])) , label = "NS Equation")
|
| 201 |
+
plt.legend()
|
| 202 |
+
plt.xlim(-2,2)
|
| 203 |
+
plt.show()
|
| 204 |
+
plt.title("k = "+ str(k_titla_freq[k_number]))
|
| 205 |
+
plt.plot(omega_plot , filtered_spectra, label = "DSMC")
|
| 206 |
+
plt.plot( np.fft.fftshift(omega_freq)/(kx_freq[k_number]*speed_of_sound) , np.fft.fftshift( TH_spectra(space_scale,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_titla_freq,num_effect,k_titla_freq[k_number])) , label = "TheorysBGK")
|
| 207 |
+
plt.legend()
|
| 208 |
+
plt.xlim(-2,2)
|
| 209 |
+
plt.show()
|
| 210 |
+
plt.title("k = "+ str(k_titla_freq[k_number]))
|
| 211 |
+
plt.plot(omega_plot , filtered_spectra, label = "DSMC")
|
| 212 |
+
plt.plot( np.fft.fftshift(omega_freq)/(kx_freq[k_number]*speed_of_sound) , np.fft.fftshift( THBGK_spectra(space_scale,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_titla_freq,num_effect,k_titla_freq[k_number])) , label = "TheoryBGK")
|
| 213 |
+
plt.legend()
|
| 214 |
+
plt.xlim(-2,2)
|
| 215 |
+
plt.show()
|
| 216 |
+
|
| 217 |
+
'''
|
| 218 |
+
k_traval = np.logspace(-2, 2.79817986094985, 2048, endpoint=True)
|
| 219 |
+
from jax import grad, jit, vmap
|
| 220 |
+
from numpy.polynomial.hermite import hermgauss
|
| 221 |
+
from scipy import optimize
|
| 222 |
+
import jaxopt
|
| 223 |
+
from scipy.sparse.linalg import LinearOperator
|
| 224 |
+
from jax.scipy.optimize import minimize
|
| 225 |
+
from functools import partial
|
| 226 |
+
# Define the function \tilde{h}^{(+)}
|
| 227 |
+
@jit
|
| 228 |
+
def h_plus(u, k, omega):
|
| 229 |
+
# Dummy implementation of \tilde{h}^{(+)} for demonstration purposes
|
| 230 |
+
#out = np.sin(np.dot(u, k)[:, np.newaxis] + omega)
|
| 231 |
+
out = np.sin(np.dot(u, k)[:, np.newaxis] + omega)*0
|
| 232 |
+
return out
|
| 233 |
+
@jit
|
| 234 |
+
def compute_n_plus(k, h_values, u_mesh, u_weights):
|
| 235 |
+
u_squared = np.sum(u_mesh**2, axis=-1)
|
| 236 |
+
pre_factor = 1
|
| 237 |
+
|
| 238 |
+
# Vectorize the computation over omega
|
| 239 |
+
|
| 240 |
+
integrand = h_values[:, :, np.newaxis]
|
| 241 |
+
integral = np.sum(integrand * u_weights[:, np.newaxis, np.newaxis], axis=0)
|
| 242 |
+
q_plus = pre_factor * integral
|
| 243 |
+
|
| 244 |
+
return q_plus
|
| 245 |
+
@jit
|
| 246 |
+
def compute_v_plus(k, h_values, u_mesh, u_weights):
|
| 247 |
+
u_squared = np.sum(u_mesh**2, axis=-1)
|
| 248 |
+
pre_factor = 1
|
| 249 |
+
|
| 250 |
+
# Vectorize the computation over omega
|
| 251 |
+
|
| 252 |
+
integrand = u_mesh[:, np.newaxis, :] * h_values[:, :, np.newaxis]
|
| 253 |
+
integral = np.sum(integrand * u_weights[:, np.newaxis, np.newaxis], axis=0)
|
| 254 |
+
q_plus = pre_factor * integral
|
| 255 |
+
|
| 256 |
+
return q_plus
|
| 257 |
+
@jit
|
| 258 |
+
def compute_T_plus(k, h_values, u_mesh, u_weights):
|
| 259 |
+
u_squared = np.sum(u_mesh**2, axis=-1)
|
| 260 |
+
pre_factor = 1
|
| 261 |
+
|
| 262 |
+
# Vectorize the computation over omega
|
| 263 |
+
|
| 264 |
+
integrand = 1/3 * (u_squared[:, np.newaxis, np.newaxis] * h_values[:, :, np.newaxis])
|
| 265 |
+
integral = np.sum(integrand * u_weights[:, np.newaxis, np.newaxis], axis=0)
|
| 266 |
+
q_plus = pre_factor * integral
|
| 267 |
+
|
| 268 |
+
return q_plus
|
| 269 |
+
@jit
|
| 270 |
+
def compute_sigma_plus(k, h_values, u_mesh, u_weights):
|
| 271 |
+
u_squared = np.sum(u_mesh**2, axis=-1)
|
| 272 |
+
pre_factor = 1
|
| 273 |
+
|
| 274 |
+
# Vectorize the computation over omega
|
| 275 |
+
|
| 276 |
+
integrand = ( ((u_mesh[:,np.newaxis,:]*u_mesh[:,:,np.newaxis]).reshape(u_mesh.shape[0],1,-1)- 1/3 * (np.sum(u_mesh**2, axis=-1)[:,np.newaxis,np.newaxis]*np.eye(3).reshape(-1))) * h_values[:, :, np.newaxis])
|
| 277 |
+
integral = np.sum(integrand * u_weights[:, np.newaxis, np.newaxis], axis=0)
|
| 278 |
+
q_plus = pre_factor * integral
|
| 279 |
+
|
| 280 |
+
return q_plus
|
| 281 |
+
|
| 282 |
+
# Function to compute \tilde{q}^{(+)} _i
|
| 283 |
+
@jit
|
| 284 |
+
def compute_q_plus(k, h_values, u_mesh, u_weights):
|
| 285 |
+
u_squared = np.sum(u_mesh**2, axis=-1)
|
| 286 |
+
pre_factor = 1
|
| 287 |
+
|
| 288 |
+
# Vectorize the computation over omega
|
| 289 |
+
|
| 290 |
+
integrand = 1/2*u_mesh[:, np.newaxis, :] * (u_squared[:, np.newaxis, np.newaxis] * h_values[:, :, np.newaxis])
|
| 291 |
+
integral = np.sum(integrand * u_weights[:, np.newaxis, np.newaxis], axis=0)
|
| 292 |
+
q_plus = pre_factor * integral
|
| 293 |
+
|
| 294 |
+
return q_plus
|
| 295 |
+
|
| 296 |
+
|
| 297 |
+
@jit
|
| 298 |
+
def taus(k):
|
| 299 |
+
m = molecule_mass
|
| 300 |
+
mu1 = 0
|
| 301 |
+
Kn = (np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/space_scale)[0]
|
| 302 |
+
mu2 = -4/3*Kn
|
| 303 |
+
mu3 = 0
|
| 304 |
+
kap1 = 0
|
| 305 |
+
kap2 = 0
|
| 306 |
+
kap3 = -15/4*Kn
|
| 307 |
+
kabs = np.abs(k)
|
| 308 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 309 |
+
tau2 = kabs**2*mu2
|
| 310 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 311 |
+
tau4 = 2/3*kabs**2*kap1
|
| 312 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 313 |
+
tau6 = 2/3*kabs**2*kap3
|
| 314 |
+
return tau1, tau2, tau3, tau4, tau5, tau6
|
| 315 |
+
|
| 316 |
+
@jit
|
| 317 |
+
def denominator_reg(denominator):
|
| 318 |
+
sign = 1-2*(denominator < 0)
|
| 319 |
+
return sign*np.maximum(np.abs(denominator), 1e-10)
|
| 320 |
+
@jit
|
| 321 |
+
def get_rhoRe(k,omega):
|
| 322 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 323 |
+
# Define the numerator
|
| 324 |
+
numerator = k * omega**2 * (tau1 * tau2 + tau3 * tau4) - k * (tau3 * tau4 - tau1 * tau6) * (tau2 * tau6 + tau3 * tau5)
|
| 325 |
+
|
| 326 |
+
# Define the denominator
|
| 327 |
+
denominator = (omega**2 * (k**2 * tau1**2 - 2 * k * (tau1 * tau3 * tau5 - tau1 * tau6**2 + tau2 * tau3 * tau4 + tau3 * tau4 * tau6)
|
| 328 |
+
+ (tau2 * tau6 + tau3 * tau5)**2) + k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 329 |
+
+ omega**4 * (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2) + omega**6)
|
| 330 |
+
# Define the expression
|
| 331 |
+
expression = numerator / denominator_reg(denominator)
|
| 332 |
+
return expression
|
| 333 |
+
@jit
|
| 334 |
+
def get_rhoIm(k,omega):
|
| 335 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 336 |
+
# Define the numerator
|
| 337 |
+
numerator_2 = omega * (-(tau3 * tau5 + tau2 * tau6)**2 - (tau2**2 - 2 * tau3 * tau5 + tau6**2) * omega**2
|
| 338 |
+
- omega**4 + k * (tau2 * tau3 * tau4 + tau1 * tau3 * tau5 + tau3 * tau4 * tau6
|
| 339 |
+
- tau1 * tau6**2 - tau1 * omega**2))
|
| 340 |
+
|
| 341 |
+
# Define the denominator
|
| 342 |
+
denominator_2 = (k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 343 |
+
+ (k**2 * tau1**2 + (tau3 * tau5 + tau2 * tau6)**2
|
| 344 |
+
- 2 * k * (tau2 * tau3 * tau4 + tau1 * tau3 * tau5 + tau3 * tau4 * tau6 - tau1 * tau6**2)) * omega**2
|
| 345 |
+
+ (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2) * omega**4 + omega**6)
|
| 346 |
+
|
| 347 |
+
# Define the expression
|
| 348 |
+
expression_2 = numerator_2 / denominator_reg(denominator_2)
|
| 349 |
+
return expression_2
|
| 350 |
+
@jit
|
| 351 |
+
def get_vRe(k,omega):
|
| 352 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 353 |
+
# Define the numerator
|
| 354 |
+
numerator_3 = omega * (tau3 * tau4 - tau1 * tau6) * (tau2 * tau6 + tau3 * tau5) - omega**3 * (tau1 * tau2 + tau3 * tau4)
|
| 355 |
+
|
| 356 |
+
# Define the denominator
|
| 357 |
+
denominator_3 = (omega**2 * (k**2 * tau1**2 - 2 * k * (tau1 * tau3 * tau5 - tau1 * tau6**2 + tau2 * tau3 * tau4 + tau3 * tau4 * tau6)
|
| 358 |
+
+ (tau2 * tau6 + tau3 * tau5)**2)
|
| 359 |
+
+ k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 360 |
+
+ omega**4 * (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2)
|
| 361 |
+
+ omega**6)
|
| 362 |
+
|
| 363 |
+
# Define the expression
|
| 364 |
+
expression_3 = numerator_3 / denominator_reg(denominator_3)
|
| 365 |
+
return expression_3
|
| 366 |
+
@jit
|
| 367 |
+
def get_vIm(k,omega):
|
| 368 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 369 |
+
# Define the numerator
|
| 370 |
+
numerator_4 = (-k * (tau3 * tau4 - tau1 * tau6)**2 + (-k * tau1**2 + tau2 * tau3 * tau4 + tau1 * tau3 * tau5
|
| 371 |
+
+ tau3 * tau4 * tau6 - tau1 * tau6**2) * omega**2
|
| 372 |
+
- tau1 * omega**4)
|
| 373 |
+
|
| 374 |
+
# Define the denominator
|
| 375 |
+
denominator_4 = (k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 376 |
+
+ (k**2 * tau1**2 + (tau3 * tau5 + tau2 * tau6)**2
|
| 377 |
+
- 2 * k * (tau2 * tau3 * tau4 + tau1 * tau3 * tau5 + tau3 * tau4 * tau6 - tau1 * tau6**2)) * omega**2
|
| 378 |
+
+ (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2) * omega**4 + omega**6)
|
| 379 |
+
|
| 380 |
+
# Define the expression
|
| 381 |
+
expression_4 = numerator_4 / denominator_reg(denominator_4)
|
| 382 |
+
return expression_4
|
| 383 |
+
@jit
|
| 384 |
+
def get_TRe(k,omega):
|
| 385 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 386 |
+
# Define the numerator
|
| 387 |
+
numerator_5 = (-omega**2 * (k * tau1 * tau4 + tau1 * tau2 * tau5 + tau1 * tau5 * tau6 + tau2**2 * tau4 - tau3 * tau4 * tau5)
|
| 388 |
+
+ k * (tau1 * tau5 + tau2 * tau4) * (tau3 * tau4 - tau1 * tau6) - tau4 * omega**4)
|
| 389 |
+
|
| 390 |
+
# Define the denominator
|
| 391 |
+
denominator_5 = (omega**2 * (k**2 * tau1**2 - 2 * k * (tau1 * tau3 * tau5 - tau1 * tau6**2 + tau2 * tau3 * tau4 + tau3 * tau4 * tau6)
|
| 392 |
+
+ (tau2 * tau6 + tau3 * tau5)**2)
|
| 393 |
+
+ k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 394 |
+
+ omega**4 * (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2)
|
| 395 |
+
+ omega**6)
|
| 396 |
+
|
| 397 |
+
# Define the expression
|
| 398 |
+
expression_5 = numerator_5 / denominator_reg(denominator_5)
|
| 399 |
+
return expression_5
|
| 400 |
+
@jit
|
| 401 |
+
def get_TIm(k,omega):
|
| 402 |
+
tau1, tau2, tau3, tau4, tau5, tau6 = taus(k)
|
| 403 |
+
# Define the numerator
|
| 404 |
+
numerator_6 = omega * (-k * (tau3 * tau4**2 + tau1**2 * tau5 + tau1 * tau4 * (tau2 - tau6))
|
| 405 |
+
+ (tau2 * tau4 + tau1 * tau5) * (tau3 * tau5 + tau2 * tau6)
|
| 406 |
+
+ (-tau1 * tau5 + tau4 * tau6) * omega**2)
|
| 407 |
+
|
| 408 |
+
# Define the denominator
|
| 409 |
+
denominator_6 = (k**2 * (tau3 * tau4 - tau1 * tau6)**2
|
| 410 |
+
+ (k**2 * tau1**2 + (tau3 * tau5 + tau2 * tau6)**2
|
| 411 |
+
- 2 * k * (tau2 * tau3 * tau4 + tau1 * tau3 * tau5 + tau3 * tau4 * tau6 - tau1 * tau6**2)) * omega**2
|
| 412 |
+
+ (2 * k * tau1 + tau2**2 - 2 * tau3 * tau5 + tau6**2) * omega**4 + omega**6)
|
| 413 |
+
|
| 414 |
+
# Define the expression
|
| 415 |
+
expression_6 = numerator_6 / denominator_reg(denominator_6)
|
| 416 |
+
return expression_6
|
| 417 |
+
@jit
|
| 418 |
+
def get_rhoRe_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 419 |
+
h_values_Re = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 420 |
+
return compute_n_plus(k, h_values_Re, u_mesh, u_weights)
|
| 421 |
+
@jit
|
| 422 |
+
def get_rhoIm_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 423 |
+
h_values_Im = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 424 |
+
return compute_n_plus(k, h_values_Im, u_mesh, u_weights)
|
| 425 |
+
@jit
|
| 426 |
+
def get_vRe_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 427 |
+
h_values_Re = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 428 |
+
return compute_v_plus(k, h_values_Re, u_mesh, u_weights)
|
| 429 |
+
@jit
|
| 430 |
+
def get_vIm_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 431 |
+
h_values_Im = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 432 |
+
return compute_v_plus(k, h_values_Im, u_mesh, u_weights)
|
| 433 |
+
@jit
|
| 434 |
+
def get_TRe_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 435 |
+
h_values_Re = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 436 |
+
return compute_T_plus(k, h_values_Re, u_mesh, u_weights) - compute_n_plus(k, h_values_Re, u_mesh, u_weights)
|
| 437 |
+
@jit
|
| 438 |
+
def get_TIm_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 439 |
+
h_values_Im = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 440 |
+
return compute_T_plus(k, h_values_Im, u_mesh, u_weights) - compute_n_plus(k, h_values_Im, u_mesh, u_weights)
|
| 441 |
+
@jit
|
| 442 |
+
def get_sigmaRe_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 443 |
+
h_values_Re = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 444 |
+
return compute_sigma_plus(k, h_values_Re, u_mesh, u_weights)
|
| 445 |
+
@jit
|
| 446 |
+
def get_sigmaIm_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 447 |
+
h_values_Im = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 448 |
+
return compute_sigma_plus(k, h_values_Im, u_mesh, u_weights)
|
| 449 |
+
@jit
|
| 450 |
+
def get_qRe_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 451 |
+
h_values_Re = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 452 |
+
return compute_q_plus(k, h_values_Re, u_mesh, u_weights) - 5/2*compute_v_plus(k, h_values_Re, u_mesh, u_weights)
|
| 453 |
+
@jit
|
| 454 |
+
def get_qIm_Asymp(k, Kn, omega_mesh, u_mesh, u_weights):
|
| 455 |
+
h_values_Im = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 456 |
+
return compute_q_plus(k, h_values_Im, u_mesh, u_weights) - 5/2*compute_v_plus(k, h_values_Im, u_mesh, u_weights)
|
| 457 |
+
|
| 458 |
+
|
| 459 |
+
@jit
|
| 460 |
+
def func(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh):
|
| 461 |
+
lamb = 1
|
| 462 |
+
h_values_Re, h_values_Im = x[:len(x)//2], x[len(x)//2:]
|
| 463 |
+
n_plus_result_Re = compute_n_plus(k, h_values_Re, u_mesh, u_weights)
|
| 464 |
+
n_plus_result_Im = compute_n_plus(k, h_values_Im, u_mesh, u_weights)
|
| 465 |
+
|
| 466 |
+
v_plus_result_Re = compute_v_plus(k, h_values_Re, u_mesh, u_weights)
|
| 467 |
+
v_plus_result_Im = compute_v_plus(k, h_values_Im, u_mesh, u_weights)
|
| 468 |
+
|
| 469 |
+
T_plus_result_Re = compute_T_plus(k, h_values_Re, u_mesh, u_weights) - n_plus_result_Re
|
| 470 |
+
T_plus_result_Im = compute_T_plus(k, h_values_Im, u_mesh, u_weights) - n_plus_result_Im
|
| 471 |
+
|
| 472 |
+
sigma_plus_result_Re = compute_sigma_plus(k, h_values_Re, u_mesh, u_weights)
|
| 473 |
+
sigma_plus_result_Im = compute_sigma_plus(k, h_values_Im, u_mesh, u_weights)
|
| 474 |
+
|
| 475 |
+
q_plus_result_Re = compute_q_plus(k, h_values_Re, u_mesh, u_weights) - 5/2*v_plus_result_Re
|
| 476 |
+
q_plus_result_Im = compute_q_plus(k, h_values_Im, u_mesh, u_weights) - 5/2*v_plus_result_Im
|
| 477 |
+
# Spectra
|
| 478 |
+
rho0k = 1
|
| 479 |
+
# Density impulse
|
| 480 |
+
|
| 481 |
+
|
| 482 |
+
h_values_Re_new = Kn*(h_values_Im*omega_mesh + u_mesh.dot(k)[:,np.newaxis]*h_values_Im + rho0k) + lamb*(-\
|
| 483 |
+
(1-Pr)*(1 - np.sum( u_mesh**2, axis = -1 )[:,np.newaxis]/5 )*np.sum( u_mesh[:, np.newaxis,:]*q_plus_result_Re, axis = -1 ) +\
|
| 484 |
+
n_plus_result_Re[:,0] + np.sum( u_mesh[:, np.newaxis,:]*v_plus_result_Re, axis = -1 ) +\
|
| 485 |
+
(np.sum( u_mesh**2, axis = -1 )[:,np.newaxis]/2 - 3/2 )*T_plus_result_Re[:,0] )
|
| 486 |
+
h_values_Im_new = -Kn*(h_values_Re*omega_mesh + u_mesh.dot(k)[:,np.newaxis]*h_values_Re) + lamb*( -\
|
| 487 |
+
(1-Pr)*(1 - np.sum( u_mesh**2, axis = -1 )[:,np.newaxis]/5 )*np.sum( u_mesh[:, np.newaxis,:]*q_plus_result_Im, axis = -1 )+\
|
| 488 |
+
n_plus_result_Im[:,0] + np.sum( u_mesh[:, np.newaxis,:]*v_plus_result_Im, axis = -1 ) +\
|
| 489 |
+
(np.sum( u_mesh**2, axis = -1 )[:,np.newaxis]/2 - 3/2 )*T_plus_result_Im[:,0] )
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
resRe = (h_values_Re_new - h_values_Re)#*(u_weights/np.max(u_weights))[:, np.newaxis]
|
| 493 |
+
resIm = (h_values_Im_new - h_values_Im)#*(u_weights/np.max(u_weights))[:, np.newaxis]
|
| 494 |
+
|
| 495 |
+
return np.concatenate( (resRe , resIm) , axis = 0)
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
|
| 501 |
+
@jit
|
| 502 |
+
def mv(h_flat, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re):
|
| 503 |
+
shape = h_values_Re.shape
|
| 504 |
+
h_values_Re = h_flat[:len(h_flat)//2].reshape(shape)
|
| 505 |
+
h_values_Im = h_flat[len(h_flat)//2:].reshape(shape)
|
| 506 |
+
x = np.concatenate( (h_values_Re , h_values_Im) , axis = 0)
|
| 507 |
+
return func(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh).reshape(-1)
|
| 508 |
+
|
| 509 |
+
@jit
|
| 510 |
+
def rescompute_mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re):
|
| 511 |
+
return np.mean( mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re)**2 )
|
| 512 |
+
|
| 513 |
+
@jit
|
| 514 |
+
def grad_rescompute_mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re):
|
| 515 |
+
return grad(rescompute_mv)(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re)
|
| 516 |
+
|
| 517 |
+
@partial(jit, static_argnames=["method"])
|
| 518 |
+
def compute_h(k, omega_mesh, u_mesh, u_weights, molecule_mass, Boltz, Temp_0, viscosity_coef, density_0, space_scale, tol=1e-8, verbose = False, method = "SBGK"):
|
| 519 |
+
|
| 520 |
+
|
| 521 |
+
#N = 2000
|
| 522 |
+
#u_mesh = np.random.randn(N, 3)
|
| 523 |
+
#u_weights = np.zeros(N) + 1/N
|
| 524 |
+
#print("u_mesh", u_mesh.shape)
|
| 525 |
+
#print("u_weights", u_weights.shape)
|
| 526 |
+
#print("omega_mesh", omega_mesh.shape)
|
| 527 |
+
|
| 528 |
+
|
| 529 |
+
khat = (k/np.sqrt(denominator_reg(np.sum(k**2))))
|
| 530 |
+
h_values_Re = h_plus(u_mesh, k, omega_mesh)
|
| 531 |
+
h_values_Im = h_plus(u_mesh, k, omega_mesh)
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
Kn = (np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/space_scale)[0]
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
|
| 538 |
+
|
| 539 |
+
|
| 540 |
+
rhoRe = get_rhoRe(np.abs(k[0]), omega_mesh)
|
| 541 |
+
rhoIm = get_rhoIm(np.abs(k[0]), omega_mesh)
|
| 542 |
+
vRe = get_vRe(np.abs(k[0]), omega_mesh)
|
| 543 |
+
vIm = get_vIm(np.abs(k[0]), omega_mesh)
|
| 544 |
+
TRe = get_TRe(np.abs(k[0]), omega_mesh)
|
| 545 |
+
TIm = get_TIm(np.abs(k[0]), omega_mesh)
|
| 546 |
+
|
| 547 |
+
h_values_Re_ini_NS = (u_mesh[:,0:1]*0+rhoRe + np.sum( ( u_mesh[:,np.newaxis,:]*(vRe[:,np.newaxis]*khat) ) ,axis=-1) ) + (np.sum( u_mesh[:,np.newaxis,:]**2 ,axis=-1)/2 - 3/2)*TRe
|
| 548 |
+
h_values_Im_ini_NS = (u_mesh[:,0:1]*0+rhoIm + np.sum( ( u_mesh[:,np.newaxis,:]*(vIm[:,np.newaxis]*khat) ) ,axis=-1) ) + (np.sum( u_mesh[:,np.newaxis,:]**2 ,axis=-1)/2 - 3/2)*TIm
|
| 549 |
+
h_values_Re_ini_Asmp = Kn/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 550 |
+
h_values_Im_ini_Asmp = -Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)/(1+Kn**2*( u_mesh.dot(k)[...,None] + omega_mesh)**2)
|
| 551 |
+
less20 = k[0] < 20
|
| 552 |
+
h_values_Re = h_values_Re_ini_NS * less20 + (1 - less20) * h_values_Re_ini_Asmp
|
| 553 |
+
h_values_Im = h_values_Im_ini_NS * less20 + (1 - less20) * h_values_Im_ini_Asmp
|
| 554 |
+
|
| 555 |
+
'''
|
| 556 |
+
h_values_Re = np.zeros_like(h_values_Re_ini)
|
| 557 |
+
h_values_Im = np.zeros_like(h_values_Im_ini)
|
| 558 |
+
for i, omega in enumerate(omega_mesh):
|
| 559 |
+
nearest_index = np.argmin(np.abs(omega_mesh_ini - omega))
|
| 560 |
+
#print(len(h_values_Re_ini))
|
| 561 |
+
h_values_Re = h_values_Re.at[:,i].set(h_values_Re_ini[:,nearest_index])
|
| 562 |
+
h_values_Im = h_values_Im.at[:,i].set(h_values_Im_ini[:,nearest_index])
|
| 563 |
+
'''
|
| 564 |
+
# sBGK model
|
| 565 |
+
|
| 566 |
+
lamb = 1.0
|
| 567 |
+
stepI = 0.005
|
| 568 |
+
nite = 10000
|
| 569 |
+
reshist = []
|
| 570 |
+
|
| 571 |
+
h_flat = np.concatenate( (h_values_Re.reshape(-1) , h_values_Im.reshape(-1)) , axis = 0)
|
| 572 |
+
#print("h_flat", h_flat.shape)
|
| 573 |
+
|
| 574 |
+
|
| 575 |
+
'''
|
| 576 |
+
A = LinearOperator((len(h_flat),len(h_flat)), matvec=lambda x: mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re.shape))
|
| 577 |
+
from scipy.sparse.linalg import bicgstab, lgmres, tfqmr
|
| 578 |
+
x, exit_code = tfqmr(A, np.zeros_like(h_flat), atol=1e-15, x0 = h_flat, maxiter = 1000)
|
| 579 |
+
print("exit_code",exit_code)
|
| 580 |
+
print("residual", np.linalg.norm(A@x - np.zeros_like(h_flat)))
|
| 581 |
+
#x = spsolve(A, np.zeros_like(h_flat), maxiter = 1000)
|
| 582 |
+
h_values_Re = x[:len(x)//2].reshape(h_values_Re.shape)
|
| 583 |
+
h_values_Im = x[len(x)//2:].reshape(h_values_Im.shape)
|
| 584 |
+
'''
|
| 585 |
+
#h_ini = np.concatenate( (h_values_Re , h_values_Im) , axis = 0)
|
| 586 |
+
if method == "SBGK":
|
| 587 |
+
rescompute = lambda x: rescompute_mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re)
|
| 588 |
+
jac_rescompute = lambda x: grad_rescompute_mv(x, k, Kn, Pr, u_mesh, u_weights, omega_mesh, h_values_Re)
|
| 589 |
+
solver = jaxopt.LBFGS(fun=rescompute, maxiter=1000, tol=tol)
|
| 590 |
+
#solver = jaxopt.ScipyMinimize(fun=rescompute, method="L-BFGS-B", maxiter=1000, tol=tol)
|
| 591 |
+
x = solver.run(h_flat)[0]
|
| 592 |
+
#x = jax.scipy.optimize.minimize(rescompute,h_flat, tol=1e-3, options = {'maxiter': 1000}, method="BFGS").x
|
| 593 |
+
#if k[0] > 1 and k[0] < 200:
|
| 594 |
+
# x = jaxopt.ScipyMinimize(rescompute, h_flat, tol=tol, options = {"disp":False, 'maxiter': 1000}, method="L-BFGS-B").x
|
| 595 |
+
h_values_Re = x[:len(x)//2].reshape(h_values_Re.shape)
|
| 596 |
+
h_values_Im = x[len(x)//2:].reshape(h_values_Im.shape)
|
| 597 |
+
|
| 598 |
+
|
| 599 |
+
rho_spec_S = np.sum( 2*h_values_Re * u_weights[:,np.newaxis] ,axis = 0)
|
| 600 |
+
return h_values_Re, h_values_Im, rho_spec_S
|
| 601 |
+
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
def hermGauss(N):
|
| 605 |
+
gh_nodes, gh_weights = hermgauss(N) # integrate exp(- x^2)
|
| 606 |
+
gh_nodes, gh_weights = 2**0.5*gh_nodes, 2**0.5*gh_weights #https://en.wikipedia.org/wiki/Gauss%E2%80%93Hermite_quadrature # integrate exp(- x^2/2)
|
| 607 |
+
# Create the 3D mesh for \tilde{\mathbf{u}}
|
| 608 |
+
u_mesh_x, u_mesh_y, u_mesh_z = np.meshgrid(gh_nodes, gh_nodes, gh_nodes, indexing='ij')
|
| 609 |
+
u_weights_x, u_weights_y, u_weights_z = np.meshgrid(gh_weights, gh_weights, gh_weights, indexing='ij')
|
| 610 |
+
|
| 611 |
+
# Flatten the mesh and weights for vectorized operations
|
| 612 |
+
u_mesh = np.stack([u_mesh_x.ravel(), u_mesh_y.ravel(), u_mesh_z.ravel()], axis=-1)
|
| 613 |
+
u_weights = (1 / (2 * np.pi)**(3/2)) * np.prod(np.stack([u_weights_x.ravel(), u_weights_y.ravel(), u_weights_z.ravel()], axis=-1), axis=-1)
|
| 614 |
+
return u_mesh, u_weights
|
| 615 |
+
|
| 616 |
+
def monteCarlo(N):
|
| 617 |
+
u_mesh = np.random.randn(N, 3)
|
| 618 |
+
u_weights = np.zeros(N) + 1/N
|
| 619 |
+
return u_mesh, u_weights
|
| 620 |
+
from scipy.stats import qmc, norm
|
| 621 |
+
|
| 622 |
+
def quasiMonteCarlo(N):
|
| 623 |
+
# Initialize a Sobol sequence sampler for 3 dimensions
|
| 624 |
+
sampler = qmc.Sobol(d=3, scramble=True)
|
| 625 |
+
|
| 626 |
+
# Generate N quasi-random samples in the unit cube [0, 1]^3
|
| 627 |
+
sample = sampler.random(N)
|
| 628 |
+
|
| 629 |
+
# Transform the samples to follow a standard normal distribution
|
| 630 |
+
# by applying the inverse cumulative distribution function (CDF)
|
| 631 |
+
u_mesh = norm.ppf(sample)
|
| 632 |
+
|
| 633 |
+
# Assign equal weights to each sample
|
| 634 |
+
u_weights = np.full(N, 1/N)
|
| 635 |
+
|
| 636 |
+
return u_mesh, u_weights
|
| 637 |
+
|
| 638 |
+
def quasiMonteCarloGaussian(N):
|
| 639 |
+
sampler = qmc.MultivariateNormalQMC(mean=np.zeros(3), cov=np.eye(3))
|
| 640 |
+
sample = sampler.random(N)
|
| 641 |
+
u_weights = np.full(N, 1/N)
|
| 642 |
+
return sample, u_weights
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
# Example usage
|
| 646 |
+
Pr = 2/3
|
| 647 |
+
N = 2**14
|
| 648 |
+
|
| 649 |
+
#h_values_Res = []
|
| 650 |
+
#h_values_Ims = []
|
| 651 |
+
omegas = []
|
| 652 |
+
k_numbers = []
|
| 653 |
+
macro_values = []
|
| 654 |
+
|
| 655 |
+
|
| 656 |
+
amplitude = molecule_mass*num_effect/density_0
|
| 657 |
+
|
| 658 |
+
u_mesh, u_weights = quasiMonteCarloGaussian(N)
|
| 659 |
+
|
| 660 |
+
|
| 661 |
+
impulse = 1/(2*np.pi)**2/space_scale**3*amplitude
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
|
| 665 |
+
import tqdm
|
| 666 |
+
for k_val in tqdm.tqdm(k_traval[1900:1901]):
|
| 667 |
+
|
| 668 |
+
#k_val = k_traval[k_number]
|
| 669 |
+
|
| 670 |
+
k = np.array([k_val, 0, 0])
|
| 671 |
+
Kn = (np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/space_scale)[0]
|
| 672 |
+
eps = 1e-1
|
| 673 |
+
peakwidth_NS = (15*(k_val + eps)**2*Kn)/(4*(1+5*(k_val + eps)**2*Kn**2))
|
| 674 |
+
peakwidth_Asympt = np.exp(-(1/(2*k_val**2*Kn**2)))*k_val*np.sqrt(2/np.pi)
|
| 675 |
+
peakwidth = np.maximum(peakwidth_NS, peakwidth_Asympt)
|
| 676 |
+
domainwidth = 10*abs( (k_val + eps) )
|
| 677 |
+
number_of_points = int(20*domainwidth/peakwidth)//2 + 1
|
| 678 |
+
#print("number_of_points", number_of_points)
|
| 679 |
+
omega_mesh = np.linspace(-domainwidth/2, domainwidth/2, number_of_points)
|
| 680 |
+
|
| 681 |
+
rhoRe = get_rhoRe(np.abs(k[0]), omega_mesh)
|
| 682 |
+
|
| 683 |
+
omega_plt = omega_mesh/(denominator_reg(k[0])*(5/3)**0.5)
|
| 684 |
+
|
| 685 |
+
|
| 686 |
+
|
| 687 |
+
|
| 688 |
+
|
| 689 |
+
|
| 690 |
+
#for N in [9,10, 11, 12]:
|
| 691 |
+
#for N in [9,10, 11, 12]:
|
| 692 |
+
|
| 693 |
+
#h_values_Re, h_values_Im, rho_spec_S = compute_h(k,omega_mesh, *hermGauss(N), verbose = True)
|
| 694 |
+
if k_val < 1 or k_val > 200:
|
| 695 |
+
optmethod = "Theory"
|
| 696 |
+
else:
|
| 697 |
+
optmethod = "SBGK"
|
| 698 |
+
h_values_Re, h_values_Im, rho_spec_S = compute_h(k,omega_mesh, u_mesh, u_weights, molecule_mass, Boltz, Temp_0, viscosity_coef, density_0, space_scale, tol = 1e-8, verbose = True, method = optmethod)
|
| 699 |
+
|
| 700 |
+
|
| 701 |
+
n_plus_result_Re = compute_n_plus(k, h_values_Re, u_mesh, u_weights)
|
| 702 |
+
n_plus_result_Im = compute_n_plus(k, h_values_Im, u_mesh, u_weights)
|
| 703 |
+
|
| 704 |
+
v_plus_result_Re = compute_v_plus(k, h_values_Re, u_mesh, u_weights)
|
| 705 |
+
v_plus_result_Im = compute_v_plus(k, h_values_Im, u_mesh, u_weights)
|
| 706 |
+
|
| 707 |
+
T_plus_result_Re = compute_T_plus(k, h_values_Re, u_mesh, u_weights) - n_plus_result_Re
|
| 708 |
+
T_plus_result_Im = compute_T_plus(k, h_values_Im, u_mesh, u_weights) - n_plus_result_Im
|
| 709 |
+
|
| 710 |
+
sigma_plus_result_Re = compute_sigma_plus(k, h_values_Re, u_mesh, u_weights)
|
| 711 |
+
sigma_plus_result_Im = compute_sigma_plus(k, h_values_Im, u_mesh, u_weights)
|
| 712 |
+
|
| 713 |
+
q_plus_result_Re = compute_q_plus(k, h_values_Re, u_mesh, u_weights) - 5/2*v_plus_result_Re
|
| 714 |
+
q_plus_result_Im = compute_q_plus(k, h_values_Im, u_mesh, u_weights) - 5/2*v_plus_result_Im
|
| 715 |
+
|
| 716 |
+
current_result = (omega_mesh, n_plus_result_Re, n_plus_result_Im, v_plus_result_Re, v_plus_result_Im, T_plus_result_Re, T_plus_result_Im )
|
| 717 |
+
|
| 718 |
+
macro_values.append(current_result)
|
| 719 |
+
# append the current_result to a file
|
| 720 |
+
jax.clear_caches()
|
| 721 |
+
|
| 722 |
+
|
| 723 |
+
#h_values_Res.append(h_values_Re)
|
| 724 |
+
#h_values_Ims.append(h_values_Im)
|
| 725 |
+
|
| 726 |
+
#plt.plot( omega_plt, impulse*2*rhoRe, label = "NS")
|
| 727 |
+
#plt.plot( omega_plt, impulse*rho_spec_S, label = "N = "+str(N) )
|
| 728 |
+
#plt.xlim(-2*peakwidth /(denominator_reg(k[0])*(5/3)**0.5), 2*peakwidth /(denominator_reg(k[0])*(5/3)**0.5) )
|
| 729 |
+
#plt.legend()
|
| 730 |
+
#plt.show()
|
| 731 |
+
|
| 732 |
+
|
| 733 |
+
|
| 734 |
+
# save the macro values results
|
| 735 |
+
import pickle
|
| 736 |
+
|
| 737 |
+
#save_data = { "values": macro_values , "k": k_traval, "omega": omega_mesh }
|
| 738 |
+
#with open("Boltzmann3_macro_values_Adapt_FullExp.pkl", "wb") as f:
|
| 739 |
+
# pickle.dump(save_data, f)
|
| 740 |
+
|
| 741 |
+
# load the macro values results
|
| 742 |
+
#"Boltzmann3_macro_values_500.pkl"
|
| 743 |
+
|
| 744 |
+
def denominator_reg(denominator):
|
| 745 |
+
sign = 1-2*(denominator < 0)
|
| 746 |
+
return sign*np.maximum(np.abs(denominator), 1e-10)
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
with open("Boltzmann3_macro_values_Adapt_FullExp.pkl", "rb") as f:
|
| 750 |
+
save_data = pickle.load(f)
|
| 751 |
+
macro_values = save_data["values"]
|
| 752 |
+
k_traval = save_data["k"]
|
| 753 |
+
omega_mesh = save_data["omega"]
|
| 754 |
+
|
| 755 |
+
def bump_fourier(a, k, b):
|
| 756 |
+
result1 = 1/(2*np.sqrt(2)*np.pi**(3/2))-(a**2*k**2)/(20*(np.sqrt(2)*np.pi**(3/2)))
|
| 757 |
+
|
| 758 |
+
k = denominator_reg(k)
|
| 759 |
+
coefficient = 3/(2*np.sqrt(2)*np.pi**(3/2))
|
| 760 |
+
numerator = -a * k * np.cos(a * k) + np.sin(a * k)
|
| 761 |
+
denominator = a**3 * k**3
|
| 762 |
+
exponential = np.exp(-k**2 * b**2 / 2)
|
| 763 |
+
result2 = (coefficient * numerator / denominator) * exponential
|
| 764 |
+
mask = np.abs(k) < 5e-1
|
| 765 |
+
result = result1*exponential*mask + result2*(1-mask)
|
| 766 |
+
return result
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
#!/usr/bin/env python
|
| 770 |
+
|
| 771 |
+
import numpy as nnp
|
| 772 |
+
from scipy.special import gamma, spherical_jn
|
| 773 |
+
from scipy.fft import ifft, rfft, irfft
|
| 774 |
+
|
| 775 |
+
# usefull constants
|
| 776 |
+
PI = nnp.pi
|
| 777 |
+
TPI = 2.0 * nnp.pi
|
| 778 |
+
II = 1.0j
|
| 779 |
+
|
| 780 |
+
class pyNumSBT(object):
|
| 781 |
+
'''
|
| 782 |
+
Numerically perform spherical Bessel transform (SBT) in O(Nln(N)) time based
|
| 783 |
+
on the algorithm proposed by J. Talman.
|
| 784 |
+
|
| 785 |
+
Talman, J. Computer Physics Communications 2009, 180, 332-338.
|
| 786 |
+
|
| 787 |
+
For a function "f(r)" defined numerically on a LOGARITHMIC radial grid "r",
|
| 788 |
+
the SBT for the function gives
|
| 789 |
+
|
| 790 |
+
g(k) = \sqrt{2\over\pi} \int_0^\infty j_l(kr) f(r) r^2 dr (c1)
|
| 791 |
+
|
| 792 |
+
and the inverse SBT (iSBT) gives
|
| 793 |
+
|
| 794 |
+
f(r) = \sqrt{2\over\pi} \int_0^\infty j_l(kr) g(k) k^2 dk (c2)
|
| 795 |
+
'''
|
| 796 |
+
|
| 797 |
+
def __init__(self, rr, kmax: float=500, lmax: int=10):
|
| 798 |
+
'''
|
| 799 |
+
Init
|
| 800 |
+
'''
|
| 801 |
+
|
| 802 |
+
self.rr = nnp.asarray(rr, dtype=float) # the real-space logarithmic radial grid
|
| 803 |
+
self.nr = self.rr.size # No. of grid points
|
| 804 |
+
self.nr2 = 2 * self.nr
|
| 805 |
+
self.sbt_init(rr, kmax)
|
| 806 |
+
|
| 807 |
+
self.lmax = lmax
|
| 808 |
+
self.sbt_mltb(self.lmax)
|
| 809 |
+
|
| 810 |
+
def sbt_init(self, rr, kmax: float):
|
| 811 |
+
'''
|
| 812 |
+
Initialize the real-space grid (rr) and momentum-space grid (kk).
|
| 813 |
+
|
| 814 |
+
\rho = \ln(rr)
|
| 815 |
+
\kappa = \ln(kk)
|
| 816 |
+
|
| 817 |
+
The algorithm by Talman requries
|
| 818 |
+
|
| 819 |
+
\Delta\kappa = \Delta\rho
|
| 820 |
+
'''
|
| 821 |
+
|
| 822 |
+
self.r_min = rr[0]
|
| 823 |
+
self.r_max = rr[-1]
|
| 824 |
+
|
| 825 |
+
self.rho_min = nnp.log(self.r_min)
|
| 826 |
+
self.rho_max = nnp.log(self.r_max)
|
| 827 |
+
# \Delta\rho = \ln(rr[1] - rr[0])
|
| 828 |
+
self.drho = (self.rho_max - self.rho_min) / (self.nr - 1)
|
| 829 |
+
|
| 830 |
+
self.kappa_max = nnp.log(kmax)
|
| 831 |
+
self.kappa_min = self.kappa_max - (self.rho_max - self.rho_min)
|
| 832 |
+
|
| 833 |
+
# the reciprocal-space (momentum-space) logarithmic grid
|
| 834 |
+
self.kk = nnp.exp(self.kappa_min) * nnp.exp(nnp.arange(self.nr)*self.drho)
|
| 835 |
+
self.k_min = self.kk[0]
|
| 836 |
+
self.k_max = self.kk[-1]
|
| 837 |
+
|
| 838 |
+
self.rr3 = self.rr**3
|
| 839 |
+
self.kk3 = self.kk**3
|
| 840 |
+
|
| 841 |
+
# r values for the extended mesh as discussed in Sec.4 of Talman paper.
|
| 842 |
+
self.rr_ext = self.r_min * nnp.exp(nnp.arange(-self.nr, 0) * self.drho)
|
| 843 |
+
|
| 844 |
+
# the multiply factor as in Talman paper after Eq.(32)
|
| 845 |
+
self.rr15 = nnp.zeros((2, self.nr), dtype=float)
|
| 846 |
+
self.rr15[0] = self.rr_ext**1.5 / self.r_min**1.5 # the extended r-mesh
|
| 847 |
+
self.rr15[1] = self.rr**1.5 / self.r_min**1.5 # the normal r-mesh
|
| 848 |
+
|
| 849 |
+
# \Delta\rho \times \Delta t = \frac{2\pi}{N}
|
| 850 |
+
# as in Talman paper after Eq.(30), where N = 2 * nr as discussed in
|
| 851 |
+
# Sec. 4
|
| 852 |
+
self.dt = TPI / (self.nr2 * self.drho)
|
| 853 |
+
|
| 854 |
+
# the post-division factor (1 / k^1.5) as in Eq. (32) of Talman paper.
|
| 855 |
+
# Note that the factor is (1 / r^1.5) for inverse-SBT, as a result, we
|
| 856 |
+
# omit the r_min^1.5 / k_min^1.5 here.
|
| 857 |
+
self.post_div_fac = nnp.exp(-nnp.arange(self.nr)*self.drho*1.5)
|
| 858 |
+
|
| 859 |
+
# Simpson integration of a function on the logarithmic radial grid.
|
| 860 |
+
#
|
| 861 |
+
# Setup weights for simpson integration on radial grid any radial integral
|
| 862 |
+
# can then be evaluated by just summing all radial grid points with the
|
| 863 |
+
# weights SI
|
| 864 |
+
#
|
| 865 |
+
# \int dr = \sum_i w(i) * f(i)
|
| 866 |
+
self.simp_wht_rr = nnp.zeros_like(self.rr)
|
| 867 |
+
self.simp_wht_kk = nnp.zeros_like(self.kk)
|
| 868 |
+
for ii in range(self.nr-1, 1, -2):
|
| 869 |
+
self.simp_wht_rr[ii] = self.drho * self.rr[ii] / 3. \
|
| 870 |
+
+ self.simp_wht_rr[ii]
|
| 871 |
+
self.simp_wht_rr[ii-1] = self.drho * self.rr[ii-1] * 4. / 3.
|
| 872 |
+
self.simp_wht_rr[ii-2] = self.drho * self.rr[ii-2] / 3.
|
| 873 |
+
|
| 874 |
+
self.simp_wht_kk[ii] = self.drho * self.kk[ii] / 3. \
|
| 875 |
+
+ self.simp_wht_kk[ii]
|
| 876 |
+
self.simp_wht_kk[ii-1] = self.drho * self.kk[ii-1] * 4. / 3.
|
| 877 |
+
self.simp_wht_kk[ii-2] = self.drho * self.kk[ii-2] / 3.
|
| 878 |
+
|
| 879 |
+
def sbt_mltb(self, lmax_in: int):
|
| 880 |
+
'''
|
| 881 |
+
construct the M_l(t) table according to Eq. (15), (16) and (24) of
|
| 882 |
+
Talman paper.
|
| 883 |
+
|
| 884 |
+
Note that Talman paper use Stirling's approximaton to evaluate the Gamma
|
| 885 |
+
function, whereas I just call scipy.special.gamma here.
|
| 886 |
+
'''
|
| 887 |
+
|
| 888 |
+
if lmax_in > self.lmax:
|
| 889 |
+
lmax = lmax_in
|
| 890 |
+
self.lmax = lmax
|
| 891 |
+
else:
|
| 892 |
+
lmax = self.lmax
|
| 893 |
+
|
| 894 |
+
tt = nnp.arange(self.nr) * self.dt
|
| 895 |
+
|
| 896 |
+
# M_lt1 is quantity defined by Eq. (12)
|
| 897 |
+
self.M_lt1 = nnp.zeros((lmax+1, self.nr), dtype=complex)
|
| 898 |
+
|
| 899 |
+
# Eq. (15) in Talman paper
|
| 900 |
+
# self.M_lt1[0] = gamma(0.5 - II*tt) * nnp.sin(0.5*PI*(0.5 - II*tt)) / self.nr
|
| 901 |
+
|
| 902 |
+
# Eq. (19) and Eq. (15) in Talman paper are equivalent, while the former
|
| 903 |
+
# is more stable for larger tt
|
| 904 |
+
self.M_lt1[0] = nnp.sqrt(nnp.pi / 2) * nnp.exp(
|
| 905 |
+
II * (
|
| 906 |
+
nnp.log(gamma(0.5 - II*tt)).imag
|
| 907 |
+
# + nnp.log(nnp.sin(0.5*PI*(0.5 - II*tt))).imag
|
| 908 |
+
- nnp.arctan(nnp.tanh(PI*tt/2))
|
| 909 |
+
)
|
| 910 |
+
) / self.nr
|
| 911 |
+
|
| 912 |
+
self.M_lt1[0,0] /= 2.0
|
| 913 |
+
self.M_lt1[0] *= nnp.exp(II*tt*(self.kappa_min + self.rho_min))
|
| 914 |
+
|
| 915 |
+
# Eq. (16) in Talman paper
|
| 916 |
+
phi = nnp.arctan(nnp.tanh(PI*tt/2)) - nnp.arctan(2*tt)
|
| 917 |
+
self.M_lt1[1] = self.M_lt1[0] * nnp.exp(2*II*phi)
|
| 918 |
+
|
| 919 |
+
# Eq. (24) in Talman paper
|
| 920 |
+
for ll in range(1, lmax):
|
| 921 |
+
phi_l = nnp.arctan(2*tt / (2*ll + 1))
|
| 922 |
+
self.M_lt1[ll+1] = nnp.exp(-2*II*phi_l) * self.M_lt1[ll-1]
|
| 923 |
+
|
| 924 |
+
ll = nnp.arange(lmax+1)
|
| 925 |
+
# Eq. (35) in Talman paper
|
| 926 |
+
xx = nnp.exp(self.rho_min + self.kappa_min + nnp.arange(self.nr2)*self.drho)
|
| 927 |
+
|
| 928 |
+
# M_lt2 is just the Fourier transform of spherical Bessel function j_l
|
| 929 |
+
self.M_lt2 = ifft(
|
| 930 |
+
spherical_jn(ll[:,None], xx[None,:]),
|
| 931 |
+
axis=1
|
| 932 |
+
).conj()[:,:self.nr+1]
|
| 933 |
+
|
| 934 |
+
|
| 935 |
+
def run(self,
|
| 936 |
+
ff,
|
| 937 |
+
l: int=0,
|
| 938 |
+
direction: int = 1,
|
| 939 |
+
norm: bool=False,
|
| 940 |
+
np_in: int =0,
|
| 941 |
+
return_rr: bool=False,
|
| 942 |
+
include_zero: bool=False,
|
| 943 |
+
):
|
| 944 |
+
'''
|
| 945 |
+
Perform SBT or inverse-SBT.
|
| 946 |
+
|
| 947 |
+
Input parapeters:
|
| 948 |
+
ff: the function defined on the logarithmic radial grid
|
| 949 |
+
l: the "l" as in the underscript of "j_l(kr)" of Eq. (c1) and (c2)
|
| 950 |
+
direction: 1 for forward SBT and -1 for inverse SBT
|
| 951 |
+
norm: whether to multiply the prefactor \sqrt{2\over\pi} in Eq. (c1) and (c2).
|
| 952 |
+
If False, then subsequent applicaton of SBT and iSBT will yield
|
| 953 |
+
the original data scaled by a factor of 2/pi.
|
| 954 |
+
np_in: the asymptotic bahavior of ff when r -> 0
|
| 955 |
+
|
| 956 |
+
ff(r\to 0) \approx r^{np_in + l}
|
| 957 |
+
include_zero: the SBT does not include the k = 0, i.e. self.kk.min() != 0, term by default.
|
| 958 |
+
'''
|
| 959 |
+
|
| 960 |
+
assert l <= self.lmax, \
|
| 961 |
+
"lmax = {} smaller than l = {}! Increase lmax!".format(self.lmax, l)
|
| 962 |
+
|
| 963 |
+
|
| 964 |
+
ff = nnp.asarray(ff, dtype=float)
|
| 965 |
+
gg = nnp.zeros_like(ff)
|
| 966 |
+
|
| 967 |
+
r2c_in = nnp.zeros(self.nr2, dtype=float)
|
| 968 |
+
r2c_out = nnp.zeros(self.nr + 1, dtype=complex)
|
| 969 |
+
|
| 970 |
+
c2r_in = nnp.zeros(self.nr + 1, dtype=complex)
|
| 971 |
+
c2r_out = nnp.zeros(self.nr2, dtype=float)
|
| 972 |
+
|
| 973 |
+
# The prefactor as in Eq. (c1) and (c2) of the Class docstring.
|
| 974 |
+
sqrt_2_over_pi = nnp.sqrt(2 / PI) if norm else 1.0
|
| 975 |
+
|
| 976 |
+
if direction == 1:
|
| 977 |
+
rmin = self.r_min
|
| 978 |
+
kmin = self.k_min
|
| 979 |
+
C = ff[0] / self.r_min**(np_in + l)
|
| 980 |
+
elif direction == -1:
|
| 981 |
+
rmin = self.k_min
|
| 982 |
+
kmin = self.r_min
|
| 983 |
+
C = ff[0] / self.k_min**(np_in + l)
|
| 984 |
+
else:
|
| 985 |
+
raise ValueError("Use direction=1/-1 for forward- and inverse-SBT!")
|
| 986 |
+
|
| 987 |
+
# SBT for LARGE k values extend the input to the doubled mesh,
|
| 988 |
+
# extrapolating the input as C r^(np_in + l)
|
| 989 |
+
|
| 990 |
+
# Step 1 in the procedure after Eq. (32) of Talman paper
|
| 991 |
+
r2c_in[:self.nr] = C * self.rr_ext**(np_in + l) * self.rr15[0]
|
| 992 |
+
r2c_in[self.nr:] = ff * self.rr15[1]
|
| 993 |
+
|
| 994 |
+
# Step 2 in the procedure after Eq. (32) of Talman paper
|
| 995 |
+
r2c_out = rfft(r2c_in)
|
| 996 |
+
|
| 997 |
+
# Step 3 in the procedure after Eq. (32) of Talman paper
|
| 998 |
+
tmp1 = nnp.zeros(self.nr2, dtype=complex)
|
| 999 |
+
tmp1[:self.nr] = r2c_out[:self.nr].conj() * self.M_lt1[l]
|
| 1000 |
+
|
| 1001 |
+
# Step 4 and 5 in the procedure after Eq. (32) of Talman paper
|
| 1002 |
+
tmp2 = ifft(tmp1) * self.nr2
|
| 1003 |
+
gg = (rmin / kmin)**1.5 * tmp2[self.nr:].real * self.post_div_fac * sqrt_2_over_pi
|
| 1004 |
+
|
| 1005 |
+
# obtain the SMALL k results in the array c2r_out
|
| 1006 |
+
|
| 1007 |
+
if direction == 1:
|
| 1008 |
+
r2c_in[:self.nr] = self.rr3 * ff
|
| 1009 |
+
else:
|
| 1010 |
+
r2c_in[:self.nr] = self.kk3 * ff
|
| 1011 |
+
r2c_in[self.nr:] = 0.0
|
| 1012 |
+
r2c_out = rfft(r2c_in)
|
| 1013 |
+
|
| 1014 |
+
c2r_in = r2c_out.conj() * self.M_lt2[l] * sqrt_2_over_pi
|
| 1015 |
+
c2r_out = irfft(c2r_in) * self.nr2
|
| 1016 |
+
c2r_out[:self.nr] *= self.drho
|
| 1017 |
+
|
| 1018 |
+
# compare the minimum difference between large and small k as described
|
| 1019 |
+
# in the paragraph above Eq. (39) of Talman paper.
|
| 1020 |
+
gdiff = nnp.abs(gg - c2r_out[:self.nr])
|
| 1021 |
+
minloc = nnp.argmin(gdiff)
|
| 1022 |
+
gg[:minloc+1] = c2r_out[:minloc+1]
|
| 1023 |
+
|
| 1024 |
+
# include k = 0 in the SBT and r = 0 in the i-SBT.
|
| 1025 |
+
if include_zero:
|
| 1026 |
+
if direction == 1:
|
| 1027 |
+
gg0 = sqrt_2_over_pi * spherical_jn(l, 0) * nnp.sum(
|
| 1028 |
+
self.simp_wht_rr * self.rr**2 * ff
|
| 1029 |
+
)
|
| 1030 |
+
else:
|
| 1031 |
+
gg0 = sqrt_2_over_pi * spherical_jn(l, 0) * nnp.sum(
|
| 1032 |
+
self.simp_wht_kk * self.kk**2 * ff
|
| 1033 |
+
)
|
| 1034 |
+
|
| 1035 |
+
if return_rr:
|
| 1036 |
+
if direction == 1:
|
| 1037 |
+
return (nnp.r_[0, self.kk], nnp.r_[gg0, gg]) if include_zero else (self.kk, gg)
|
| 1038 |
+
else:
|
| 1039 |
+
return (nnp.r_[0, self.rr], nnp.r_[gg0, gg]) if include_zero else (self.rr, gg)
|
| 1040 |
+
else:
|
| 1041 |
+
return nnp.r_[gg0, gg] if include_zero else gg
|
| 1042 |
+
|
| 1043 |
+
|
| 1044 |
+
def run_int(self,
|
| 1045 |
+
ff,
|
| 1046 |
+
l: int=0,
|
| 1047 |
+
direction: int = 1,
|
| 1048 |
+
norm: bool=False,
|
| 1049 |
+
return_rr: bool=False,
|
| 1050 |
+
include_zero: bool=False,
|
| 1051 |
+
):
|
| 1052 |
+
'''
|
| 1053 |
+
Perform SBT or inverse-SBT by numerically integrating Eq. (c1) and (c2).
|
| 1054 |
+
|
| 1055 |
+
Input parapeters:
|
| 1056 |
+
ff: the function defined on the logarithmic radial grid
|
| 1057 |
+
l: the "l" as in the underscript of "j_l(kr)" of Eq. (c1) and (c2)
|
| 1058 |
+
direction: 1 for forward SBT and -1 for inverse SBT
|
| 1059 |
+
norm: whether to multiply the prefactor \sqrt{2\over\pi} in Eq. (c1) and (c2).
|
| 1060 |
+
If False, then subsequent applicaton of SBT and iSBT will yield
|
| 1061 |
+
the original data scaled by a factor of 2/pi.
|
| 1062 |
+
include_zero: the SBT does not include the k = 0, i.e. self.kk.min() != 0, term by default.
|
| 1063 |
+
'''
|
| 1064 |
+
|
| 1065 |
+
kr = self.rr[:,None] * self.kk[None,:]
|
| 1066 |
+
jl_kr = spherical_jn(l, kr)
|
| 1067 |
+
ff = nnp.asarray(ff, dtype=float)
|
| 1068 |
+
|
| 1069 |
+
# The prefactor as in Eq. (c1) and (c2) of the Class docstring.
|
| 1070 |
+
sqrt_2_over_pi = nnp.sqrt(2 / PI) if norm else 1.0
|
| 1071 |
+
|
| 1072 |
+
if direction == 1:
|
| 1073 |
+
gg = sqrt_2_over_pi * nnp.sum(
|
| 1074 |
+
jl_kr * (self.rr**2 * ff * self.simp_wht_rr)[:,None],
|
| 1075 |
+
axis=0
|
| 1076 |
+
)
|
| 1077 |
+
# include k = 0 in the SBT and r = 0 in the i-SBT.
|
| 1078 |
+
if include_zero:
|
| 1079 |
+
gg0 = sqrt_2_over_pi * spherical_jn(l, 0) * nnp.sum(
|
| 1080 |
+
self.simp_wht_rr * self.rr**2 * ff
|
| 1081 |
+
)
|
| 1082 |
+
elif direction == -1:
|
| 1083 |
+
gg = sqrt_2_over_pi * nnp.sum(
|
| 1084 |
+
jl_kr * (self.kk**2 * ff * self.simp_wht_kk)[None,:],
|
| 1085 |
+
axis=1
|
| 1086 |
+
)
|
| 1087 |
+
# include k = 0 in the SBT and r = 0 in the i-SBT.
|
| 1088 |
+
if include_zero:
|
| 1089 |
+
gg0 = sqrt_2_over_pi * spherical_jn(l, 0) * nnp.sum(
|
| 1090 |
+
self.simp_wht_kk * self.kk**2 * ff
|
| 1091 |
+
)
|
| 1092 |
+
else:
|
| 1093 |
+
raise ValueError("Use direction=1/-1 for forward- and inverse-SBT!")
|
| 1094 |
+
|
| 1095 |
+
if return_rr:
|
| 1096 |
+
if direction == 1:
|
| 1097 |
+
return (nnp.r_[0, self.kk], nnp.r_[gg0, gg]) if include_zero else (self.kk, gg)
|
| 1098 |
+
else:
|
| 1099 |
+
return (nnp.r_[0, self.rr], nnp.r_[gg0, gg]) if include_zero else (self.rr, gg)
|
| 1100 |
+
else:
|
| 1101 |
+
return nnp.r_[gg0, gg] if include_zero else gg
|
| 1102 |
+
|
| 1103 |
+
|
| 1104 |
+
|
| 1105 |
+
N = 256
|
| 1106 |
+
rmin = 2.0 / 1024 / 32
|
| 1107 |
+
rmax = 30
|
| 1108 |
+
rr = nnp.logspace(nnp.log10(rmin), nnp.log10(rmax), N, endpoint=True)
|
| 1109 |
+
f1 = 2*nnp.exp(-rr)
|
| 1110 |
+
|
| 1111 |
+
xx = pyNumSBT(rr)
|
| 1112 |
+
|
| 1113 |
+
g1 = xx.run(f1, direction=1, norm=False)
|
| 1114 |
+
f2 = xx.run(g1 * g1, direction=-1, norm=False)
|
| 1115 |
+
|
| 1116 |
+
|
| 1117 |
+
import matplotlib.pyplot as plt
|
| 1118 |
+
|
| 1119 |
+
# fig = plt.figure(
|
| 1120 |
+
# dpi=100,
|
| 1121 |
+
# )
|
| 1122 |
+
# ax = plt.subplot()
|
| 1123 |
+
|
| 1124 |
+
# # ax.plot(rr, f1)
|
| 1125 |
+
# ax.plot(rr, f2 * 2 / nnp.pi, ls='-')
|
| 1126 |
+
# ax.plot(rr, nnp.exp(-rr) * (1 + rr + rr**2 / 3), ls='--')
|
| 1127 |
+
|
| 1128 |
+
# ax.set_xlabel('X-label', labelpad=5)
|
| 1129 |
+
# ax.set_ylabel('Y-label', labelpad=5)
|
| 1130 |
+
|
| 1131 |
+
# plt.tight_layout()
|
| 1132 |
+
# plt.show()
|
| 1133 |
+
|
| 1134 |
+
from scipy.interpolate import krogh_interpolate
|
| 1135 |
+
n_plus_resoult_Re_fines = []
|
| 1136 |
+
v_plus_result_Re_fines = []
|
| 1137 |
+
T_plus_result_Re_fines = []
|
| 1138 |
+
omega_mesh = np.linspace(-5* 50 - 1e-6, 5*50 + 1e-6, 10419)
|
| 1139 |
+
for i in range(len(macro_values)):
|
| 1140 |
+
omega_mesh_data = macro_values[i][0]
|
| 1141 |
+
n_plus_resoult_Re = macro_values[i][1][...,0]
|
| 1142 |
+
v_plus_result_Re = macro_values[i][3][...,0]
|
| 1143 |
+
T_plus_result_Re = macro_values[i][5][...,0]
|
| 1144 |
+
|
| 1145 |
+
# interpolate the data
|
| 1146 |
+
n_plus_resoult_Re_fine = np.interp(omega_mesh, omega_mesh_data, n_plus_resoult_Re, left = 0, right = 0)
|
| 1147 |
+
v_plus_result_Re_fine = np.interp(omega_mesh, omega_mesh_data, v_plus_result_Re, left = 0, right = 0)
|
| 1148 |
+
T_plus_result_Re_fine = np.interp(omega_mesh, omega_mesh_data, T_plus_result_Re, left = 0, right = 0)
|
| 1149 |
+
# interpolate the data using the
|
| 1150 |
+
n_plus_resoult_Re_fines.append(n_plus_resoult_Re_fine)
|
| 1151 |
+
v_plus_result_Re_fines.append(v_plus_result_Re_fine)
|
| 1152 |
+
T_plus_result_Re_fines.append(T_plus_result_Re_fine)
|
| 1153 |
+
|
| 1154 |
+
n_plus_resoult_Re_fines = np.array(n_plus_resoult_Re_fines)
|
| 1155 |
+
v_plus_result_Re_fines = np.array(v_plus_result_Re_fines)
|
| 1156 |
+
T_plus_result_Re_fines = np.array(T_plus_result_Re_fines)
|
| 1157 |
+
|
| 1158 |
+
|
| 1159 |
+
kk = np.logspace(-2, 2.79817986094985, 2048, endpoint=True)
|
| 1160 |
+
rho0k = np.array( [ bump_fourier(1, kvalue, 1) for kvalue in kk] )
|
| 1161 |
+
SBT = pyNumSBT(kk.__array__())
|
| 1162 |
+
# plt.plot( kk,rho0k, label = "NS")
|
| 1163 |
+
# plt.show()
|
| 1164 |
+
# g1 = SBT.run(rho0k.__array__(), direction=1, norm=True)
|
| 1165 |
+
# plt.plot( SBT.kk, g1)
|
| 1166 |
+
# plt.xlim(0, 10)
|
| 1167 |
+
# plt.show()
|
| 1168 |
+
# f1 = SBT.run(g1.__array__(), direction=-1, norm=True)
|
| 1169 |
+
# plt.plot( kk, f1 )
|
| 1170 |
+
# plt.plot( kk, rho0k, linestyle = "dotted")
|
| 1171 |
+
|
| 1172 |
+
# plt.xlim(0, 10)
|
| 1173 |
+
# plt.show()
|
| 1174 |
+
|
| 1175 |
+
|
| 1176 |
+
|
| 1177 |
+
|
| 1178 |
+
# Compute delta_rho(k) from delta_rho(r) (Forward Transform)
|
| 1179 |
+
def forward_transform(delta_rho_r, r, k):
|
| 1180 |
+
# Compute kr matrix
|
| 1181 |
+
kr = np.outer(k, r) # Shape: (N_k, N_r)
|
| 1182 |
+
|
| 1183 |
+
# Compute the sine of kr
|
| 1184 |
+
sin_kr = np.sinc(kr / np.pi)
|
| 1185 |
+
|
| 1186 |
+
# Compute the integrand
|
| 1187 |
+
integrand = delta_rho_r * r**2 * sin_kr # Broadcasting over r
|
| 1188 |
+
|
| 1189 |
+
# Compute the integral over r for each k
|
| 1190 |
+
integral = np.trapezoid(integrand, x=r, axis=1) # Shape: (N_k,)
|
| 1191 |
+
|
| 1192 |
+
# Compute the prefactor
|
| 1193 |
+
prefactor = (4 * np.pi) / ((2 * np.pi) ** 1.5 * np.ones_like(k))
|
| 1194 |
+
|
| 1195 |
+
# Compute delta_rho(k)
|
| 1196 |
+
delta_rho_k = prefactor * integral
|
| 1197 |
+
|
| 1198 |
+
return delta_rho_k
|
| 1199 |
+
|
| 1200 |
+
|
| 1201 |
+
|
| 1202 |
+
# Compute delta_rho(r) from delta_rho(k) (Inverse Transform)
|
| 1203 |
+
def inverse_transform(delta_rho_k, k, r):
|
| 1204 |
+
# Compute kr matrix
|
| 1205 |
+
kr = np.outer(r, k) # Shape: (N_r, N_k)
|
| 1206 |
+
|
| 1207 |
+
# Compute the sine of kr
|
| 1208 |
+
sin_kr = np.sinc(kr / np.pi)
|
| 1209 |
+
|
| 1210 |
+
# Compute the integrand
|
| 1211 |
+
integrand = delta_rho_k * k**2 * sin_kr # Broadcasting over k
|
| 1212 |
+
|
| 1213 |
+
# Compute the integral over k for each r
|
| 1214 |
+
integral = np.trapezoid(integrand, x=k, axis=1) # Shape: (N_r,)
|
| 1215 |
+
|
| 1216 |
+
# Compute the prefactor
|
| 1217 |
+
prefactor = (4 * np.pi) / ((2 * np.pi) ** 1.5 * np.ones_like(r) )
|
| 1218 |
+
|
| 1219 |
+
|
| 1220 |
+
# Compute delta_rho(r)
|
| 1221 |
+
delta_rho_r_rec = prefactor * integral
|
| 1222 |
+
|
| 1223 |
+
return delta_rho_r_rec
|
| 1224 |
+
|
| 1225 |
+
rho0k = np.array( [ bump_fourier(2, kvalue, 100) for kvalue in k_traval] )
|
| 1226 |
+
import torch
|
| 1227 |
+
import torch.nn as nn
|
| 1228 |
+
import numpy as nnp
|
| 1229 |
+
device = "cpu"
|
| 1230 |
+
dtype = torch.float
|
| 1231 |
+
sNet= torch.load("./DSMC3ModelsExp/DSMC3LearnModelFull6.pt", weights_only=False, map_location=torch.device('cpu'))
|
| 1232 |
+
#sNet.load_state_dict(torch.load("./DSMC3ModelsV/DSMC3LearnModelN250", map_location=torch.device('cpu')))
|
| 1233 |
+
sNet.eval()
|
| 1234 |
+
kTest = 5
|
| 1235 |
+
with torch.no_grad():
|
| 1236 |
+
net_spectra, net_spectra_omega, _, _, _, _, _ = sNet(torch.tensor( nnp.array( kTest ), device = device, dtype = dtype), torch.tensor( nnp.array(omega_mesh[None,:]/(kTest *(5/3)**0.5) ), device = device, dtype = dtype))
|
| 1237 |
+
net_spectra = net_spectra.cpu().numpy()
|
| 1238 |
+
net_spectra_omega = net_spectra_omega.cpu().numpy()
|
| 1239 |
+
|
| 1240 |
+
# plt.plot( omega_mesh, 2*get_rhoRe(kTest , omega_mesh), label = "NS", linewidth = 2)
|
| 1241 |
+
# plt.plot(omega_mesh, net_spectra[0]/impulse, label = "NN")
|
| 1242 |
+
# plt.legend()
|
| 1243 |
+
# plt.show()
|
| 1244 |
+
#k_traval = np.linspace( 0, 30, 200 )
|
| 1245 |
+
# suppress the outbound omega spectra by a Gaussian filter in omega space
|
| 1246 |
+
#omega_fft_range = np.max( np.abs(omega_mesh) )
|
| 1247 |
+
#fft_omega_filter = np.exp( - (omega_mesh)**2 / (2 * (omega_fft_range/2)**2) )
|
| 1248 |
+
|
| 1249 |
+
rho_k_omega_Bol3_re = 2*n_plus_resoult_Re_fines#*fft_omega_filter
|
| 1250 |
+
rho_k_omega_NS_re = np.array([2*get_rhoRe(k_traval[i], omega_mesh) for i in range(len(k_traval))])#*fft_omega_filter
|
| 1251 |
+
#rho_k_omega_Bol3_re = rho_k_omega_Bol3_re.at[k_traval < 1].set(rho_k_omega_NS_re[k_traval < 1])
|
| 1252 |
+
rho_k_omega_Learn_re = []
|
| 1253 |
+
|
| 1254 |
+
|
| 1255 |
+
#rho_k_omega_Learn_re[0] = 2*get_rhoRe(k_traval[0], omega_mesh)
|
| 1256 |
+
|
| 1257 |
+
|
| 1258 |
+
v_plus_k_omega_Bol3_re = 2*v_plus_result_Re_fines#*fft_omega_filter
|
| 1259 |
+
v_plus_k_omega_NS_re = np.array([2*get_vRe(k_traval[i], omega_mesh) for i in range(len(k_traval))])#*fft_omega_filter
|
| 1260 |
+
#v_plus_k_omega_Bol3_re = v_plus_k_omega_Bol3_re.at[k_traval < 1].set(v_plus_k_omega_NS_re[k_traval < 1])
|
| 1261 |
+
|
| 1262 |
+
T_plus_k_omega_Bol3_re = 2*T_plus_result_Re_fines#*fft_omega_filter
|
| 1263 |
+
T_plus_k_omega_NS_re = np.array([2*get_TRe(k_traval[i], omega_mesh) for i in range(len(k_traval))])#*fft_omega_filter
|
| 1264 |
+
T_plus_k_omega_Learn_re = []
|
| 1265 |
+
for kTest in k_traval:
|
| 1266 |
+
with torch.no_grad():
|
| 1267 |
+
net_spectra, net_spectra_omega, _, rhoSpec, vSpec, TSpec, _ = sNet(torch.tensor( nnp.array( kTest ), device = device, dtype = dtype), torch.tensor( nnp.array(omega_mesh[None,:]/(kTest *(5/3)**0.5) ), device = device, dtype = dtype))
|
| 1268 |
+
net_spectra = net_spectra.cpu().numpy()
|
| 1269 |
+
net_spectra_omega = net_spectra_omega.cpu().numpy()
|
| 1270 |
+
rho_k_omega_Learn_re.append( rhoSpec[0].cpu().numpy()/impulse )
|
| 1271 |
+
T_plus_k_omega_Learn_re.append( TSpec[0].cpu().numpy()/impulse )
|
| 1272 |
+
rho_k_omega_Learn_re = np.array(rho_k_omega_Learn_re)#*fft_omega_filter
|
| 1273 |
+
T_plus_k_omega_Learn_re = np.array(T_plus_k_omega_Learn_re)#*fft_omega_filter
|
| 1274 |
+
|
| 1275 |
+
|
| 1276 |
+
|
| 1277 |
+
|
| 1278 |
+
#T_plus_k_omega_Bol3_re = T_plus_k_omega_Bol3_re.at[k_traval < 1].set(T_plus_k_omega_NS_re[k_traval < 1])
|
| 1279 |
+
|
| 1280 |
+
|
| 1281 |
+
#for i in range(20,25):
|
| 1282 |
+
#plt.plot( rho_k_omega_Bol3_re[i], label = "Bol3")
|
| 1283 |
+
#plt.plot( rho_k_omega_NS_re[i], label = "NS")
|
| 1284 |
+
#plt.legend()
|
| 1285 |
+
#plt.show()
|
| 1286 |
+
# rho_k_omega_Bol3_re = rho_k_omega_Bol3_re.at[i].set(rho_k_omega_NS_re[i])
|
| 1287 |
+
#
|
| 1288 |
+
|
| 1289 |
+
# plt.plot( omega_mesh, rho_k_omega_Bol3_re[100], linewidth = 3, label = "Bol3")
|
| 1290 |
+
# plt.plot( omega_mesh, rho_k_omega_NS_re[100], label = "NS", linewidth = 1)
|
| 1291 |
+
# plt.plot( omega_mesh, rho_k_omega_Learn_re[100], label = "Learn", linewidth = 0.5)
|
| 1292 |
+
# plt.xlim(-30,30)
|
| 1293 |
+
# plt.legend()
|
| 1294 |
+
# plt.show()
|
| 1295 |
+
|
| 1296 |
+
rho0k = np.array( [ bump_fourier(0.5, kvalue, 0.02) for kvalue in k_traval] )
|
| 1297 |
+
v0k = np.zeros_like(rho0k)
|
| 1298 |
+
T0k = np.zeros_like(rho0k)
|
| 1299 |
+
# plt.plot( k_traval,rho0k, label = "NS")
|
| 1300 |
+
|
| 1301 |
+
# plt.show()
|
| 1302 |
+
time_travel = 2*np.pi*np.fft.fftfreq(len(omega_mesh), d = omega_mesh[1] - omega_mesh[0])
|
| 1303 |
+
SBT = pyNumSBT(k_traval.__array__())
|
| 1304 |
+
r_travel = SBT.kk
|
| 1305 |
+
rho0x = SBT.run(rho0k.__array__(), direction=1, norm=True)
|
| 1306 |
+
# plt.plot( r_travel, rho0x)
|
| 1307 |
+
# plt.xlim(0,2)
|
| 1308 |
+
# plt.show()
|
| 1309 |
+
'''
|
| 1310 |
+
r_travel = np.linspace( 0, np.pi/(k_traval[1] - k_traval[0]), len(k_traval) )
|
| 1311 |
+
|
| 1312 |
+
rho0x = inverse_transform(rho0k, k_traval, r_travel)
|
| 1313 |
+
plt.plot( r_travel, rho0x)
|
| 1314 |
+
plt.xlim(0,2)
|
| 1315 |
+
plt.show()
|
| 1316 |
+
'''
|
| 1317 |
+
|
| 1318 |
+
wavelength = 2*np.pi/k_traval*space_scale
|
| 1319 |
+
Kn_number = viscosity_coef/(density_0*wavelength)/np.sqrt(Boltz*Temp_0/molecule_mass)
|
| 1320 |
+
#rho_k_omega_re = np.array([compute_n_plus( None, 2*h_values_Res[i], u_mesh, u_weights)[...,0] for i in range(len(k_traval))])
|
| 1321 |
+
|
| 1322 |
+
#rho_k_omega_re = rho_k_omega_re.at[0].set(2*get_rhoRe(5e-2, omega_mesh))
|
| 1323 |
+
#plt.plot( omega_plt, rho_k_omega_re[0], label = "NS")
|
| 1324 |
+
#rhoRe = get_rhoRe(k_titla_freq[0], omega_mesh)
|
| 1325 |
+
#plt.plot(omega_plt,2*rhoRe)
|
| 1326 |
+
#plt.show()
|
| 1327 |
+
#plt.show()
|
| 1328 |
+
def time_evolution(rho_k_omega_re, rho0k, k_traval, omega_mesh):
|
| 1329 |
+
#print( rho0k )
|
| 1330 |
+
rho_k_omega_re = rho_k_omega_re * rho0k[:,np.newaxis] /(2*np.pi)**0.5
|
| 1331 |
+
rho_k_t = np.real( np.fft.ifft( np.fft.fftshift( rho_k_omega_re[:,:-1] , axes=-1) , axis = -1) ) / (2*np.pi)**0.5 * ( (omega_mesh[1] - omega_mesh[0]) * len(omega_mesh) )
|
| 1332 |
+
rho_k_values = k_traval
|
| 1333 |
+
SBT = pyNumSBT(k_traval.__array__())
|
| 1334 |
+
x_travel = SBT.kk
|
| 1335 |
+
#x_travel = np.linspace(0, np.pi/(k_traval[1] - k_traval[0]), len(k_traval) )
|
| 1336 |
+
rho_x_t = np.array( [SBT.run(rho_k_t[:,i].__array__(), direction=1, norm=True) for i in range( rho_k_t.shape[1] ) ] ).T
|
| 1337 |
+
#rho_x_t = np.array( [ inverse_transform(rho_k_t[:,i], k_traval, x_travel) for i in range( rho_k_t.shape[1] ) ] ).T
|
| 1338 |
+
time_travel = 2*np.pi*np.fft.fftfreq(len(omega_mesh), d = omega_mesh[1] - omega_mesh[0])
|
| 1339 |
+
return x_travel, time_travel, rho_x_t
|
| 1340 |
+
|
| 1341 |
+
x_travel, time_travel, rho_x_t_NS = time_evolution(rho_k_omega_NS_re, rho0k, k_traval, omega_mesh)
|
| 1342 |
+
x_travel, time_travel, rho_x_t_Bol3 = time_evolution(rho_k_omega_Bol3_re, rho0k, k_traval, omega_mesh)
|
| 1343 |
+
x_travel, time_travel, rho_x_t_Learn = time_evolution(rho_k_omega_Learn_re, rho0k, k_traval, omega_mesh)
|
| 1344 |
+
|
| 1345 |
+
x_travel, time_travel, v_x_t_NS = time_evolution(v_plus_k_omega_NS_re, rho0k, k_traval, omega_mesh)
|
| 1346 |
+
x_travel, time_travel, v_x_t_Bol3 = time_evolution(v_plus_k_omega_Bol3_re, rho0k, k_traval, omega_mesh)
|
| 1347 |
+
|
| 1348 |
+
x_travel, time_travel, T_x_t_NS = time_evolution(T_plus_k_omega_NS_re, rho0k, k_traval, omega_mesh)
|
| 1349 |
+
x_travel, time_travel, T_x_t_Bol3 = time_evolution(T_plus_k_omega_Bol3_re, rho0k, k_traval, omega_mesh)
|
| 1350 |
+
x_travel, time_travel, T_x_t_Learn = time_evolution(T_plus_k_omega_Learn_re, rho0k, k_traval, omega_mesh)
|
| 1351 |
+
|
| 1352 |
+
# plot the time evolution in 2 x 2 grid
|
| 1353 |
+
tplots = [0.0, 0.2, 0.4]
|
| 1354 |
+
fig, axs = plt.subplots(len(tplots)+1, 2, figsize=(8, 2.5*(len(tplots)+1)), dpi=200)
|
| 1355 |
+
for i,time in enumerate([0.0, 0.2, 0.4]):
|
| 1356 |
+
time_index = np.argmin(np.abs(time_travel - time))
|
| 1357 |
+
# +1 here is to add reference rho and T back to the perturbation value
|
| 1358 |
+
axs[i, 0].plot(x_travel, rho_x_t_Bol3[:, time_index]+1, label = "SBGK t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1359 |
+
axs[i, 0].plot(x_travel, rho_x_t_NS[:, time_index]+1, linestyle = 'dotted', label = "NS t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1360 |
+
axs[i, 0].plot(x_travel, rho_x_t_Learn[:, time_index]+1, linestyle = 'dashed', label = "Learn t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1361 |
+
axs[i, 0].set_title("Density")
|
| 1362 |
+
axs[i, 0].legend()
|
| 1363 |
+
axs[i, 0].set_xlim(0, 1)
|
| 1364 |
+
axs[i, 0].set_ylim(1-0.1, 1+2.1)
|
| 1365 |
+
axs[i, 0].set_xlabel("r")
|
| 1366 |
+
axs[i, 0].set_ylabel("ρ")
|
| 1367 |
+
axs[i, 1].plot(x_travel, T_x_t_Bol3[:, time_index]+1, label = "SBGK t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1368 |
+
axs[i, 1].plot(x_travel, T_x_t_NS[:, time_index]+1, linestyle = 'dotted', label = "NS t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1369 |
+
axs[i, 1].plot(x_travel, T_x_t_Learn[:, time_index]+1, linestyle = 'dashed', label = "Learn t=" + "{:.2f}".format( time_travel[ time_index ] ) , linewidth = 2)
|
| 1370 |
+
axs[i, 1].set_title("Temperature")
|
| 1371 |
+
axs[i, 1].legend()
|
| 1372 |
+
axs[i, 1].set_xlim(0, 1)
|
| 1373 |
+
axs[i, 1].set_ylim(1-1, 1+0.2)
|
| 1374 |
+
axs[i, 1].set_xlabel("r")
|
| 1375 |
+
axs[i, 1].set_ylabel("T")
|
| 1376 |
+
#axs[0, 1].set_title("Velocity")
|
| 1377 |
+
|
| 1378 |
+
axs[i+1, 0].plot( Kn_number,rho0k, label = "t=0.00")
|
| 1379 |
+
axs[i+1, 0].set_xlim(0,0.5)
|
| 1380 |
+
axs[i+1, 0].set_xlabel("Kn")
|
| 1381 |
+
axs[i+1, 0].set_ylabel("ρ")
|
| 1382 |
+
axs[i+1, 0].set_title("Initial Density (Fourier Space)")
|
| 1383 |
+
axs[i+1, 0].legend()
|
| 1384 |
+
axs[i+1, 1].plot( Kn_number,rho0k, label = "t=0.00")
|
| 1385 |
+
axs[i+1, 1].set_xlim(0.5,2)
|
| 1386 |
+
axs[i+1, 1].set_ylim(-0.001,0.001)
|
| 1387 |
+
axs[i+1, 1].set_xlabel("Kn")
|
| 1388 |
+
axs[i+1, 1].set_ylabel("ρ")
|
| 1389 |
+
from matplotlib.ticker import FormatStrFormatter
|
| 1390 |
+
axs[i+1, 1].xaxis.set_major_formatter(FormatStrFormatter('%.2f'))
|
| 1391 |
+
axs[i+1, 1].yaxis.set_major_formatter(FormatStrFormatter('%.3f'))
|
| 1392 |
+
axs[i+1, 1].set_title("Initial Density (Fourier Space)")
|
| 1393 |
+
axs[i+1, 1].legend()
|
| 1394 |
+
fig.tight_layout()
|
| 1395 |
+
|
| 1396 |
+
fig.savefig("dynamics.png", dpi=200)
|
| 1397 |
+
|
| 1398 |
+
|
| 1399 |
+
|
| 1400 |
+
|
| 1401 |
+
def CE_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k):
|
| 1402 |
+
m = molecule_mass
|
| 1403 |
+
mu1 = 0
|
| 1404 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 1405 |
+
mu2 = -4/3*Kn
|
| 1406 |
+
mu3 = 0
|
| 1407 |
+
kap1 = 0
|
| 1408 |
+
kap2 = 0
|
| 1409 |
+
kap3 = -15/4*Kn
|
| 1410 |
+
kabs = np.abs(k)
|
| 1411 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 1412 |
+
tau2 = kabs**2*mu2
|
| 1413 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 1414 |
+
tau4 = 2/3*kabs**2*kap1
|
| 1415 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 1416 |
+
tau6 = 2/3*kabs**2*kap3
|
| 1417 |
+
omega = omega_freq
|
| 1418 |
+
Neff = num_effect
|
| 1419 |
+
rho0 = density_0
|
| 1420 |
+
L = delta_x
|
| 1421 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 1422 |
+
return spec
|
| 1423 |
+
#m = molecule_mass*num_effect/(4*np.pi**2*wavelength**3)
|
| 1424 |
+
#spec = -((complex(0,1)*m*(-4*k**2-20*k**4*Kn**2-23*complex(0,1)*k**2*Kn*omega_freq+6*omega_freq**2))/(density_0*(15*complex(0,1)*k**4*Kn-10*k**2*omega_freq-20*k**4*Kn**2*omega_freq-23*complex(0,1)*k**2*Kn*omega_freq**2+6*omega_freq**3)))
|
| 1425 |
+
#return 2*np.real(spec)
|
| 1426 |
+
def R13_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k):
|
| 1427 |
+
m = molecule_mass
|
| 1428 |
+
mu1 = 0
|
| 1429 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 1430 |
+
mu2 = -4/3*Kn
|
| 1431 |
+
mu3 = 0
|
| 1432 |
+
kap1 = 0
|
| 1433 |
+
kap2 = 0
|
| 1434 |
+
kap3 = -15/4*Kn
|
| 1435 |
+
kabs = np.abs(k)
|
| 1436 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 1437 |
+
tau2 = kabs**2*mu2
|
| 1438 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 1439 |
+
tau4 = 2/3*kabs**2*kap1
|
| 1440 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 1441 |
+
tau6 = 2/3*kabs**2*kap3
|
| 1442 |
+
omega = omega_freq
|
| 1443 |
+
Neff = num_effect
|
| 1444 |
+
rho0 = density_0
|
| 1445 |
+
L = delta_x
|
| 1446 |
+
spec = 2*(15*k**4*Kn*m*Neff*(5*k**2*(5+6*k**2*Kn**2)*(25+210*k**2*Kn**2+162*k**4*Kn**4)+(500+5775*k**2*Kn**2+29295*k**4*Kn**4+17496*k**6*Kn**6)*omega**2+225*Kn**2*(5+6*k**2*Kn**2)*omega**4))/(L**3*np.pi**2*density_0*(5625*k**8*Kn**2*(5+6*k**2*Kn**2)**2+25*k**4*(2500+3*k**2*Kn**2*(3500+35175*k**2*Kn**2+60480*k**4*Kn**4+34992*k**6*Kn**6))*omega**2-30*k**2*(2500+3*k**2*Kn**2*(625+20850*k**2*Kn**2-6030*k**4*Kn**4+34992*k**6*Kn**6))*omega**4+18*(1250-7750*k**2*Kn**2+50775*k**4*Kn**4-125820*k**6*Kn**6+52488*k**8*Kn**8)*omega**6+1125*Kn**2*(65+72*k**2*Kn**2*(-2+9*k**2*Kn**2))*omega**8+50625*Kn**4*omega**10))
|
| 1447 |
+
return spec
|
| 1448 |
+
def TH_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k, mask = -1):
|
| 1449 |
+
m = molecule_mass
|
| 1450 |
+
mu1 = 0
|
| 1451 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 1452 |
+
mu2 = -4/3*Kn
|
| 1453 |
+
mu3 = 0
|
| 1454 |
+
kap1 = 0
|
| 1455 |
+
kap2 = 0
|
| 1456 |
+
kap3 = -15/4*Kn
|
| 1457 |
+
kabs = np.abs(k)
|
| 1458 |
+
print(kabs)
|
| 1459 |
+
tau1 = -0.910858854965221635639183580413607*kabs-0.0681031747662745635208073664825305*kabs**2
|
| 1460 |
+
tau2 = -0.137647159761080650249789096758410*kabs**2+0.00258989586650062128792005410176610*kabs**3
|
| 1461 |
+
tau3 = -0.980736834542179305331651160476348*kabs+0.002878781203443508188808986885745442*kabs**3
|
| 1462 |
+
tau4 = 0.00270043719488066581208735095210*kabs**2-0.000956430940350492874510704526398*kabs**3+0.0000398354558076273539332410866928*kabs**4
|
| 1463 |
+
#tau4 = 2/3*kabs**2*kap1
|
| 1464 |
+
tau5 = -0.677006693600986515897927777975082*kabs-0.02720695551116714037510321445687466*kabs**2
|
| 1465 |
+
tau6 = -0.248523533056964259160237397019776*kabs**2+0.00978711916205478871774188307120469*kabs**3
|
| 1466 |
+
|
| 1467 |
+
|
| 1468 |
+
if mask == 0:
|
| 1469 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 1470 |
+
elif mask == 1:
|
| 1471 |
+
tau2 = kabs**2*mu2
|
| 1472 |
+
elif mask == 2:
|
| 1473 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 1474 |
+
elif mask == 3:
|
| 1475 |
+
tau4 = 2/3*kabs**2*kap1
|
| 1476 |
+
elif mask == 4:
|
| 1477 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 1478 |
+
elif mask == 5:
|
| 1479 |
+
tau6 = 2/3*kabs**2*kap3
|
| 1480 |
+
omega = omega_freq
|
| 1481 |
+
Neff = num_effect
|
| 1482 |
+
rho0 = density_0
|
| 1483 |
+
L = delta_x
|
| 1484 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 1485 |
+
return spec
|
| 1486 |
+
|
| 1487 |
+
def THBGK_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k, mask = -1):
|
| 1488 |
+
m = molecule_mass
|
| 1489 |
+
mu1 = 0
|
| 1490 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 1491 |
+
mu2 = -4/3*Kn
|
| 1492 |
+
mu3 = 0
|
| 1493 |
+
kap1 = 0
|
| 1494 |
+
kap2 = 0
|
| 1495 |
+
kap3 = -15/4*Kn
|
| 1496 |
+
kabs = np.abs(k)
|
| 1497 |
+
print(kabs)
|
| 1498 |
+
#tau1 = -0.910858854965221635639183580413607*kabs-0.0681031747662745635208073664825305*kabs**2
|
| 1499 |
+
#tau1 = -0.9858867248408030*kabs-0.04701941111476196*kabs**2
|
| 1500 |
+
tau1 = -0.991013044792487766036126122635640*kabs-0.0403239332346867445520412638803096*kabs**2-0.002166184469076816223924007295632155*kabs**3
|
| 1501 |
+
#tau2 = -0.137647159761080650249789096758410*kabs**2+0.00258989586650062128792005410176610*kabs**3
|
| 1502 |
+
#tau2 = -0.129198118429724*kabs**2+0.00400848955369925*kabs**3
|
| 1503 |
+
tau2 = -0.149161289391781081302603295336010*kabs**2 + 0.00594195008578441066220857129869587*kabs**3 - 0.000232348591684703766188347436129974*kabs**4
|
| 1504 |
+
#tau3 = -0.980736834542179305331651160476348*kabs+0.002878781203443508188808986885745442*kabs**3
|
| 1505 |
+
#tau3 = -1.002964233770220*kabs-0.0000911571759799050*kabs**3
|
| 1506 |
+
tau3 = -1.064641200298265511954132389066412*kabs + 0.02791589569574715853735528833289102*kabs**2 + 0.000762400543447067776385421347639320*kabs**3
|
| 1507 |
+
#tau4 = 0.00270043719488066581208735095210*kabs**2-0.000956430940350492874510704526398*kabs**3+0.0000398354558076273539332410866928*kabs**4
|
| 1508 |
+
#tau4 = -0.0084451424529939*kabs**2-0.00060032464997635*kabs**3+0.000017125859875981*kabs**4
|
| 1509 |
+
tau4 = 0.00270043719488066581208735095210*kabs**2 - 0.000956430940350492874510704526398*kabs**3 + 0.0000398354558076273539332410866928*kabs**4
|
| 1510 |
+
#tau4 = 2/3*kabs**2*kap1
|
| 1511 |
+
#tau5 = -0.677006693600986515897927777975082*kabs-0.02720695551116714037510321445687466*kabs**2
|
| 1512 |
+
#tau5 = -0.677965329349480*kabs-0.002348308957845470*kabs**2
|
| 1513 |
+
tau5 = -0.664300463755129273501867308536487*kabs - 0.0316105859215623339424006394153918*kabs^2 + 0.000343388633980720341529015301083001*kabs^3
|
| 1514 |
+
#tau6 = -0.248523533056964259160237397019776*kabs**2+0.00978711916205478871774188307120469*kabs**3
|
| 1515 |
+
#tau6 = -0.185259190536085*kabs**2+0.0068634125525231*kabs**3
|
| 1516 |
+
tau6 = -0.280753259910037449250341065089074*kabs^2 + 0.0191700074349251339913376848978025*kabs^3 - 0.000650377569549622175919978516795108*kabs^4
|
| 1517 |
+
|
| 1518 |
+
|
| 1519 |
+
if mask == 0:
|
| 1520 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 1521 |
+
elif mask == 1:
|
| 1522 |
+
tau2 = kabs**2*mu2
|
| 1523 |
+
elif mask == 2:
|
| 1524 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 1525 |
+
elif mask == 3:
|
| 1526 |
+
tau4 = 2/3*kabs**2*kap1
|
| 1527 |
+
elif mask == 4:
|
| 1528 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 1529 |
+
elif mask == 5:
|
| 1530 |
+
tau6 = 2/3*kabs**2*kap3
|
| 1531 |
+
omega = omega_freq
|
| 1532 |
+
Neff = num_effect
|
| 1533 |
+
rho0 = density_0
|
| 1534 |
+
L = delta_x
|
| 1535 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 1536 |
+
return spec
|
| 1537 |
+
def MW_spectra(delta_x,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,omega_freq,num_effect,k):
|
| 1538 |
+
m = molecule_mass
|
| 1539 |
+
mu1 = 0
|
| 1540 |
+
Kn = np.sqrt(molecule_mass/(Boltz*Temp_0))*viscosity_coef/density_0/delta_x
|
| 1541 |
+
mu2 = -4/3*Kn
|
| 1542 |
+
mu3 = 0
|
| 1543 |
+
kap1 = 0
|
| 1544 |
+
kap2 = 0
|
| 1545 |
+
kap3 = -15/4*Kn
|
| 1546 |
+
kabs = np.abs(k)
|
| 1547 |
+
tau1 = -kabs*(1-kabs**2*mu1)
|
| 1548 |
+
tau2 = kabs**2*mu2
|
| 1549 |
+
tau3 = -kabs*(1-kabs**2*mu3)
|
| 1550 |
+
tau4 = 2/3*kabs**2*kap1
|
| 1551 |
+
tau5 = -2/3*kabs*(1+kap2)
|
| 1552 |
+
tau6 = 2/3*kabs**2*kap3
|
| 1553 |
+
omega = omega_freq
|
| 1554 |
+
Neff = num_effect
|
| 1555 |
+
rho0 = density_0
|
| 1556 |
+
L = delta_x
|
| 1557 |
+
spec = (k*m*Neff*(-(tau3*tau4-tau1*tau6)*(tau3*tau5+tau2*tau6)+(tau1*tau2+tau3*tau4)*omega**2))/(2*L**3*np.pi**2*rho0*(k**2*(tau3*tau4-tau1*tau6)**2+(k**2*tau1**2+(tau3*tau5+tau2*tau6)**2-2*k*(tau2*tau3*tau4+tau1*tau3*tau5+tau3*tau4*tau6-tau1*tau6**2))*omega**2+(2*k*tau1+tau2**2-2*tau3*tau5+tau6**2)*omega**4+omega**6))
|
| 1558 |
+
return spec
|
| 1559 |
+
#m = molecule_mass*num_effect/(4*np.pi**2*wavelength**3)
|
| 1560 |
+
#spec = -((complex(0,1)*m*(-4*k**2-20*k**4*Kn**2-23*complex(0,1)*k**2*Kn*omega_freq+6*omega_freq**2))/(density_0*(15*complex(0,1)*k**4*Kn-10*k**2*omega_freq-20*k**4*Kn**2*omega_freq-23*complex(0,1)*k**2*Kn*omega_freq**2+6*omega_freq**3)))
|
| 1561 |
+
#return 2*np.real(spec)
|
| 1562 |
+
|
| 1563 |
+
|
| 1564 |
+
|
| 1565 |
+
|
| 1566 |
+
|
| 1567 |
+
|
| 1568 |
+
wavelength = 2*np.pi/k_traval*space_scale
|
| 1569 |
+
Kn_number = viscosity_coef/(density_0*wavelength)/np.sqrt(Boltz*Temp_0/molecule_mass)
|
| 1570 |
+
Kn_number
|
| 1571 |
+
|
| 1572 |
+
plt_grid = (2, 3)
|
| 1573 |
+
|
| 1574 |
+
fig, axs = plt.subplots(2, 3, figsize=(14, 8), dpi = 200)
|
| 1575 |
+
for i, kn_plot in enumerate( [0.01511645, 0.04534935, 0.10116449, 0.63489085, 2.51188643, 10. ] ):
|
| 1576 |
+
ind = np.argmin( np.abs(Kn_number - kn_plot) )
|
| 1577 |
+
k_plot = k_traval[ind]
|
| 1578 |
+
axs[i//plt_grid[1], i%plt_grid[1]].plot(macro_values[ind][0]/(k_plot*(5/3)**0.5), impulse*2*macro_values[ind][1][...,0], label = "SBGK (ref)")
|
| 1579 |
+
axs[i//plt_grid[1], i%plt_grid[1]].plot(macro_values[ind][0]/(k_plot*(5/3)**0.5), impulse*2*get_rhoRe(k_traval[ind], macro_values[ind][0]), label = "NS", linestyle = 'dotted')
|
| 1580 |
+
axs[i//plt_grid[1], i%plt_grid[1]].plot(macro_values[ind][0]/(k_plot*(5/3)**0.5) , R13_spectra(space_scale,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,macro_values[ind][0],num_effect,k_plot) , label = "R13 Equation", linestyle = 'dashed')
|
| 1581 |
+
|
| 1582 |
+
with torch.no_grad():
|
| 1583 |
+
net_spectra, net_spectra_omega, _, rhoSpec, vSpec, TSpec,_ = sNet(torch.tensor( nnp.array( k_plot ), device = device, dtype = dtype), torch.tensor( nnp.array(macro_values[ind][0][None,:]/(k_plot *(5/3)**0.5) ), device = device, dtype = dtype))
|
| 1584 |
+
net_spectra = net_spectra.cpu().numpy()
|
| 1585 |
+
net_spectra_omega = net_spectra_omega.cpu().numpy()
|
| 1586 |
+
axs[i//plt_grid[1], i%plt_grid[1]].plot(net_spectra_omega[0] , net_spectra[0], label = "Learned")
|
| 1587 |
+
|
| 1588 |
+
if k_plot < 50:
|
| 1589 |
+
k_number = np.argmin( np.abs(k_titla_freq - k_plot) )
|
| 1590 |
+
omega_plot = np.fft.fftshift(omega_freq)/(kx_freq[k_number]*speed_of_sound)
|
| 1591 |
+
omega_spacing = np.mean( omega_plot[1:]-omega_plot[:-1] )
|
| 1592 |
+
plot_spectra = np.fft.fftshift( spectra[:,k_number])/space_scale**3/time_scale
|
| 1593 |
+
b, a = signal.butter(1, 20, fs = 1/omega_spacing)
|
| 1594 |
+
filtered_spectra = signal.filtfilt(b, a, plot_spectra)
|
| 1595 |
+
axs[i//plt_grid[1], i%plt_grid[1]].plot(omega_plot , filtered_spectra, label = "DSMC (ref)")
|
| 1596 |
+
if k_plot < 13:
|
| 1597 |
+
#axs[i//plt_grid[1], i%plt_grid[1]].plot(macro_values[ind][0]/(k_plot*(5/3)**0.5) , TH_spectra(space_scale,viscosity_coef,Boltz,Temp_0,molecule_mass,density_0,macro_values[ind][0],num_effect,k_plot) , label = "Hydro Manifold")
|
| 1598 |
+
pass
|
| 1599 |
+
|
| 1600 |
+
|
| 1601 |
+
axs[i//plt_grid[1], i%plt_grid[1]].set_xlim(0,2)
|
| 1602 |
+
axs[i//plt_grid[1], i%plt_grid[1]].set_title("Kn = " + "{:.2f}".format(Kn_number[ind]))
|
| 1603 |
+
axs[i//plt_grid[1], i%plt_grid[1]].set_xlabel("ω")
|
| 1604 |
+
axs[i//plt_grid[1], i%plt_grid[1]].set_ylabel("$<ρ^2>$")
|
| 1605 |
+
axs[i//plt_grid[1], i%plt_grid[1]].legend()
|
| 1606 |
+
# adjust the space between the plots
|
| 1607 |
+
plt.tight_layout()
|
| 1608 |
+
fig.savefig("spectra.png", dpi=200)
|
| 1609 |
+
|
| 1610 |
+
|
| 1611 |
+
|
| 1612 |
+
#rho_k_omega_re = ( np.flip(rho_k_omega_re,axis=-1) + rho_k_omega_re )/2
|
dynamics.png
ADDED
|
Git LFS Details
|
requirements.txt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
jax
|
| 2 |
+
jaxlib
|
| 3 |
+
numpy
|
| 4 |
+
scipy
|
| 5 |
+
matplotlib
|
| 6 |
+
ipython
|
| 7 |
+
jaxopt
|
| 8 |
+
tqdm
|
| 9 |
+
torch
|
spectra.png
ADDED
|
Git LFS Details
|