├── .codecov.yml ├── .environment.yaml ├── .flake8 ├── .git-blame-ignore-revs ├── .github └── workflows │ ├── black.yml │ ├── docker_publish.yml │ ├── draft-pdf.yml │ ├── flake8.yml │ ├── python_publish.yml │ └── tests.yml ├── .gitignore ├── .readthedocs.yaml ├── CHANGELOG.md ├── CITATION.cff ├── Dockerfile ├── LICENSE ├── README.md ├── docs ├── Makefile ├── _templates │ ├── custom-class-template.rst │ └── custom-module-template.rst ├── api.rst ├── conf.py ├── developer_guide │ ├── contributing_guide.rst │ └── writing_docs.rst ├── examples │ ├── bicoherence.rst │ ├── example.py │ ├── example_JETTO.py │ ├── example_JETTO_1dscan.py │ ├── example_JETTO_1dscan_complicated.py │ ├── example_PFILE.py │ ├── example_SCENE.py │ ├── example_TRANSP.py │ ├── example_add_bespoke_gk_output_data.py │ ├── example_addflags.py │ ├── example_cgyro.py │ ├── example_gene.py │ ├── example_generate_global_profiles.py │ ├── example_geqdsk.py │ ├── example_gs2.py │ ├── example_gx.py │ ├── example_ideal_ballooning.py │ ├── example_imas.py │ ├── example_merge_species.py │ ├── example_modify_shear.py │ ├── example_neoclassical.py │ ├── example_nonlinear_cgyro.py │ ├── example_poincare.py │ ├── example_pyro.py │ ├── example_pyroscan_to_netcdf.py │ ├── example_read_cgyro_output.py │ ├── example_read_gene_output.py │ ├── example_read_gs2_output.py │ ├── example_read_pyroscan_output.py │ ├── example_read_tglf_linear.py │ ├── example_read_tglf_transport.py │ ├── example_real_space_moment.py │ ├── example_saturation.py │ ├── example_syn_hk_dbs.py │ ├── figures │ │ ├── .DS_Store │ │ └── ideal_ballooning.png │ ├── ideal_ballooning.rst │ ├── index.rst │ ├── load_jetto.rst │ ├── load_transp.rst │ ├── parameter_scan.rst │ ├── pyro_example.rst │ └── read_output.rst ├── howtos │ ├── convert.rst │ ├── figures │ │ ├── CGYRO_ky_flux_spectrum.png │ │ ├── CGYRO_phi_kxky.png │ │ ├── CGYRO_total_heat_timetrace.png │ │ ├── GS2_eigenfunction_plot.png │ │ ├── GS2_ion_linear_flux_plot.png │ │ ├── GS2_linear_phi_field_plot.png │ │ ├── GS2_mode_frequency_plot.png │ │ └── jet_example_scatloc.png │ ├── index.rst │ ├── linear_outputs.rst │ ├── merge_species.rst │ ├── normalisations.rst │ ├── parameter_scans.rst │ ├── read_eq_prof.rst │ ├── read_nonlinear_data.rst │ └── syn_hkdbs.rst ├── index.rst ├── joss │ ├── paper.bib │ └── paper.md ├── make.bat ├── tutorials │ ├── equilibrium.rst │ ├── figures │ │ ├── equilibrium_composite_plot.png │ │ ├── equilibrium_contour_plot.png │ │ ├── equilibrium_q_plot.png │ │ ├── flux_surface_b_poloidal_plot.png │ │ └── flux_surface_path_plot.png │ ├── file_readers.rst │ ├── index.rst │ └── using_pyrokinetics_on_hpc_systems.rst └── user_guide │ ├── analysis.rst │ ├── collisions.rst │ ├── figures │ ├── equilibrium.png │ ├── gk_code.png │ ├── kinetics.png │ └── pyro_structure.png │ ├── getting_started.rst │ ├── index.rst │ ├── metric_terms.rst │ ├── miller.rst │ ├── modify_shear.rst │ └── structure.rst ├── pyproject.toml ├── src └── pyrokinetics │ ├── __init__.py │ ├── __main__.py │ ├── cli │ ├── __init__.py │ ├── convert.py │ ├── entrypoint.py │ └── generate.py │ ├── constants.py │ ├── databases │ ├── __init__.py │ └── imas.py │ ├── dataset_wrapper.py │ ├── decorators.py │ ├── diagnostics │ ├── __init__.py │ ├── neoclassical.py │ ├── saturation_rules.py │ └── synthetic_highk_dbs.py │ ├── equilibrium │ ├── __init__.py │ ├── eliteinp.py │ ├── equilibrium.py │ ├── flux_surface.py │ ├── gacode.py │ ├── geqdsk.py │ ├── imas.py │ ├── transp.py │ └── utils.py │ ├── factory.py │ ├── file_utils.py │ ├── gk_code │ ├── __init__.py │ ├── cgyro.py │ ├── gene.py │ ├── gk_input.py │ ├── gk_output.py │ ├── gkw.py │ ├── gs2.py │ ├── gx.py │ ├── ids.py │ ├── stella.py │ └── tglf.py │ ├── kinetics │ ├── __init__.py │ ├── eliteinp.py │ ├── gacode.py │ ├── imas.py │ ├── jetto.py │ ├── kinetics.py │ ├── pfile.py │ ├── scene.py │ └── transp.py │ ├── local_geometry │ ├── __init__.py │ ├── fourier_cgyro.py │ ├── fourier_gene.py │ ├── local_geometry.py │ ├── metric.py │ ├── miller.py │ ├── miller_turnbull.py │ └── mxh.py │ ├── local_species.py │ ├── metadata.py │ ├── normalisation.py │ ├── numerics.py │ ├── plugins.py │ ├── pyro.py │ ├── pyroscan.py │ ├── species.py │ ├── templates.py │ ├── templates │ ├── core_profiles.h5 │ ├── equilibrium.h5 │ ├── input.cgyro │ ├── input.gacode │ ├── input.gene │ ├── input.gkw │ ├── input.gs2 │ ├── input.gx │ ├── input.stella │ ├── input.stella_nl │ ├── input.tglf │ ├── jetto.jsp │ ├── jetto.jss │ ├── outputs │ │ ├── CGYRO_linear │ │ │ ├── bin.cgyro.geo │ │ │ ├── bin.cgyro.kxky_phi │ │ │ ├── bin.cgyro.ky_cflux │ │ │ ├── bin.cgyro.ky_flux │ │ │ ├── bin.cgyro.phib │ │ │ ├── input.cgyro │ │ │ ├── out.cgyro.equilibrium │ │ │ ├── out.cgyro.freq │ │ │ ├── out.cgyro.grids │ │ │ └── out.cgyro.time │ │ ├── CGYRO_linear_scan │ │ │ ├── input.cgyro │ │ │ ├── ky_0.10 │ │ │ │ ├── bin.cgyro.geo │ │ │ │ ├── bin.cgyro.kxky_phi │ │ │ │ ├── bin.cgyro.ky_cflux │ │ │ │ ├── bin.cgyro.ky_flux │ │ │ │ ├── bin.cgyro.phib │ │ │ │ ├── input.cgyro │ │ │ │ ├── out.cgyro.equilibrium │ │ │ │ ├── out.cgyro.freq │ │ │ │ ├── out.cgyro.grids │ │ │ │ └── out.cgyro.time │ │ │ ├── ky_0.20 │ │ │ │ ├── bin.cgyro.geo │ │ │ │ ├── bin.cgyro.kxky_phi │ │ │ │ ├── bin.cgyro.ky_cflux │ │ │ │ ├── bin.cgyro.ky_flux │ │ │ │ ├── bin.cgyro.phib │ │ │ │ ├── input.cgyro │ │ │ │ ├── out.cgyro.equilibrium │ │ │ │ ├── out.cgyro.freq │ │ │ │ ├── out.cgyro.grids │ │ │ │ └── out.cgyro.time │ │ │ └── ky_0.30 │ │ │ │ ├── bin.cgyro.geo │ │ │ │ ├── bin.cgyro.kxky_phi │ │ │ │ ├── bin.cgyro.ky_cflux │ │ │ │ ├── bin.cgyro.ky_flux │ │ │ │ ├── bin.cgyro.phib │ │ │ │ ├── input.cgyro │ │ │ │ ├── out.cgyro.equilibrium │ │ │ │ ├── out.cgyro.freq │ │ │ │ ├── out.cgyro.grids │ │ │ │ └── out.cgyro.time │ │ ├── CGYRO_nonlinear │ │ │ ├── bin.cgyro.freq │ │ │ ├── bin.cgyro.geo │ │ │ ├── bin.cgyro.kxky_apar │ │ │ ├── bin.cgyro.kxky_bpar │ │ │ ├── bin.cgyro.kxky_e │ │ │ ├── bin.cgyro.kxky_n │ │ │ ├── bin.cgyro.kxky_phi │ │ │ ├── bin.cgyro.kxky_v │ │ │ ├── bin.cgyro.ky_flux │ │ │ ├── input.cgyro │ │ │ ├── out.cgyro.equilibrium │ │ │ ├── out.cgyro.grids │ │ │ └── out.cgyro.time │ │ ├── GENE_linear │ │ │ ├── field_0001 │ │ │ ├── miller_0001 │ │ │ ├── mom_electron_0001 │ │ │ ├── mom_ion_0001 │ │ │ ├── nrg_0001 │ │ │ ├── omega_0001 │ │ │ └── parameters_0001 │ │ ├── GKW_linear │ │ │ └── GKW_linear.zip │ │ ├── GS2_linear │ │ │ ├── gs2.in │ │ │ └── gs2.out.nc │ │ ├── GX_linear │ │ │ ├── gx.big.nc │ │ │ ├── gx.in │ │ │ └── gx.out.nc │ │ ├── STELLA_linear │ │ │ ├── stella.final_fields │ │ │ ├── stella.fluxes │ │ │ ├── stella.geometry │ │ │ ├── stella.in │ │ │ ├── stella.omega │ │ │ ├── stella.out │ │ │ ├── stella.out.nc │ │ │ └── stella.species.input │ │ ├── TGLF_linear │ │ │ ├── input.tglf │ │ │ ├── input.tglf.gen │ │ │ ├── out.tglf.globaldump │ │ │ ├── out.tglf.prec │ │ │ ├── out.tglf.run │ │ │ ├── out.tglf.version │ │ │ └── out.tglf.wavefunction │ │ └── TGLF_transport │ │ │ ├── input.tglf │ │ │ ├── input.tglf.gen │ │ │ ├── out.tglf.QL_flux_spectrum │ │ │ ├── out.tglf.ave_p0_spectrum │ │ │ ├── out.tglf.density_spectrum │ │ │ ├── out.tglf.eigenvalue_spectrum │ │ │ ├── out.tglf.field_spectrum │ │ │ ├── out.tglf.gbflux │ │ │ ├── out.tglf.globaldump │ │ │ ├── out.tglf.grid │ │ │ ├── out.tglf.intensity_spectrum │ │ │ ├── out.tglf.ky_spectrum │ │ │ ├── out.tglf.nete_crossphase_spectrum │ │ │ ├── out.tglf.nsts_crossphase_spectrum │ │ │ ├── out.tglf.prec │ │ │ ├── out.tglf.run │ │ │ ├── out.tglf.scalar_saturation_parameters │ │ │ ├── out.tglf.spectral_shift_spectrum │ │ │ ├── out.tglf.sum_flux_spectrum │ │ │ ├── out.tglf.temperature_spectrum │ │ │ ├── out.tglf.version │ │ │ ├── out.tglf.width_spectrum │ │ │ └── regress │ ├── pfile.txt │ ├── reverse_ipbt.geqdsk │ ├── scene.cdf │ ├── step.geqdsk │ ├── test.eliteinp │ ├── test.geqdsk │ ├── transp.cdf │ └── transp_eq.geqdsk │ ├── typing.py │ └── units.py └── tests ├── cli └── test_convert.py ├── conftest.py ├── databases ├── golden_answers │ ├── Apa_kykxs00000135_imag_sp │ ├── Apa_kykxs00000135_real_sp │ ├── Bpa_kykxs00000135_imag_sp │ ├── Bpa_kykxs00000135_real_sp │ ├── Phi_kykxs00000135_imag_sp │ ├── Phi_kykxs00000135_real_sp │ ├── Tpar_kykxs01_000135_imag_sp │ ├── Tpar_kykxs01_000135_real_sp │ ├── Tpar_kykxs02_000135_imag_sp │ ├── Tpar_kykxs02_000135_real_sp │ ├── Tperp_kykxs01_000135_imag_sp │ ├── Tperp_kykxs01_000135_real_sp │ ├── Tperp_kykxs02_000135_imag_sp │ ├── Tperp_kykxs02_000135_real_sp │ ├── dens_kykxs01_000135_imag_sp │ ├── dens_kykxs01_000135_real_sp │ ├── dens_kykxs02_000135_imag_sp │ ├── dens_kykxs02_000135_real_sp │ ├── file_count │ ├── fluxes.dat │ ├── fluxes_bpar.dat │ ├── fluxes_em.dat │ ├── geom.dat │ ├── imas_example.h5 │ ├── input.dat │ ├── input.out │ ├── krho │ ├── kxrh │ ├── parallel.dat │ ├── time.dat │ ├── vpar_kykxs01_000135_imag_sp │ ├── vpar_kykxs01_000135_real_sp │ ├── vpar_kykxs02_000135_imag_sp │ └── vpar_kykxs02_000135_real_sp └── test_imas.py ├── diagnostics ├── golden_answers │ ├── ideal_ball.npy │ └── poincare.npy ├── test_gs2_geometry.py ├── test_ideal_ball.py ├── test_neoclassical.py └── test_poincare.py ├── equilibrium ├── test_eliteinp.py ├── test_equilibrium.py ├── test_gacode.py ├── test_geqdsk.py ├── test_imas.py └── test_transp.py ├── gk_code ├── __init__.py ├── golden_answers │ ├── cgyro_linear_output_899a2cb8.netcdf4 │ ├── gene_linear_output_899a2cb8.netcdf4 │ ├── gkw_linear_output_899a2cb8.netcdf4 │ ├── gs2_linear_output_899a2cb8.netcdf4 │ ├── gx_linear_output_899a2cb8.netcdf4 │ ├── stella_linear_output_899a2cb8.netcdf4 │ └── tglf_linear_output_899a2cb8.netcdf4 ├── test_gk_code_output.py ├── test_gk_input_cgyro.py ├── test_gk_input_gene.py ├── test_gk_input_gkw.py ├── test_gk_input_gs2.py ├── test_gk_input_gx.py ├── test_gk_input_stella.py ├── test_gk_input_tglf.py ├── test_gk_output.py ├── test_gk_output_reader_cgyro.py ├── test_gk_output_reader_gene.py ├── test_gk_output_reader_gkw.py ├── test_gk_output_reader_gs2.py ├── test_gk_output_reader_gx.py ├── test_gk_output_reader_stella.py └── test_gk_output_reader_tglf.py ├── kinetics ├── test_kinetics.py ├── test_kinetics_reader_eliteinp.py ├── test_kinetics_reader_gacode.py ├── test_kinetics_reader_imas.py ├── test_kinetics_reader_jetto.py ├── test_kinetics_reader_pfile.py ├── test_kinetics_reader_scene.py └── test_kinetics_reader_transp.py ├── local_geometry ├── test_fourier.py ├── test_fourier_cgyro.py ├── test_local_geometry.py ├── test_local_geometry_factory.py ├── test_metric_terms.py ├── test_miller.py ├── test_miller_turnbull.py ├── test_mxh.py └── test_transp_cdf_vs_geqdsk.py ├── test_decorators.py ├── test_deepcopy.py ├── test_file_utils.py ├── test_local_species.py ├── test_normalisation.py ├── test_numerics.py ├── test_plugins.py ├── test_pyro.py ├── test_pyroscan.py ├── test_roundtrip.py └── test_species.py /.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: true 3 | 4 | coverage: 5 | status: 6 | project: 7 | default: 8 | target: 80% 9 | threshold: 1% 10 | -------------------------------------------------------------------------------- /.environment.yaml: -------------------------------------------------------------------------------- 1 | name: pyrokinetics 2 | channels: 3 | - conda-forge 4 | - defaults 5 | dependencies: 6 | - python=3.10 7 | - cmake 8 | - numpy 9 | - compilers 10 | - pygacode 11 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 160 3 | extend-ignore = E203, W503 4 | per-file-ignores = __init__.py:F401, E402 5 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Apply black 2 | dfa5cac7268ada9249d96262dd3bbd8a04866f3e 3 | 4 | # Apply dos2unix 5 | 0fd71813361824a01fbf2f22c8267777650bfef5 6 | -------------------------------------------------------------------------------- /.github/workflows/black.yml: -------------------------------------------------------------------------------- 1 | name: black 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**.py' 7 | pull_request: 8 | paths: 9 | - '**.py' 10 | 11 | defaults: 12 | run: 13 | shell: bash 14 | 15 | jobs: 16 | black: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | ref: ${{ github.head_ref }} 22 | - name: Setup Python 23 | uses: actions/setup-python@v5 24 | with: 25 | python-version: 3.x 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install black isort 30 | - name: Version 31 | run: | 32 | python --version 33 | black --version 34 | isort --version 35 | - name: Run black 36 | run: | 37 | black src tests 38 | - name: Run isort 39 | run: | 40 | isort src 41 | - uses: stefanzweifel/git-auto-commit-action@v4 42 | with: 43 | commit_message: "[skip ci] Apply black changes" 44 | -------------------------------------------------------------------------------- /.github/workflows/docker_publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker Image 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | release: 7 | types: [published] 8 | 9 | jobs: 10 | publish-docker: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | 18 | - name: Set up Docker Buildx 19 | uses: docker/setup-buildx-action@v3 20 | 21 | - name: Docker meta 22 | id: meta 23 | uses: docker/metadata-action@v4 24 | with: 25 | images: ghcr.io/pyro-kinetics/pyrokinetics 26 | 27 | - name: Log in to GHCR 28 | uses: docker/login-action@v2 29 | with: 30 | registry: ghcr.io 31 | username: ${{ secrets.GHCR_USERNAME }} 32 | password: ${{ secrets.GHCR_TOKEN }} 33 | 34 | - name: Build and push Docker image 35 | uses: docker/build-push-action@v5 36 | with: 37 | context: . 38 | push: ${{ github.event_name == 'release' }} 39 | tags: ${{ steps.meta.outputs.tags }} 40 | labels: ${{ steps.meta.outputs.labels }} 41 | build-args: SETUPTOOLS_SCM_PRETEND_VERSION=${{ github.ref_type == 'tag' && github.ref_name || '0.0.1' }} 42 | -------------------------------------------------------------------------------- /.github/workflows/draft-pdf.yml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | 3 | jobs: 4 | paper: 5 | runs-on: ubuntu-latest 6 | name: Paper Draft 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v4 10 | - name: Build draft PDF 11 | uses: openjournals/openjournals-draft-action@master 12 | with: 13 | journal: joss 14 | # This should be the path to the paper within your repo. 15 | paper-path: docs/joss/paper.md 16 | - name: Upload 17 | uses: actions/upload-artifact@v4 18 | with: 19 | name: paper 20 | # This is the output path where Pandoc will write the compiled 21 | # PDF. Note, this should be the same directory as the input 22 | # paper.md 23 | path: docs/joss/paper.pdf 24 | -------------------------------------------------------------------------------- /.github/workflows/flake8.yml: -------------------------------------------------------------------------------- 1 | name: Flake8 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**.py' 7 | pull_request: 8 | paths: 9 | - '**.py' 10 | 11 | jobs: 12 | flake8_py3: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Setup Python 16 | uses: actions/setup-python@v5 17 | with: 18 | python-version: 3.x 19 | - uses: actions/checkout@v4 20 | - name: Install flake8 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install flake8 black 24 | 25 | # Avoid errors from formatting that the separate black workflow 26 | # is going to solve anyway 27 | - name: Run black 28 | run: | 29 | black src tests 30 | - name: Run flake8 31 | uses: suo/flake8-github-action@releases/v1 32 | with: 33 | checkName: 'flake8_py3' # NOTE: this needs to be the same as the job name 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.github/workflows/python_publish.yml: -------------------------------------------------------------------------------- 1 | name: Build/publish Python Package 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | - name: Set up Python 13 | uses: actions/setup-python@v5 14 | with: 15 | python-version: '3.x' 16 | - name: Install dependencies 17 | run: | 18 | python -m pip install --upgrade pip 19 | python -m pip install build twine 20 | - name: Build package 21 | run: | 22 | python -m build --sdist --wheel 23 | - name: Check package 24 | run: | 25 | python -m twine check dist/* 26 | - name: Store the distribution packages 27 | uses: actions/upload-artifact@v4 28 | with: 29 | name: python-package-distributions 30 | path: dist/ 31 | 32 | publish-to-pypi: 33 | if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes 34 | needs: 35 | - build 36 | runs-on: ubuntu-latest 37 | environment: 38 | name: pypi 39 | url: https://pypi.org/p/pyrokinetics 40 | permissions: 41 | id-token: write # IMPORTANT: mandatory for trusted publishing 42 | steps: 43 | - name: Download distribution packages 44 | uses: actions/download-artifact@v4 45 | with: 46 | name: python-package-distributions 47 | path: dist/ 48 | - name: Publish to PyPI 49 | uses: pypa/gh-action-pypi-publish@release/v1 50 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**.py' 7 | - 'pyproject.toml' 8 | pull_request: 9 | paths: 10 | - '**.py' 11 | - 'pyproject.toml' 12 | 13 | jobs: 14 | 15 | pytest: 16 | runs-on: ubuntu-latest 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | python-version: ["3.10", "3.11", "3.12"] 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up Python ${{ matrix.python-version }} 25 | uses: actions/setup-python@v5 26 | with: 27 | python-version: ${{ matrix.python-version }} 28 | - name: Install dependencies 29 | run: | 30 | python -m pip install --upgrade pip 31 | python -m pip install .[tests] 32 | - name: Test with pytest 33 | run: | 34 | pytest --cov=pyrokinetics --cov-report=xml --cov-report=term -vv ./tests 35 | - name: Upload coverage artifacts 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: ${{ format('coverage-python-{0}', matrix.python-version) }} 39 | path: coverage.xml 40 | 41 | code-coverage: 42 | name: Code coverage 43 | needs: 44 | - pytest 45 | runs-on: ubuntu-latest 46 | 47 | steps: 48 | - uses: actions/checkout@v4 49 | - name: Download coverage report 50 | uses: actions/download-artifact@v4 51 | with: 52 | name: "coverage-python-3.10" 53 | path: coverage.xml 54 | - name: Upload coverage reports to Codecov 55 | uses: codecov/codecov-action@v3 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Auto-generated version file 2 | _version.py 3 | 4 | # Auto-generated docs 5 | generated/ 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | pip-wheel-metadata/ 30 | share/python-wheels/ 31 | *.egg-info/ 32 | .installed.cfg 33 | *.egg 34 | MANIFEST 35 | 36 | # PyInstaller 37 | # Usually these files are written by a python script from a template 38 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 39 | *.manifest 40 | *.spec 41 | 42 | # Installer logs 43 | pip-log.txt 44 | pip-delete-this-directory.txt 45 | 46 | # Unit test / coverage reports 47 | htmlcov/ 48 | .tox/ 49 | .nox/ 50 | .coverage 51 | .coverage.* 52 | .cache 53 | nosetests.xml 54 | coverage.xml 55 | *.cover 56 | *.py,cover 57 | .hypothesis/ 58 | .pytest_cache/ 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | 80 | # PyBuilder 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | 137 | # Emacs 138 | *~ 139 | \#* 140 | 141 | # vim 142 | *.swp 143 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-20.04 11 | tools: 12 | python: "mambaforge-22.9" 13 | 14 | # You can also specify other tool versions: 15 | # nodejs: "16" 16 | # rust: "1.55" 17 | # golang: "1.17" 18 | 19 | # Build documentation in the docs/ directory with Sphinx 20 | sphinx: 21 | configuration: docs/conf.py 22 | 23 | # Optionally build your docs in additional formats such as PDF 24 | # formats: 25 | # - pdf 26 | 27 | conda: 28 | environment: .environment.yaml 29 | 30 | 31 | # Optionally declare the Python requirements required to build your docs 32 | python: 33 | install: 34 | - method: pip 35 | path: . 36 | extra_requirements: 37 | - docs 38 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Change Log 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] - 2021-01-26 9 | 10 | ### Added 11 | 12 | ### Changed 13 | - Changed Pyro kwarg from `gk_type` to `gk_code` 14 | 15 | ### Fixed 16 | 17 | ## [0.0.1] - 2021-01-26 18 | 19 | ### Added 20 | 21 | ### Changed 22 | 23 | ### Fixed 24 | 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | from python:3.11 2 | 3 | RUN apt-get update 4 | RUN apt-get -y install gfortran && apt-get clean 5 | 6 | COPY . /pyrokinetics 7 | WORKDIR /pyrokinetics 8 | 9 | ARG SETUPTOOLS_SCM_PRETEND_VERSION 10 | RUN pip install --no-cache-dir .[tests] 11 | 12 | CMD [ "ipython" ] 13 | 14 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | #%: Makefile 20 | # @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | %: Makefile 22 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 23 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -b coverage 24 | -------------------------------------------------------------------------------- /docs/_templates/custom-class-template.rst: -------------------------------------------------------------------------------- 1 | {{ fullname | escape | underline}} 2 | 3 | .. currentmodule:: {{ module }} 4 | 5 | .. autoclass:: {{ objname }} 6 | :members: 7 | :undoc-members: 8 | :show-inheritance: 9 | 10 | {% block methods %} 11 | .. automethod:: __init__ 12 | 13 | {% if methods %} 14 | .. rubric:: {{ _('Methods') }} 15 | 16 | .. autosummary:: 17 | {% for item in methods %} 18 | ~{{ name }}.{{ item }} 19 | {%- endfor %} 20 | {% endif %} 21 | {% endblock %} 22 | 23 | {% block attributes %} 24 | {% if attributes %} 25 | .. rubric:: {{ _('Attributes') }} 26 | 27 | .. autosummary:: 28 | {% for item in attributes %} 29 | ~{{ name }}.{{ item }} 30 | {%- endfor %} 31 | {% endif %} 32 | {% endblock %} 33 | -------------------------------------------------------------------------------- /docs/_templates/custom-module-template.rst: -------------------------------------------------------------------------------- 1 | {{ fullname | escape | underline}} 2 | 3 | .. automodule:: {{ fullname }} 4 | 5 | {% block attributes %} 6 | {% if attributes %} 7 | .. rubric:: {{ _('Module Attributes') }} 8 | 9 | .. autosummary:: 10 | :toctree: 11 | {% for item in attributes %} 12 | {{ item }} 13 | {%- endfor %} 14 | {% endif %} 15 | {% endblock %} 16 | 17 | {% block functions %} 18 | {% if functions %} 19 | .. rubric:: {{ _('Functions') }} 20 | 21 | .. autosummary:: 22 | :toctree: 23 | {% for item in functions %} 24 | {{ item }} 25 | {%- endfor %} 26 | {% endif %} 27 | {% endblock %} 28 | 29 | {% block classes %} 30 | {% if classes %} 31 | .. rubric:: {{ _('Classes') }} 32 | 33 | .. autosummary:: 34 | :toctree: 35 | :template: custom-class-template.rst 36 | {% for item in classes %} 37 | {{ item }} 38 | {%- endfor %} 39 | {% endif %} 40 | {% endblock %} 41 | 42 | {% block exceptions %} 43 | {% if exceptions %} 44 | .. rubric:: {{ _('Exceptions') }} 45 | 46 | .. autosummary:: 47 | :toctree: 48 | {% for item in exceptions %} 49 | {{ item }} 50 | {%- endfor %} 51 | {% endif %} 52 | {% endblock %} 53 | 54 | {% block modules %} 55 | {% if modules %} 56 | .. rubric:: Modules 57 | 58 | .. autosummary:: 59 | :toctree: 60 | :template: custom-module-template.rst 61 | :recursive: 62 | {% for item in modules %} 63 | {{ item }} 64 | {%- endfor %} 65 | {% endif %} 66 | {% endblock %} 67 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | API Reference 3 | =============== 4 | 5 | .. autosummary:: 6 | :toctree: generated 7 | :template: custom-module-template.rst 8 | :recursive: 9 | 10 | pyrokinetics 11 | -------------------------------------------------------------------------------- /docs/examples/example.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | gs2input = template_dir / "input.gs2" 4 | eqfile = template_dir / "test.geqdsk" 5 | pyro = Pyro(gk_code="GS2", gk_file=gs2input) 6 | 7 | geo = pyro.local_geometry 8 | 9 | geo["shat"] = 2.3 10 | 11 | 12 | flags = { 13 | "gs2_diagnostics_knobs": { 14 | "write_fields": True, 15 | "write_kpar": True, 16 | }, 17 | } 18 | 19 | pyro.add_flags(flags) 20 | pyro.write_gk_file(file_name="test_pyro.in") 21 | -------------------------------------------------------------------------------- /docs/examples/example_JETTO.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import os 3 | import pathlib 4 | from typing import Union 5 | 6 | 7 | def main(base_path: Union[os.PathLike, str] = ".", geometry_type: str = "Miller"): 8 | # Equilibrium file 9 | eq_file = template_dir / "test.geqdsk" 10 | 11 | # Kinetics data file 12 | kinetics_file = template_dir / "jetto.jsp" 13 | 14 | # Load up pyro object 15 | pyro = Pyro( 16 | eq_file=eq_file, 17 | kinetics_file=kinetics_file, 18 | kinetics_type="JETTO", 19 | kinetics_kwargs={"time": 550}, 20 | ) 21 | 22 | # Generate local parameters at psi_n=0.5 23 | pyro.load_local(psi_n=0.5, local_geometry=geometry_type) 24 | 25 | # Select code as CGYRO 26 | pyro.gk_code = "CGYRO" 27 | 28 | base_path = pathlib.Path(base_path) 29 | 30 | # Write CGYRO input file using default template 31 | pyro.write_gk_file(file_name=base_path / "test_jetto.cgyro") 32 | 33 | # Write single GS2 input file, specifying the code type 34 | # in the call. 35 | pyro.write_gk_file(file_name=base_path / "test_jetto.gs2", gk_code="GS2") 36 | 37 | # Write single GENE input file, specifying the code type 38 | # in the call. 39 | pyro.write_gk_file(file_name=base_path / "test_jetto.gene", gk_code="GENE") 40 | 41 | pyro.write_gk_file(file_name=base_path / "test_jetto.tglf", gk_code="TGLF") 42 | 43 | pyro.write_gk_file(file_name=base_path / "test_jetto.gkw", gk_code="GKW") 44 | 45 | if geometry_type == "Miller": 46 | pyro.write_gk_file(file_name=base_path / "test_jetto.stella", gk_code="STELLA") 47 | 48 | if geometry_type == "Miller": 49 | pyro.write_gk_file(file_name=base_path / "test_jetto.gx", gk_code="GX") 50 | 51 | return pyro 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /docs/examples/example_JETTO_1dscan.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, PyroScan, template_dir 2 | import numpy as np 3 | 4 | # Equilibrium file 5 | eq_file = template_dir / "test.geqdsk" 6 | 7 | # Kinetics data file 8 | kinetics_file = template_dir / "jetto.jsp" 9 | 10 | # Load up pyro object 11 | pyro = Pyro( 12 | eq_file=eq_file, 13 | eq_type="GEQDSK", 14 | kinetics_file=kinetics_file, 15 | kinetics_type="JETTO", 16 | ) 17 | 18 | # Generate local parameters at psi_n=0.5 19 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 20 | 21 | # Change GK code to GS2 22 | pyro.gk_code = "GS2" 23 | 24 | # GS2 template input file 25 | template_file = template_dir / "input.gs2" 26 | 27 | # Write single input file using my own template 28 | pyro.write_gk_file(file_name="test_jetto.gs2", template_file=template_file) 29 | 30 | # Use existing parameter 31 | param_1 = "ky" 32 | values_1 = np.arange(0.1, 0.3, 0.1) 33 | 34 | # Add new parameter to scan through 35 | param_2 = "my_electron_gradient" 36 | values_2 = np.arange(0.0, 1.5, 0.5) 37 | 38 | # Dictionary of param and values 39 | param_dict = {param_1: values_1, param_2: values_2} 40 | 41 | # Create PyroScan object 42 | pyro_scan = PyroScan( 43 | pyro, 44 | param_dict, 45 | value_fmt=".3f", 46 | value_separator="_", 47 | parameter_separator="_", 48 | file_name="mygs2.in", 49 | base_directory="test_GS2", 50 | ) 51 | 52 | pyro_scan.add_parameter_key(param_2, "local_species", ["electron", "inverse_lt"]) 53 | 54 | pyro_scan.write() 55 | 56 | pyro.gk_code = "CGYRO" 57 | 58 | pyro_scan.write(file_name="input.cgyro", base_directory="test_CGYRO") 59 | -------------------------------------------------------------------------------- /docs/examples/example_JETTO_1dscan_complicated.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, PyroScan, template_dir 2 | import numpy as np 3 | 4 | # Equilibrium file 5 | eq_file = template_dir / "test.geqdsk" 6 | 7 | # Kinetics data file 8 | kinetics_file = template_dir / "jetto.jsp" 9 | 10 | # Load up pyro object 11 | pyro = Pyro( 12 | eq_file=eq_file, 13 | eq_type="GEQDSK", 14 | kinetics_file=kinetics_file, 15 | kinetics_type="JETTO", 16 | ) 17 | 18 | # Generate local parameters at psi_n=0.5 19 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 20 | 21 | # Change GK code to GS2 22 | pyro.gk_code = "GS2" 23 | 24 | # GS2 template input file 25 | template_file = template_dir / "input.gs2" 26 | 27 | # Write single input file using my own template 28 | pyro.write_gk_file(file_name="test_jetto.gs2", template_file=template_file) 29 | 30 | # Use existing parameter 31 | param_1 = "q" 32 | values_1 = np.arange(1.0, 1.5, 0.1) 33 | 34 | # Add new parameter to scan through 35 | param_2 = "my_electron_gradient" 36 | values_2 = np.arange(0.0, 1.5, 0.5) 37 | 38 | # Dictionary of param and values 39 | param_dict = {param_1: values_1, param_2: values_2} 40 | 41 | # Create PyroScan object 42 | pyro_scan = PyroScan( 43 | pyro, 44 | param_dict, 45 | value_fmt=".3f", 46 | value_separator="_", 47 | parameter_separator="_", 48 | file_name="mygs2.in", 49 | base_directory="test_GS2", 50 | ) 51 | 52 | 53 | # Add in path to each defined parameter to scan through 54 | pyro_scan.add_parameter_key(param_1, "local_geometry", ["q"]) 55 | pyro_scan.add_parameter_key(param_2, "local_species", ["electron", "inverse_ln"]) 56 | 57 | 58 | # When scanning through param_2 (a/Lne) match ion density gradient to maintain quasi-neutrality 59 | def maintain_quasineutrality(pyro): 60 | for species in pyro.local_species.names: 61 | if species != "electron": 62 | pyro.local_species[species].inverse_ln = pyro.local_species.electron.inverse_ln 63 | 64 | 65 | # If there are kwargs to function then define here 66 | param_2_kwargs = {} 67 | 68 | # Add function to pyro 69 | pyro_scan.add_parameter_func(param_2, maintain_quasineutrality, param_2_kwargs) 70 | 71 | # Write input files 72 | pyro_scan.write() 73 | 74 | # Switch to CGYRO 75 | pyro_scan.convert_gk_code("CGYRO") 76 | pyro_scan.write(file_name="input.cgyro", base_directory="test_CGYRO") 77 | -------------------------------------------------------------------------------- /docs/examples/example_PFILE.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import os 3 | import pathlib 4 | from typing import Union 5 | 6 | 7 | def main(base_path: Union[os.PathLike, str] = "."): 8 | # Equilibrium file 9 | eq_file = template_dir / "test.geqdsk" 10 | 11 | # Kinetics data file 12 | kinetics_file = template_dir / "pfile.txt" 13 | 14 | # Load up pyro object 15 | pyro = Pyro( 16 | eq_file=eq_file, 17 | eq_type="GEQDSK", 18 | kinetics_file=kinetics_file, 19 | kinetics_type="pFile", 20 | ) 21 | 22 | pyro.local_geometry = "Miller" 23 | 24 | # Generate local Miller parameters at psi_n=0.5 25 | pyro.load_local_geometry(psi_n=0.5) 26 | pyro.load_local_species(psi_n=0.5) 27 | 28 | pyro.gk_code = "GS2" 29 | 30 | base_path = pathlib.Path(base_path) 31 | 32 | # Write out GK 33 | pyro.write_gk_file(file_name=base_path / "test_pfile.gs2") 34 | 35 | pyro.write_gk_file(file_name=base_path / "test_pfile.gene", gk_code="GENE") 36 | 37 | pyro.write_gk_file(file_name=base_path / "test_pfile.tglf", gk_code="TGLF") 38 | 39 | pyro.write_gk_file(file_name=base_path / "test_pfile.cgyro", gk_code="CGYRO") 40 | 41 | pyro.write_gk_file(file_name=base_path / "test_pfile.gkw", gk_code="GKW") 42 | 43 | pyro.write_gk_file(file_name=base_path / "test_pfile.stella", gk_code="STELLA") 44 | 45 | pyro.write_gk_file(file_name=base_path / "test_pfile.gx", gk_code="GX") 46 | 47 | return pyro 48 | 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /docs/examples/example_SCENE.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import os 3 | import pathlib 4 | from typing import Union 5 | 6 | 7 | def main(base_path: Union[os.PathLike, str] = "."): 8 | # Equilibrium file 9 | eq_file = template_dir / "test.geqdsk" 10 | 11 | # Kinetics data file 12 | kinetics_file = template_dir / "scene.cdf" 13 | 14 | pyro = Pyro( 15 | eq_file=eq_file, 16 | eq_type="GEQDSK", 17 | kinetics_file=kinetics_file, 18 | kinetics_type="SCENE", 19 | ) 20 | 21 | # Generate local Miller parameters at psi_n=0.5 22 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 23 | 24 | # Select code as CGYRO 25 | pyro.gk_code = "CGYRO" 26 | 27 | base_path = pathlib.Path(base_path) 28 | 29 | # Write CGYRO input file using default template 30 | pyro.write_gk_file(file_name=base_path / "test_scene.cgyro") 31 | 32 | # Write single GS2 input file, specifying the code type 33 | # in the call. 34 | pyro.write_gk_file(file_name=base_path / "test_scene.gs2", gk_code="GS2") 35 | 36 | # Write single GENE input file, specifying the code type 37 | # in the call. 38 | pyro.write_gk_file(file_name=base_path / "test_scene.gene", gk_code="GENE") 39 | 40 | pyro.write_gk_file(file_name=base_path / "test_scene.tglf", gk_code="TGLF") 41 | 42 | return pyro 43 | 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /docs/examples/example_TRANSP.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | # Equilibrium file 4 | eq_file = template_dir / "test.geqdsk" 5 | 6 | # Kinetics data file 7 | kinetics_file = template_dir / "transp.cdf" 8 | 9 | # Load up pyro object 10 | pyro = Pyro( 11 | eq_file=eq_file, 12 | eq_type="GEQDSK", 13 | kinetics_file=kinetics_file, 14 | kinetics_type="TRANSP", 15 | ) 16 | 17 | pyro.local_geometry = "Miller" 18 | 19 | # Generate local Miller parameters at psi_n=0.5 20 | pyro.load_local_geometry(psi_n=0.5) 21 | pyro.load_local_species(psi_n=0.5) 22 | 23 | pyro.gk_code = "GS2" 24 | 25 | pyro.write_gk_file(file_name="test_transp.in") 26 | -------------------------------------------------------------------------------- /docs/examples/example_addflags.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | # Equilibrium file 4 | eq_file = template_dir / "test.geqdsk" 5 | 6 | # Kinetics data file 7 | kinetics_file = template_dir / "jetto.cdf" 8 | 9 | # GS2 template input file 10 | gk_file = template_dir / "input.gs2" 11 | 12 | # Load up pyro object 13 | pyro = Pyro( 14 | eq_file=eq_file, 15 | eq_type="GEQDSK", 16 | kinetics_file=kinetics_file, 17 | kinetics_type="JETTO", 18 | gk_file=gk_file, 19 | gk_code="GS2", 20 | ) 21 | 22 | # Generate local parameters at psi_n=0.5 23 | pyro.load_local(psi_n=0.5) 24 | 25 | # Change GK code to GS2 26 | pyro.gk_code = "GS2" 27 | 28 | # Dictionary for extra flags 29 | # Nested for GS2 namelist 30 | flags = { 31 | "gs2_diagnostics_knobs": { 32 | "write_fields": True, 33 | "write_kpar": True, 34 | }, 35 | } 36 | 37 | pyro.add_flags(flags) 38 | 39 | # Write single input file using my own template 40 | pyro.write_gk_file(file_name="test_jetto.gs2") 41 | -------------------------------------------------------------------------------- /docs/examples/example_cgyro.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | cgyro_template = template_dir / "input.cgyro" 4 | 5 | pyro = Pyro(gk_file=cgyro_template, gk_code="CGYRO") 6 | 7 | flags = {"THETA_PLOT": 32} 8 | 9 | pyro.add_flags(flags) 10 | pyro.write_gk_file(file_name="test_cgyro.cgyro") 11 | 12 | pyro.gk_code = "GS2" 13 | pyro.write_gk_file(file_name="test_cgyro.gs2") 14 | 15 | pyro.gk_code = "GENE" 16 | pyro.write_gk_file(file_name="test_cgyro.gene") 17 | -------------------------------------------------------------------------------- /docs/examples/example_gene.py: -------------------------------------------------------------------------------- 1 | import pyrokinetics 2 | 3 | gene_template = pyrokinetics.template_dir / "input.gene" 4 | 5 | pyro = pyrokinetics.Pyro(gk_file=gene_template, gk_code="GENE") 6 | 7 | pyro.write_gk_file(file_name="test_gene.gene") 8 | 9 | pyro.gk_code = "GS2" 10 | pyro.write_gk_file(file_name="test_gene.gs2") 11 | 12 | # pyro.gk_code = 'CGYRO' 13 | # pyro.write_gk_file(file_name='test_gene.cgyro') 14 | -------------------------------------------------------------------------------- /docs/examples/example_generate_global_profiles.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import numpy as np 3 | 4 | # Set up Pyro object 5 | 6 | eq_file = template_dir / "test.geqdsk" 7 | kinetics_file = template_dir / "jetto.jsp" 8 | 9 | pyro = Pyro( 10 | eq_file=eq_file, 11 | eq_kwargs={"psi_n_lcfs": 0.9999}, 12 | kinetics_file=kinetics_file, 13 | ) 14 | 15 | # Add a merge species to the Kinetics object one day to make the loop more general 16 | # pyro.kinetics.merge_species("deuterium", ["all", "other", "ions"] 17 | 18 | # Need data on rho_tor grid to map from psi_n to rho_tor 19 | n_rho_tor = 1001 20 | pyro_psi_n = np.linspace(0.0001, 1.0, n_rho_tor * 10) 21 | pyro_rho_tor = pyro.eq.rho_tor(pyro_psi_n) 22 | 23 | rho_tor = np.linspace(0, 1.0, n_rho_tor) 24 | psi_n = np.interp(rho_tor, pyro_rho_tor, pyro_psi_n) 25 | 26 | # Different species data 27 | species_data = pyro.kinetics.species_data 28 | species = species_data.keys() 29 | n_species = len(species) 30 | 31 | 32 | # Reference values at each surface 33 | nref = species_data.electron.get_dens(psi_n) 34 | tref = species_data.electron.get_temp(psi_n) 35 | mref = species_data.deuterium.get_mass() 36 | qref = abs(species_data.electron.get_charge(psi_n)) 37 | bref = pyro.eq.F(psi_n) / pyro.eq.R_major(psi_n) 38 | lref = pyro.eq.a_minor 39 | 40 | # Larmor radius 41 | rho_ref = (np.sqrt(tref * mref) / (qref * bref)).to("meter") 42 | 43 | # GENE defn of x 44 | x = lref * rho_tor 45 | 46 | # Iterate through all species 47 | for name, species in species_data.items(): 48 | global_data = np.empty((4, n_rho_tor)) 49 | 50 | global_data[0, :] = (x / lref).m 51 | global_data[1, :] = (x / rho_ref).m 52 | global_data[2, :] = (species.get_temp(psi_n).to("keV")).m 53 | global_data[3, :] = (species.get_dens(psi_n).to("meter**-3") * 1e-19).m 54 | np.savetxt( 55 | f"{name}.dat", 56 | global_data.T, 57 | fmt="%.6e", 58 | header="x/a x/rho_ref T n ", 59 | ) 60 | 61 | # Deuterium merged - electron density but ion temp - good for 2 species global sims 62 | # Ideally have a merged species function 63 | name = "deuterium" 64 | global_data = np.empty((4, n_rho_tor)) 65 | global_data[0, :] = (x / lref).m 66 | global_data[1, :] = (x / rho_ref).m 67 | global_data[2, :] = (species_data.deuterium.get_temp(psi_n).to("keV")).m 68 | global_data[3, :] = (species_data.electron.get_dens(psi_n).to("meter**-3") * 1e-19).m 69 | np.savetxt( 70 | f"{name}_merged.dat", 71 | global_data.T, 72 | fmt="%.6e", 73 | header="x/a x/rho_ref T n ", 74 | ) 75 | -------------------------------------------------------------------------------- /docs/examples/example_geqdsk.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | # Equilibrium file 4 | eq_file = template_dir / "test.geqdsk" 5 | # Kinetics data file 6 | kinetics_file = template_dir / "scene.cdf" 7 | 8 | # Load up pyro object 9 | pyro = Pyro( 10 | eq_file=eq_file, 11 | eq_type="GEQDSK", 12 | kinetics_file=kinetics_file, 13 | kinetics_type="SCENE", 14 | ) 15 | 16 | # Show fit when loading in data 17 | show_fit = True 18 | 19 | # Generate local Miller parameters at psi_n=0.5 20 | pyro.load_local_geometry(psi_n=0.5, local_geometry="Miller", show_fit=show_fit) 21 | 22 | # Switch to different geometry types and plot fit 23 | pyro.switch_local_geometry(local_geometry="MillerTurnbull", show_fit=show_fit) 24 | 25 | pyro.switch_local_geometry(local_geometry="FourierGENE", show_fit=show_fit) 26 | 27 | pyro.switch_local_geometry(local_geometry="FourierCGYRO", show_fit=show_fit) 28 | 29 | pyro.switch_local_geometry(local_geometry="MXH", show_fit=show_fit) 30 | -------------------------------------------------------------------------------- /docs/examples/example_gs2.py: -------------------------------------------------------------------------------- 1 | import pyrokinetics 2 | 3 | gs2_template = pyrokinetics.template_dir / "input.gs2" 4 | 5 | pyro = pyrokinetics.Pyro(gk_file=gs2_template, gk_code="GS2") 6 | 7 | flags = { 8 | "gs2_diagnostics_knobs": { 9 | "write_fields": True, 10 | "write_kpar": True, 11 | }, 12 | } 13 | 14 | pyro.add_flags(flags) 15 | pyro.write_gk_file(file_name="step.gs2") 16 | 17 | pyro.gk_code = "CGYRO" 18 | pyro.write_gk_file(file_name="step.cgyro") 19 | 20 | pyro.gk_code = "GENE" 21 | pyro.write_gk_file(file_name="step.gene") 22 | -------------------------------------------------------------------------------- /docs/examples/example_gx.py: -------------------------------------------------------------------------------- 1 | import pyrokinetics 2 | 3 | gx_template = pyrokinetics.template_dir / "input.gx" 4 | 5 | # Read input 6 | pyro = pyrokinetics.Pyro(gk_file=gx_template, gk_code="GX") 7 | 8 | # Write input file 9 | pyro.write_gk_file(file_name="test.gx") 10 | 11 | # Load output 12 | pyro.load_gk_output() 13 | -------------------------------------------------------------------------------- /docs/examples/example_ideal_ballooning.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from pyrokinetics import Pyro 4 | from pyrokinetics.diagnostics import Diagnostics 5 | from pyrokinetics import template_dir 6 | 7 | nshat = 15 8 | nbprime = 20 9 | shat = np.linspace(0.0, 2, nshat) 10 | bprime = np.linspace(0.0, -0.5, nbprime) 11 | 12 | pyro = Pyro(gk_file=template_dir / "input.gs2") 13 | 14 | gamma = np.empty((nshat, nbprime)) 15 | 16 | for i_s, s in enumerate(shat): 17 | for i_b, b in enumerate(bprime): 18 | pyro.local_geometry.shat = s 19 | pyro.local_geometry.beta_prime = b 20 | diag = Diagnostics(pyro) 21 | gamma[i_s, i_b] = diag.ideal_ballooning_solver() 22 | 23 | 24 | fig, ax = plt.subplots(1, 1, sharex=True, figsize=(8, 7)) 25 | 26 | cs = ax.contourf(abs(bprime), shat, gamma) 27 | cs_0 = ax.contour( 28 | abs(bprime), 29 | shat, 30 | gamma, 31 | colors="w", 32 | linewidths=(2,), 33 | levels=[ 34 | 0.0, 35 | ], 36 | ) 37 | 38 | ax.clabel(cs_0, fmt="%.1e", colors="w", fontsize=22) 39 | ax.set_ylabel(r"$\hat{s}$") 40 | ax.set_xlabel(r"$|\beta'|$") 41 | fig.colorbar(cs) 42 | ax.set_title("IBM growth rate") 43 | fig.tight_layout() 44 | plt.show() 45 | -------------------------------------------------------------------------------- /docs/examples/example_merge_species.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | 3 | 4 | def main(): 5 | 6 | # Equilibrium file 7 | eq_file = template_dir / "test.geqdsk" 8 | 9 | # Kinetics data file 10 | kinetics_file = template_dir / "jetto.jsp" 11 | 12 | # Load up pyro object 13 | pyro = Pyro( 14 | eq_file=eq_file, 15 | kinetics_file=kinetics_file, 16 | kinetics_type="JETTO", 17 | kinetics_kwargs={"time": 550}, 18 | ) 19 | 20 | # Generate local parameters at psi_n=0.5 21 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 22 | 23 | # merge species 'impurity1' into 'deuterium' 24 | pyro.local_species.merge_species( 25 | "deuterium", 26 | ["impurity1"], 27 | keep_base_species_mass=False, 28 | keep_base_species_z=False, 29 | ) 30 | 31 | # write to file 32 | pyro.write_gk_file(file_name="input.gene", gk_code="GENE") 33 | 34 | return pyro 35 | 36 | 37 | if __name__ == "__main__": 38 | 39 | main() 40 | -------------------------------------------------------------------------------- /docs/examples/example_nonlinear_cgyro.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Point to CGYRO input file 6 | cgyro_template = template_dir / "outputs/CGYRO_nonlinear/input.cgyro" 7 | 8 | # Load in file 9 | pyro = Pyro(gk_file=cgyro_template) 10 | 11 | # Load in CGYRO output data 12 | pyro.load_gk_output(load_fields=True, load_fluxes=True, load_moments=True) 13 | data = pyro.gk_output 14 | 15 | # Plot electron energy flux as a function of ky 16 | electron_heat_flux_ky = data["heat"].sel(field="phi", species="electron").isel(time=-1) 17 | electron_heat_flux_ky.plot() 18 | plt.show() 19 | 20 | # Plot electron energy flux as a function of ky 21 | total_heat_flux_time = data["heat"].sum(dim=["field", "species", "ky"]) 22 | total_heat_flux_time.plot() 23 | plt.show() 24 | 25 | # Plot phi 26 | phi = data["phi"].sel(theta=0.0, method="nearest", drop=True).isel(time=-1, drop=True) 27 | # Can't log something with units to need to remove them 28 | log_phi = np.log(np.abs(phi).pint.dequantify()) 29 | log_phi.plot(x="kx", y="ky") 30 | plt.show() 31 | -------------------------------------------------------------------------------- /docs/examples/example_poincare.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | from pyrokinetics import Pyro, template_dir 5 | from pyrokinetics.diagnostics import Diagnostics 6 | 7 | # Load data 8 | fname = template_dir / "outputs/CGYRO_nonlinear/input.cgyro" 9 | pyro = Pyro(gk_file=fname, gk_code="CGYRO") 10 | pyro.load_gk_output() 11 | 12 | # Set input for Poincare map 13 | xarray = np.linspace(6, 8, 5) 14 | yarray = np.linspace(-10, 10, 3) 15 | nturns = 1000 16 | time = 1 17 | rhostar = 0.036 18 | 19 | # Generate Poincare map 20 | diag = Diagnostics(pyro) 21 | coords = diag.poincare(xarray, yarray, nturns, time, rhostar) 22 | 23 | # Simple plot 24 | plt.figure() 25 | plt.plot(coords[0, :].ravel(), coords[1, :].ravel(), "k.") 26 | 27 | # Plot with colors 28 | ntot = nturns * yarray.shape[0] 29 | colorlist = plt.cm.jet(np.linspace(0, 1, xarray.shape[0])) 30 | plt.figure() 31 | for i, color in enumerate(colorlist): 32 | plt.plot(coords[0, :, :, i].ravel(), coords[1, :, :, i].ravel(), ".", color=color) 33 | plt.show() 34 | -------------------------------------------------------------------------------- /docs/examples/example_pyro.py: -------------------------------------------------------------------------------- 1 | """ 2 | example_pyro.py 3 | 4 | Demonstrates the creation of a Pyro object, and the various ways in which a GK input 5 | file may be manipulated. 6 | """ 7 | 8 | from pyrokinetics import Pyro, gk_templates, eq_templates, kinetics_templates 9 | from pyrokinetics.gk_code import GKInputGS2, GKInputCGYRO 10 | 11 | gs2_file = gk_templates["GS2"] 12 | eq_file = eq_templates["GEQDSK"] 13 | kinetics_file = kinetics_templates["SCENE"] 14 | 15 | 16 | # Read a GK input file (with automatic file type inference 17 | pyro = Pyro(gk_file=gs2_file) 18 | 19 | # Can then access Pyrofied data: 20 | ntheta = pyro.numerics["ntheta"] 21 | shat = pyro.local_geometry["shat"] 22 | ion_density = pyro.local_species["ion1"]["dens"] 23 | assert "deuterium" not in pyro.local_species 24 | 25 | # We can replace the local_geometry with one generated from a global equilibrium 26 | psi_n = 0.5 27 | pyro.load_global_eq(eq_file) 28 | pyro.load_local_geometry(psi_n) 29 | # Show that local_geometry has been updated: 30 | assert pyro.local_geometry["psi_n"] == 0.5 31 | assert pyro.local_geometry["shat"] != shat 32 | 33 | # We can also replace local_species with one generated from global kinetics 34 | # If we were to do this without setting from a global equilibrium, we would also 35 | # need to set a_minor. We'll explicitly set it to None to demonstrate usage. 36 | pyro.load_global_kinetics(kinetics_file) 37 | pyro.load_local_species(psi_n, a_minor=None) 38 | # Show that local_species has been updated: 39 | assert "deuterium" in pyro.local_species 40 | assert "ion1" not in pyro.local_species 41 | 42 | # We may also read multiple files in with the constructor 43 | pyro = Pyro( 44 | gk_file=gs2_file, 45 | eq_file=eq_file, 46 | kinetics_file=kinetics_file, 47 | ) 48 | # And we may set local_species and local_geometry together 49 | pyro.load_local(psi_n=psi_n) 50 | 51 | # We may then write out a new GS2 input file given this new info 52 | pyro.write_gk_file("modified_gs2.in", "GS2") 53 | # This will modify the current file name, and its internal representation (gk_input) 54 | assert str(pyro.gk_file) == "modified_gs2.in" 55 | 56 | # We may also convert to a different gyrokinetics code 57 | pyro.write_gk_file("modified_gs2_to_cgyro.in", "CGYRO") 58 | # This action has created a new 'context'. We may access the new context by setting the 59 | # gk_code attribute 60 | pyro.gk_code = "CGYRO" 61 | assert str(pyro.gk_file) == "modified_gs2_to_cgyro.in" 62 | assert isinstance(pyro.gk_input, GKInputCGYRO) 63 | # Each of the attributes local_geometry, local_species, numerics, gk_input, gk_output, 64 | # and gk_file now point to the new context. We can switch back to the old context 65 | # similarly. 66 | pyro.gk_code = "GS2" 67 | assert str(pyro.gk_file) == "modified_gs2.in" 68 | assert isinstance(pyro.gk_input, GKInputGS2) 69 | # If we call read_gk_file, that will overwrite the corresponding gyrokinetics context 70 | # and switch to it. We can also convert the current context to a different type using 71 | # convert_gk_code. 72 | -------------------------------------------------------------------------------- /docs/examples/example_read_cgyro_output.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Point to CGYRO input file 6 | cgyro_template = template_dir / "outputs/CGYRO_linear/input.cgyro" 7 | 8 | # Load in file 9 | pyro = Pyro(gk_file=cgyro_template, gk_code="CGYRO") 10 | 11 | # Load in CGYRO output data 12 | pyro.load_gk_output() 13 | data = pyro.gk_output 14 | 15 | # Get eigenvalues 16 | eigenvalues = data["eigenvalues"] 17 | growth_rate = data["growth_rate"] 18 | mode_freq = data["mode_frequency"] 19 | 20 | # Plot growth and mode frequency 21 | growth_rate.plot(x="time") 22 | plt.show() 23 | 24 | mode_freq.plot(x="time") 25 | plt.show() 26 | 27 | # Plot eigenfunction 28 | phi_eig = np.real(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 29 | phi_eig.plot(x="theta", marker="x") 30 | 31 | phi_i_eig = np.imag(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 32 | phi_i_eig.plot(x="theta") 33 | plt.show() 34 | 35 | # Plot electron energy flux 36 | energy_flux = ( 37 | data["heat"].sel(field="phi", species="electron").sum(dim="ky").plot.line() 38 | ) 39 | plt.show() 40 | 41 | # Plot phi 42 | phi = data["phi"].sel(theta=0.0, method="nearest").isel(ky=0).isel(kx=0) 43 | phi = np.abs(phi) 44 | phi.plot.line(x="time") 45 | 46 | plt.yscale("log") 47 | plt.show() 48 | -------------------------------------------------------------------------------- /docs/examples/example_read_gene_output.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Point to GENE input file 6 | gene_template = template_dir / "outputs/GENE_linear/parameters_0001" 7 | 8 | # Load in file 9 | pyro = Pyro(gk_file=gene_template, gk_code="GENE") 10 | 11 | # Load in GENE output data 12 | pyro.load_gk_output() 13 | data = pyro.gk_output 14 | 15 | # Get eigenvalues 16 | eigenvalues = data["eigenvalues"] 17 | growth_rate = data["growth_rate"] 18 | mode_freq = data["mode_frequency"] 19 | 20 | # Plot growth and mode frequency 21 | growth_rate.plot(x="time") 22 | plt.show() 23 | 24 | mode_freq.plot(x="time") 25 | plt.show() 26 | 27 | # Plot eigenfunction 28 | phi_eig = np.real(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 29 | phi_eig.plot(x="theta") 30 | 31 | phi_i_eig = np.imag(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 32 | phi_i_eig.plot(x="theta") 33 | plt.show() 34 | 35 | # Plot electron energy flux 36 | energy_flux = data["heat"].sel(species="electron").sum(dim=["field"]).plot.line() 37 | plt.show() 38 | 39 | # Plot phi 40 | phi = data["phi"].isel(ky=0).isel(kx=0).sel(theta=0.0, method="nearest") 41 | phi = np.abs(phi) 42 | phi.plot.line(x="time") 43 | 44 | plt.yscale("log") 45 | plt.show() 46 | 47 | # Plot apar 48 | if "apar" in data: 49 | apar = data["apar"].isel(ky=0).isel(kx=0).sel(theta=0.0, method="nearest") 50 | apar = np.abs(apar) 51 | apar.plot.line(x="time") 52 | 53 | plt.yscale("log") 54 | plt.show() 55 | -------------------------------------------------------------------------------- /docs/examples/example_read_gs2_output.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Point to GS2 input file 6 | gs2_template = template_dir / "outputs/GS2_linear/gs2.in" 7 | 8 | # Load in file 9 | pyro = Pyro(gk_file=gs2_template, gk_code="GS2") 10 | 11 | # Load in GS2 output data 12 | pyro.load_gk_output() 13 | data = pyro.gk_output 14 | 15 | # Get eigenvalues 16 | eigenvalues = data["eigenvalues"] 17 | growth_rate = data["growth_rate"] 18 | mode_freq = data["mode_frequency"] 19 | 20 | # Plot growth and mode frequency 21 | growth_rate_tolerance = data["growth_rate_tolerance"] 22 | growth_rate.plot(x="time") 23 | plt.title(f"Growth rate tolerance = {growth_rate_tolerance.data}") 24 | plt.show() 25 | 26 | mode_freq.plot(x="time") 27 | plt.show() 28 | 29 | # Plot eigenfunction 30 | phi_eig = np.real(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 31 | phi_eig.plot(x="theta", label="Real") 32 | 33 | phi_i_eig = np.imag(data["eigenfunctions"].sel(field="phi").isel(time=-1)) 34 | phi_i_eig.plot(x="theta", label="Imag") 35 | 36 | plt.legend() 37 | plt.show() 38 | 39 | # Plot electron energy flux 40 | energy_flux = ( 41 | data["heat"].sel(field="phi", species="electron").sum(dim="ky").plot.line() 42 | ) 43 | plt.show() 44 | 45 | # Plot phi 46 | phi = data["phi"].sel(theta=0.0, method="nearest").isel(ky=0).isel(kx=0) 47 | phi = np.abs(phi) 48 | phi.plot.line(x="time") 49 | 50 | plt.yscale("log") 51 | plt.show() 52 | -------------------------------------------------------------------------------- /docs/examples/example_read_pyroscan_output.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, PyroScan, template_dir 2 | import numpy as np 3 | 4 | 5 | base_directory = template_dir / "outputs/CGYRO_linear_scan" 6 | 7 | gk_file = base_directory / "input.cgyro" 8 | 9 | pyro = Pyro(gk_file=gk_file) 10 | 11 | param_key = "ky" 12 | param_value = np.array([0.1, 0.2, 0.3]) 13 | param_dict = {param_key: param_value} 14 | 15 | # Create PyroScan object 16 | pyro_scan = PyroScan(pyro, param_dict, base_directory=base_directory) 17 | 18 | pyro_scan.load_gk_output() 19 | -------------------------------------------------------------------------------- /docs/examples/example_read_tglf_linear.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | gk_file = template_dir / "outputs/TGLF_linear/input.tglf" 6 | 7 | pyro = Pyro(gk_file=gk_file) 8 | 9 | pyro.load_gk_output() 10 | 11 | # Plot dominant eigenfunction 12 | dominant = pyro.gk_output["eigenfunctions"].isel(mode=0) 13 | 14 | np.real(dominant.sel(field="phi")).plot(x="theta", marker="x") 15 | np.imag(dominant.sel(field="phi")).plot(x="theta", marker="o") 16 | plt.show() 17 | 18 | if "apar" in dominant: 19 | np.real(dominant.sel(field="apar")).plot(marker="x") 20 | np.imag(dominant.sel(field="apar")).plot(marker="o") 21 | plt.show() 22 | 23 | # Plot subdominant eigenfunction 24 | subdominant = pyro.gk_output["eigenfunctions"].isel(mode=1) 25 | np.real(subdominant.sel(field="phi")).plot(marker="x") 26 | np.imag(subdominant.sel(field="phi")).plot(marker="o") 27 | plt.show() 28 | 29 | if "apar" in subdominant: 30 | np.real(subdominant.sel(field="apar")).plot(marker="x") 31 | np.imag(subdominant.sel(field="apar")).plot(marker="o") 32 | plt.show() 33 | 34 | # Plot growth rate and frequency 35 | growth_rate = pyro.gk_output["growth_rate"] 36 | growth_rate.plot() 37 | plt.show() 38 | 39 | mode_frequency = pyro.gk_output["mode_frequency"] 40 | mode_frequency.plot() 41 | plt.show() 42 | -------------------------------------------------------------------------------- /docs/examples/example_read_tglf_transport.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | 4 | gk_file = template_dir / "outputs/TGLF_transport/input.tglf" 5 | 6 | pyro = Pyro(gk_file=gk_file, gk_code="TGLF") 7 | 8 | pyro.load_gk_output() 9 | 10 | plt.ion() 11 | 12 | # Plot fields 13 | plt.figure(1, figsize=(16, 10), dpi=80) 14 | plt.subplot(2, 3, 1) 15 | field = pyro.gk_output["phi"] 16 | field.isel(mode=0).plot(marker="x", label="mode 1") 17 | field.isel(mode=1).plot(marker="o", label="mode 2") 18 | plt.show(block=False) 19 | plt.legend() 20 | plt.title("Phi") 21 | 22 | 23 | # plt.figure(2) 24 | if "apar" in pyro.gk_output["field"].data: 25 | plt.subplot(2, 3, 2) 26 | field = pyro.gk_output["apar"] 27 | field.isel(mode=0).plot(marker="x", label="mode 1") 28 | field.isel(mode=1).plot(marker="o", label="mode 2") 29 | plt.show(block=False) 30 | plt.legend() 31 | plt.title("Apar") 32 | 33 | # Plot fluxes 34 | # plt.figure(3) 35 | plt.subplot(2, 3, 3) 36 | heat_es = pyro.gk_output["heat"].sel(field="phi") 37 | heat_es.sel(species="electron").plot(marker="x", label="electron ES") 38 | heat_es.sel(species="ion1").plot(marker="o", label="ion ES") 39 | heat_em = pyro.gk_output["heat"].sel(field="apar") 40 | heat_em.sel(species="electron").plot(marker="+", label="electron EM") 41 | plt.show(block=False) 42 | plt.legend() 43 | plt.title("Fluxes") 44 | 45 | # Plot growth rate/frequency spectrum 46 | # plt.figure(4) 47 | plt.subplot(2, 3, 4) 48 | growth_rate = pyro.gk_output[r"growth_rate"] 49 | growth_rate.isel(mode=0).plot(marker="x", label="mode 1") 50 | growth_rate.isel(mode=1).plot(marker="o", label="mode 2") 51 | plt.show(block=False) 52 | plt.legend() 53 | plt.title("Eigenvalue Growth.") 54 | 55 | # plt.figure(5) 56 | plt.subplot(2, 3, 5) 57 | mode_frequency = pyro.gk_output["mode_frequency"] 58 | mode_frequency.isel(mode=0).plot(marker="x", label="mode 1") 59 | mode_frequency.isel(mode=1).plot(marker="o", label="mode 2") 60 | plt.show(block=True) 61 | plt.legend() 62 | plt.title("Eigenvalue Freq.") 63 | -------------------------------------------------------------------------------- /docs/examples/example_real_space_moment.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, template_dir 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | import xrft 5 | 6 | cgyro_template = template_dir / "outputs/CGYRO_nonlinear/input.cgyro" 7 | 8 | # Load in file 9 | pyro = Pyro(gk_file=cgyro_template) 10 | 11 | pyro.load_gk_output(load_moments=True, load_fluxes=False, load_fields=True) 12 | 13 | data = pyro.gk_output.data 14 | density = data["density"].pint.dequantify() 15 | density = density.isel(time=-1).sel(theta=0.0, method="nearest").sel(species="electron") 16 | 17 | nkx = len(density.kx) 18 | nky = len(density.ky) 19 | 20 | rs_density = xrft.ifft(density, real_dim="ky", true_amplitude=True, true_phase=False) 21 | max_ne = np.max(rs_density.data) 22 | min_ne = np.min(rs_density.data) 23 | levels = np.arange(min_ne, max_ne, (max_ne - min_ne) / 256) 24 | 25 | ky = pyro.numerics.ky 26 | shat = pyro.local_geometry.shat 27 | length = pyro.cgyro_input["BOX_SIZE"] / (ky * shat) 28 | 29 | nx = len(rs_density.freq_kx.data) 30 | x = np.linspace(-1 / 2, 1 / 2, nx) * length 31 | 32 | ny = len(rs_density.freq_ky.data) 33 | y = np.linspace(-np.pi / ky, np.pi / ky, ny) 34 | 35 | 36 | plt.contourf(x, y, rs_density.data.T, levels, cmap=plt.get_cmap("jet")) 37 | plt.xlabel(r"$x$") 38 | plt.ylabel(r"$y$") 39 | plt.title(r"$\delta n_e$") 40 | plt.grid() 41 | ax = plt.gca() 42 | 43 | ax.set_aspect("equal") 44 | plt.show() 45 | -------------------------------------------------------------------------------- /docs/examples/example_saturation.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import Pyro, PyroScan 2 | from pyrokinetics.diagnostics.saturation_rules import SaturationRules 3 | import numpy as np 4 | 5 | # Choose convention 6 | output_convention = "pyrokinetics" 7 | 8 | # Base file 9 | base_dir = "/common/CSD3/ir-giac2/t3d/resolution/nth128/restart6/outputs" 10 | base_file = "r3-ky0-th00-0.in" 11 | 12 | pyro = Pyro(gk_file=f"{base_dir}/{base_file}") 13 | 14 | base_ky = pyro.numerics.ky.to(pyro.norms.pyrokinetics) / 2 15 | 16 | # Set up ky and theta0 grid 17 | param_1 = "ky" 18 | param_2 = "th0" 19 | 20 | kys = np.array([2, 3, 5, 10, 20, 30, 40, 50, 70, 100, 120, 140]) * base_ky 21 | th0s = np.array([0, 0.1, 0.2, 0.4, 1.2, 3.14]) 22 | 23 | values_1 = kys 24 | values_2 = th0s 25 | 26 | # Create dictionary mapping input files to parameters in scan 27 | runfile_dict = {} 28 | for iky, ky in enumerate(kys): 29 | for ith0, th0 in enumerate(th0s): 30 | runfile_dict[ 31 | (f"{param_1}_{values_1[iky]}", f"{param_2}_{values_2[ith0]}") 32 | ] = f"{base_dir}/r3-ky{iky}-th0{ith0}-0.in" 33 | 34 | # Dictionary of param and values 35 | param_dict = {param_1: values_1, param_2: values_2} 36 | 37 | # Create PyroScan object 38 | pyro_scan = PyroScan( 39 | pyro, 40 | param_dict, 41 | value_fmt="d", 42 | value_separator="", 43 | parameter_separator="-", 44 | file_name="", 45 | base_directory=base_dir, 46 | runfile_dict=runfile_dict, 47 | ) 48 | 49 | # Add in path to each defined parameter to scan through 50 | pyro_scan.add_parameter_key( 51 | param_1, "gk_input", ["data", "kt_grids_single_parameters", "n0"] 52 | ) 53 | 54 | # Load outputs 55 | pyro_scan.load_gk_output(output_convention=output_convention, tolerance_time_range=0.9) 56 | 57 | # Create saturation object 58 | saturation = SaturationRules(pyro_scan) 59 | 60 | # Inputs for QL model 61 | alpha = 2.5 62 | Q0 = 25 63 | 64 | # Must match convention 65 | gamma_exb = ( 66 | 0.04380304982261718 * pyro.norms.pyrokinetics.vref / pyro.norms.pyrokinetics.lref 67 | ) 68 | 69 | gk_output = saturation.mg_saturation( 70 | Q0=Q0, 71 | alpha=alpha, 72 | gamma_exb=gamma_exb, 73 | output_convention=output_convention, 74 | gamma_tolerance=0.3, 75 | theta0_dim="th0", 76 | ) 77 | 78 | print("GK output", gk_output) 79 | print("Heat flux calculation", gk_output["heat"]) 80 | print("Gamma flux calculation", gk_output["particle"]) 81 | -------------------------------------------------------------------------------- /docs/examples/example_syn_hk_dbs.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.diagnostics import SyntheticHighkDBS 2 | import numpy as np 3 | from pyrokinetics.units import ureg 4 | 5 | """ 6 | Example file for synthetic diagnostic. Use for producing synthetic frequency/k-spectra from gyrokinetic simulations 7 | 8 | Define here inputs characteristic of diagnostic SyntheticHighkDBS 9 | """ 10 | 11 | # inputs 12 | diag = "highk" # 'highk', 'dbs', 'rcdr', 'bes' 13 | filter_type = "gauss" # 'bt_slab', 'bt_scotty', 'gauss' 14 | Rloc = 2.89678 * ureg.meter # [m] 15 | Zloc = 0.578291 * ureg.meter # [m] 16 | Kn0_exp = np.asarray([0.5, 1]) / ureg.rhoref_unit # [cm-1] 17 | Kb0_exp = np.asarray([0.1, 0.2]) / ureg.rhoref_unit # [cm-1] 18 | wR = 0.1 * ureg.meter # 19 | wZ = 0.05 * ureg.meter # 20 | eq_file = "/marconi_work/FUA38_TURBTAE/97090V04.CDF" 21 | kinetics_file = eq_file 22 | simdir = "/marconi_work/FUA38_TURBTAE/ky01_15_lowr" 23 | gk_file = "input.cgyro" 24 | savedir = simdir + "/syndiag" 25 | if_save = 0 26 | fsize = 22 27 | 28 | syn_diag = SyntheticHighkDBS( 29 | diag=diag, 30 | filter_type=filter_type, 31 | Rloc=Rloc, 32 | Zloc=Zloc, 33 | Kn0_exp=Kn0_exp, 34 | Kb0_exp=Kb0_exp, 35 | wR=wR, 36 | wZ=wZ, 37 | eq_file=eq_file, 38 | kinetics_file=kinetics_file, 39 | simdir=simdir, 40 | gk_file=gk_file, 41 | savedir=simdir, 42 | fsize=fsize, 43 | ) 44 | 45 | # map k 46 | syn_diag.mapk() 47 | 48 | # apply synthetic diagnostic: 49 | [pkf, pkf_hann, pkf_kx0ky0, pks, sigma_ks_hann] = syn_diag.get_syn_fspec( 50 | 0.7, 1, savedir, if_save 51 | ) 52 | 53 | syn_diag.plot_syn() 54 | -------------------------------------------------------------------------------- /docs/examples/figures/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/examples/figures/.DS_Store -------------------------------------------------------------------------------- /docs/examples/figures/ideal_ballooning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/examples/figures/ideal_ballooning.png -------------------------------------------------------------------------------- /docs/examples/ideal_ballooning.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | Ideal ballooning solver 3 | ======================= 4 | 5 | 6 | This example runs the ideal ballooning solver in pyrokinetics for a 7 | range of :math:`\hat{s}` and :math:`\beta` and plots this data 8 | 9 | .. literalinclude:: example_ideal_ballooning.py 10 | 11 | This would generate the following figure 12 | 13 | .. image:: figures/ideal_ballooning.png 14 | :width: 400 15 | 16 | Note this works for any `pyro` object independant of the `LocalGeometry` 17 | chosen. 18 | 19 | The algorithm used to solve the ideal ballooning equation was taken from 20 | `ideal-ballooning-solver`_ 21 | 22 | .. _ideal-ballooning-solver: https://github.com/rahulgaur104/ideal-ballooning-solver 23 | -------------------------------------------------------------------------------- /docs/examples/index.rst: -------------------------------------------------------------------------------- 1 | .. _sec-example-list: 2 | 3 | ========== 4 | Examples 5 | ========== 6 | 7 | Several example scripts detailing how to use Pyrokinetics can be found `here`_ 8 | 9 | 10 | Here we walk through how to use pyrokinetics for a few of the example use 11 | cases: 12 | 13 | .. toctree:: 14 | :glob: 15 | 16 | * 17 | 18 | .. _reStructuredText Primer: 19 | .. _here: https://github.com/pyro-kinetics/pyrokinetics/tree/unstable/docs/examples 20 | -------------------------------------------------------------------------------- /docs/examples/load_jetto.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Load JETTO data 3 | ================ 4 | 5 | 6 | This example just loads a JETTO input file 7 | 8 | .. literalinclude:: example_JETTO.py 9 | 10 | Notice that we don't have to tell `Pyro` which kind of equilibrium 11 | file is used, as it can auto-detect this from the file 12 | itself. You also do not need to specify the kinetics type as `JETTO` 13 | 14 | JETTO profile is 2D so you have the option to select the time via 15 | selection or indexing using the argument `kinetics_kwargs={"time": 550}` 16 | -------------------------------------------------------------------------------- /docs/examples/load_transp.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Load TRANSP data 3 | ================= 4 | 5 | 6 | This example just loads a TRANSP input file 7 | 8 | .. literalinclude:: example_TRANSP.py 9 | 10 | Notice that we don't have to tell `Pyro` which kind of equilibrium 11 | file is used, as it can auto-detect this from the file 12 | itself. You also do not need to specify the kinetics type as `JETTO` 13 | 14 | TRANSP profile is 2D so you have the option to select the time via 15 | selection or indexing using the argument `kinetics_kwargs={"time": 550}` 16 | 17 | TRANSP also stores the equilibrium file so that can be used as well. 18 | Note below the code uses the auto-detect method built into pyro. In this 19 | example we select the 10th time slice for the equilibrium and profiles 20 | 21 | .. code:: python 22 | 23 | from pyrokinetics import Pyro, template_dir 24 | 25 | # Equilibrium file 26 | eq_file = template_dir / "transp.cdf" 27 | 28 | # Kinetics data file 29 | kinetics_file = template_dir / "transp.cdf" 30 | 31 | # Load up pyro object 32 | pyro = Pyro( 33 | eq_file=eq_file, 34 | eq_kwargs={"time_index": 10}, 35 | kinetics_file=kinetics_file, 36 | kinetics_kwargs={"time_index": 10}, 37 | ) 38 | 39 | pyro.local_geometry = "Miller" 40 | 41 | # Generate local Miller parameters at psi_n=0.5 42 | pyro.load_local(psi_n=0.5) 43 | 44 | pyro.gk_code = "GS2" 45 | 46 | pyro.write_gk_file(file_name="test_transp.in") 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/examples/parameter_scan.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Parameter scans 3 | =============== 4 | 5 | 6 | This example generates an input file from a JETTO output and then 7 | writes a series of input files covering a scan in :math:`k_y\rho_s` 8 | and :math:`a/L_{Te}` for GS2. This is done by using a dictionary 9 | stating the parameter name and values. 10 | 11 | .. literalinclude:: example_JETTO_1dscan.py 12 | 13 | :math:`k_y\rho_s` is a pre-defined parameter to scan through, but we 14 | can add in custom parameters using the `PyroScan.add_parameter_key` 15 | function in the `PyroScan` object which tells pyrokinetics how to find 16 | the relevant parameter 17 | 18 | More details on parameter scans can be found in `sec-nd-parameter-scans` 19 | -------------------------------------------------------------------------------- /docs/examples/pyro_example.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Pyro basic usage 3 | ================ 4 | 5 | 6 | This example shows several different ways you can use Pyrokinetics. 7 | Below we instantiate a `Pyro` object from a gyrokinetic input file 8 | as well as a Equilibrium/Kinetic profiles files. From there we are 9 | able to write gyrokinetic input files that be can ran as normal. 10 | 11 | .. literalinclude:: example_pyro.py 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/examples/read_output.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Read GK Outputs 3 | =============== 4 | 5 | 6 | Once a gyrokinetic simulation is complete it is possible to load the 7 | outputs from this simulation (both linear and nonlinear) into a 8 | `GKOutput` object. 9 | 10 | .. literalinclude:: example_read_gs2_output.py 11 | 12 | More information about the outputs can be found `sec-linear-outputs` and `sec-read-nonlinear-data` 13 | 14 | -------------------------------------------------------------------------------- /docs/howtos/convert.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Convert input files from code A to code B 3 | =========================================== 4 | 5 | One way to do this is from the command line: 6 | 7 | .. code:: console 8 | 9 | $ pyro convert CGYRO "my_gs2_file.in" -o "input.cgyro" 10 | 11 | Pyrokinetics will automatically detect the type of the input file. Note 12 | that when converting between codes only the data stored in `LocalGeometry`, 13 | `LocalSpecies` and `Numerics` is transferred over. Any other CGYRO input 14 | parameters are taking from a template file in `pyrokinetics.template_dir` 15 | 16 | This is effectively the same as doing the following in a python script 17 | 18 | .. code:: python 19 | 20 | from pyrokinetics import Pyro 21 | 22 | # Point to GS2 input file 23 | gs2_template = "my_gs2_file.in" 24 | 25 | # Load in GS2 file 26 | pyro = Pyro(gk_file=gs2_template) 27 | 28 | # Switch to CGYRO 29 | pyro.gk_code = "CGYRO" 30 | 31 | # Write CGYRO input file 32 | pyro.write_gk_file(file_name="input.cgyro") 33 | 34 | 35 | If you have your own template CGYRO input file with specific flags 36 | turned on you can do the following 37 | 38 | 39 | .. code:: console 40 | 41 | $ pyro convert CGYRO "my_gs2_file.in" -o "input.cgyro" --template "my_cgyro_template_file.in" 42 | 43 | Or in a python console for the last line simply do 44 | 45 | 46 | .. code:: python 47 | 48 | # Write CGYRO input file using a CGYRO template file 49 | pyro.write_gk_file(file_name="input.cgyro", template_file="my_cgyro_template_file.in") 50 | 51 | -------------------------------------------------------------------------------- /docs/howtos/figures/CGYRO_ky_flux_spectrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/CGYRO_ky_flux_spectrum.png -------------------------------------------------------------------------------- /docs/howtos/figures/CGYRO_phi_kxky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/CGYRO_phi_kxky.png -------------------------------------------------------------------------------- /docs/howtos/figures/CGYRO_total_heat_timetrace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/CGYRO_total_heat_timetrace.png -------------------------------------------------------------------------------- /docs/howtos/figures/GS2_eigenfunction_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/GS2_eigenfunction_plot.png -------------------------------------------------------------------------------- /docs/howtos/figures/GS2_ion_linear_flux_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/GS2_ion_linear_flux_plot.png -------------------------------------------------------------------------------- /docs/howtos/figures/GS2_linear_phi_field_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/GS2_linear_phi_field_plot.png -------------------------------------------------------------------------------- /docs/howtos/figures/GS2_mode_frequency_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/GS2_mode_frequency_plot.png -------------------------------------------------------------------------------- /docs/howtos/figures/jet_example_scatloc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/howtos/figures/jet_example_scatloc.png -------------------------------------------------------------------------------- /docs/howtos/index.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | How-to Guides 3 | =============== 4 | 5 | .. todo:: 6 | These how-to guides give an overview of how to accomplish different 7 | tasks with pyrokinetics, and signpost the user towards more 8 | detailed documentation 9 | 10 | How do I...? 11 | 12 | .. toctree:: 13 | :glob: 14 | 15 | * 16 | 17 | .. todo:: 18 | Write all of these 19 | 20 | - Read kinetics/equilibrium data from A and make input file for gk code B... 21 | - Look at linear/nonlinear outputs... 22 | - Run a scan in parameter A, B, C... 23 | - Generation of input files from data sources like GEQDSK and TRANSP... 24 | - Conversion of input files from one GK code to another... 25 | - Cross-code validation for simple and complicated geometries... 26 | - Performing scans using the code... 27 | - Reading and plotting of basic output data... 28 | - More advanced output analysis (Poincare plots, field line tearing, non-zonal transitions)... 29 | - Applications of generation database for ML training... 30 | - Synthetic diagnostic comparisons... 31 | - Using GK outputs with QL saturation rules... 32 | - Submitting simulations to databases (simDB, GKDB) via IMAS DD... 33 | - Submitting jobs to cluster... 34 | - Storing metadata of simulations... 35 | - Access metric elements (jacobian, gxx, gxy, etc…)... 36 | - How to use synthetic diagnostics... 37 | -------------------------------------------------------------------------------- /docs/howtos/merge_species.rst: -------------------------------------------------------------------------------- 1 | .. _sec-merge-species-docs: 2 | 3 | ============================================= 4 | Merge (multiple) species into a base species 5 | ============================================= 6 | 7 | In the interest of computational gain, it may be useful to combine multiple species into a single species. A simple approach is to perform a density-weighted average which preserves quasineutrality. The attributes density (:math:`n`), charge (:math:`z`), density gradient (:math:`1/L_n`) and mass (:math:`M`) of the new species can be calculated as (for example): 8 | 9 | .. math:: 10 | 11 | \begin{align*} 12 | n_m &= \sum_s n_s \\ 13 | z_m &= \frac{\sum_s (z_s n_s)}{ n_m } \\ 14 | M_m &= \frac{\sum_s (M_s n_s)} {n_m} \\ 15 | 1/L_{n_m} &= \frac{\sum_s (z_s n_s(1/L_{n_s}))} { z_m n_m } 16 | \end{align*} 17 | 18 | The summation :math:`\sum_s` is over all the species :math:`s` participating in the merge, whereas the subscript :math:`m` represents the merged-species. The optional argument ``keep_base_species_z = True`` preserves the charge of the base species and adjusts the merged density, whereas ``keep_base_species_z = False`` preserves the number density of the ions (before and after the merge) and adjusts the charge state to ensure a quasineutral plasma. Both methods give the same density gradient. We can either choose to retain the mass of the base species by setting ``keep_base_species_mass = True``, or if ``False``, then depending on the logical value of ``keep_base_species_z`` (affects density), the new merged mass can assume (very) different values. 19 | 20 | .. attention:: 21 | The flag ``keep_base_species_z = False`` preserves the kinetic pressure before and after the merge along with ensuring quasineutrality. However, the option ``keep_base_species_z = True`` changes the total pressure contained in the species as quasineutrality is maintained. 22 | 23 | 24 | This is achieved in ``pyrokinetics`` as follows: 25 | 26 | .. code-block:: python 27 | 28 | >>> from pyrokinetics import template_dir, Pyro 29 | >>> 30 | >>> # point to equilibrium and kinetics files 31 | >>> eq_file = template_dir / "test.geqdsk" 32 | >>> kinetics_file = template_dir / "jetto.jsp" 33 | >>> 34 | >>> # create pyro object which contains global properties 35 | >>> pyro = Pyro( 36 | eq_file=eq_file, 37 | kinetics_file=kinetics_file, 38 | kinetics_type="JETTO", 39 | kinetics_kwargs={"time": 550}, 40 | ) 41 | >>> 42 | >>> # generate local parameters at psi_n=0.5 43 | >>> pyro.load_local(psi_n=0.5, local_geometry="Miller") 44 | >>> 45 | >>> # merge species `impurity1` into `deuterium` (and remove impurity1 attributes) 46 | >>> # by calling the merge_local method 47 | >>> pyro.local_species.merge_species('deuterium',['impurity1']) 48 | >>> 49 | >>> # now write to your choice of GK code input (e.g. GENE) 50 | >>> pyro.write_gk_file(file_name="input.gene", gk_code="GENE") 51 | 52 | A script `example_merge_species.py` is provided which does this. 53 | -------------------------------------------------------------------------------- /docs/howtos/read_eq_prof.rst: -------------------------------------------------------------------------------- 1 | ==================================================== 2 | Generate an input file from equilibrium and profiles 3 | ==================================================== 4 | 5 | Here a step-by-step guide on how to generate an input file 6 | for any gyrokinetic codes supported in ``pyrokinetics``, 7 | starting from equilibrium and profile files. 8 | 9 | 10 | Let's first import ``pyrokinetics`` and define our equilibrium and input files. 11 | 12 | .. code-block:: python 13 | 14 | >>> from pyrokinetics import Pyro, template_dir 15 | >>> eq_file = template_dir / "test.geqdsk" 16 | >>> kinetics_file = template_dir / "jetto.jsp" 17 | >>> gk_file = template_dir / "input.cgyro" 18 | 19 | The equilibrium file ``test.geqdsk`` and the kinetics file ``jetto.jsp`` 20 | are stored in the template folder and used here as an example. 21 | The gyrokinetic file ``input.cgyro`` is our input file template where 22 | we set all the extra flags we need. The input parameters related to the 23 | geometry and species will be added to this template by ``pyrokinetics``. 24 | We now load these files into ``pyrokinetics``: 25 | 26 | .. code-block:: python 27 | 28 | >>> pyro = Pyro( 29 | eq_file=eq_file, 30 | kinetics_file=kinetics_file, 31 | kinetics_type="JETTO", 32 | kinetics_kwargs={"time": 550}, 33 | gk_file=gk_file, 34 | ) 35 | 36 | 37 | During initialization, `Pyro` calls `read_equilibrium` from 38 | the class `Equilibrium` and initializes the class `Kinetics`. 39 | The global equilibrium and profiles are now stored in ``pyro``. 40 | Let's suppose we want to generate an input file for a local gyrokinetic 41 | simulation at :math:`\Psi_n = 0.5`. This requires loading the local geometry 42 | at the chosen surface, which can be done by simply calling the ``load_local`` method: 43 | 44 | .. code-block:: python 45 | 46 | >>> pyro.load_local(psi_n=0.5, local_geometry="Miller") 47 | 48 | Here we have used the ``Miller`` parametrization of the local surface. Other 49 | parametrizations are possible in ``pyrokinetics``. See the output of ``pyro.supported_local_geometries``. 50 | Before generating an input file, we need to specify ``gk_code``: 51 | 52 | .. code-block:: python 53 | 54 | >>> pyro.gk_code = "CGYRO" 55 | 56 | Note that ``gk_code`` can be any code supported in ``pyrokinetics``, which can 57 | be found in ``pyro.supported_gk_inputs``. 58 | We are now ready to write our input file: 59 | 60 | .. code-block:: python 61 | 62 | >>> pyro.write_gk_file(file_name="test_jetto.cgyro") 63 | 64 | Alternatively, ``gk_code`` can be pass as keyword argument to ``write_gk_file``, 65 | 66 | .. code-block:: python 67 | 68 | >>> pyro.write_gk_file(file_name="test_jetto.cgyro", gk_code="CGYRO") 69 | 70 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | This project aims to standardise gyrokinetic analysis by providing a single 5 | interface for reading and writing input and output files from different 6 | gyrokinetic codes, normalising to a common standard, and performing standard 7 | analysis methods. 8 | 9 | A general ``Pyro`` object can be loaded either from simulation/experimental data or 10 | from an existing gyrokinetics file. 11 | 12 | Currently pyrokinetics can do the following: 13 | 14 | - Read data in from: 15 | 16 | - Gyrokinetic input files 17 | - Integrated modelling/Global Equilibrium simulation output 18 | 19 | - Write input files for various gyrokinetics codes 20 | - Generate N-D ``Pyro`` object for scans 21 | - Read in gyrokinetic outputs 22 | - Standardise analysis of gyrokinetics outputs 23 | 24 | Future development includes: 25 | 26 | - Submit gyrokinetics simulations to cluster 27 | - Integrate with GKDB to store/catalog GK runs 28 | 29 | At a minimum pyrokinetics needs the local geometry and species data. This can be 30 | taken from a GK input file. At the moment the following local gyrokinetic codes 31 | are supported: 32 | 33 | - `GS2 `_ 34 | - `CGYRO `_ 35 | - `GENE `_ 36 | - `STELLA `_ 37 | - `TGLF `_ 38 | - `GKW `_ 39 | - `GX `_ 40 | 41 | It is also possible to load in global data from the following codes, from which 42 | local parameters can be calculated. 43 | 44 | - `TRANSP `_ 45 | - JETTO 46 | - SCENE 47 | - `IMAS `_ 48 | - `GACODE `_ 49 | - ELITEINP 50 | - `GEQDSK `_ 51 | - PFILE 52 | 53 | 54 | .. toctree:: 55 | :maxdepth: 2 56 | :caption: User Guide 57 | 58 | Getting Started 59 | User Guide 60 | How-to Guides 61 | Examples 62 | Tutorials 63 | 64 | .. toctree:: 65 | :maxdepth: 2 66 | :caption: Reference 67 | 68 | API Reference 69 | 70 | .. toctree:: 71 | :maxdepth: 2 72 | :caption: Developer Guide 73 | 74 | Contributing Guide 75 | Writing Documentation 76 | 77 | Indices and tables 78 | ================== 79 | 80 | * :ref:`genindex` 81 | * :ref:`modindex` 82 | * :ref:`search` 83 | -------------------------------------------------------------------------------- /docs/joss/paper.bib: -------------------------------------------------------------------------------- 1 | @article{giacomin:2023a, 2 | title={Nonlinear microtearing modes in MAST and their stochastic layer formation}, 3 | author={Giacomin, Maurizio and Dickinson, David and Kennedy, Daniel and Patel, BS and Roach, CM}, 4 | journal={Plasma Physics and Controlled Fusion}, 5 | volume={65}, 6 | number={9}, 7 | pages={095019}, 8 | year={2023}, 9 | publisher={IOP Publishing}, 10 | doi={10.1088/1361-6587/aceb89}, 11 | } 12 | 13 | @article{giacomin:2023b, 14 | title={Electromagnetic gyrokinetic instabilities in the Spherical Tokamak for Energy Production (STEP) part II: transport and turbulence}, 15 | author={Giacomin, Maurizio and Kennedy, Daniel and Casson, Francis J and Dickinson, David and Patel, Bhavin S and Roach, Colin M and others}, 16 | journal={arXiv preprint arXiv:2307.01669}, 17 | year={2023}, 18 | doi={10.48550/arXiv.2307.01669}, 19 | } 20 | 21 | @article{kennedy:2023, 22 | title={Electromagnetic gyrokinetic instabilities in the Spherical Tokamak for Energy Production (STEP) part I: linear physics and sensitivity}, 23 | author={Kennedy, Daniel and Giacomin, Maurizio and Casson, Francis J and Dickinson, David and Hornsby, William A and Patel, Bhavin S and Roach, Colin M}, 24 | journal={arXiv preprint arXiv:2307.01670}, 25 | year={2023}, 26 | doi={10.48550/arXiv.2307.01670}, 27 | } 28 | 29 | @article{hornsby:2023, 30 | title={Gaussian Process Regression models for the properties of micro-tearing modes for spherical tokamaks}, 31 | author={W.A Hornsby, A. Gray, J. Buchanan, B.S. Patel, D. Kennedy, F.J. Casson, C. Roach, M. B. Lykkegaard, H.Nguyen, N. Papadimas, B. Fourcin, J. Hart}, 32 | journal={arXiv preprint arXiv:2309.09785}, 33 | year={2023}, 34 | doi={10.48550/arXiv.2309.09785}, 35 | } 36 | 37 | @article{imbeaux:2015, 38 | title={Design and first applications of the ITER integrated modelling \& analysis suite}, 39 | author={Imbeaux, Fr{\'e}d{\'e}ric and Pinches, SD and Lister, JB and Buravand, Y and Casper, T and Duval, Basil and Guillerminet, B and Hosokawa, Masanari and Houlberg, Wayne and Huynh, Philippe and others}, 40 | journal={Nuclear Fusion}, 41 | volume={55}, 42 | number={12}, 43 | pages={123006}, 44 | year={2015}, 45 | publisher={IOP Publishing}, 46 | doi={10.1088/0029-5515/55/12/123006}, 47 | } 48 | 49 | @article{pankin:2004, 50 | title={The tokamak Monte Carlo fast ion module NUBEAM in the National Transport Code Collaboration library}, 51 | author={Pankin, Alexei and McCune, Douglas and Andre, Robert and Bateman, Glenn and Kritz, Arnold}, 52 | journal={Computer Physics Communications}, 53 | volume={159}, 54 | number={3}, 55 | pages={157--184}, 56 | year={2004}, 57 | publisher={Elsevier}, 58 | doi={10.1016/j.cpc.2003.11.002}, 59 | } 60 | 61 | @article{cenacchi:1988, 62 | title={JETTO: A free-boundary plasma transport code (basic version) Report JET-IR (88) 03 JET Joint Undertaking}, 63 | author={Cenacchi, G and Taroni, A}, 64 | journal={Joint European Torus}, 65 | year={1988} 66 | } -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/tutorials/figures/equilibrium_composite_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/tutorials/figures/equilibrium_composite_plot.png -------------------------------------------------------------------------------- /docs/tutorials/figures/equilibrium_contour_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/tutorials/figures/equilibrium_contour_plot.png -------------------------------------------------------------------------------- /docs/tutorials/figures/equilibrium_q_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/tutorials/figures/equilibrium_q_plot.png -------------------------------------------------------------------------------- /docs/tutorials/figures/flux_surface_b_poloidal_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/tutorials/figures/flux_surface_b_poloidal_plot.png -------------------------------------------------------------------------------- /docs/tutorials/figures/flux_surface_path_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/tutorials/figures/flux_surface_path_plot.png -------------------------------------------------------------------------------- /docs/tutorials/index.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Tutorials 3 | =========== 4 | 5 | These are in-depth guides to using, developing, and extending pyrokinetics 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | :glob: 10 | 11 | * 12 | -------------------------------------------------------------------------------- /docs/user_guide/analysis.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Analysis 3 | ========== 4 | 5 | Once you have a completed simulation, you can read the output into a 6 | `Pyro` object. By default, some common analysis is either read from 7 | the output file(s) or automatically performed for you. 8 | 9 | - :class:`GKOutputReader` 10 | 11 | - Accessed via ``pyro.gk_output`` 12 | - Stores output from a GK simulation 13 | - Data stored in `Xarray `_ ``Datasets`` 14 | -------------------------------------------------------------------------------- /docs/user_guide/figures/equilibrium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/user_guide/figures/equilibrium.png -------------------------------------------------------------------------------- /docs/user_guide/figures/gk_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/user_guide/figures/gk_code.png -------------------------------------------------------------------------------- /docs/user_guide/figures/kinetics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/user_guide/figures/kinetics.png -------------------------------------------------------------------------------- /docs/user_guide/figures/pyro_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/docs/user_guide/figures/pyro_structure.png -------------------------------------------------------------------------------- /docs/user_guide/getting_started.rst: -------------------------------------------------------------------------------- 1 | .. _sec-getting-started: 2 | 3 | ================= 4 | Getting Started 5 | ================= 6 | 7 | Installation 8 | ------------ 9 | 10 | Install pyrokinetics with pip as follows: 11 | 12 | 13 | .. code-block:: bash 14 | 15 | $ pip install --user pyrokinetics 16 | 17 | 18 | Otherwise, for the latest version install directly with: 19 | 20 | 21 | .. code-block:: bash 22 | 23 | $ git clone https://github.com/pyro-kinetics/pyrokinetics.git 24 | $ cd pyrokinetics 25 | $ pip install . 26 | 27 | 28 | If you are developing pyrokinetics: 29 | 30 | .. code-block:: bash 31 | 32 | $ pip install -e .[docs,tests] 33 | 34 | 35 | Command Line Interface 36 | ---------------------- 37 | 38 | After installing, simple pyrokinetics operations can be performed on the command line 39 | using either of the following methods: 40 | 41 | .. code:: console 42 | 43 | $ python3 -m pyrokinetics {args...} 44 | $ pyro {args...} 45 | 46 | For example, to convert a GS2 input file to CGYRO: 47 | 48 | .. code:: console 49 | 50 | $ pyro convert CGYRO "my_gs2_file.in" -o "input.cgyro" 51 | 52 | You can get help on how to use the command line interface or any of its subcommands 53 | by providing ``-h`` or ``--help``: 54 | 55 | .. code:: console 56 | 57 | $ pyro --help 58 | $ pyro convert --help 59 | 60 | 61 | Library 62 | ------- 63 | 64 | Example scripts can be found in the examples folder where GK/Transport code data 65 | is read in and GK outputs are read in. Here's how you could generate input files 66 | for GS2, CGYRO, and GENE from one SCENE equilibrium:: 67 | 68 | from pyrokinetics import Pyro 69 | 70 | # Create a Pyro object from GEQDSK and SCENE files 71 | # By setting 'gk_code' to "CGYRO", we implicitly load a CGYRO input file template 72 | # All file types are inferred automatically 73 | pyro = Pyro( 74 | gk_code="CGYRO", 75 | eq_file="test.geqdsk", 76 | kinetics_file="scene.cdf", 77 | ) 78 | 79 | # Generate local Miller parameters at psi_n=0.5 80 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 81 | 82 | # Write CGYRO input file using default template 83 | pyro.write_gk_file(file_name="test_scene.cgyro", gk_code="CGYRO") 84 | 85 | # Write single GS2 input file 86 | pyro.write_gk_file(file_name="test_scene.gs2", gk_code="GS2") 87 | 88 | # Write single GENE input file 89 | pyro.write_gk_file(file_name="test_scene.gene", gk_code="GENE") 90 | -------------------------------------------------------------------------------- /docs/user_guide/index.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | User Guide 3 | ============ 4 | 5 | In this section you can find high-level descriptions of the various 6 | components of pyrokinetics, as well as some of the more important 7 | background maths and physics. 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | structure 13 | analysis 14 | miller 15 | metric_terms 16 | collisions 17 | modify_shear 18 | -------------------------------------------------------------------------------- /docs/user_guide/structure.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Structure 3 | =========== 4 | 5 | The central interface of pyrokinetics is the `Pyro` class. Its main 6 | components are as follows: 7 | 8 | - `Equilibrium` 9 | 10 | - Accessed via ``pyro.eq`` 11 | - Represents full 2D equilibrium 12 | - Only loaded when full equilibrium data is provided 13 | 14 | - :py:class:`.LocalGeometry` 15 | 16 | - Accessed via ``pyro.local_geometry`` 17 | - Represents local geometry of a flux surface 18 | - Current supported :class:`.LocalGeometry` subclasses are: 19 | 20 | - :class:`.LocalGeometryMiller` (see also :ref:`sec-miller`) 21 | - :class:`.LocalGeometryMillerTurnbull` 22 | - :class:`.LocalGeometryMXH` 23 | - :class:`.LocalGeometryFourierCGYRO` 24 | - :class:`.LocalGeometryFourierGENE` 25 | 26 | - :py:class:`.Kinetics` 27 | 28 | - Accessed via ``pyro.kinetics`` 29 | - Represents 1D profiles for each kinetic species 30 | - Only loaded when full profile data is provided 31 | 32 | - `LocalSpecies` 33 | 34 | - Accessed via ``pyro.local_species`` 35 | - Contains local species parameters 36 | 37 | - `Numerics` 38 | 39 | - Accessed via ``pyro.numerics`` 40 | - Sets up numerical grid and certain physics models 41 | 42 | - :py:class:`.GKInput` 43 | 44 | - Accessed via ``pyro.gk_input`` 45 | - Holds gyrokinetics input data and methods specific to each gyrokinetics code 46 | - Can be used to directly populate :py:class:`.LocalGeometry` and `LocalSpecies` 47 | - Used to set `Numerics` 48 | 49 | * `normalisation` 50 | 51 | * Accessed via ``pyro.norms`` 52 | * Holds physical reference values 53 | * Allows automatic conversion between different normalisation conventions 54 | 55 | .. image:: figures/pyro_structure.png 56 | :width: 600 57 | -------------------------------------------------------------------------------- /src/pyrokinetics/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pyrokinetics 3 | ============ 4 | 5 | Python package for running and analysising GK data 6 | 7 | 8 | .. moduleauthor:: Bhavin Patel 9 | 10 | License 11 | ------- 12 | Copyright 2023 UKAEA 13 | Email: bhavin.s.patel@ukaea.uk 14 | Pyrokinetics is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | Pyrokinetics is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with Pyrokinetics. If not, see . 24 | """ 25 | 26 | from .equilibrium import ( 27 | Equilibrium, 28 | FluxSurface, 29 | read_equilibrium, 30 | supported_equilibrium_types, 31 | ) 32 | from .kinetics import Kinetics, read_kinetics, supported_kinetics_types 33 | from .metadata import __commit__, __version__ 34 | from .numerics import Numerics 35 | from .pyro import Pyro 36 | from .pyroscan import PyroScan 37 | from .templates import eq_templates, gk_templates, kinetics_templates, template_dir 38 | 39 | __all__ = [ 40 | "__version__", 41 | "Pyro", 42 | "PyroScan", 43 | "template_dir", 44 | "Equilibrium", 45 | "FluxSurface", 46 | "read_equilibrium", 47 | "supported_equilibrium_types", 48 | "Kinetics", 49 | "read_kinetics", 50 | "supported_kinetics_types", 51 | "Numerics", 52 | "gk_templates", 53 | "eq_templates", 54 | "kinetics_templates", 55 | ] 56 | -------------------------------------------------------------------------------- /src/pyrokinetics/__main__.py: -------------------------------------------------------------------------------- 1 | from .cli import entrypoint 2 | 3 | if __name__ == "__main__": 4 | entrypoint() 5 | -------------------------------------------------------------------------------- /src/pyrokinetics/cli/__init__.py: -------------------------------------------------------------------------------- 1 | from .entrypoint import entrypoint 2 | 3 | __all__ = ["entrypoint"] 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/cli/entrypoint.py: -------------------------------------------------------------------------------- 1 | from argparse import ArgumentParser 2 | from textwrap import dedent 3 | 4 | from .convert import add_arguments as convert_add_arguments 5 | from .convert import description as convert_description 6 | from .convert import main as convert_main 7 | from .generate import add_arguments as generate_add_arguments 8 | from .generate import description as generate_description 9 | from .generate import main as generate_main 10 | 11 | 12 | def entrypoint() -> None: 13 | """ 14 | The entrypoint for the Command Line Interface (CLI). Uses ``argparse`` to handle 15 | command line arguments, and makes use of subparsers to delegate tasks across 16 | multiple functions. 17 | """ 18 | 19 | # Set up ArgumentParser and subparsers 20 | parser = ArgumentParser( 21 | prog="Pyrokinetics", 22 | description="A tool to run and analyse gyrokinetics simulations.", 23 | ) 24 | subparsers = parser.add_subparsers( 25 | description=dedent( 26 | """\ 27 | Please provide one of the following subcommands as a positional argument. 28 | For information on how each subcommand works, try providing '--help' after 29 | the subcommand. 30 | """ 31 | ), 32 | dest="subcommand", 33 | ) 34 | 35 | # Add a subparser for each subcommand. These should provide a short description 36 | # string, and two functions: 37 | # - add_arguments(parser): Add arguments to their own subparser. Takes the subparser 38 | # as its only argument. 39 | # - main(args): Run the subroutine. Takes an argparse Namespace object as the only 40 | # argument, and must unpack the Namespace itself. 41 | # The parser should then set it's default 'main' arg to the corresponding main 42 | # function, and the add_arguments function should set up the required arguments. 43 | convert_parser = subparsers.add_parser("convert", help=convert_description) 44 | convert_parser.set_defaults(main=convert_main) 45 | convert_add_arguments(convert_parser) 46 | 47 | generate_parser = subparsers.add_parser("generate", help=generate_description) 48 | generate_parser.set_defaults(main=generate_main) 49 | generate_add_arguments(generate_parser) 50 | 51 | args = parser.parse_args() 52 | 53 | # If user provided no subcommand, print help text 54 | if args.subcommand is None: 55 | parser.print_help() 56 | parser.exit() 57 | 58 | args.main(args) 59 | -------------------------------------------------------------------------------- /src/pyrokinetics/constants.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy import constants 3 | 4 | from .units import ureg as units 5 | 6 | bk = constants.k 7 | pi = constants.pi 8 | mu0 = constants.mu_0 9 | eps0 = constants.epsilon_0 10 | 11 | electron_charge = constants.elementary_charge * units.elementary_charge 12 | 13 | electron_mass = constants.electron_mass * units.kg 14 | hydrogen_mass = constants.proton_mass * units.kg 15 | deuterium_mass = constants.physical_constants["deuteron mass"][0] * units.kg 16 | tritium_mass = constants.physical_constants["triton mass"][0] * units.kg 17 | 18 | sqrt2 = np.sqrt(2) 19 | -------------------------------------------------------------------------------- /src/pyrokinetics/databases/__init__.py: -------------------------------------------------------------------------------- 1 | from .imas import ids_to_pyro, pyro_to_ids 2 | 3 | __all__ = ["pyro_to_ids", "ids_to_pyro"] 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/decorators.py: -------------------------------------------------------------------------------- 1 | def not_implemented(func): 2 | def wrapper_not_implemented(*args, **kwargs): 3 | self = args[0] 4 | raise NotImplementedError( 5 | f"{func.__name__} method not yet implemented for GK code {self.__class__.__name__}" 6 | ) 7 | 8 | return wrapper_not_implemented 9 | -------------------------------------------------------------------------------- /src/pyrokinetics/equilibrium/__init__.py: -------------------------------------------------------------------------------- 1 | # isort: skip_file 2 | 3 | from .equilibrium import ( 4 | Equilibrium, 5 | EquilibriumCOCOSWarning, 6 | read_equilibrium, 7 | supported_equilibrium_types, 8 | ) 9 | from .flux_surface import FluxSurface 10 | 11 | # Import each module to register the associated readers 12 | from . import geqdsk # noqa 13 | from . import transp # noqa 14 | from . import gacode # noqa 15 | from . import imas # noqa 16 | from . import eliteinp 17 | 18 | from ..plugins import register_file_reader_plugins 19 | 20 | register_file_reader_plugins("equilibrium", Equilibrium) 21 | 22 | __all__ = [ 23 | "Equilibrium", 24 | "EquilibriumCOCOSWarning", 25 | "read_equilibrium", 26 | "supported_equilibrium_types", 27 | "FluxSurface", 28 | ] 29 | -------------------------------------------------------------------------------- /src/pyrokinetics/equilibrium/utils.py: -------------------------------------------------------------------------------- 1 | from ..units import ureg as units 2 | 3 | # Define basic units, COCOS 11 4 | eq_units = { 5 | "len": units.meter, 6 | "psi": units.weber, 7 | "F": units.meter * units.tesla, 8 | "p": units.pascal, 9 | "q": units.dimensionless, 10 | "B": units.tesla, 11 | "I": units.ampere, 12 | } 13 | 14 | # Add derivatives 15 | eq_units["F_prime"] = eq_units["F"] / eq_units["psi"] 16 | eq_units["FF_prime"] = eq_units["F"] ** 2 / eq_units["psi"] 17 | eq_units["p_prime"] = eq_units["p"] / eq_units["psi"] 18 | eq_units["q_prime"] = eq_units["q"] / eq_units["psi"] 19 | eq_units["len_prime"] = eq_units["len"] / eq_units["psi"] 20 | -------------------------------------------------------------------------------- /src/pyrokinetics/gk_code/__init__.py: -------------------------------------------------------------------------------- 1 | from platform import python_version_tuple 2 | 3 | # Import built-in input and output readers to register them with GkInput and GkOutput. 4 | from .cgyro import GKInputCGYRO, GKOutputReaderCGYRO # noqa 5 | from .gene import GKInputGENE, GKOutputReaderGENE # noqa 6 | from .gk_input import GKInput, read_gk_input, supported_gk_input_types 7 | from .gk_output import GKOutput, read_gk_output, supported_gk_output_types 8 | from .gkw import GKInputGKW, GKOutputReaderGKW # noqa 9 | from .gs2 import GKInputGS2, GKOutputReaderGS2 # noqa 10 | from .gx import GKInputGX, GKOutputReaderGX # noqa 11 | from .stella import GKInputSTELLA, GKOutputReaderSTELLA # noqa 12 | from .tglf import GKInputTGLF, GKOutputReaderTGLF # noqa 13 | 14 | # Only import IDS if Python version is greater than 3.9 15 | if tuple(int(x) for x in python_version_tuple()[:2]) >= (3, 9): 16 | from .ids import GKOutputReaderIDS # noqa 17 | 18 | # Register external plugins 19 | from ..plugins import register_file_reader_plugins 20 | 21 | register_file_reader_plugins("gk_input", GKInput) 22 | register_file_reader_plugins("gk_output", GKOutput) 23 | 24 | __all__ = [ 25 | "GKInput", 26 | "GKOutput", 27 | "read_gk_input", 28 | "read_gk_output", 29 | "supported_gk_input_types", 30 | "supported_gk_output_types", 31 | ] 32 | -------------------------------------------------------------------------------- /src/pyrokinetics/kinetics/__init__.py: -------------------------------------------------------------------------------- 1 | # isort: skip_file 2 | 3 | from .kinetics import Kinetics, read_kinetics, supported_kinetics_types 4 | 5 | # Import each module to register the associated readers 6 | from .scene import KineticsReaderSCENE # noqa 7 | from .transp import KineticsReaderTRANSP # noqa 8 | from .pfile import KineticsReaderpFile # noqa 9 | from .jetto import KineticsReaderJETTO # noqa 10 | from .gacode import KineticsReaderGACODE # noqa 11 | from .imas import KineticsReaderIMAS # noqa 12 | from .eliteinp import KineticsReaderELITEINP # noqa 13 | 14 | from ..plugins import register_file_reader_plugins 15 | 16 | register_file_reader_plugins("kinetics", Kinetics) 17 | 18 | __all__ = ["Kinetics", "read_kinetics", "supported_kinetics_types"] 19 | -------------------------------------------------------------------------------- /src/pyrokinetics/local_geometry/__init__.py: -------------------------------------------------------------------------------- 1 | from .fourier_cgyro import LocalGeometryFourierCGYRO, default_fourier_cgyro_inputs 2 | from .fourier_gene import LocalGeometryFourierGENE, default_fourier_gene_inputs 3 | from .local_geometry import LocalGeometry, local_geometry_factory 4 | from .metric import MetricTerms 5 | from .miller import LocalGeometryMiller, default_miller_inputs 6 | from .miller_turnbull import LocalGeometryMillerTurnbull, default_miller_turnbull_inputs 7 | from .mxh import LocalGeometryMXH, default_mxh_inputs 8 | 9 | # Register LocalGeometry objects with factory 10 | local_geometry_factory["MillerTurnbull"] = LocalGeometryMillerTurnbull 11 | local_geometry_factory["Miller"] = LocalGeometryMiller 12 | local_geometry_factory["FourierGENE"] = LocalGeometryFourierGENE 13 | local_geometry_factory["MXH"] = LocalGeometryMXH 14 | local_geometry_factory["FourierCGYRO"] = LocalGeometryFourierCGYRO 15 | 16 | __all__ = [ 17 | "LocalGeometry", 18 | "local_geometry_factory", 19 | "default_miller_inputs", 20 | "default_miller_turnbull_inputs", 21 | "default_fourier_gene_inputs", 22 | "default_mxh_inputs", 23 | "default_fourier_cgyro_inputs", 24 | "MetricTerms", 25 | ] 26 | -------------------------------------------------------------------------------- /src/pyrokinetics/metadata.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | from datetime import datetime 3 | from typing import Dict 4 | 5 | try: 6 | from importlib.metadata import PackageNotFoundError, version 7 | except ModuleNotFoundError: 8 | from importlib_metadata import PackageNotFoundError, version 9 | try: 10 | __version__ = version("pyrokinetics") 11 | except PackageNotFoundError: 12 | try: 13 | from setuptools_scm import get_version 14 | 15 | __version__ = get_version(root="../..", relative_to=__file__) 16 | except ImportError: 17 | __version__ = "0.0.1" 18 | try: 19 | from ._version import __commit__ 20 | except ImportError: 21 | __commit__ = "COMMIT_UNKNOWN" 22 | 23 | 24 | # Define UUID and session start as module-level variables. 25 | # Determined at the first import, and should be fixed during each session. 26 | 27 | __session_uuid = uuid.uuid4() 28 | __session_start = datetime.now() 29 | 30 | 31 | def metadata(title: str, obj: str, **kwargs: str) -> Dict[str, str]: 32 | """ 33 | Return a dict of metadata which can be used to uniquely identify Pyrokinetics 34 | objects. Should be written to Pyrokinetics output files to establish their 35 | provenance. 36 | 37 | Parameters 38 | ---------- 39 | title: str 40 | A title to be assigned to the object. Recommended to use the object name if 41 | no other obvious title can be determined. 42 | obj: str 43 | The type of Pyrokinetics object, expressed as a string. It is recommended to 44 | use ``self.__class__.__name__`` in external classes. 45 | **kwargs: str 46 | Extra keywords to add to the returned dict. 47 | """ 48 | return { 49 | "title": str(title), 50 | "software_name": "Pyrokinetics", 51 | "software_version": __version__, 52 | "object_type": str(obj), 53 | "object_uuid": str(uuid.uuid4()), 54 | "object_created": str(datetime.now()), 55 | "session_uuid": str(__session_uuid), 56 | "session_started": str(__session_start), 57 | **kwargs, 58 | } 59 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | template_dir = Path(__file__).parent / "templates" 4 | template_dir.resolve() 5 | 6 | gk_gs2_template = template_dir / "input.gs2" 7 | gk_cgyro_template = template_dir / "input.cgyro" 8 | gk_gene_template = template_dir / "input.gene" 9 | gk_gkw_template = template_dir / "input.gkw" 10 | gk_tglf_template = template_dir / "input.tglf" 11 | gk_stella_template = template_dir / "input.stella" 12 | gk_gx_template = template_dir / "input.gx" 13 | gk_templates = { 14 | "GS2": gk_gs2_template, 15 | "CGYRO": gk_cgyro_template, 16 | "GENE": gk_gene_template, 17 | "GKW": gk_gkw_template, 18 | "TGLF": gk_tglf_template, 19 | "STELLA": gk_stella_template, 20 | "GX": gk_gx_template, 21 | } 22 | 23 | eq_geqdsk_template = template_dir / "test.geqdsk" 24 | eq_transp_template = template_dir / "transp.cdf" 25 | eq_gacode_template = template_dir / "input.gacode" 26 | eq_templates = { 27 | "GEQDSK": eq_geqdsk_template, 28 | "TRANSP": eq_transp_template, 29 | "GACODE": eq_gacode_template, 30 | } 31 | 32 | kinetics_scene_template = template_dir / "scene.cdf" 33 | kinetics_jetto_template = template_dir / "jetto.jsp" 34 | kinetics_transp_template = template_dir / "transp.cdf" 35 | kinetics_pFile_template = template_dir / "pfile.txt" 36 | kinetics_gacode_template = template_dir / "input.gacode" 37 | kinetics_templates = { 38 | "SCENE": kinetics_scene_template, 39 | "JETTO": kinetics_jetto_template, 40 | "TRANSP": kinetics_transp_template, 41 | "pFile": kinetics_pFile_template, 42 | "GACODE": kinetics_gacode_template, 43 | } 44 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/core_profiles.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/core_profiles.h5 -------------------------------------------------------------------------------- /src/pyrokinetics/templates/equilibrium.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/equilibrium.h5 -------------------------------------------------------------------------------- /src/pyrokinetics/templates/input.cgyro: -------------------------------------------------------------------------------- 1 | # Numerical Resolution 2 | N_ENERGY = 8 3 | E_MAX = 8 4 | N_XI = 24 5 | 6 | N_THETA = 32 7 | THETA_PLOT = 32 8 | N_RADIAL = 12 9 | N_TOROIDAL = 1 10 | 11 | N_FIELD = 3 12 | DELTA_T = 0.005 13 | PRINT_STEP = 100 14 | MAX_TIME = 300.0 15 | FREQ_TOL = 0.001 16 | 17 | KY = 0.1 18 | PX0 = 0.0 19 | BOX_SIZE = 1 20 | 21 | NONLINEAR_FLAG = 0 22 | 23 | # Geometry 24 | EQUILIBRIUM_MODEL = 2 25 | RMIN = 0.5 26 | RMAJ = 3.0 27 | ZMAG = 0.0 28 | DZMAG = 0.0 29 | KAPPA = 1.0 30 | S_KAPPA = 0.0 31 | DELTA = 0.0 32 | S_DELTA = 0.0 33 | ZETA = 0.0 34 | S_ZETA = 0.0 35 | SHIFT = 0.0 36 | BETAE_UNIT = 0.004862092554737736 37 | Q = 2.0 38 | S = 1.0 39 | 40 | BETA_STAR_SCALE = 1.0 41 | 42 | # Collisions 43 | COLLISION_MODEL = 4 44 | NU_EE = 0.14142135623730953 45 | 46 | Z_EFF = 1.0 47 | Z_EFF_METHOD = 1 48 | 49 | # Profiles 50 | N_SPECIES = 2 51 | 52 | Z_1 = 1 53 | DENS_1 = 1.0 54 | TEMP_1 = 1.0 55 | MASS_1 = 1.0 56 | DLNNDR_1 = 1.0 57 | DLNTDR_1 = 3.0 58 | 59 | Z_2 = -1 60 | DENS_2 = 1.0 61 | TEMP_2 = 1.0 62 | MASS_2 = 0.00027244 63 | DLNNDR_2 = 1.0 64 | DLNTDR_2 = 3.0 65 | 66 | FIELD_PRINT_FLAG = 1 67 | MOMENT_PRINT_FLAG = 1 68 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/input.gene: -------------------------------------------------------------------------------- 1 | ¶llelization 2 | n_parallel_sims = -1 3 | n_procs_s = -1 4 | n_procs_sim = -1 5 | n_procs_v = -1 6 | n_procs_w = -1 7 | n_procs_x = -1 8 | n_procs_y = -1 9 | n_procs_z = -1 10 | / 11 | 12 | &box 13 | kx_center = -0.0 14 | kymin = 0.1 15 | lv = 3.0 16 | lw = 9.0 17 | n_spec = 2 18 | nky0 = 1 19 | nv0 = 32 20 | nw0 = 16 21 | nx0 = 12 22 | nz0 = 32 23 | mu_grid_type = 'eq_vperp' 24 | / 25 | 26 | &in_out 27 | diagdir = '.' 28 | istep_energy = 100 29 | istep_field = 100 30 | istep_mom = 600 31 | istep_nrg = 20 32 | istep_schpt = 0 33 | istep_vsp = 0 34 | write_checkpoint = .true. 35 | / 36 | 37 | &general 38 | beta = 0.005 39 | bpar = .true. 40 | calc_dt = .true. 41 | coll = 0.000583570594217362 42 | coll_cons_model = 'nakata' 43 | collision_op = 'sugama' 44 | coll_on_h = .true. 45 | coll_f_fm_on = .true. 46 | comp_type = 'IV' 47 | debye2 = 0 48 | dt_max = 0.005 49 | hyp_v = 0.0 50 | hyp_z = -1 51 | init_cond = 'alm' 52 | nonlinear = .false. 53 | ntimesteps = 1000000 54 | simtimelim = 300.0 55 | timelim = 129000 56 | zeff = 1.0 57 | / 58 | 59 | &geometry 60 | amhd = 0.48 61 | delta = 0.0 62 | dpdx_pm = -2 63 | dpdx_term = 'full_drift' 64 | drr = 0.0 65 | kappa = 1.0 66 | magn_geometry = 'miller' 67 | major_r = 3.0 68 | minor_r = 1.0 69 | q0 = 2.0 70 | s_delta = 0.0 71 | s_kappa = 0.0 72 | s_zeta = 0.0 73 | shat = 1.0 74 | sign_bt_cw = 1 75 | sign_ip_cw = 1 76 | trpeps = 0.16666666666666666 77 | zeta = 0.0 78 | / 79 | 80 | &species 81 | charge = 1 82 | dens = 1.0 83 | mass = 1.0 84 | name = 'ion' 85 | omn = 1.0 86 | omt = 3.0 87 | temp = 1.0 88 | / 89 | 90 | &species 91 | charge = -1 92 | dens = 1.0 93 | mass = 0.00027244 94 | name = 'electron' 95 | omn = 1.0 96 | omt = 3.0 97 | temp = 1.0 98 | / 99 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/input.gs2: -------------------------------------------------------------------------------- 1 | &kt_grids_knobs 2 | grid_option = 'single' 3 | / 4 | 5 | &kt_grids_single_parameters 6 | aky = 0.14142135623730953 7 | theta0 = 0.0 8 | / 9 | 10 | &theta_grid_parameters 11 | akappa = 1.0 12 | akappri = 0.0 13 | geotype = 0 14 | nperiod = 6 15 | ntheta = 32 16 | qinp = 2.0 17 | r_geo = 3.0 18 | rhoc = 0.5 19 | rmaj = 3.0 20 | shat = 4.0 21 | shift = 0.0 22 | tri = 0.0 23 | tripri = 0.0 24 | / 25 | 26 | &theta_grid_knobs 27 | equilibrium_option = 'eik' 28 | / 29 | 30 | &theta_grid_eik_knobs 31 | beta_prime_input = -0.04 32 | bishop = 4 33 | iflux = 0 34 | irho = 2 35 | local_eq = .true. 36 | s_hat_input = 1.0 37 | writelots = .true. 38 | ntheta_geometry = 1024 39 | / 40 | 41 | &le_grids_knobs 42 | nesub = 6 43 | nesuper = 4 44 | npassing = 7 45 | / 46 | 47 | &dist_fn_knobs 48 | adiabatic_option = 'iphi00=2' 49 | opt_source = .true. 50 | / 51 | 52 | &fields_knobs 53 | field_option = 'implicit' 54 | / 55 | 56 | &knobs 57 | delt = 0.007071067811865476 58 | fapar = 1.0 59 | fbpar = 1.0 60 | fphi = 1.0 61 | nstep = 40000 62 | wstar_units = .true. 63 | zeff = 1.0 64 | beta = 0.005 65 | 66 | / 67 | 68 | &layouts_knobs 69 | layout = 'xyles' 70 | / 71 | 72 | &collisions_knobs 73 | collision_model = 'default' 74 | / 75 | 76 | &species_knobs 77 | nspec = 2 78 | / 79 | 80 | &species_parameters_1 81 | bess_fac = 1.0 82 | dens = 1.0 83 | fprim = 1.0 84 | mass = 1.0 85 | temp = 1.0 86 | tprim = 3.0 87 | type = 'ion' 88 | uprim = 0.0 89 | vnewk = 0.0016505756571572234 90 | z = 1 91 | / 92 | 93 | &dist_fn_species_knobs_1 94 | bakdif = 0.05 95 | fexpr = 0.48 96 | / 97 | 98 | &species_parameters_2 99 | bess_fac = 1.0 100 | dens = 1.0 101 | fprim = 1.0 102 | mass = 0.00027244 103 | temp = 1.0 104 | tprim = 3.0 105 | type = 'electron' 106 | uprim = 0.0 107 | vnewk = 0.1 108 | z = -1 109 | / 110 | 111 | &dist_fn_species_knobs_2 112 | bakdif = 0.05 113 | fexpr = 0.48 114 | / 115 | 116 | &init_g_knobs 117 | chop_side = .false. 118 | ginit_option = 'default' 119 | phiinit = 1e-05 120 | / 121 | 122 | &gs2_diagnostics_knobs 123 | write_ascii = .false. 124 | write_omega = .true. 125 | write_final_fields = .true. 126 | write_fields = .true. 127 | write_final_epar = .true. 128 | write_phi_over_time = .true. 129 | write_bpar_over_time = .true. 130 | write_apar_over_time = .true. 131 | write_nl_flux_dist = .true. 132 | write_fluxes = .true. 133 | nwrite = 50 134 | navg = 50 135 | omegatol = 0.0001 136 | omegatinst = 500.0 137 | nsave = 5000 138 | save_for_restart = .true. 139 | / 140 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/input.tglf: -------------------------------------------------------------------------------- 1 | # Cyclone base case 2 | 3 | USE_TRANSPORT_MODEL=.false. 4 | 5 | #No. of spec 6 | NS=2 7 | 8 | # geometry type 1 is miller 9 | GEOMETRY_FLAG=1 10 | 11 | #Fields 12 | USE_BPER=T 13 | USE_BPAR=T 14 | 15 | # Specify Kys 16 | KYGRID_MODEL=1 17 | NKY=1 18 | KY=0.1 19 | 20 | SAT_RULE = 1 21 | 22 | ADIABATIC_ELEC=F 23 | 24 | # Electron beta 25 | BETAE=0.004862092554737736 26 | 27 | # ELectron Ion collisionality 28 | XNUE=0.14142135623730953 29 | 30 | # Zeff 31 | ZEFF=1.0 32 | 33 | # No. of parallel basis functions 34 | NBASIS_MAX=4 35 | NBASIS_MIN=2 36 | 37 | 38 | # No. of nodesin Gauss-Hermite quadruture 39 | NXGRID=32 40 | 41 | USE_MHD_RULE=F 42 | 43 | WRITE_WAVEFUNCTION_FLAG=1 44 | 45 | 46 | ### SPECIES vectors 47 | 48 | ZS_1=-1.0 49 | MASS_1=0.00027244 50 | RLNS_1=1.0 51 | RLTS_1=3.0 52 | TAUS_1=1.0 53 | AS_1=1.0 54 | VPAR_1=0.0 55 | VPAR_SHEAR_1=0.0 56 | 57 | 58 | ZS_2=1.0 59 | MASS_2=1.0 60 | RLNS_2=1.0 61 | RLTS_2=3.0 62 | TAUS_2=1.0 63 | AS_2=1.0 64 | VPAR_2=0.0 65 | VPAR_SHEAR_2=0.0 66 | 67 | 68 | # MILLER GEOMETRY PARAMETERS 69 | # Local flux surface parameters 70 | RMIN_LOC=0.5 71 | RMAJ_LOC=3.0 72 | ZMAJ_LOC=0.0 73 | KX0_LOC=0.0 74 | Q_LOC=2.0 75 | Q_PRIME_LOC=16.0 76 | KAPPA_LOC=1.0 77 | S_KAPPA_LOC=0.0 78 | DELTA_LOC=0.0 79 | S_DELTA_LOC=0.0 80 | ZETA_LOC=0.0 81 | S_ZETA_LOC=0.0 82 | DRMAJDX_LOC=-0.0 83 | P_PRIME_LOC = -0.006190608510854497 84 | 85 | 86 | THETA_TRAPPED=0.7 87 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/jetto.jsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/jetto.jsp -------------------------------------------------------------------------------- /src/pyrokinetics/templates/jetto.jss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/jetto.jss -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.geo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.geo -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.kxky_phi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.kxky_phi -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.ky_cflux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.ky_cflux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.ky_flux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.ky_flux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.phib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear/bin.cgyro.phib -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 24 4 | N_THETA = 24 5 | N_RADIAL = 4 6 | N_FIELD = 1 7 | DELTA_T = 0.001 8 | PRINT_STEP = 100 9 | MAX_TIME = 1.0 10 | FREQ_TOL = 0.01 11 | KY = 0.07 12 | EQUILIBRIUM_MODEL = 2 13 | RMIN = 0.6 14 | RMAJ = 3.0 15 | KAPPA = 1.0 16 | S_KAPPA = 0.0 17 | DELTA = 0.0 18 | S_DELTA = 0.0 19 | ZETA = 0.0 20 | S_ZETA = 0.0 21 | SHIFT = 0.0 22 | BETAE_UNIT = 0.0 23 | Q = 2.0 24 | S = 1.0 25 | BETA_STAR_SCALE = 1.0 26 | COLLISION_MODEL = 1 27 | NU_EE = 0.1 28 | Z_EFF = 1.0 29 | Z_EFF_METHOD = 1 30 | N_SPECIES = 2 31 | Z_1 = 1 32 | DENS_1 = 1.0 33 | TEMP_1 = 1.0 34 | MASS_1 = 1.0 35 | DLNNDR_1 = 1.0 36 | DLNTDR_1 = 3.0 37 | Z_2 = -1 38 | DENS_2 = 1.0 39 | TEMP_2 = 1.0 40 | MASS_2 = 0.0002724486 41 | DLNNDR_2 = 1.0 42 | DLNTDR_2 = 3.0 43 | NONLINEAR_FLAG = 0 44 | BOX_SIZE = 1 45 | N_TOROIDAL = 1 46 | THETA_PLOT = 24 47 | PX0 = 0.0 48 | FIELD_PRINT_FLAG = 1 49 | MOMENT_PRINT_FLAG = 1 50 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/out.cgyro.equilibrium: -------------------------------------------------------------------------------- 1 | 6.0000E-01 2 | 3.0000E+00 3 | 2.0000E+00 4 | 1.0000E+00 5 | 0.0000E+00 6 | 1.0000E+00 7 | 0.0000E+00 8 | 0.0000E+00 9 | 0.0000E+00 10 | 0.0000E+00 11 | 0.0000E+00 12 | 0.0000E+00 13 | 0.0000E+00 14 | 0.0000E+00 15 | 0.0000E+00 16 | 0.0000E+00 17 | 0.0000E+00 18 | 0.0000E+00 19 | 0.0000E+00 20 | 0.0000E+00 21 | 0.0000E+00 22 | 0.0000E+00 23 | 0.0000E+00 24 | 2.1000E-02 25 | 7.0000E-02 26 | 0.0000E+00 27 | 0.0000E+00 28 | 0.0000E+00 29 | 0.0000E+00 30 | 0.0000E+00 31 | 0.0000E+00 32 | 0.0000E+00 33 | 0.0000E+00 34 | 0.0000E+00 35 | 0.0000E+00 36 | 0.0000E+00 37 | 0.0000E+00 38 | 0.0000E+00 39 | 0.0000E+00 40 | 0.0000E+00 41 | 0.0000E+00 42 | 1.0000E+00 43 | 1.0000E+00 44 | 1.0000E+00 45 | 1.0000E+00 46 | 1.0000E+00 47 | 3.0000E+00 48 | 1.6506E-03 49 | -1.0000E+00 50 | 2.7245E-04 51 | 1.0000E+00 52 | 1.0000E+00 53 | 1.0000E+00 54 | 3.0000E+00 55 | 1.0000E-01 56 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/out.cgyro.freq: -------------------------------------------------------------------------------- 1 | 1.1687E+00 1.4771E+02 2 | -3.9733E+01 -1.8500E+02 3 | -5.0676E+01 1.9339E+01 4 | 1.4486E+01 9.5153E+01 5 | 1.0309E+02 -2.8532E+00 6 | -3.4394E+01 9.0771E+01 7 | 6.3288E+01 7.5741E+01 8 | 5.3307E+01 1.0782E+02 9 | 1.1094E+01 9.6779E+01 10 | 8.9395E+00 1.0383E+02 11 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear/out.cgyro.time: -------------------------------------------------------------------------------- 1 | 1.0000E-01 2.4942E-02 2.1594E-04 1.0000E-03 2 | 2.0000E-01 5.3954E-02 1.7888E-04 1.0000E-03 3 | 3.0000E-01 5.0446E-02 1.7326E-04 1.0000E-03 4 | 4.0000E-01 4.1420E-02 1.4408E-04 1.0000E-03 5 | 5.0000E-01 6.1582E-02 2.0631E-04 1.0000E-03 6 | 6.0000E-01 4.8880E-02 1.3853E-04 1.0000E-03 7 | 7.0000E-01 3.8913E-02 1.2117E-04 1.0000E-03 8 | 8.0000E-01 4.4099E-02 1.1706E-04 1.0000E-03 9 | 9.0000E-01 4.4370E-02 8.9564E-05 1.0000E-03 10 | 1.0000E+00 4.1104E-02 7.2538E-05 1.0000E-03 11 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 24 4 | N_THETA = 24 5 | N_RADIAL = 4 6 | N_FIELD = 1 7 | DELTA_T = 0.001 8 | PRINT_STEP = 28000 9 | RESTART_STEP = 28000 10 | MAX_TIME = 100.0 11 | FREQ_TOL = 0.01 12 | KY = 0.10 13 | EQUILIBRIUM_MODEL = 2 14 | RMIN = 0.6 15 | RMAJ = 3.0 16 | KAPPA = 1.0 17 | S_KAPPA = 0.0 18 | DELTA = 0.0 19 | S_DELTA = 0.0 20 | ZETA = 0.0 21 | S_ZETA = 0.0 22 | SHIFT = 0.0 23 | BETAE_UNIT = 0.0 24 | Q = 2.0 25 | S = 1.0 26 | BETA_STAR_SCALE = 1.0 27 | COLLISION_MODEL = 1 28 | NU_EE = 0.1 29 | Z_EFF = 1.0 30 | Z_EFF_METHOD = 1 31 | N_SPECIES = 2 32 | Z_1 = 1 33 | DENS_1 = 1.0 34 | TEMP_1 = 1.0 35 | MASS_1 = 1.0 36 | DLNNDR_1 = 1.0 37 | DLNTDR_1 = 3.0 38 | Z_2 = -1 39 | DENS_2 = 1.0 40 | TEMP_2 = 1.0 41 | MASS_2 = 0.0002724486 42 | DLNNDR_2 = 1.0 43 | DLNTDR_2 = 3.0 44 | NONLINEAR_FLAG = 0 45 | BOX_SIZE = 1 46 | N_TOROIDAL = 1 47 | THETA_PLOT = 24 48 | PX0 = 0.0 49 | FIELD_PRINT_FLAG = 1 50 | MOMENT_PRINT_FLAG = 1 51 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.geo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.geo -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.kxky_phi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.kxky_phi -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.ky_cflux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.ky_cflux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.ky_flux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.ky_flux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.phib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/bin.cgyro.phib -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 24 4 | N_THETA = 24 5 | N_RADIAL = 4 6 | N_FIELD = 1 7 | DELTA_T = 0.001 8 | PRINT_STEP = 28000 9 | RESTART_STEP = 28000 10 | MAX_TIME = 100.0 11 | FREQ_TOL = 0.01 12 | KY = 0.10 13 | EQUILIBRIUM_MODEL = 2 14 | RMIN = 0.6 15 | RMAJ = 3.0 16 | KAPPA = 1.0 17 | S_KAPPA = 0.0 18 | DELTA = 0.0 19 | S_DELTA = 0.0 20 | ZETA = 0.0 21 | S_ZETA = 0.0 22 | SHIFT = 0.0 23 | BETAE_UNIT = 0.0 24 | Q = 2.0 25 | S = 1.0 26 | BETA_STAR_SCALE = 1.0 27 | COLLISION_MODEL = 1 28 | NU_EE = 0.1 29 | Z_EFF = 1.0 30 | Z_EFF_METHOD = 1 31 | N_SPECIES = 2 32 | Z_1 = 1 33 | DENS_1 = 1.0 34 | TEMP_1 = 1.0 35 | MASS_1 = 1.0 36 | DLNNDR_1 = 1.0 37 | DLNTDR_1 = 3.0 38 | Z_2 = -1 39 | DENS_2 = 1.0 40 | TEMP_2 = 1.0 41 | MASS_2 = 0.0002724486 42 | DLNNDR_2 = 1.0 43 | DLNTDR_2 = 3.0 44 | NONLINEAR_FLAG = 0 45 | BOX_SIZE = 1 46 | N_TOROIDAL = 1 47 | THETA_PLOT = 24 48 | PX0 = 0.0 49 | FIELD_PRINT_FLAG = 1 50 | MOMENT_PRINT_FLAG = 1 51 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/out.cgyro.equilibrium: -------------------------------------------------------------------------------- 1 | 6.0000E-01 2 | 3.0000E+00 3 | 2.0000E+00 4 | 1.0000E+00 5 | 0.0000E+00 6 | 1.0000E+00 7 | 0.0000E+00 8 | 0.0000E+00 9 | 0.0000E+00 10 | 0.0000E+00 11 | 0.0000E+00 12 | 0.0000E+00 13 | 0.0000E+00 14 | 0.0000E+00 15 | 0.0000E+00 16 | 0.0000E+00 17 | 0.0000E+00 18 | 0.0000E+00 19 | 0.0000E+00 20 | 0.0000E+00 21 | 0.0000E+00 22 | 0.0000E+00 23 | 0.0000E+00 24 | 0.0000E+00 25 | 0.0000E+00 26 | 0.0000E+00 27 | 0.0000E+00 28 | 0.0000E+00 29 | 0.0000E+00 30 | 0.0000E+00 31 | 0.0000E+00 32 | 0.0000E+00 33 | 0.0000E+00 34 | 0.0000E+00 35 | 0.0000E+00 36 | 3.0000E-02 37 | 1.0000E-01 38 | 0.0000E+00 39 | 0.0000E+00 40 | 0.0000E+00 41 | 0.0000E+00 42 | 0.0000E+00 43 | 0.0000E+00 44 | 0.0000E+00 45 | 0.0000E+00 46 | 9.7980E-01 47 | 0.0000E+00 48 | 0.0000E+00 49 | 0.0000E+00 50 | 0.0000E+00 51 | 0.0000E+00 52 | 0.0000E+00 53 | 0.0000E+00 54 | 0.0000E+00 55 | 1.0000E+00 56 | 1.0000E+00 57 | 1.0000E+00 58 | 1.0000E+00 59 | 1.0000E+00 60 | 3.0000E+00 61 | 1.6506E-03 62 | -1.0000E+00 63 | 2.7245E-04 64 | 1.0000E+00 65 | 1.0000E+00 66 | 1.0000E+00 67 | 3.0000E+00 68 | 1.0000E-01 69 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/out.cgyro.freq: -------------------------------------------------------------------------------- 1 | -4.5326E-02 9.4934E-02 2 | -5.2377E-02 1.0248E-01 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.10/out.cgyro.time: -------------------------------------------------------------------------------- 1 | 2.8000E+01 1.3193E-12 1.3777E-08 1.0000E-03 2 | 5.6000E+01 1.5194E-12 1.4249E-08 1.0000E-03 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.geo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.geo -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.kxky_phi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.kxky_phi -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.ky_cflux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.ky_cflux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.ky_flux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.ky_flux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.phib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/bin.cgyro.phib -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 24 4 | N_THETA = 24 5 | N_RADIAL = 4 6 | N_FIELD = 1 7 | DELTA_T = 0.001 8 | PRINT_STEP = 8500 9 | RESTART_STEP = 8500 10 | MAX_TIME = 100.0 11 | FREQ_TOL = 0.01 12 | KY = 0.20 13 | EQUILIBRIUM_MODEL = 2 14 | RMIN = 0.6 15 | RMAJ = 3.0 16 | KAPPA = 1.0 17 | S_KAPPA = 0.0 18 | DELTA = 0.0 19 | S_DELTA = 0.0 20 | ZETA = 0.0 21 | S_ZETA = 0.0 22 | SHIFT = 0.0 23 | BETAE_UNIT = 0.0 24 | Q = 2.0 25 | S = 1.0 26 | BETA_STAR_SCALE = 1.0 27 | COLLISION_MODEL = 1 28 | NU_EE = 0.1 29 | Z_EFF = 1.0 30 | Z_EFF_METHOD = 1 31 | N_SPECIES = 2 32 | Z_1 = 1 33 | DENS_1 = 1.0 34 | TEMP_1 = 1.0 35 | MASS_1 = 1.0 36 | DLNNDR_1 = 1.0 37 | DLNTDR_1 = 3.0 38 | Z_2 = -1 39 | DENS_2 = 1.0 40 | TEMP_2 = 1.0 41 | MASS_2 = 0.0002724486 42 | DLNNDR_2 = 1.0 43 | DLNTDR_2 = 3.0 44 | NONLINEAR_FLAG = 0 45 | BOX_SIZE = 1 46 | N_TOROIDAL = 1 47 | THETA_PLOT = 24 48 | PX0 = 0.0 49 | FIELD_PRINT_FLAG = 1 50 | MOMENT_PRINT_FLAG = 1 51 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/out.cgyro.equilibrium: -------------------------------------------------------------------------------- 1 | 6.0000E-01 2 | 3.0000E+00 3 | 2.0000E+00 4 | 1.0000E+00 5 | 0.0000E+00 6 | 1.0000E+00 7 | 0.0000E+00 8 | 0.0000E+00 9 | 0.0000E+00 10 | 0.0000E+00 11 | 0.0000E+00 12 | 0.0000E+00 13 | 0.0000E+00 14 | 0.0000E+00 15 | 0.0000E+00 16 | 0.0000E+00 17 | 0.0000E+00 18 | 0.0000E+00 19 | 0.0000E+00 20 | 0.0000E+00 21 | 0.0000E+00 22 | 0.0000E+00 23 | 0.0000E+00 24 | 0.0000E+00 25 | 0.0000E+00 26 | 0.0000E+00 27 | 0.0000E+00 28 | 0.0000E+00 29 | 0.0000E+00 30 | 0.0000E+00 31 | 0.0000E+00 32 | 0.0000E+00 33 | 0.0000E+00 34 | 0.0000E+00 35 | 0.0000E+00 36 | 6.0000E-02 37 | 2.0000E-01 38 | 0.0000E+00 39 | 0.0000E+00 40 | 0.0000E+00 41 | 0.0000E+00 42 | 0.0000E+00 43 | 0.0000E+00 44 | 0.0000E+00 45 | 0.0000E+00 46 | 9.7980E-01 47 | 0.0000E+00 48 | 0.0000E+00 49 | 0.0000E+00 50 | 0.0000E+00 51 | 0.0000E+00 52 | 0.0000E+00 53 | 0.0000E+00 54 | 0.0000E+00 55 | 1.0000E+00 56 | 1.0000E+00 57 | 1.0000E+00 58 | 1.0000E+00 59 | 1.0000E+00 60 | 3.0000E+00 61 | 1.6506E-03 62 | -1.0000E+00 63 | 2.7245E-04 64 | 1.0000E+00 65 | 1.0000E+00 66 | 1.0000E+00 67 | 3.0000E+00 68 | 1.0000E-01 69 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/out.cgyro.freq: -------------------------------------------------------------------------------- 1 | -1.2114E-01 2.4510E-01 2 | -1.4291E-01 2.5031E-01 3 | -1.4008E-01 2.5443E-01 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.20/out.cgyro.time: -------------------------------------------------------------------------------- 1 | 8.5000E+00 1.4909E-10 1.9702E-08 1.0000E-03 2 | 1.7000E+01 2.4298E-11 1.9559E-08 1.0000E-03 3 | 2.5500E+01 2.4324E-11 1.9876E-08 1.0000E-03 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.geo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.geo -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.kxky_phi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.kxky_phi -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.ky_cflux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.ky_cflux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.ky_flux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.ky_flux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.phib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/bin.cgyro.phib -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 24 4 | N_THETA = 24 5 | N_RADIAL = 4 6 | N_FIELD = 1 7 | DELTA_T = 0.001 8 | PRINT_STEP = 7000 9 | RESTART_STEP = 7000 10 | MAX_TIME = 100.0 11 | FREQ_TOL = 0.01 12 | KY = 0.30 13 | EQUILIBRIUM_MODEL = 2 14 | RMIN = 0.6 15 | RMAJ = 3.0 16 | KAPPA = 1.0 17 | S_KAPPA = 0.0 18 | DELTA = 0.0 19 | S_DELTA = 0.0 20 | ZETA = 0.0 21 | S_ZETA = 0.0 22 | SHIFT = 0.0 23 | BETAE_UNIT = 0.0 24 | Q = 2.0 25 | S = 1.0 26 | BETA_STAR_SCALE = 1.0 27 | COLLISION_MODEL = 1 28 | NU_EE = 0.1 29 | Z_EFF = 1.0 30 | Z_EFF_METHOD = 1 31 | N_SPECIES = 2 32 | Z_1 = 1 33 | DENS_1 = 1.0 34 | TEMP_1 = 1.0 35 | MASS_1 = 1.0 36 | DLNNDR_1 = 1.0 37 | DLNTDR_1 = 3.0 38 | Z_2 = -1 39 | DENS_2 = 1.0 40 | TEMP_2 = 1.0 41 | MASS_2 = 0.0002724486 42 | DLNNDR_2 = 1.0 43 | DLNTDR_2 = 3.0 44 | NONLINEAR_FLAG = 0 45 | BOX_SIZE = 1 46 | N_TOROIDAL = 1 47 | THETA_PLOT = 24 48 | PX0 = 0.0 49 | FIELD_PRINT_FLAG = 1 50 | MOMENT_PRINT_FLAG = 1 51 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/out.cgyro.equilibrium: -------------------------------------------------------------------------------- 1 | 6.0000E-01 2 | 3.0000E+00 3 | 2.0000E+00 4 | 1.0000E+00 5 | 0.0000E+00 6 | 1.0000E+00 7 | 0.0000E+00 8 | 0.0000E+00 9 | 0.0000E+00 10 | 0.0000E+00 11 | 0.0000E+00 12 | 0.0000E+00 13 | 0.0000E+00 14 | 0.0000E+00 15 | 0.0000E+00 16 | 0.0000E+00 17 | 0.0000E+00 18 | 0.0000E+00 19 | 0.0000E+00 20 | 0.0000E+00 21 | 0.0000E+00 22 | 0.0000E+00 23 | 0.0000E+00 24 | 0.0000E+00 25 | 0.0000E+00 26 | 0.0000E+00 27 | 0.0000E+00 28 | 0.0000E+00 29 | 0.0000E+00 30 | 0.0000E+00 31 | 0.0000E+00 32 | 0.0000E+00 33 | 0.0000E+00 34 | 0.0000E+00 35 | 0.0000E+00 36 | 9.0000E-02 37 | 3.0000E-01 38 | 0.0000E+00 39 | 0.0000E+00 40 | 0.0000E+00 41 | 0.0000E+00 42 | 0.0000E+00 43 | 0.0000E+00 44 | 0.0000E+00 45 | 0.0000E+00 46 | 9.7980E-01 47 | 0.0000E+00 48 | 0.0000E+00 49 | 0.0000E+00 50 | 0.0000E+00 51 | 0.0000E+00 52 | 0.0000E+00 53 | 0.0000E+00 54 | 0.0000E+00 55 | 1.0000E+00 56 | 1.0000E+00 57 | 1.0000E+00 58 | 1.0000E+00 59 | 1.0000E+00 60 | 3.0000E+00 61 | 1.6506E-03 62 | -1.0000E+00 63 | 2.7245E-04 64 | 1.0000E+00 65 | 1.0000E+00 66 | 1.0000E+00 67 | 3.0000E+00 68 | 1.0000E-01 69 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/out.cgyro.freq: -------------------------------------------------------------------------------- 1 | -2.4729E-01 3.2695E-01 2 | -2.5728E-01 3.5243E-01 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_linear_scan/ky_0.30/out.cgyro.time: -------------------------------------------------------------------------------- 1 | 7.0000E+00 1.0949E-10 2.3085E-08 1.0000E-03 2 | 1.4000E+01 8.1123E-11 2.4028E-08 1.0000E-03 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.freq: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.freq -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.geo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.geo -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_apar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_apar -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_bpar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_bpar -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_e -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_n: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_n -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_phi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_phi -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.kxky_v -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.ky_flux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/CGYRO_nonlinear/bin.cgyro.ky_flux -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/input.cgyro: -------------------------------------------------------------------------------- 1 | N_ENERGY = 8 2 | E_MAX = 8 3 | N_XI = 32 4 | N_THETA = 16 5 | N_RADIAL = 256 6 | N_FIELD = 3 7 | DELTA_T = 0.01 8 | DELTA_T_METHOD = 1 9 | PRINT_STEP = 10 10 | MAX_TIME = 0.25 11 | FREQ_TOL = 0.01 12 | AMP = 0.01 13 | KY = 0.141 14 | EQUILIBRIUM_MODEL = 2 15 | RMIN = 0.5135370909371213 16 | RMAJ = 1.568207815825452 17 | KAPPA = 1.4146349399671179 18 | S_KAPPA = 0.014379547398094269 19 | DELTA = 0.16174033381753058 20 | S_DELTA = 0.11589203152344424 21 | SHIFT = -0.13384288328888674 22 | BETAE_UNIT = 0.022968550874485 23 | Q = 1.0796537393911938 24 | S = 0.34324251944410183 25 | BETA_STAR_SCALE = 2.1978478810631565 26 | COLLISION_MODEL = 4 27 | NU_EE = 0.85 28 | Z_EFF = 1.0 29 | Z_EFF_METHOD = 1 30 | N_SPECIES = 2 31 | Z_1 = -1 32 | DENS_1 = 1.0 33 | TEMP_1 = 1.0 34 | MASS_1 = 0.000272308510742333 35 | DLNNDR_1 = 0.22000811607885276 36 | DLNTDR_1 = 2.119249034613207 37 | Z_2 = 1 38 | DENS_2 = 1.0 39 | TEMP_2 = 1.1518833869839435 40 | MASS_2 = 1.0 41 | DLNNDR_2 = 0.22000811607885276 42 | DLNTDR_2 = 1.706012320319912 43 | NONLINEAR_FLAG = 1 44 | BOX_SIZE = 4 45 | N_TOROIDAL = 7 46 | THETA_PLOT = 16 47 | PX0 = 0.0 48 | FIELD_PRINT_FLAG = 1 49 | MOMENT_PRINT_FLAG = 1 50 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/out.cgyro.equilibrium: -------------------------------------------------------------------------------- 1 | 5.1354E-01 2 | 1.5682E+00 3 | 1.0797E+00 4 | 3.4324E-01 5 | -1.3384E-01 6 | 1.4146E+00 7 | 1.4380E-02 8 | 1.6174E-01 9 | 1.1589E-01 10 | 0.0000E+00 11 | 0.0000E+00 12 | 0.0000E+00 13 | 0.0000E+00 14 | 0.0000E+00 15 | 0.0000E+00 16 | 0.0000E+00 17 | 0.0000E+00 18 | 0.0000E+00 19 | 0.0000E+00 20 | 0.0000E+00 21 | 0.0000E+00 22 | 0.0000E+00 23 | 0.0000E+00 24 | 6.7067E-02 25 | 1.4100E-01 26 | 2.2969E-02 27 | 2.3008E-01 28 | 0.0000E+00 29 | 0.0000E+00 30 | 0.0000E+00 31 | 0.0000E+00 32 | 0.0000E+00 33 | 0.0000E+00 34 | 0.0000E+00 35 | 0.0000E+00 36 | 0.0000E+00 37 | 0.0000E+00 38 | 0.0000E+00 39 | 0.0000E+00 40 | 0.0000E+00 41 | 0.0000E+00 42 | -1.0000E+00 43 | 2.7231E-04 44 | 1.0000E+00 45 | 1.0000E+00 46 | 2.2001E-01 47 | 2.1192E+00 48 | 8.5000E-01 49 | 1.0000E+00 50 | 1.0000E+00 51 | 1.0000E+00 52 | 1.1519E+00 53 | 2.2001E-01 54 | 1.7060E+00 55 | 1.1346E-02 56 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/CGYRO_nonlinear/out.cgyro.time: -------------------------------------------------------------------------------- 1 | 1.0000E-01 1.8650E-03 2.2570E-07 3.8625E-03 2 | 2.0000E-01 6.7028E-04 1.0438E-07 3.8625E-03 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GENE_linear/field_0001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GENE_linear/field_0001 -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GENE_linear/mom_electron_0001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GENE_linear/mom_electron_0001 -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GENE_linear/mom_ion_0001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GENE_linear/mom_ion_0001 -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GENE_linear/omega_0001: -------------------------------------------------------------------------------- 1 | 0.07 1.848 12.207 2 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GKW_linear/GKW_linear.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GKW_linear/GKW_linear.zip -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GS2_linear/gs2.in: -------------------------------------------------------------------------------- 1 | &kt_grids_knobs 2 | grid_option = 'single' 3 | / 4 | 5 | &kt_grids_single_parameters 6 | aky = 0.09899494936611666 7 | theta0 = 0.0 8 | / 9 | 10 | &theta_grid_parameters 11 | ntheta = 64 12 | nperiod = 2 13 | shat = 4.0 14 | qinp = 2.0 15 | shift = 0.0 16 | rhoc = 0.6 17 | r_geo = 3.0 18 | rmaj = 3.0 19 | akappa = 1.0 20 | akappri = 0.0 21 | tri = 0.0 22 | tripri = 0.0 23 | geotype = 0 24 | / 25 | 26 | &theta_grid_knobs 27 | equilibrium_option = 'eik' 28 | / 29 | 30 | &theta_grid_eik_knobs 31 | bishop = 4 32 | irho = 2 33 | writelots = .true. 34 | iflux = 0 35 | s_hat_input = 1.0 36 | beta_prime_input = 0.0 37 | local_eq = .true. 38 | / 39 | 40 | &le_grids_knobs 41 | ngauss = 12 42 | negrid = 8 43 | / 44 | 45 | &dist_fn_knobs 46 | adiabatic_option = 'iphi00=2' 47 | / 48 | 49 | &fields_knobs 50 | field_option = 'implicit' 51 | / 52 | 53 | &knobs 54 | fphi = 1.0 55 | fapar = 0.0 56 | fbpar = 0.0 57 | delt = 0.0014142135623730952 58 | nstep = 1000 59 | wstar_units = .true. 60 | beta = 0.0 61 | tite = 1.0 62 | zeff = 1.0 63 | / 64 | 65 | &layouts_knobs 66 | layout = 'xyles' 67 | / 68 | 69 | &collisions_knobs 70 | collision_model = 'default' 71 | / 72 | 73 | &species_knobs 74 | nspec = 2 75 | / 76 | 77 | &species_parameters_1 78 | z = 1 79 | mass = 1.0 80 | dens = 1.0 81 | temp = 1.0 82 | tprim = 3.0 83 | fprim = 1.0 84 | uprim = 0.0 85 | vnewk = 0.0011671516610963634 86 | type = 'ion' 87 | bess_fac = 1.0 88 | / 89 | 90 | &dist_fn_species_knobs_1 91 | fexpr = 0.48 92 | bakdif = 0.05 93 | / 94 | 95 | &species_parameters_2 96 | z = -1 97 | mass = 0.0002724486 98 | dens = 1.0 99 | temp = 1.0 100 | tprim = 3.0 101 | fprim = 1.0 102 | uprim = 0.0 103 | vnewk = 0.07071067811865475 104 | type = 'electron' 105 | bess_fac = 1.0 106 | / 107 | 108 | &dist_fn_species_knobs_2 109 | fexpr = 0.48 110 | bakdif = 0.05 111 | / 112 | 113 | &init_g_knobs 114 | ginit_option = 'default' 115 | chop_side = .false. 116 | phiinit = 1e-05 117 | / 118 | 119 | &gs2_diagnostics_knobs 120 | write_ascii = .false. 121 | write_omega = .true. 122 | write_final_fields = .true. 123 | write_fields = .true. 124 | write_final_epar = .true. 125 | write_phi_over_time = .true. 126 | write_apar_over_time = .true. 127 | write_bpar_over_time = .true. 128 | write_fluxes = .true. 129 | nwrite = 50 130 | navg = 50 131 | omegatol = 0.0001 132 | omegatinst = 500.0 133 | nsave = 50000 134 | save_for_restart = .true. 135 | / 136 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GS2_linear/gs2.out.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GS2_linear/gs2.out.nc -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GX_linear/gx.big.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GX_linear/gx.big.nc -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GX_linear/gx.in: -------------------------------------------------------------------------------- 1 | debug = false 2 | 3 | [Dimensions] 4 | ntheta = 32 5 | nperiod = 6 6 | nky = 2 7 | nkx = 1 8 | nhermite = 24 9 | nlaguerre = 12 10 | nspecies = 2 11 | 12 | [Domain] 13 | y0 = 10.0 14 | boundary = "linked" 15 | 16 | [Physics] 17 | beta = 0.005 18 | fphi = 1.0 19 | fapar = 1.0 20 | fbpar = 1.0 21 | nonlinear_mode = false 22 | 23 | [Time] 24 | #t_max = 750.0 25 | nstep = 600000 26 | cfl = 0.8 27 | scheme = "rk4" 28 | dt = 0.005 29 | 30 | [Initialization] 31 | gaussian_init = true 32 | init_field = "density" 33 | init_amp = 1e-3 34 | 35 | [Geometry] 36 | geo_option = "miller" 37 | rhoc = 0.5 38 | Rmaj = 3.0 39 | R_geo = 3.0 40 | qinp = 2.0 41 | shat = 1.0 42 | shift = 0.0 43 | akappa = 1.0 44 | akappri = 0.0 45 | tri = 0.0 46 | tripri = 0.0 47 | betaprim = -0.04 48 | 49 | [species] 50 | z = [ 1.0, -1.0,] 51 | mass = [ 1.0, 0.00027244,] 52 | dens = [ 1.0, 1.0,] 53 | temp = [ 1.0, 1.0,] 54 | tprim = [ 3.0, 3.0,] 55 | fprim = [ 0.5, 0.5,] 56 | vnewk = [ 0.0023342664800746296, 0.14142135623730953,] 57 | type = [ "ion", "electron",] 58 | 59 | [Boltzmann] 60 | add_Boltzmann_species = false 61 | Boltzmann_type = "electrons" 62 | tau_fac = 1.0 63 | 64 | [Dissipation] 65 | closure_model = "none" 66 | hypercollisions = true 67 | hyper = false 68 | 69 | [Restart] 70 | restart_if_exists = false 71 | append_on_restart = false 72 | save_for_restart = false 73 | 74 | [Diagnostics] 75 | nwrite = 60000 76 | nwrite_big = 60000 77 | omega = true 78 | free_energy = true 79 | fields = true 80 | moments = false 81 | fluxes = true 82 | lh_spectrum = true 83 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/GX_linear/gx.out.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/GX_linear/gx.out.nc -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/STELLA_linear/stella.fluxes: -------------------------------------------------------------------------------- 1 | #time pflux vflux qflux 2 | 0.0000E+000 0.0000E+000 0.0000E+000 -5.9724E-030 -1.4277E-026 0.0000E+000 0.0000E+000 3 | 1.0000E+001 -1.2060E-008 -1.2060E-008 8.5122E-021 -1.6771E-019 -4.3324E-008 3.0492E-007 4 | 2.0000E+001 4.0145E-007 4.0145E-007 8.9998E-020 -5.5790E-019 8.2641E-007 2.5812E-006 5 | 3.0000E+001 1.4909E-006 1.4909E-006 6.5179E-019 -6.5047E-018 2.0959E-006 1.6845E-005 6 | 4.0000E+001 1.3931E-005 1.3931E-005 1.5428E-018 -4.8834E-017 2.6744E-005 1.3745E-004 7 | 5.0000E+001 1.0885E-004 1.0885E-004 -1.0901E-017 -2.6735E-016 1.7484E-004 9.6254E-004 8 | 6.0000E+001 7.1672E-004 7.1672E-004 3.6304E-016 -2.0107E-015 1.2446E-003 7.2229E-003 9 | 7.0000E+001 5.7560E-003 5.7560E-003 2.7842E-015 -1.7392E-014 9.7154E-003 5.2984E-002 10 | 8.0000E+001 4.0300E-002 4.0300E-002 9.8776E-015 -8.0756E-014 6.8312E-002 3.8911E-001 11 | 9.0000E+001 3.0346E-001 3.0346E-001 2.2481E-013 -9.8453E-013 5.1636E-001 2.8713E+000 12 | 1.0000E+002 2.2160E+000 2.2160E+000 1.0930E-012 -6.9310E-012 3.7534E+000 2.1085E+001 13 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/STELLA_linear/stella.omega: -------------------------------------------------------------------------------- 1 | #time ky kx frequency growth rate 2 | 0.10000000E+02 0.50000000E+00 0.00000000E+00 0.13330348E+00 -0.18861665E+00 3 | 0.20000000E+02 0.50000000E+00 0.00000000E+00 0.19426647E+00 0.17722316E+00 4 | 0.30000000E+02 0.50000000E+00 0.00000000E+00 0.28152807E+00 0.75179632E-01 5 | 0.40000000E+02 0.50000000E+00 0.00000000E+00 0.22366863E+00 0.98897170E-01 6 | 0.50000000E+02 0.50000000E+00 0.00000000E+00 0.25298250E+00 0.10532349E+00 7 | 0.60000000E+02 0.50000000E+00 0.00000000E+00 0.24039973E+00 0.95148693E-01 8 | 0.70000000E+02 0.50000000E+00 0.00000000E+00 0.24363019E+00 0.10269052E+00 9 | 0.80000000E+02 0.50000000E+00 0.00000000E+00 0.24391481E+00 0.98350643E-01 10 | 0.90000000E+02 0.50000000E+00 0.00000000E+00 0.24275243E+00 0.10032878E+00 11 | 0.10000000E+03 0.50000000E+00 0.00000000E+00 0.24377935E+00 0.99686133E-01 12 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/STELLA_linear/stella.out: -------------------------------------------------------------------------------- 1 | istep time |phi|^2 |apar|^2 |bpar|^2 2 | --------------------------------------------------------------------- 3 | 0 0.0000E+000 8.1263E-008 8.8905E-041 4.0177E-011 4 | 1000 1.0000E+001 5.3047E-007 4.4199E-009 9.4369E-011 5 | 2000 2.0000E+001 5.6612E-006 3.0135E-008 1.0297E-009 6 | 3000 3.0000E+001 3.2399E-005 2.1680E-007 6.5237E-009 7 | 4000 4.0000E+001 2.8387E-004 1.6740E-006 5.0742E-008 8 | 5000 5.0000E+001 1.9050E-003 1.2043E-005 3.7516E-007 9 | 6000 6.0000E+001 1.4577E-002 8.9469E-005 2.7083E-006 10 | 7000 7.0000E+001 1.0624E-001 6.5739E-004 2.0267E-005 11 | 8000 8.0000E+001 7.8101E-001 4.8339E-003 1.4764E-004 12 | 9000 9.0000E+001 5.7688E+000 3.5613E-002 1.0918E-003 13 | 10000 1.0000E+002 4.2316E+001 2.6183E-001 8.0193E-003 14 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/STELLA_linear/stella.out.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/outputs/STELLA_linear/stella.out.nc -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/STELLA_linear/stella.species.input: -------------------------------------------------------------------------------- 1 | #1.z 2.mass 3.dens 4.temp 5.tprim 6.fprim 7.vnewss 8.dens_psi0 9.temp_psi0 11.type 2 | -0.1000E+01 0.2700E-03 0.1000E+01 0.1000E+01 0.2300E+01 0.7330E+00 0.0000E+00 0.1000E+01 0.1000E+01 2 3 | 0.1000E+01 0.1000E+01 0.1000E+01 0.1000E+01 0.2300E+01 0.7330E+00 0.0000E+00 0.1000E+01 0.1000E+01 1 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_linear/input.tglf: -------------------------------------------------------------------------------- 1 | NS = 2 2 | GEOMETRY_FLAG = 1 3 | USE_BPER = F 4 | USE_BPAR = F 5 | KYGRID_MODEL = 1 6 | NKY = 1 7 | KY = 0.07 8 | SAT_RULE = 1 9 | ADIABATIC_ELEC = F 10 | BETAE = 0.0 11 | XNUE = 0.1 12 | ZEFF = 1.0 13 | NBASIS_MAX = 4 14 | NBASIS_MIN = 2 15 | NXGRID = 24 16 | USE_MHD_RULE = F 17 | WRITE_WAVEFUNCTION_FLAG = 1 18 | ZS_1 = -1 19 | MASS_1 = 0.0002724486 20 | RLNS_1 = 1.0 21 | RLTS_1 = 3.0 22 | TAUS_1 = 1.0 23 | AS_1 = 1.0 24 | VPAR_1 = 0.0 25 | VPAR_SHEAR_1 = 0.0 26 | ZS_2 = 1 27 | MASS_2 = 1.0 28 | RLNS_2 = 1.0 29 | RLTS_2 = 3.0 30 | TAUS_2 = 1.0 31 | AS_2 = 1.0 32 | VPAR_2 = 0.0 33 | VPAR_SHEAR_2 = 0.0 34 | RMIN_LOC = 0.6 35 | RMAJ_LOC = 3.0 36 | ZMAJ_LOC = 0.0 37 | KX0_LOC = 0.0 38 | Q_LOC = 2.0 39 | Q_PRIME_LOC = 11.111111111111112 40 | KAPPA_LOC = 1.0 41 | S_KAPPA_LOC = 0.0 42 | DELTA_LOC = 0.0 43 | S_DELTA_LOC = 0.0 44 | ZETA_LOC = 0.0 45 | S_ZETA_LOC = 0.0 46 | DRMAJDX_LOC = 0.0 47 | P_PRIME_LOC = 0.0 48 | THETA_TRAPPED = 0.7 49 | USE_TRANSPORT_MODEL = F 50 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_linear/out.tglf.prec: -------------------------------------------------------------------------------- 1 | 0.122842931954344 2 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_linear/out.tglf.run: -------------------------------------------------------------------------------- 1 | [Parsing data in input.tglf] 2 | no mpi 3 | D(R) = 0.0000E+00 D(I) = 0.0000E+00 4 | kinetic species = 2 non-kinetic species = 0 5 | ky: 7.0000E-02 6 | ft: 5.5394E-01 7 | Guassian width = 1.6500E+00 8 | (wr,wi): -4.8426E-02 5.6637E-02 9 | (wr,wi): -3.8928E-02 2.8636E-02 10 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_linear/out.tglf.version: -------------------------------------------------------------------------------- 1 | d9d842be [2022-06-06] 2 | CSD3_CCLAKE 3 | Tue 12 Jul 10:58:20 BST 2022 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/input.tglf: -------------------------------------------------------------------------------- 1 | # Empty input.tglf file (GA standard case with Miller geometry) 2 | USE_TRANSPORT_MODEL = T 3 | NS = 2 4 | GEOMETRY_FLAG = 1 5 | USE_BPER = T 6 | USE_BPAR = T 7 | KYGRID_MODEL = 1 8 | NKY = 12 9 | KY = 0.3 10 | SAT_RULE = 1 11 | ADIABATIC_ELEC = F 12 | BETAE = 0.004862092554737736 13 | XNUE = 0.0 14 | ZEFF = 1.0 15 | NBASIS_MAX = 4 16 | NBASIS_MIN = 2 17 | NXGRID = 32 18 | USE_MHD_RULE = F 19 | WRITE_WAVEFUNCTION_FLAG = 0 20 | ZS_2 = 1 21 | MASS_2 = 1.0 22 | RLNS_2 = 1.0 23 | RLTS_2 = 3.0 24 | TAUS_2 = 1.0 25 | AS_2 = 1.0 26 | VPAR_2 = 0.0 27 | VPAR_SHEAR_2 = 0.0 28 | ZS_1 = -1 29 | MASS_1 = 0.00027244 30 | RLNS_1 = 1.0 31 | RLTS_1 = 3.0 32 | TAUS_1 = 1.0 33 | AS_1 = 1.0 34 | VPAR_1 = 0.0 35 | VPAR_SHEAR_1 = 0.0 36 | RMIN_LOC = 0.5 37 | RMAJ_LOC = 3.0 38 | ZMAJ_LOC = 0.0 39 | KX0_LOC = 0.0 40 | Q_LOC = 2.0 41 | Q_PRIME_LOC = 16.0 42 | KAPPA_LOC = 1.0 43 | S_KAPPA_LOC = 0.0 44 | DELTA_LOC = 0.0 45 | S_DELTA_LOC = 0.0 46 | ZETA_LOC = 0.0 47 | S_ZETA_LOC = 0.0 48 | DRMAJDX_LOC = 0.0 49 | P_PRIME_LOC = 0.0 50 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.ave_p0_spectrum: -------------------------------------------------------------------------------- 1 | ave_p0 is used for normalization of SAT0 2 | index limits: nky 3 | 21 4 | 1.99999999999999 5 | 1.99999999999999 6 | 1.99999999999999 7 | 1.99999999999999 8 | 1.99999999999999 9 | 1.99999999999999 10 | 1.99999999999999 11 | 1.99999999999999 12 | 1.99999999999999 13 | 1.99999999999999 14 | 1.99999999999999 15 | 1.99999999999999 16 | 1.99999999999999 17 | 1.99999999999999 18 | 1.99999999999999 19 | 1.99999999999999 20 | 1.99999999999999 21 | 1.99999999999999 22 | 1.99999999999999 23 | 1.99999999999999 24 | 1.99999999999999 25 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.density_spectrum: -------------------------------------------------------------------------------- 1 | gyro-bohm normalized density fluctuation amplitude spectra 2 | (density(is),is=1,ns_in) 3 | 22.3526525459882 22.3526525459875 4 | 8.07576358435903 8.07576358435888 5 | 4.23318436442333 4.23318436442326 6 | 2.53133683523616 2.53133683523612 7 | 1.64964977191808 1.64964977191806 8 | 1.65325646353509 1.65325646353509 9 | 1.80430068447198 1.80430068447197 10 | 1.28695460830815 1.28695460830816 11 | 0.963561580888770 0.963561580888778 12 | 0.738724545362864 0.738724545362871 13 | 0.419673352183458 0.419673352183462 14 | 0.257717367829613 0.257717367829616 15 | 0.146907476670620 0.146907476670622 16 | 8.987463874698778E-002 8.987463874698866E-002 17 | 4.991535231580350E-002 4.991535231580437E-002 18 | 3.149568395881328E-002 3.149568395881384E-002 19 | 2.013936018669280E-002 2.013936018669315E-002 20 | 1.299880706265783E-002 1.299880706265807E-002 21 | 8.435313054250956E-003 8.435313054251112E-003 22 | 5.467696710060321E-003 5.467696710060411E-003 23 | 3.655000122571181E-003 3.655000122571236E-003 24 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.eigenvalue_spectrum: -------------------------------------------------------------------------------- 1 | gyro-bohm normalized eigenvalue spectra 2 | (gamma(n),freq(n),n=1,nmodes_in) 3 | 0.114306787910359 -7.768300143141446E-002 5.179588518392683E-002 4 | 4.403682543765407E-002 5 | 0.154389025889083 -0.185008708788330 0.105736899693515 6 | -0.763919132619721 7 | 0.178127943220191 -0.270511727180224 0.135312998115015 8 | -0.921894197868871 9 | 0.183092953900542 -0.351431545098090 0.108768575104702 10 | -1.12220937822872 11 | 0.207351707882177 -0.467408419598378 0.127648120465761 12 | 0.195678144531953 13 | 0.159083267323940 -0.559544773848312 0.141212897498910 14 | 0.246736965860605 15 | 0.111195944181667 -0.579163316674141 0.109726640122268 16 | 0.206322952948972 17 | 0.177384417448033 0.322758881753249 0.164460642453283 18 | 0.346976677399384 19 | 0.202799920987538 0.368503093708389 0.176982917493693 20 | 0.398984075542161 21 | 0.231699019139446 0.415069778890751 0.192672205597634 22 | 0.453259727811429 23 | 0.342291637740486 0.577981513035432 0.283017569409487 24 | 0.640608896345815 25 | 0.489447668971707 0.805205527587193 0.426547237180876 26 | 0.843887739792896 27 | 0.666503934749836 1.11728189554404 0.514612380617238 28 | 1.09043575311893 29 | 0.872542484659214 1.54658611884824 0.663952490011981 30 | 2.74583988179153 31 | 2.21718993460713 2.58060483880243 1.09834102309122 32 | 2.13241952455666 33 | 3.39615611406471 2.95145662933780 1.35724361447020 34 | 2.92411110373714 35 | 4.53988709026884 4.68683223305836 1.27150638541665 36 | 0.127731977097698 37 | 6.62127551417151 5.80331709150738 1.58512933758592 38 | 5.61867829799430 39 | 8.63444912708069 8.42641367433542 2.36062923725408 40 | 9.41236068817430 41 | 10.4514817899480 12.7652875801149 2.79871259096712 42 | 13.8196406334720 43 | 11.5469342623902 18.4951932721919 5.90615267452429 44 | 18.7758960561287 45 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.gbflux: -------------------------------------------------------------------------------- 1 | 6.0949E+00 6.0949E+00 2.7624E+01 7.2155E+01 -1.4748E-07 -6.7202E-04 2.6926E+01 -1.9439E+01 2 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.grid: -------------------------------------------------------------------------------- 1 | 2 2 | 32 3 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.ky_spectrum: -------------------------------------------------------------------------------- 1 | index limits: nky 2 | 21 3 | 0.100000000000000 4 | 0.200000000000000 5 | 0.300000000000000 6 | 0.400000000000000 7 | 0.500000000000000 8 | 0.600000000000000 9 | 0.700000000000000 10 | 0.800000000000000 11 | 0.900000000000000 12 | 1.00000000000000 13 | 1.33615480493145 14 | 1.78530966274139 15 | 2.38545008416245 16 | 3.18733059187778 17 | 4.25876708524249 18 | 5.69037210403064 19 | 7.60321802864840 20 | 10.1590763019200 21 | 13.5740986144755 22 | 18.1370970863448 23 | 24.2339694194277 24 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.nete_crossphase_spectrum: -------------------------------------------------------------------------------- 1 | electron density-temperature cross phase spectra per mode 2 | (ne_te_phase,n=1,nmodes_in) 3 | -1.69196112862257 1.18550999463117 4 | -1.77543083358016 -1.874424543487061E-002 5 | -1.84484235505829 6.288706729864871E-003 6 | -1.99229240472601 6.101929230087674E-002 7 | -2.01602255868684 1.75821835568774 8 | -1.91591367434903 1.68787397511442 9 | -1.84936456036180 1.65272005571711 10 | 1.65578251025759 1.57860600822841 11 | 1.62500053714537 1.48737396948221 12 | 1.59769992613887 1.37637458039228 13 | 1.53841779195601 1.26728264693328 14 | 1.51935994523158 1.49170516219576 15 | 1.53583360945613 1.78606642193218 16 | 1.56181578577757 2.69788334605306 17 | 1.86388610433144 1.57251883282875 18 | 1.61024884684037 1.59465682577750 19 | 1.67990867079914 1.26157051628551 20 | 1.49703510025199 1.71511862537684 21 | 1.51047261003956 1.99234206388259 22 | 1.64385009506047 1.93208484825077 23 | 1.76915009539147 1.80025937875292 24 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.nsts_crossphase_spectrum: -------------------------------------------------------------------------------- 1 | density-temperature cross phase spectra per mode for 2 species 2 | species index = 1 3 | (nsts_phase_spectrum_out,n=1,nmodes_in) 4 | -1.69196112862257 1.18550999463117 5 | -1.77543083358016 -1.874424543487061E-002 6 | -1.84484235505829 6.288706729864871E-003 7 | -1.99229240472601 6.101929230087674E-002 8 | -2.01602255868684 1.75821835568774 9 | -1.91591367434903 1.68787397511442 10 | -1.84936456036180 1.65272005571711 11 | 1.65578251025759 1.57860600822841 12 | 1.62500053714537 1.48737396948221 13 | 1.59769992613887 1.37637458039228 14 | 1.53841779195601 1.26728264693328 15 | 1.51935994523158 1.49170516219576 16 | 1.53583360945613 1.78606642193218 17 | 1.56181578577757 2.69788334605306 18 | 1.86388610433144 1.57251883282875 19 | 1.61024884684037 1.59465682577750 20 | 1.67990867079914 1.26157051628551 21 | 1.49703510025199 1.71511862537684 22 | 1.51047261003956 1.99234206388259 23 | 1.64385009506047 1.93208484825077 24 | 1.76915009539147 1.80025937875292 25 | species index = 2 26 | (nsts_phase_spectrum_out,n=1,nmodes_in) 27 | -1.05726592319899 2.26412214411768 28 | -1.21578383362899 -6.371432435194366E-003 29 | -1.37556510415716 2.752089211358946E-002 30 | -1.59120592394324 3.820752630031618E-002 31 | -1.77927026432249 -3.00962669969183 32 | -2.02000544238941 -3.01941139930812 33 | -2.38064778563922 -3.10690721671015 34 | -3.09065117753387 -3.03966846640064 35 | -3.11758971215737 -3.05514943801556 36 | 3.13767207061312 -3.07190285740527 37 | 3.05250466553234 -3.13662032542762 38 | 2.98608078819885 3.07794967295274 39 | 2.95420504273930 3.07254318667940 40 | 2.94925574598889 2.94883212935177 41 | 2.64208176666911 2.96830036935893 42 | 2.48917279670973 2.99912209435462 43 | 2.54394897316067 2.18587913760346 44 | 2.44808786983532 -3.13621199758812 45 | 2.49035917959557 3.10487694391640 46 | 2.59060268374774 2.91319772571621 47 | 2.72871915152056 3.02986058084986 48 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.prec: -------------------------------------------------------------------------------- 1 | 211.373551226353 2 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.run: -------------------------------------------------------------------------------- 1 | [Parsing data in input.tglf] 2 | no mpi 3 | D(R) = 0.0000E+00 D(I) = 0.0000E+00 4 | kinetic species = 2 non-kinetic species = 0 5 | Gam/Gam_GB Q/Q_GB Q_low/Q_GB Pi/Pi_GB S/S_GB 6 | elec 6.0949E+00 2.7624E+01 2.7226E+01 -1.4748E-07 2.6926E+01 7 | ion1 6.0949E+00 7.2155E+01 7.2178E+01 -6.7202E-04 -1.9439E+01 8 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.scalar_saturation_parameters: -------------------------------------------------------------------------------- 1 | !This file has all of the scalar staturation parameters used for different SAT_ 2 | RULE options 3 | SAT_RULE = 1 4 | UNITS = GYRO 5 | XNU_MODEL = 2 6 | ! SAT0 model 7 | ETG_FACTOR = 1.25000000000000 8 | B_unit = 1.00000000000000 9 | R_unit = 3.35714285824049 10 | q_unit = 1.76851903123472 11 | ! SAT1 & SAT2 models 12 | ALPHA_ZF = 1.00000000000000 13 | SAT_geo0_out = 1.00000000000000 14 | SAT_geo1_out = 1.00000000000000 15 | SAT_geo2_out = 1.00000000000000 16 | Bt0_out = 0.986013487956141 17 | B_geo0_out = 1.00000000000000 18 | grad_r0_out = 1.00000000000000 19 | rho_ion = 1.00000000000000 20 | rho_e = 1.650575657157223E-002 21 | kymax_out = 0.100000000000000 22 | vzf_out = 1.14306787910359 23 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.spectral_shift_spectrum: -------------------------------------------------------------------------------- 1 | kx spectral shift model is used when ALPHA_QUENCH=0 and ALPHA_E=1.0 2 | note: the model for the spectral shift (kx_e) = / 3 | depends on which staturation model is being used: SAT_RULE and UNITS settings 4 | index limits: nky 5 | 21 6 | 0.000000000000000E+000 7 | 0.000000000000000E+000 8 | 0.000000000000000E+000 9 | 0.000000000000000E+000 10 | 0.000000000000000E+000 11 | 0.000000000000000E+000 12 | 0.000000000000000E+000 13 | 0.000000000000000E+000 14 | 0.000000000000000E+000 15 | 0.000000000000000E+000 16 | 0.000000000000000E+000 17 | 0.000000000000000E+000 18 | 0.000000000000000E+000 19 | 0.000000000000000E+000 20 | 0.000000000000000E+000 21 | 0.000000000000000E+000 22 | 0.000000000000000E+000 23 | 0.000000000000000E+000 24 | 0.000000000000000E+000 25 | 0.000000000000000E+000 26 | 0.000000000000000E+000 27 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.temperature_spectrum: -------------------------------------------------------------------------------- 1 | gyro-bohm normalized temperature fluctuation amplitude spectra 2 | (temperature(is),is=1,ns_in) 3 | 31.0980164430995 62.7905643200403 4 | 6.64491249851558 16.6574035019584 5 | 2.87439336193427 7.04749887725389 6 | 1.27865821796149 3.48271757720170 7 | 1.05391665512562 2.04990849721115 8 | 1.05061211073303 1.61383144371383 9 | 0.968794731764140 1.43434679537278 10 | 0.843220539885560 0.792757173150351 11 | 0.642755917622966 0.548031239603831 12 | 0.520032600533068 0.397636674612528 13 | 0.408517653845421 0.189254031526772 14 | 0.389802511031025 8.897016084875840E-002 15 | 0.279931263720342 3.711216684853922E-002 16 | 0.108999968827097 1.461444940987277E-002 17 | 8.518797044259795E-002 5.634719717558091E-003 18 | 5.769872184068811E-002 2.777890733270628E-003 19 | 3.544395251832930E-002 1.277812123769071E-003 20 | 2.176578538821865E-002 5.888683130201869E-004 21 | 1.312322028608818E-002 2.760634634322023E-004 22 | 7.608916967013694E-003 1.260202218263740E-004 23 | 4.887194434808582E-003 6.280951289387716E-005 24 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.version: -------------------------------------------------------------------------------- 1 | 22b2712 [2023-01-05] 2 | MARCONI_SKL 3 | Fri 28 Apr 17:19:54 CEST 2023 4 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/out.tglf.width_spectrum: -------------------------------------------------------------------------------- 1 | width of the Gaussian envelope for the Hermite basis functions 2 | index limits: nky 3 | 21 4 | 1.65000000000000 5 | 1.26416066811879 6 | 1.19857700097546 7 | 1.19857700097546 8 | 1.65000000000000 9 | 1.65000000000000 10 | 1.19857700097546 11 | 1.65000000000000 12 | 1.65000000000000 13 | 1.65000000000000 14 | 1.65000000000000 15 | 1.65000000000000 16 | 1.65000000000000 17 | 1.65000000000000 18 | 1.65000000000000 19 | 1.65000000000000 20 | 1.48323947784843 21 | 1.56439928996721 22 | 1.56439928996721 23 | 1.40629017333177 24 | 1.19857700097546 25 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/outputs/TGLF_transport/regress: -------------------------------------------------------------------------------- 1 | [GA standard case, Miller geometry] 2 | -------------------------------------------------------------------------------- /src/pyrokinetics/templates/scene.cdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/scene.cdf -------------------------------------------------------------------------------- /src/pyrokinetics/templates/transp.cdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/src/pyrokinetics/templates/transp.cdf -------------------------------------------------------------------------------- /src/pyrokinetics/typing.py: -------------------------------------------------------------------------------- 1 | from os import PathLike as os_PathLike 2 | from typing import Union 3 | 4 | from numpy import floating, integer 5 | from numpy.typing import ArrayLike # noqa 6 | 7 | Scalar = Union[float, integer, floating] 8 | PathLike = Union[os_PathLike, str] 9 | -------------------------------------------------------------------------------- /tests/databases/golden_answers/Apa_kykxs00000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Apa_kykxs00000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Apa_kykxs00000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Apa_kykxs00000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Bpa_kykxs00000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Bpa_kykxs00000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Bpa_kykxs00000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Bpa_kykxs00000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Phi_kykxs00000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Phi_kykxs00000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Phi_kykxs00000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Phi_kykxs00000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tpar_kykxs01_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tpar_kykxs01_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tpar_kykxs01_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tpar_kykxs01_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tpar_kykxs02_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tpar_kykxs02_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tpar_kykxs02_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tpar_kykxs02_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tperp_kykxs01_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tperp_kykxs01_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tperp_kykxs01_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tperp_kykxs01_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tperp_kykxs02_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tperp_kykxs02_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/Tperp_kykxs02_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/Tperp_kykxs02_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/dens_kykxs01_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/dens_kykxs01_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/dens_kykxs01_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/dens_kykxs01_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/dens_kykxs02_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/dens_kykxs02_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/dens_kykxs02_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/dens_kykxs02_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/file_count: -------------------------------------------------------------------------------- 1 | 1. 2 | 2. 3 | 3. 4 | 4. 5 | 5. 6 | 6. 7 | 7. 8 | 8. 9 | 9. 10 | 10. 11 | 11. 12 | 12. 13 | 13. 14 | 14. 15 | 15. 16 | 16. 17 | 17. 18 | 18. 19 | 19. 20 | 20. 21 | 21. 22 | 22. 23 | 23. 24 | 24. 25 | 25. 26 | 26. 27 | 27. 28 | 28. 29 | 29. 30 | 30. 31 | 31. 32 | 32. 33 | 33. 34 | 34. 35 | 35. 36 | 36. 37 | 37. 38 | 38. 39 | 39. 40 | 40. 41 | 41. 42 | 42. 43 | 43. 44 | 44. 45 | 45. 46 | 46. 47 | 47. 48 | 48. 49 | 49. 50 | 50. 51 | 51. 52 | 52. 53 | 53. 54 | 54. 55 | 55. 56 | 56. 57 | 57. 58 | 58. 59 | 59. 60 | 60. 61 | 61. 62 | 62. 63 | 63. 64 | 64. 65 | 65. 66 | 66. 67 | 67. 68 | 68. 69 | 69. 70 | 70. 71 | 71. 72 | 72. 73 | 73. 74 | 74. 75 | 75. 76 | 76. 77 | 77. 78 | 78. 79 | 79. 80 | 80. 81 | 81. 82 | 82. 83 | 83. 84 | 84. 85 | 85. 86 | 86. 87 | 87. 88 | 88. 89 | 89. 90 | 90. 91 | 91. 92 | 92. 93 | 93. 94 | 94. 95 | 95. 96 | 96. 97 | 97. 98 | 98. 99 | 99. 100 | 100. 101 | 101. 102 | 102. 103 | 103. 104 | 104. 105 | 105. 106 | 106. 107 | 107. 108 | 108. 109 | 109. 110 | 110. 111 | 111. 112 | 112. 113 | 113. 114 | 114. 115 | 115. 116 | 116. 117 | 117. 118 | 118. 119 | 119. 120 | 120. 121 | 121. 122 | 122. 123 | 123. 124 | 124. 125 | 125. 126 | 126. 127 | 127. 128 | 128. 129 | 129. 130 | 130. 131 | 131. 132 | 132. 133 | 133. 134 | 134. 135 | 135. 136 | -------------------------------------------------------------------------------- /tests/databases/golden_answers/imas_example.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/imas_example.h5 -------------------------------------------------------------------------------- /tests/databases/golden_answers/krho: -------------------------------------------------------------------------------- 1 | 6.00000E-01 2 | -------------------------------------------------------------------------------- /tests/databases/golden_answers/kxrh: -------------------------------------------------------------------------------- 1 | 0.00000E+00 2 | -------------------------------------------------------------------------------- /tests/databases/golden_answers/vpar_kykxs01_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/vpar_kykxs01_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/vpar_kykxs01_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/vpar_kykxs01_000135_real_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/vpar_kykxs02_000135_imag_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/vpar_kykxs02_000135_imag_sp -------------------------------------------------------------------------------- /tests/databases/golden_answers/vpar_kykxs02_000135_real_sp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/databases/golden_answers/vpar_kykxs02_000135_real_sp -------------------------------------------------------------------------------- /tests/diagnostics/golden_answers/ideal_ball.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/diagnostics/golden_answers/ideal_ball.npy -------------------------------------------------------------------------------- /tests/diagnostics/golden_answers/poincare.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/diagnostics/golden_answers/poincare.npy -------------------------------------------------------------------------------- /tests/diagnostics/test_gs2_geometry.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numpy.testing import assert_allclose 3 | import netCDF4 as nc 4 | 5 | from pyrokinetics import Pyro, template_dir 6 | from pyrokinetics.diagnostics import Diagnostics 7 | from pyrokinetics.units import ureg 8 | 9 | 10 | def test_gs2_geometry(): 11 | pyro = Pyro(gk_file=template_dir / "outputs/GS2_linear/gs2.in") 12 | 13 | diag = Diagnostics(pyro) 14 | 15 | geometry_terms = diag.gs2_geometry_terms(ntheta_multiplier=1) 16 | 17 | gs2_data = nc.Dataset(template_dir / "outputs/GS2_linear/gs2.out.nc") 18 | 19 | pyro_theta = geometry_terms["theta"] 20 | 21 | gs2_theta = gs2_data["theta"][:].data 22 | 23 | ignore_keys = ["dpdrho"] 24 | 25 | for key in geometry_terms.keys(): 26 | if key not in ignore_keys: 27 | gs2_geo_term = np.interp(pyro_theta, gs2_theta, gs2_data[key][:].data) 28 | assert_allclose( 29 | ureg.Quantity(gs2_geo_term).magnitude, 30 | ureg.Quantity(geometry_terms[key]).magnitude, 31 | rtol=3e-2, 32 | atol=5e-3, 33 | ) 34 | -------------------------------------------------------------------------------- /tests/diagnostics/test_ideal_ball.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_allclose 4 | from pathlib import Path 5 | 6 | from pyrokinetics import Pyro, template_dir 7 | from pyrokinetics.diagnostics import Diagnostics 8 | 9 | 10 | @pytest.fixture(scope="module") 11 | def gamma_benchmark(): 12 | return np.load(Path(__file__).parent / "golden_answers/ideal_ball.npy") 13 | 14 | 15 | def test_ideal_ballooning(gamma_benchmark): 16 | nshat = 5 17 | nbprime = 5 18 | shat = np.linspace(0.0, 2, nshat) 19 | bprime = np.linspace(0.0, -0.5, nbprime) 20 | 21 | pyro = Pyro(gk_file=template_dir / "input.gs2") 22 | 23 | gamma = np.empty((nshat, nbprime)) 24 | 25 | for i_s, s in enumerate(shat): 26 | for i_b, b in enumerate(bprime): 27 | pyro.local_geometry.shat = s 28 | pyro.local_geometry.beta_prime = b 29 | diag = Diagnostics(pyro) 30 | gamma[i_s, i_b] = diag.ideal_ballooning_solver() 31 | 32 | assert_allclose(gamma_benchmark, gamma, rtol=1e-3, atol=1e-4) 33 | -------------------------------------------------------------------------------- /tests/diagnostics/test_neoclassical.py: -------------------------------------------------------------------------------- 1 | import netCDF4 as nc 2 | from numpy.testing import assert_allclose 3 | 4 | from pyrokinetics import Pyro, template_dir 5 | from pyrokinetics.diagnostics.neoclassical import Redl2021, Sauter1999 6 | from pyrokinetics.units import ureg as units 7 | 8 | 9 | def test_bootstrap_current(): 10 | 11 | # Equilibrium and Kinetics data file 12 | scene_cdf = template_dir / "scene.cdf" 13 | scene_eqdsk = template_dir / "step.geqdsk" 14 | 15 | scene_data = nc.Dataset(scene_cdf) 16 | indices = slice(10, -10, 2) 17 | scene_psin = scene_data["rho_psi"][indices] ** 2 18 | 19 | # SCENE gives / 20 | scene_jbsdotb_b2 = ( 21 | scene_data["Jbs.B"][indices].data * units.ampere / units.tesla / units.meter**2 22 | ) 23 | scene_zeff = scene_data["zeff"][indices].data * units.elementary_charge 24 | 25 | scene_jtotdotb_b2 = ( 26 | scene_data["Jtot.B"][indices].data * units.ampere / units.tesla / units.meter**2 27 | ) 28 | 29 | redl_jbsdotb_b2 = scene_jbsdotb_b2 * 0.0 30 | sauter_jbsdotb_b2 = scene_jbsdotb_b2 * 0.0 31 | redl_jtotdotb_b2 = scene_jtotdotb_b2 * 0.0 32 | sauter_jtotdotb_b2 = scene_jtotdotb_b2 * 0.0 33 | 34 | # Load up pyro object 35 | pyro = Pyro( 36 | eq_file=scene_eqdsk, 37 | eq_type="GEQDSK", 38 | kinetics_file=scene_cdf, 39 | kinetics_type="SCENE", 40 | ) 41 | 42 | for i, psi_n in enumerate(scene_psin): 43 | try: 44 | pyro.load_local(psi_n=psi_n, local_geometry="MXH") 45 | except Exception: 46 | continue 47 | 48 | pyro.local_species.zeff = scene_zeff[i] 49 | 50 | redl = Redl2021(pyro) 51 | redl_jbsdotb_b2[i] = (redl.JbsdotB / redl.B2_fsa).to("ampere / tesla / m**2") 52 | redl_jtotdotb_b2[i] = (redl.JdotB / redl.B2_fsa).to("ampere / tesla / m**2") 53 | 54 | sauter = Sauter1999(pyro) 55 | sauter_jbsdotb_b2[i] = (sauter.JbsdotB / sauter.B2_fsa).to( 56 | "ampere / tesla / m**2" 57 | ) 58 | sauter_jtotdotb_b2[i] = (sauter.JdotB / sauter.B2_fsa).to( 59 | "ampere / tesla / m**2" 60 | ) 61 | 62 | assert_allclose(redl_jbsdotb_b2.m, scene_jbsdotb_b2.m, rtol=6e-2) 63 | assert_allclose(sauter_jbsdotb_b2.m, scene_jbsdotb_b2.m, rtol=15e-2) 64 | assert_allclose(redl_jtotdotb_b2.m, scene_jtotdotb_b2.m, rtol=1e-2) 65 | assert_allclose(sauter_jtotdotb_b2.m, scene_jtotdotb_b2.m, rtol=1e-2) 66 | -------------------------------------------------------------------------------- /tests/diagnostics/test_poincare.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_allclose 4 | from pathlib import Path 5 | 6 | from pyrokinetics import Pyro, template_dir 7 | from pyrokinetics.diagnostics import Diagnostics 8 | 9 | 10 | def call_poincare(pyro): 11 | xarray = np.linspace(6, 8, 5) 12 | yarray = np.linspace(-10, 10, 3) 13 | nturns = 1000 14 | time = 1 15 | rhos = 0.036 16 | diag = Diagnostics(pyro) 17 | coords = diag.poincare(xarray, yarray, nturns, time, rhos, smoothing=0.0) 18 | return coords 19 | 20 | 21 | def test_linear_poincare(): 22 | pyro = Pyro( 23 | gk_file=template_dir / "outputs" / "CGYRO_linear" / "input.cgyro", 24 | gk_code="CGYRO", 25 | ) 26 | pyro.load_gk_output() 27 | with pytest.raises(RuntimeError): 28 | call_poincare(pyro) 29 | 30 | 31 | def test_poincare(): 32 | pyro = Pyro( 33 | gk_file=template_dir / "outputs" / "CGYRO_nonlinear" / "input.cgyro", 34 | gk_code="CGYRO", 35 | ) 36 | pyro.load_gk_output() 37 | coords = call_poincare(pyro) 38 | filename = Path(__file__).parent / "golden_answers" / "poincare.npy" 39 | data = np.asarray(np.load(filename)) 40 | assert_allclose(coords, data, rtol=1e-5, atol=1e-8) 41 | -------------------------------------------------------------------------------- /tests/gk_code/__init__.py: -------------------------------------------------------------------------------- 1 | # hello world 2 | -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/cgyro_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/cgyro_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/gene_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/gene_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/gkw_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/gkw_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/gs2_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/gs2_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/gx_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/gx_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/stella_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/stella_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/gk_code/golden_answers/tglf_linear_output_899a2cb8.netcdf4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyro-kinetics/pyrokinetics/a40227ef35e23d458423116bb0f9a38f2e4a6d43/tests/gk_code/golden_answers/tglf_linear_output_899a2cb8.netcdf4 -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_eliteinp.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.equilibrium.equilibrium import read_equilibrium 2 | from pyrokinetics.kinetics import Kinetics, KineticsReaderELITEINP 3 | from pyrokinetics.species import Species 4 | from pyrokinetics import template_dir 5 | import pytest 6 | 7 | 8 | class TestKineticsReaderELITEINP: 9 | @pytest.fixture 10 | def transp_reader(self): 11 | return KineticsReaderELITEINP() 12 | 13 | @pytest.fixture 14 | def example_file(self): 15 | return template_dir / "test.eliteinp" 16 | 17 | @pytest.fixture 18 | def example_eq(self): 19 | eq_file = template_dir / "test.geqdsk" 20 | return read_equilibrium(eq_file) 21 | 22 | def test_read(self, transp_reader, example_file, example_eq): 23 | """ 24 | Ensure it can read the example ELITEINP file, and that it produces a Species dict. 25 | """ 26 | result = transp_reader(example_file, eq=example_eq) 27 | assert isinstance(result, Kinetics) 28 | for _, value in result.species_data.items(): 29 | assert isinstance(value, Species) 30 | 31 | def test_verify_file_type(self, transp_reader, example_file): 32 | """Ensure verify_file_type completes without throwing an error""" 33 | transp_reader.verify_file_type(example_file) 34 | 35 | def test_read_file_does_not_exist(self, transp_reader): 36 | """Ensure failure when given a non-existent file""" 37 | filename = template_dir / "helloworld" 38 | with pytest.raises((FileNotFoundError, ValueError)): 39 | transp_reader(filename) 40 | 41 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 42 | def test_read_file_is_not_transp(self, transp_reader, filename): 43 | """Ensure failure when given a non-transp netcdf file 44 | 45 | This could fail for any number of reasons during processing. 46 | """ 47 | filename = template_dir / filename 48 | with pytest.raises(Exception): 49 | transp_reader(filename) 50 | 51 | def test_verify_file_does_not_exist(self, transp_reader): 52 | """Ensure failure when given a non-existent file""" 53 | filename = template_dir / "helloworld" 54 | with pytest.raises((FileNotFoundError, ValueError)): 55 | transp_reader.verify_file_type(filename) 56 | 57 | def test_verify_file_is_not_netcdf(self, transp_reader): 58 | """Ensure failure when given a non-netcdf file""" 59 | filename = template_dir / "input.gs2" 60 | with pytest.raises(ValueError): 61 | transp_reader.verify_file_type(filename) 62 | 63 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 64 | def test_verify_file_is_not_transp(self, transp_reader, filename): 65 | """Ensure failure when given a non-transp netcdf file""" 66 | filename = template_dir / filename 67 | with pytest.raises(ValueError): 68 | transp_reader.verify_file_type(filename) 69 | -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_gacode.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.kinetics import Kinetics, KineticsReaderGACODE 2 | from pyrokinetics.species import Species 3 | from pyrokinetics import template_dir 4 | import pytest 5 | 6 | 7 | class TestKineticsReaderGACODE: 8 | @pytest.fixture 9 | def gacode_reader(self): 10 | return KineticsReaderGACODE() 11 | 12 | @pytest.fixture 13 | def example_file(self): 14 | return template_dir / "input.gacode" 15 | 16 | def test_read(self, gacode_reader, example_file): 17 | """ 18 | Ensure it can read the example GACODE file, and that it produces a Species dict. 19 | """ 20 | result = gacode_reader(example_file) 21 | assert isinstance(result, Kinetics) 22 | for _, value in result.species_data.items(): 23 | assert isinstance(value, Species) 24 | 25 | def test_verify_file_type(self, gacode_reader, example_file): 26 | """Ensure verify_file_type completes without throwing an error""" 27 | gacode_reader.verify_file_type(example_file) 28 | 29 | def test_read_file_does_not_exist(self, gacode_reader): 30 | """Ensure failure when given a non-existent file""" 31 | filename = template_dir / "helloworld" 32 | with pytest.raises((FileNotFoundError, ValueError)): 33 | gacode_reader(filename) 34 | 35 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 36 | def test_read_file_is_not_gacode(self, gacode_reader, filename): 37 | """Ensure failure when given a non-gacode netcdf file 38 | 39 | This could fail for any number of reasons during processing. 40 | """ 41 | filename = template_dir / filename 42 | with pytest.raises(ValueError): 43 | gacode_reader(filename) 44 | 45 | def test_verify_file_does_not_exist(self, gacode_reader): 46 | """Ensure failure when given a non-existent file""" 47 | filename = template_dir / "helloworld" 48 | with pytest.raises((FileNotFoundError, ValueError)): 49 | gacode_reader.verify_file_type(filename) 50 | 51 | def test_verify_file_is_not_netcdf(self, gacode_reader): 52 | """Ensure failure when given a non-netcdf file""" 53 | filename = template_dir / "input.gs2" 54 | with pytest.raises(ValueError): 55 | gacode_reader.verify_file_type(filename) 56 | 57 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 58 | def test_verify_file_is_not_gacode(self, gacode_reader, filename): 59 | """Ensure failure when given a non-gacode netcdf file""" 60 | filename = template_dir / filename 61 | with pytest.raises(ValueError): 62 | gacode_reader.verify_file_type(filename) 63 | -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_imas.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.equilibrium.equilibrium import read_equilibrium 2 | from pyrokinetics.kinetics import Kinetics, KineticsReaderIMAS 3 | from pyrokinetics.species import Species 4 | from pyrokinetics import template_dir 5 | import pytest 6 | 7 | 8 | class TestKineticsReaderIMAS: 9 | @pytest.fixture 10 | def imas_reader(self): 11 | return KineticsReaderIMAS() 12 | 13 | @pytest.fixture 14 | def example_file(self): 15 | return template_dir / "core_profiles.h5" 16 | 17 | @pytest.fixture 18 | def example_eq(self): 19 | eq_file = template_dir / "test.geqdsk" 20 | return read_equilibrium(eq_file) 21 | 22 | def test_read(self, imas_reader, example_file, example_eq): 23 | """ 24 | Ensure it can read the example imas file, and that it produces a Species dict. 25 | """ 26 | result = imas_reader(example_file, eq=example_eq) 27 | assert isinstance(result, Kinetics) 28 | for _, value in result.species_data.items(): 29 | assert isinstance(value, Species) 30 | 31 | def test_verify_file_type(self, imas_reader, example_file): 32 | """Ensure verify_file_type completes without throwing an error""" 33 | imas_reader.verify_file_type(example_file) 34 | 35 | def test_read_file_does_not_exist(self, imas_reader, example_eq): 36 | """Ensure failure when given a non-existent file""" 37 | filename = template_dir / "helloworld" 38 | with pytest.raises(FileNotFoundError): 39 | imas_reader(filename, eq=example_eq) 40 | 41 | def test_read_file_without_geqdsk(self, imas_reader, example_file): 42 | """Ensure failure when no GEQDSK file given""" 43 | with pytest.raises(ValueError): 44 | imas_reader(example_file, eq=None) 45 | 46 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 47 | def test_read_file_is_not_imas(self, imas_reader, filename, example_eq): 48 | """Ensure failure when given a non-imas netcdf file 49 | 50 | This could fail for any number of reasons during processing. 51 | """ 52 | filename = template_dir / filename 53 | with pytest.raises(Exception): 54 | imas_reader(filename, eq=example_eq) 55 | 56 | def test_verify_file_does_not_exist(self, imas_reader): 57 | """Ensure failure when given a non-existent file""" 58 | filename = template_dir / "helloworld" 59 | with pytest.raises((FileNotFoundError, ValueError)): 60 | imas_reader.verify_file_type(filename) 61 | 62 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 63 | def test_verify_file_is_not_imas(self, imas_reader, filename): 64 | """Ensure failure when given a non-imas netcdf file""" 65 | filename = template_dir / filename 66 | with pytest.raises(ValueError): 67 | imas_reader.verify_file_type(filename) 68 | -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_jetto.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.kinetics import Kinetics, KineticsReaderJETTO 2 | from pyrokinetics.species import Species 3 | from pyrokinetics import template_dir 4 | import pytest 5 | 6 | 7 | class TestKineticsReaderJETTO: 8 | @pytest.fixture 9 | def jetto_reader(self): 10 | return KineticsReaderJETTO() 11 | 12 | @pytest.fixture 13 | def example_file(self): 14 | return template_dir / "jetto.jsp" 15 | 16 | def test_read_from_file(self, jetto_reader, example_file): 17 | """ 18 | Ensure it can read the example JETTO file, and that it produces a Species dict. 19 | """ 20 | result = jetto_reader(example_file) 21 | assert isinstance(result, Kinetics) 22 | for _, value in result.species_data.items(): 23 | assert isinstance(value, Species) 24 | 25 | def test_verify_file_type(self, jetto_reader, example_file): 26 | """Ensure verify_file_type completes without throwing an error""" 27 | jetto_reader.verify_file_type(example_file) 28 | 29 | def test_read_file_does_not_exist(self, jetto_reader): 30 | """Ensure failure when given a non-existent file""" 31 | filename = template_dir / "helloworld" 32 | with pytest.raises((FileNotFoundError, ValueError)): 33 | jetto_reader(filename) 34 | 35 | def test_read_file_is_not_jsp(self, jetto_reader): 36 | """Ensure failure when given a non-netcdf file""" 37 | filename = template_dir / "input.gs2" 38 | with pytest.raises(ValueError): 39 | jetto_reader(filename) 40 | 41 | @pytest.mark.parametrize("filename", ["transp.cdf", "scene.cdf"]) 42 | def test_read_file_is_not_jetto(self, jetto_reader, filename): 43 | """Ensure failure when given a non-jetto netcdf file 44 | 45 | This could fail for any number of reasons during processing. 46 | """ 47 | filename = template_dir / filename 48 | with pytest.raises(Exception): 49 | jetto_reader(filename) 50 | 51 | def test_verify_file_does_not_exist(self, jetto_reader): 52 | """Ensure failure when given a non-existent file""" 53 | filename = template_dir / "helloworld" 54 | with pytest.raises((FileNotFoundError, ValueError)): 55 | jetto_reader.verify_file_type(filename) 56 | 57 | def test_verify_file_is_not_netcdf(self, jetto_reader): 58 | """Ensure failure when given a non-netcdf file""" 59 | filename = template_dir / "input.gs2" 60 | with pytest.raises(ValueError): 61 | jetto_reader.verify_file_type(filename) 62 | 63 | @pytest.mark.parametrize("filename", ["transp.cdf", "scene.cdf"]) 64 | def test_verify_file_is_not_jetto(self, jetto_reader, filename): 65 | """Ensure failure when given a non-jetto netcdf file""" 66 | filename = template_dir / filename 67 | with pytest.raises(ValueError): 68 | jetto_reader.verify_file_type(filename) 69 | -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_pfile.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.equilibrium.equilibrium import read_equilibrium 2 | from pyrokinetics.kinetics import Kinetics, KineticsReaderpFile 3 | from pyrokinetics.species import Species 4 | from pyrokinetics import template_dir 5 | import pytest 6 | 7 | 8 | class TestKineticsReaderpFile: 9 | @pytest.fixture 10 | def pfile_reader(self): 11 | return KineticsReaderpFile() 12 | 13 | @pytest.fixture 14 | def example_file(self): 15 | return template_dir / "pfile.txt" 16 | 17 | @pytest.fixture 18 | def example_eq(self): 19 | eq_file = template_dir / "test.geqdsk" 20 | return read_equilibrium(eq_file) 21 | 22 | def test_read(self, pfile_reader, example_file, example_eq): 23 | """ 24 | Ensure it can read the example pfile file, and that it produces a Species dict. 25 | """ 26 | result = pfile_reader(example_file, eq=example_eq) 27 | assert isinstance(result, Kinetics) 28 | for _, value in result.species_data.items(): 29 | assert isinstance(value, Species) 30 | 31 | def test_verify_file_type(self, pfile_reader, example_file): 32 | """Ensure verify_file_type completes without throwing an error""" 33 | pfile_reader.verify_file_type(example_file) 34 | 35 | def test_read_file_does_not_exist(self, pfile_reader, example_eq): 36 | """Ensure failure when given a non-existent file""" 37 | filename = template_dir / "helloworld" 38 | with pytest.raises(FileNotFoundError): 39 | pfile_reader(filename, eq=example_eq) 40 | 41 | def test_read_file_without_geqdsk(self, pfile_reader, example_file): 42 | """Ensure failure when no GEQDSK file given""" 43 | with pytest.raises(ValueError): 44 | pfile_reader(example_file, eq=None) 45 | 46 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 47 | def test_read_file_is_not_pfile(self, pfile_reader, filename, example_eq): 48 | """Ensure failure when given a non-pfile netcdf file 49 | 50 | This could fail for any number of reasons during processing. 51 | """ 52 | filename = template_dir / filename 53 | with pytest.raises(Exception): 54 | pfile_reader(filename, eq=example_eq) 55 | 56 | def test_verify_file_does_not_exist(self, pfile_reader): 57 | """Ensure failure when given a non-existent file""" 58 | filename = template_dir / "helloworld" 59 | with pytest.raises((FileNotFoundError, ValueError)): 60 | pfile_reader.verify_file_type(filename) 61 | 62 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 63 | def test_verify_file_is_not_pfile(self, pfile_reader, filename): 64 | """Ensure failure when given a non-pfile netcdf file""" 65 | filename = template_dir / filename 66 | with pytest.raises(ValueError): 67 | pfile_reader.verify_file_type(filename) 68 | -------------------------------------------------------------------------------- /tests/kinetics/test_kinetics_reader_transp.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics.kinetics import Kinetics, KineticsReaderTRANSP 2 | from pyrokinetics.species import Species 3 | from pyrokinetics import template_dir 4 | import pytest 5 | 6 | 7 | class TestKineticsReaderTRANSP: 8 | @pytest.fixture 9 | def transp_reader(self): 10 | return KineticsReaderTRANSP() 11 | 12 | @pytest.fixture 13 | def example_file(self): 14 | return template_dir / "transp.cdf" 15 | 16 | def test_read(self, transp_reader, example_file): 17 | """ 18 | Ensure it can read the example TRANSP file, and that it produces a Species dict. 19 | """ 20 | result = transp_reader(example_file) 21 | assert isinstance(result, Kinetics) 22 | for _, value in result.species_data.items(): 23 | assert isinstance(value, Species) 24 | 25 | def test_verify_file_type(self, transp_reader, example_file): 26 | """Ensure verify_file_type completes without throwing an error""" 27 | transp_reader.verify_file_type(example_file) 28 | 29 | def test_read_file_does_not_exist(self, transp_reader): 30 | """Ensure failure when given a non-existent file""" 31 | filename = template_dir / "helloworld" 32 | with pytest.raises((FileNotFoundError, ValueError)): 33 | transp_reader(filename) 34 | 35 | def test_read_file_is_not_netcdf(self, transp_reader): 36 | """Ensure failure when given a non-netcdf file""" 37 | filename = template_dir / "input.gs2" 38 | with pytest.raises(OSError): 39 | transp_reader(filename) 40 | 41 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 42 | def test_read_file_is_not_transp(self, transp_reader, filename): 43 | """Ensure failure when given a non-transp netcdf file 44 | 45 | This could fail for any number of reasons during processing. 46 | """ 47 | filename = template_dir / filename 48 | with pytest.raises(Exception): 49 | transp_reader(filename) 50 | 51 | def test_verify_file_does_not_exist(self, transp_reader): 52 | """Ensure failure when given a non-existent file""" 53 | filename = template_dir / "helloworld" 54 | with pytest.raises((FileNotFoundError, ValueError)): 55 | transp_reader.verify_file_type(filename) 56 | 57 | def test_verify_file_is_not_netcdf(self, transp_reader): 58 | """Ensure failure when given a non-netcdf file""" 59 | filename = template_dir / "input.gs2" 60 | with pytest.raises(ValueError): 61 | transp_reader.verify_file_type(filename) 62 | 63 | @pytest.mark.parametrize("filename", ["jetto.jsp", "scene.cdf"]) 64 | def test_verify_file_is_not_transp(self, transp_reader, filename): 65 | """Ensure failure when given a non-transp netcdf file""" 66 | filename = template_dir / filename 67 | with pytest.raises(ValueError): 68 | transp_reader.verify_file_type(filename) 69 | -------------------------------------------------------------------------------- /tests/local_geometry/test_local_geometry_factory.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from pyrokinetics.local_geometry import local_geometry_factory, LocalGeometryMiller 4 | 5 | 6 | def test_miller(): 7 | """Ensure a miller object is created successfully""" 8 | miller = local_geometry_factory("Miller") 9 | assert isinstance(miller, LocalGeometryMiller) 10 | 11 | 12 | def test_non_local_geometry(): 13 | """Ensure failure when getting a non-existent LocalGeometry""" 14 | with pytest.raises(KeyError): 15 | local_geometry_factory("Hello world") 16 | -------------------------------------------------------------------------------- /tests/local_geometry/test_transp_cdf_vs_geqdsk.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | import warnings 4 | from pyrokinetics import template_dir 5 | from pyrokinetics.equilibrium import EquilibriumCOCOSWarning, read_equilibrium 6 | from pyrokinetics.local_geometry import LocalGeometryMillerTurnbull 7 | from pyrokinetics.normalisation import SimulationNormalisation 8 | 9 | 10 | @pytest.fixture(scope="module") 11 | def transp_cdf_equilibrium(): 12 | warnings.simplefilter("ignore", EquilibriumCOCOSWarning) 13 | eq = read_equilibrium(template_dir / "transp.cdf", time=0.2) 14 | warnings.simplefilter("default", EquilibriumCOCOSWarning) 15 | return eq 16 | 17 | 18 | @pytest.fixture(scope="module") 19 | def transp_gq_equilibrium(): 20 | warnings.simplefilter("ignore", EquilibriumCOCOSWarning) 21 | eq = read_equilibrium(template_dir / "transp_eq.geqdsk") 22 | warnings.simplefilter("default", EquilibriumCOCOSWarning) 23 | return eq 24 | 25 | 26 | def assert_within_ten_percent(key, cdf_value, gq_value): 27 | 28 | cdf_value = cdf_value 29 | gq_value = gq_value 30 | 31 | # Same units so can take magnitude 32 | difference = np.abs((cdf_value - gq_value)).m 33 | smallest_value = np.min(np.abs([cdf_value.m, gq_value.m])) 34 | 35 | if smallest_value == 0.0: 36 | if np.allclose(difference, 0.0): 37 | assert True 38 | else: 39 | assert np.allclose( 40 | difference / np.max(np.abs([cdf_value.m, gq_value.m])), 0.0, atol=0.1 41 | ), f"{key} not within 10 percent" 42 | else: 43 | assert difference / smallest_value < 0.1, f"{key} not within 10 percent" 44 | 45 | 46 | def test_compare_transp_cdf_geqdsk(transp_cdf_equilibrium, transp_gq_equilibrium): 47 | # TODO Rather than ignoring most attrs, better to explicitly include them 48 | psi_n = 0.5 49 | lg_gq = LocalGeometryMillerTurnbull() 50 | lg_cdf = LocalGeometryMillerTurnbull() 51 | 52 | norms_transp = SimulationNormalisation("test_compare_transp_cdf_geqdsk_transp") 53 | norms_geqdsk = SimulationNormalisation("test_compare_transp_cdf_geqdsk_geqdsk") 54 | 55 | lg_gq.from_global_eq(transp_gq_equilibrium, psi_n=psi_n, norms=norms_geqdsk) 56 | lg_cdf.from_global_eq(transp_cdf_equilibrium, psi_n=psi_n, norms=norms_transp) 57 | 58 | ignored_geometry_attrs = [ 59 | "R", 60 | "Z", 61 | "theta", 62 | "b_poloidal", 63 | "R_eq", 64 | "Z_eq", 65 | "theta_eq", 66 | "b_poloidal_eq", 67 | "dRdtheta", 68 | "dZdtheta", 69 | "dRdr", 70 | "dZdr", 71 | "s_kappa", 72 | "delta", 73 | "s_delta", 74 | "zeta", 75 | "local_geometry", 76 | "jacob", 77 | "unit_mapping", 78 | "_already_warned", 79 | ] 80 | 81 | for key in lg_gq.keys(): 82 | if key in ignored_geometry_attrs: 83 | continue 84 | assert_within_ten_percent(key, lg_gq[key], lg_cdf[key]) 85 | -------------------------------------------------------------------------------- /tests/test_decorators.py: -------------------------------------------------------------------------------- 1 | from pyrokinetics import decorators 2 | 3 | import pytest 4 | 5 | 6 | def test_not_implemented(): 7 | class FakeThing: 8 | @decorators.not_implemented 9 | def this_should_raise_error(self): 10 | return 1 11 | 12 | with pytest.raises(NotImplementedError) as error: 13 | assert FakeThing().this_should_raise_error() != 1 14 | 15 | assert "FakeThing" in str(error) 16 | -------------------------------------------------------------------------------- /tests/test_deepcopy.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import numpy as np 3 | import operator 4 | from copy import deepcopy 5 | from functools import reduce 6 | 7 | from pyrokinetics import Pyro, PyroScan, template_dir 8 | 9 | 10 | @pytest.fixture 11 | def default_pyro(): 12 | pyro = Pyro( 13 | gk_file=template_dir / "input.cgyro", 14 | eq_file=template_dir / "test.geqdsk", 15 | kinetics_file=template_dir / "scene.cdf", 16 | ) 17 | pyro.load_local(psi_n=0.5, local_geometry="Miller") 18 | return pyro 19 | 20 | 21 | @pytest.fixture 22 | def default_pyro_gk_file(): 23 | pyro = Pyro( 24 | gk_file=template_dir / "input.cgyro", 25 | ) 26 | return pyro 27 | 28 | 29 | def get_from_dict(data_dict, map_list): 30 | """ 31 | Gets item in dict given location as a list of string 32 | """ 33 | return reduce(operator.getitem, map_list, data_dict) 34 | 35 | 36 | def test_deepcopy_pyro_norm(tmp_path, default_pyro_gk_file): 37 | pyro = default_pyro_gk_file 38 | copy_pyro = deepcopy(pyro) 39 | 40 | pyro.enforce_consistent_beta_prime() 41 | copy_pyro.enforce_consistent_beta_prime() 42 | 43 | assert pyro.local_geometry.beta_prime == copy_pyro.local_geometry.beta_prime 44 | 45 | 46 | def test_deepcopy_pyro(tmp_path, default_pyro): 47 | pyro = default_pyro 48 | copy_pyro = deepcopy(pyro) 49 | 50 | for name, old_component, new_component in zip( 51 | pyro.__dict__.keys(), pyro.__dict__.values(), copy_pyro.__dict__.values() 52 | ): 53 | if name not in ["eq", "kinetics", "gk_output"]: 54 | if not isinstance(old_component, (str, type(None), bool)): 55 | assert id(old_component) != id(new_component) 56 | 57 | 58 | @pytest.mark.parametrize( 59 | "param,values", 60 | [ 61 | ["ky", np.arange(0.1, 0.3, 0.1)], # test numerics 62 | ["kappa", np.arange(0.1, 0.3, 0.1)], # test local geometry 63 | ["electron_temp_gradient", np.arange(0.1, 0.3, 0.1)], # test local species 64 | ], 65 | ) 66 | def test_deepcopy_pyroscan(tmp_path, default_pyro, param, values): 67 | pyro = default_pyro 68 | 69 | # Dictionary of param and values 70 | param_dict = {param: values} 71 | 72 | pyro_scan = PyroScan(pyro, param_dict, base_directory=tmp_path) 73 | pyro_scan.write() 74 | param = list(param_dict.keys())[0] 75 | 76 | (attr_name, keys_to_param) = pyro_scan.parameter_map[param] 77 | 78 | # Get attribute in Pyro storing the parameter 79 | pyro_attr = getattr(pyro, attr_name) 80 | 81 | original_value = get_from_dict(pyro_attr, keys_to_param) 82 | 83 | for pyro_run in pyro_scan.pyro_dict.values(): 84 | scan_attr = getattr(pyro_run, attr_name) 85 | scan_value = get_from_dict(scan_attr, keys_to_param) 86 | assert id(scan_value) != id(original_value) 87 | -------------------------------------------------------------------------------- /tests/test_file_utils.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from pyrokinetics.file_utils import ( 4 | FileReader, 5 | ReadableFromFile, 6 | ) 7 | from pyrokinetics.typing import PathLike 8 | 9 | 10 | class MyReadable(ReadableFromFile): 11 | """Defines a minimal readable object""" 12 | 13 | def __init__(self, data: str): 14 | self.data = data 15 | 16 | 17 | class MyReader(FileReader, file_type="MyReader", reads=MyReadable): 18 | """Defines a minimal reader object""" 19 | 20 | def read_from_file(self, filename: PathLike) -> MyReadable: 21 | with open(filename, "r") as f: 22 | return MyReadable(f.read()) 23 | 24 | 25 | @pytest.fixture 26 | def example_input_file(tmp_path): 27 | d = tmp_path / "test_file_utils" 28 | d.mkdir(parents=True, exist_ok=True) 29 | path = d / "example_input_file.txt" 30 | with open(path, "w") as f: 31 | f.write("hello world") 32 | return path 33 | 34 | 35 | def test_supported_file_types(): 36 | """Test that a Reader has been successfully registered""" 37 | assert "MyReader" in MyReadable.supported_file_types() 38 | 39 | 40 | @pytest.mark.parametrize("file_type", ("MyReader", None)) 41 | def test_from_file(example_input_file, file_type): 42 | readable = MyReadable.from_file(example_input_file) 43 | assert readable.data == "hello world" 44 | -------------------------------------------------------------------------------- /tests/test_numerics.py: -------------------------------------------------------------------------------- 1 | import dataclasses 2 | import json 3 | 4 | from pyrokinetics import Numerics 5 | 6 | import pytest 7 | import time 8 | 9 | 10 | def test_keys(): 11 | numerics = Numerics() # use defaults 12 | # Test you can set an existing key 13 | numerics["ntheta"] = 42 14 | assert numerics.ntheta == 42 15 | # Test you can't set a key that doesn't exist 16 | with pytest.raises(KeyError): 17 | numerics["n_theta"] = 42 18 | 19 | 20 | def test_attrs(): 21 | numerics = Numerics() # use defaults 22 | # Test you can set an existing attr 23 | numerics.ntheta = 42 24 | assert numerics.ntheta == 42 25 | # Test you can't set a key that doesn't exist 26 | with pytest.raises(AttributeError): 27 | numerics.n_theta = 42 28 | 29 | 30 | def test_write(tmp_path): 31 | numerics = Numerics() # use defaults 32 | d = tmp_path / "numerics" 33 | d.mkdir(exist_ok=True) 34 | filename = d / "test_write.json" 35 | with open(filename, "w") as f: 36 | f.write(numerics.to_json()) 37 | # Read as standard json and check values match 38 | with open(filename) as f: 39 | data = json.load(f) 40 | for key, value in data.items(): 41 | if key == "_metadata": 42 | for k2, v2 in data["_metadata"].items(): 43 | assert v2 == numerics._metadata[k2] 44 | else: 45 | assert value == numerics[key] 46 | 47 | 48 | def test_roundtrip(tmp_path): 49 | numerics = Numerics() # use defaults 50 | d = tmp_path / "numerics" 51 | d.mkdir(exist_ok=True) 52 | filename = d / "test_roundtrip.json" 53 | with open(filename, "w") as f: 54 | f.write(numerics.to_json()) 55 | # Read as a new numerics 56 | with open(filename) as f: 57 | new_numerics = Numerics.from_json(f.read()) 58 | assert numerics == new_numerics 59 | 60 | 61 | def test_roundtrip_new_metadata(tmp_path): 62 | numerics = Numerics() # use defaults 63 | d = tmp_path / "numerics" 64 | d.mkdir(exist_ok=True) 65 | filename = d / "test_roundtrip_new_metadata.json" 66 | with open(filename, "w") as f: 67 | f.write(numerics.to_json()) 68 | # Ensure object_created metadata is different 69 | time.sleep(0.001) 70 | # Read as a new numerics, overwriting metadata 71 | with open(filename) as f: 72 | new_numerics = Numerics.from_json( 73 | f.read(), 74 | overwrite_metadata=True, 75 | overwrite_title="hello world", 76 | ) 77 | data = dataclasses.asdict(new_numerics) 78 | for key, value in data.items(): 79 | if key == "_metadata": 80 | for k2, v2 in data["_metadata"].items(): 81 | if "software" in k2 or "session" in k2 or "object_type" in k2: 82 | assert v2 == numerics._metadata[k2] 83 | else: 84 | assert v2 != numerics._metadata[k2] 85 | else: 86 | assert value == numerics[key] 87 | -------------------------------------------------------------------------------- /tests/test_plugins.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pytest 4 | 5 | from pyrokinetics.equilibrium import ( 6 | Equilibrium, 7 | read_equilibrium, 8 | supported_equilibrium_types, 9 | ) 10 | from pyrokinetics.gk_code import ( 11 | GKInput, 12 | GKOutput, 13 | read_gk_input, 14 | read_gk_output, 15 | supported_gk_input_types, 16 | supported_gk_output_types, 17 | ) 18 | from pyrokinetics.kinetics import Kinetics, read_kinetics, supported_kinetics_types 19 | from pyrokinetics.normalisation import SimulationNormalisation 20 | 21 | # Skip tests if plugin library is missing 22 | try: 23 | from pyrokinetics_plugin_examples import make_plugin_example_file 24 | except ImportError: 25 | pytest.skip("Plugin test library not found.", allow_module_level=True) 26 | 27 | 28 | @pytest.fixture 29 | def plugin_file(tmp_path: Path) -> Path: 30 | """The pyrokinetics-plugin-examples repository contains a number of different plugin 31 | implementations, including variants for Equilibrium, Kinetics, GKInput, and 32 | GKOutput. 33 | 34 | However, all share the same input file. This fixture creates a new copy of this 35 | universal input file. 36 | """ 37 | d = tmp_path / "plugin_test_files" 38 | d.mkdir(parents=True, exist_ok=True) 39 | filename = d / "universal_input_file.txt" 40 | make_plugin_example_file(filename) 41 | return filename 42 | 43 | 44 | def test_equilibrium_plugin(plugin_file: Path) -> None: 45 | assert "_test" in supported_equilibrium_types() 46 | assert isinstance(read_equilibrium(plugin_file), Equilibrium) 47 | 48 | 49 | def test_kinetics_plugin(plugin_file: Path) -> None: 50 | assert "_test" in supported_kinetics_types() 51 | assert isinstance(read_kinetics(plugin_file), Kinetics) 52 | 53 | 54 | def test_gk_input_plugin(plugin_file: Path) -> None: 55 | assert "_test" in supported_gk_input_types() 56 | assert isinstance(read_gk_input(plugin_file), GKInput) 57 | 58 | 59 | def test_gk_output_plugin(plugin_file: Path) -> None: 60 | assert "_test" in supported_gk_output_types() 61 | norm = SimulationNormalisation("_test", convention="pyrokinetics") 62 | assert isinstance(read_gk_output(plugin_file, norm), GKOutput) 63 | --------------------------------------------------------------------------------