diff --git a/.coveragerc b/.coveragerc
index a67a87f0..a27c0920 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,4 +1,4 @@
[run]
plugins = Cython.Coverage
source = cherab
-omit = *tests*
+omit = */tests/*
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 56bc565f..f4c15ee4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,11 +11,8 @@ jobs:
strategy:
fail-fast: false
matrix:
- numpy-version: ["1.15.0", "1.16.6", "1.19.2"]
- python-version: ["3.6", "3.7", "3.8"]
- exclude:
- - python-version: "3.8"
- numpy-version: "1.15.0"
+ numpy-version: ["oldest-supported-numpy", "numpy"]
+ python-version: ["3.7", "3.8", "3.9", "3.10"]
steps:
- name: Checkout code
uses: actions/checkout@v2
@@ -26,11 +23,9 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
- run: python -m pip install cython>=0.28 numpy==${{ matrix.numpy-version }} scipy matplotlib pyopencl[pocl]==2022.1
- - name: Work around PyOpenCL issue 537
- run: echo OCL_ICD_VENDORS=$(python -c 'import os, pyopencl; print(os.path.join(*pyopencl.__path__, ".libs"))') >> $GITHUB_ENV
+ run: python -m pip install --prefer-binary cython>=0.28 ${{ matrix.numpy-version }} scipy matplotlib "pyopencl[pocl]>=2022.2.4"
- name: Install Raysect from pypi
- run: pip install raysect==0.7.1
+ run: pip install raysect==0.8.1
- name: Build cherab
run: dev/build.sh
- name: Run tests
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbe69a21..13202802 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,25 +1,49 @@
Project Changelog
=================
-Release 1.4.0 (TBD)
+Release 1.5.0 (TBD)
+-------------------
+
+New:
+* Support Raysect 0.8
+* Add custom line shape support to BeamCXLine model. (#394)
+* Add PeriodicTransformXD and VectorPeriodicTransformXD functions to support the data simulated with periodic boundary conditions. (#387)
+* Add CylindricalTransform and VectorCylindricalTransform to transform functions from cylindrical to Cartesian coordinates. (#387)
+* Add numerical integration of Bremsstrahlung spectrum over a spectral bin. (#395)
+* Replace the coarse numerical constant in the Bremsstrahlung model with an exact expression. (#409)
+* Add the kind attribute to RayTransferPipelineXD that determines whether the ray transfer matrix is multiplied by sensitivity ('power') or not ('radiance'). (#412)
+* Improved parsing of metadata from the ADAS ADF15 'bnd' files for H-like ions. Raises a runtime error if the metadata cannot be parsed. (#424)
+
+Bug fixes:
+* Fix deprecated transforms being cached in LaserMaterial after laser.transform update (#420)
+
+Release 1.4.0 (3 Feb 2023)
-------------------
API changes:
-* Spectroscopic observers and their groups are deprecated and replaced by groups based on Raysect's 0D observers. (#332)
+* Spectroscopic observers and their groups are deprecated and replaced by groups based on Raysect's 0D observers. (#332)
+* Support for Python 3.6 is dropped. It may still work, but is no longer actively tested.
+
+Bug fixes:
+* Fix and improve OpenCL utility functions. (#358)
+* Fixed Bremsstrahlung trapezium evaluation (#384).
New:
* Make f_profile (current flux) a read-only attribute of EFITEquilibrium. (#355)
* Add group observer class for each of Raysect's 0D observers. (#332)
* Add a demo for observer group handling and plotting.
* Add verbose parameter to SartOpencl solver (default is False). (#358)
+* Add Thomson Scattering model. (#97)
* Add Generomak core plasma profiles. (#360)
* Add toroidal_mesh_from_polygon for making mesh for not fully-360 degrees axisymmetric elements. (#365)
-
-Bug Fixes:
-----------
-* Fixed Bremsstrahlung trapezium evaluation (#384).
-* Fixed generomak plasma edge data paths.
-* Fix and improve OpenCL utility functions. (#358)
+* Add common spectroscopic instruments: Polychromator, SurveySpectrometer, CzernyTurnerSpectrometer. (#299)
+* Add new classes for free-free Gaunt factors and improve accuracy of the Gaunt factor used in Bremsstrahlung emission model. (#352)
+* Add GaussianQuadrature integration method for Function1D. (#366)
+* Add integrator attribute to LineShapeModel to use with lineshapes that cannot be analytically integrated over a spectral bin. (#366)
+* Add a numerical integration of StarkBroadenedLine over the spectral bin. (#366)
+* Add Generomak full plasma profiles obtained by blending the core and edge profiles. (#372)
+* Clean up build/install dependencies. (#353)
+* Test against Python 3.10 and latest released Numpy. Drop Python 3.6 and older Numpy from tests. (#391)
Release 1.3.0 (8 Dec 2021)
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 2f977070..00000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,6 +0,0 @@
-include README.md CHANGELOG.md LICENSE.txt CITE.md AUTHORS.md MANIFEST.in setup.py requirements.txt .gitignore
-include cherab/core/VERSION
-recursive-include cherab *.py *.pyx *.pxd *.json *.cl *.npy *.obj
-prune demos*
-
-
diff --git a/README.md b/README.md
index 963b0834..177feb9b 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,13 @@ with a build-time dependency on Cherab need to use a Cython version newer than
3.0a5, due to a [bug](https://github.com/cython/cython/issues/2918) in how
earlier versions of Cython handle namespaces.
+By default, pip will install from wheel archives on PyPI. If a binary wheel is not
+available for your version of Python, or if you are installing in editable mode
+for development, the package will be compiled locally on your machine. Compilation
+is done in parallel by default, using all available processors, but can be
+overridden by setting the environment variable `CHERAB_NCPU` to the number of
+processors to use.
+
Governance
----------
diff --git a/cherab/core/VERSION b/cherab/core/VERSION
index f0bb29e7..c831dd27 100644
--- a/cherab/core/VERSION
+++ b/cherab/core/VERSION
@@ -1 +1 @@
-1.3.0
+1.5.0.dev1
diff --git a/cherab/core/atomic/__init__.pxd b/cherab/core/atomic/__init__.pxd
index 0aa3cb90..3b2aa5c6 100644
--- a/cherab/core/atomic/__init__.pxd
+++ b/cherab/core/atomic/__init__.pxd
@@ -22,4 +22,5 @@ from cherab.core.atomic.line cimport Line
from cherab.core.atomic.interface cimport AtomicData
from cherab.core.atomic.rates cimport *
from cherab.core.atomic.zeeman cimport ZeemanStructure
+from cherab.core.atomic.gaunt cimport *
diff --git a/cherab/core/atomic/__init__.py b/cherab/core/atomic/__init__.py
index 3bb11780..35a7f80e 100644
--- a/cherab/core/atomic/__init__.py
+++ b/cherab/core/atomic/__init__.py
@@ -22,3 +22,4 @@
from .interface import AtomicData
from .rates import *
from .zeeman import ZeemanStructure
+from .gaunt import *
diff --git a/cherab/core/atomic/data/maxwellian_free_free_gaunt_factor.json b/cherab/core/atomic/data/maxwellian_free_free_gaunt_factor.json
new file mode 100644
index 00000000..124e0622
--- /dev/null
+++ b/cherab/core/atomic/data/maxwellian_free_free_gaunt_factor.json
@@ -0,0 +1,946 @@
+{
+ "u": [
+ 0.0001,
+ 0.001,
+ 0.01,
+ 0.1,
+ 1.0,
+ 10.0,
+ 100.0,
+ 1000.0,
+ 10000.0
+ ],
+ "gamma2": [
+ 1e-08,
+ 1.5848931924611143e-08,
+ 2.511886431509582e-08,
+ 3.981071705534969e-08,
+ 6.30957344480193e-08,
+ 1e-07,
+ 1.584893192461114e-07,
+ 2.5118864315095823e-07,
+ 3.981071705534969e-07,
+ 6.30957344480193e-07,
+ 1e-06,
+ 1.584893192461114e-06,
+ 2.5118864315095823e-06,
+ 3.981071705534969e-06,
+ 6.30957344480193e-06,
+ 1e-05,
+ 1.584893192461114e-05,
+ 2.5118864315095822e-05,
+ 3.9810717055349695e-05,
+ 6.309573444801929e-05,
+ 0.0001,
+ 0.00015848931924611142,
+ 0.00025118864315095795,
+ 0.00039810717055349735,
+ 0.000630957344480193,
+ 0.001,
+ 0.001584893192461114,
+ 0.0025118864315095794,
+ 0.003981071705534973,
+ 0.00630957344480193,
+ 0.01,
+ 0.015848931924611134,
+ 0.025118864315095794,
+ 0.039810717055349734,
+ 0.06309573444801933,
+ 0.1,
+ 0.15848931924611134,
+ 0.251188643150958,
+ 0.3981071705534972,
+ 0.6309573444801932,
+ 1.0,
+ 1.5848931924611136,
+ 2.51188643150958,
+ 3.9810717055349722,
+ 6.309573444801933,
+ 10.0,
+ 15.848931924611133,
+ 25.118864315095795,
+ 39.810717055349734,
+ 63.09573444801933,
+ 100.0,
+ 158.48931924611142,
+ 251.18864315095797,
+ 398.1071705534973,
+ 630.957344480193,
+ 1000.0,
+ 1584.893192461114,
+ 2511.88643150958,
+ 3981.0717055349733,
+ 6309.57344480193,
+ 10000.0,
+ 15848.93192461114,
+ 25118.864315095823,
+ 39810.71705534969,
+ 63095.7344480193,
+ 100000.0,
+ 158489.3192461114,
+ 251188.6431509582,
+ 398107.1705534969,
+ 630957.344480193,
+ 1000000.0,
+ 1584893.1924611141,
+ 2511886.4315095823,
+ 3981071.7055349695,
+ 6309573.44480193,
+ 10000000.0,
+ 15848931.924611142,
+ 25118864.315095823,
+ 39810717.05534969,
+ 63095734.448019296,
+ 100000000.0,
+ 158489319.2461111,
+ 251188643.1509582,
+ 398107170.5534969,
+ 630957344.4801943,
+ 1000000000.0,
+ 1584893192.4611108,
+ 2511886431.509582,
+ 3981071705.5349693,
+ 6309573444.801943,
+ 10000000000.0
+ ],
+ "gaunt_factor": [
+ [
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.528,
+ 5.527,
+ 5.527,
+ 5.527,
+ 5.527,
+ 5.526,
+ 5.525,
+ 5.523,
+ 5.52,
+ 5.516,
+ 5.51,
+ 5.501,
+ 5.489,
+ 5.472,
+ 5.449,
+ 5.419,
+ 5.379,
+ 5.329,
+ 5.267,
+ 5.193,
+ 5.107,
+ 5.01,
+ 4.904,
+ 4.792,
+ 4.676,
+ 4.557,
+ 4.436,
+ 4.315,
+ 4.194,
+ 4.073,
+ 3.953,
+ 3.833,
+ 3.714,
+ 3.596,
+ 3.479,
+ 3.363,
+ 3.249,
+ 3.136,
+ 3.025,
+ 2.916,
+ 2.808,
+ 2.703,
+ 2.6,
+ 2.5,
+ 2.402,
+ 2.307,
+ 2.215,
+ 2.127,
+ 2.042,
+ 1.96,
+ 1.882,
+ 1.807,
+ 1.737,
+ 1.67,
+ 1.608,
+ 1.549,
+ 1.494,
+ 1.444,
+ 1.397,
+ 1.354,
+ 1.314,
+ 1.278,
+ 1.246,
+ 1.217,
+ 1.19,
+ 1.167,
+ 1.146,
+ 1.127,
+ 1.11,
+ 1.096,
+ 1.083,
+ 1.072
+ ],
+ [
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.259,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.26,
+ 4.259,
+ 4.258,
+ 4.257,
+ 4.254,
+ 4.249,
+ 4.241,
+ 4.231,
+ 4.216,
+ 4.195,
+ 4.167,
+ 4.131,
+ 4.083,
+ 4.025,
+ 3.955,
+ 3.873,
+ 3.782,
+ 3.682,
+ 3.577,
+ 3.468,
+ 3.357,
+ 3.245,
+ 3.134,
+ 3.024,
+ 2.915,
+ 2.808,
+ 2.703,
+ 2.601,
+ 2.5,
+ 2.403,
+ 2.308,
+ 2.216,
+ 2.127,
+ 2.042,
+ 1.96,
+ 1.882,
+ 1.808,
+ 1.737,
+ 1.671,
+ 1.608,
+ 1.549,
+ 1.495,
+ 1.444,
+ 1.397,
+ 1.354,
+ 1.314,
+ 1.279,
+ 1.246,
+ 1.217,
+ 1.19,
+ 1.167,
+ 1.146,
+ 1.127,
+ 1.11,
+ 1.096,
+ 1.083,
+ 1.072,
+ 1.062,
+ 1.054,
+ 1.046,
+ 1.04,
+ 1.034,
+ 1.03,
+ 1.026,
+ 1.022,
+ 1.019,
+ 1.016
+ ],
+ [
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.002,
+ 3.003,
+ 3.003,
+ 3.003,
+ 3.004,
+ 3.004,
+ 3.005,
+ 3.006,
+ 3.007,
+ 3.008,
+ 3.01,
+ 3.011,
+ 3.013,
+ 3.015,
+ 3.016,
+ 3.018,
+ 3.018,
+ 3.016,
+ 3.012,
+ 3.004,
+ 2.991,
+ 2.971,
+ 2.944,
+ 2.907,
+ 2.86,
+ 2.803,
+ 2.735,
+ 2.658,
+ 2.574,
+ 2.486,
+ 2.396,
+ 2.306,
+ 2.216,
+ 2.129,
+ 2.045,
+ 1.963,
+ 1.885,
+ 1.811,
+ 1.74,
+ 1.673,
+ 1.61,
+ 1.552,
+ 1.497,
+ 1.446,
+ 1.399,
+ 1.355,
+ 1.316,
+ 1.28,
+ 1.247,
+ 1.218,
+ 1.191,
+ 1.167,
+ 1.146,
+ 1.128,
+ 1.111,
+ 1.096,
+ 1.084,
+ 1.072,
+ 1.063,
+ 1.054,
+ 1.047,
+ 1.04,
+ 1.035,
+ 1.03,
+ 1.026,
+ 1.022,
+ 1.019,
+ 1.016,
+ 1.014,
+ 1.012,
+ 1.01,
+ 1.009,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004
+ ],
+ [
+ 1.806,
+ 1.806,
+ 1.806,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.807,
+ 1.808,
+ 1.808,
+ 1.808,
+ 1.809,
+ 1.81,
+ 1.81,
+ 1.812,
+ 1.813,
+ 1.815,
+ 1.817,
+ 1.819,
+ 1.823,
+ 1.827,
+ 1.832,
+ 1.838,
+ 1.846,
+ 1.855,
+ 1.865,
+ 1.877,
+ 1.89,
+ 1.903,
+ 1.914,
+ 1.923,
+ 1.928,
+ 1.926,
+ 1.917,
+ 1.898,
+ 1.869,
+ 1.831,
+ 1.785,
+ 1.733,
+ 1.678,
+ 1.622,
+ 1.566,
+ 1.512,
+ 1.461,
+ 1.413,
+ 1.369,
+ 1.328,
+ 1.291,
+ 1.257,
+ 1.227,
+ 1.199,
+ 1.175,
+ 1.153,
+ 1.133,
+ 1.116,
+ 1.101,
+ 1.087,
+ 1.076,
+ 1.065,
+ 1.056,
+ 1.049,
+ 1.042,
+ 1.036,
+ 1.031,
+ 1.027,
+ 1.023,
+ 1.02,
+ 1.017,
+ 1.015,
+ 1.013,
+ 1.011,
+ 1.009,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001
+ ],
+ [
+ 0.8424,
+ 0.8425,
+ 0.8425,
+ 0.8426,
+ 0.8426,
+ 0.8427,
+ 0.8428,
+ 0.8429,
+ 0.8431,
+ 0.8433,
+ 0.8436,
+ 0.8439,
+ 0.8443,
+ 0.8449,
+ 0.8455,
+ 0.8464,
+ 0.8474,
+ 0.8487,
+ 0.8504,
+ 0.8525,
+ 0.8552,
+ 0.8586,
+ 0.8628,
+ 0.8682,
+ 0.875,
+ 0.8835,
+ 0.8944,
+ 0.9079,
+ 0.925,
+ 0.9461,
+ 0.9719,
+ 1.003,
+ 1.04,
+ 1.081,
+ 1.126,
+ 1.172,
+ 1.216,
+ 1.253,
+ 1.279,
+ 1.294,
+ 1.296,
+ 1.287,
+ 1.27,
+ 1.248,
+ 1.224,
+ 1.2,
+ 1.178,
+ 1.157,
+ 1.137,
+ 1.12,
+ 1.104,
+ 1.091,
+ 1.079,
+ 1.068,
+ 1.059,
+ 1.051,
+ 1.044,
+ 1.038,
+ 1.032,
+ 1.028,
+ 1.024,
+ 1.021,
+ 1.018,
+ 1.015,
+ 1.013,
+ 1.011,
+ 1.01,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ [
+ 0.3035,
+ 0.3035,
+ 0.3035,
+ 0.3035,
+ 0.3036,
+ 0.3036,
+ 0.3037,
+ 0.3038,
+ 0.3039,
+ 0.304,
+ 0.3042,
+ 0.3044,
+ 0.3046,
+ 0.305,
+ 0.3054,
+ 0.3059,
+ 0.3066,
+ 0.3074,
+ 0.3084,
+ 0.3098,
+ 0.3114,
+ 0.3136,
+ 0.3163,
+ 0.3197,
+ 0.324,
+ 0.3296,
+ 0.3367,
+ 0.3457,
+ 0.3573,
+ 0.3722,
+ 0.3913,
+ 0.4156,
+ 0.4464,
+ 0.485,
+ 0.5328,
+ 0.5905,
+ 0.6581,
+ 0.7343,
+ 0.8157,
+ 0.8975,
+ 0.9731,
+ 1.037,
+ 1.084,
+ 1.113,
+ 1.127,
+ 1.129,
+ 1.124,
+ 1.115,
+ 1.104,
+ 1.093,
+ 1.083,
+ 1.073,
+ 1.064,
+ 1.056,
+ 1.049,
+ 1.042,
+ 1.036,
+ 1.032,
+ 1.027,
+ 1.023,
+ 1.02,
+ 1.017,
+ 1.015,
+ 1.013,
+ 1.011,
+ 1.01,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ [
+ 0.09801,
+ 0.09802,
+ 0.09803,
+ 0.09804,
+ 0.09806,
+ 0.09808,
+ 0.0981,
+ 0.09814,
+ 0.09818,
+ 0.09823,
+ 0.09829,
+ 0.09838,
+ 0.09848,
+ 0.09861,
+ 0.09877,
+ 0.09898,
+ 0.09924,
+ 0.09957,
+ 0.09999,
+ 0.1005,
+ 0.1012,
+ 0.102,
+ 0.1031,
+ 0.1045,
+ 0.1062,
+ 0.1084,
+ 0.1113,
+ 0.115,
+ 0.1198,
+ 0.126,
+ 0.134,
+ 0.1445,
+ 0.1582,
+ 0.1759,
+ 0.199,
+ 0.2286,
+ 0.2662,
+ 0.3132,
+ 0.3706,
+ 0.4388,
+ 0.5173,
+ 0.6044,
+ 0.6967,
+ 0.7898,
+ 0.8782,
+ 0.9561,
+ 1.019,
+ 1.064,
+ 1.091,
+ 1.104,
+ 1.107,
+ 1.103,
+ 1.096,
+ 1.087,
+ 1.078,
+ 1.069,
+ 1.061,
+ 1.054,
+ 1.047,
+ 1.041,
+ 1.036,
+ 1.031,
+ 1.027,
+ 1.023,
+ 1.02,
+ 1.017,
+ 1.015,
+ 1.013,
+ 1.011,
+ 1.009,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.0,
+ 1.0
+ ],
+ [
+ 0.03107,
+ 0.03107,
+ 0.03107,
+ 0.03108,
+ 0.03108,
+ 0.03109,
+ 0.0311,
+ 0.03111,
+ 0.03112,
+ 0.03114,
+ 0.03116,
+ 0.03119,
+ 0.03122,
+ 0.03127,
+ 0.03132,
+ 0.03139,
+ 0.03148,
+ 0.03159,
+ 0.03173,
+ 0.03191,
+ 0.03214,
+ 0.03242,
+ 0.03279,
+ 0.03325,
+ 0.03384,
+ 0.0346,
+ 0.03558,
+ 0.03684,
+ 0.03847,
+ 0.0406,
+ 0.04337,
+ 0.04702,
+ 0.05181,
+ 0.05812,
+ 0.06644,
+ 0.07735,
+ 0.09158,
+ 0.11,
+ 0.1335,
+ 0.1631,
+ 0.1998,
+ 0.2445,
+ 0.2981,
+ 0.361,
+ 0.4334,
+ 0.5146,
+ 0.6031,
+ 0.696,
+ 0.7892,
+ 0.8773,
+ 0.9548,
+ 1.017,
+ 1.062,
+ 1.089,
+ 1.102,
+ 1.104,
+ 1.101,
+ 1.094,
+ 1.085,
+ 1.076,
+ 1.068,
+ 1.06,
+ 1.053,
+ 1.046,
+ 1.04,
+ 1.035,
+ 1.03,
+ 1.026,
+ 1.023,
+ 1.019,
+ 1.017,
+ 1.014,
+ 1.012,
+ 1.011,
+ 1.009,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001,
+ 1.001
+ ],
+ [
+ 0.009826,
+ 0.009827,
+ 0.009828,
+ 0.00983,
+ 0.009831,
+ 0.009834,
+ 0.009836,
+ 0.00984,
+ 0.009845,
+ 0.00985,
+ 0.009857,
+ 0.009866,
+ 0.009877,
+ 0.009892,
+ 0.009909,
+ 0.009932,
+ 0.00996,
+ 0.009996,
+ 0.01004,
+ 0.0101,
+ 0.01017,
+ 0.01026,
+ 0.01038,
+ 0.01053,
+ 0.01072,
+ 0.01097,
+ 0.01128,
+ 0.01169,
+ 0.01222,
+ 0.01291,
+ 0.01381,
+ 0.015,
+ 0.01656,
+ 0.01863,
+ 0.02137,
+ 0.02499,
+ 0.02975,
+ 0.03597,
+ 0.04404,
+ 0.05439,
+ 0.06753,
+ 0.08403,
+ 0.1046,
+ 0.1299,
+ 0.161,
+ 0.1987,
+ 0.244,
+ 0.2979,
+ 0.3609,
+ 0.4334,
+ 0.5146,
+ 0.6031,
+ 0.696,
+ 0.7891,
+ 0.8772,
+ 0.9547,
+ 1.017,
+ 1.061,
+ 1.089,
+ 1.101,
+ 1.104,
+ 1.1,
+ 1.093,
+ 1.085,
+ 1.076,
+ 1.068,
+ 1.06,
+ 1.053,
+ 1.046,
+ 1.04,
+ 1.035,
+ 1.03,
+ 1.026,
+ 1.023,
+ 1.019,
+ 1.017,
+ 1.014,
+ 1.012,
+ 1.011,
+ 1.009,
+ 1.008,
+ 1.007,
+ 1.006,
+ 1.005,
+ 1.004,
+ 1.004,
+ 1.003,
+ 1.003,
+ 1.002,
+ 1.002,
+ 1.002
+ ]
+ ],
+ "reference": "M.A. de Avillez and D. Breitschwerdt, Temperature-averaged and total free-free Gaunt factors for κ and Maxwellian distributions of electrons, 2015, Astron. & Astrophys. 580, A124"
+}
diff --git a/cherab/core/atomic/gaunt.pxd b/cherab/core/atomic/gaunt.pxd
new file mode 100644
index 00000000..827831b6
--- /dev/null
+++ b/cherab/core/atomic/gaunt.pxd
@@ -0,0 +1,39 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from cherab.core.math cimport Function2D
+
+
+cdef class FreeFreeGauntFactor():
+
+ cpdef double evaluate(self, double z, double temperature, double wavelength) except? -1e999
+
+
+cdef class InterpolatedFreeFreeGauntFactor(FreeFreeGauntFactor):
+
+ cdef:
+ readonly tuple u_range, gamma2_range
+ readonly dict raw_data
+ double _u_min, _u_max, _gamma2_min, _gamma2_max
+ Function2D _gaunt_factor
+
+
+cdef class MaxwellianFreeFreeGauntFactor(InterpolatedFreeFreeGauntFactor):
+
+ pass
+
diff --git a/cherab/core/atomic/gaunt.pyx b/cherab/core/atomic/gaunt.pyx
new file mode 100644
index 00000000..eb1dbe59
--- /dev/null
+++ b/cherab/core/atomic/gaunt.pyx
@@ -0,0 +1,158 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from os import path
+import numpy as np
+import json
+
+from libc.math cimport log10, log, M_PI, sqrt
+from raysect.core.math.function.float cimport Interpolator2DArray
+from cherab.core.utility.constants cimport RYDBERG_CONSTANT_EV, SPEED_OF_LIGHT, ELEMENTARY_CHARGE, PLANCK_CONSTANT
+
+cimport cython
+
+
+DEF EULER_GAMMA = 0.5772156649015329
+
+cdef double PH_TO_EV_FACTOR = PLANCK_CONSTANT * SPEED_OF_LIGHT * 1e9 / ELEMENTARY_CHARGE
+
+
+cdef class FreeFreeGauntFactor():
+ """
+ The base class for temperature-averaged free-free Gaunt factors.
+ """
+
+ cpdef double evaluate(self, double z, double temperature, double wavelength) except? -1e999:
+ """
+ Returns the temperature-averaged free-free Gaunt factor for the supplied parameters.
+
+ :param double z: Species charge or effective plasma charge.
+ :param double temperature: Electron temperature in eV.
+ :param double wavelength: Spectral wavelength.
+
+ :return: free-free Gaunt factor
+ """
+ raise NotImplementedError("The evaluate() virtual method must be implemented.")
+
+ def __call__(self, double z, double temperature, double wavelength):
+ """
+ Returns the temperature-averaged free-free Gaunt factor for the supplied parameters.
+
+ :param double z: Species charge or effective plasma charge.
+ :param double temperature: Electron temperature in eV.
+ :param double wavelength: Spectral wavelength.
+
+ :return: free-free Gaunt factor
+ """
+
+ return self.evaluate(z, temperature, wavelength)
+
+
+cdef class InterpolatedFreeFreeGauntFactor(FreeFreeGauntFactor):
+ r"""
+ The temperature-averaged free-free Gaunt factors interpolated in the space of parameters:
+ :math:`u = h{\nu}/kT` and :math:`{\gamma}^{2} = Z^{2}Ry/kT`.
+ See T.R. Carson, 1988, Astron. & Astrophys., 189,
+ `319 `_ for details.
+
+ The cubic interpolation in a semi-log space is used.
+
+ The Born approximation is used outside the interpolation range.
+
+ :param object u: A 1D array-like object of real values.
+ :param object gamma2: A 1D array-like object of real values.
+ :param object gaunt_factor: 2D array-like object of real values
+ storing the Gaunt factor values at u, gamma2.
+
+ :ivar tuple u_range: The interpolation range of `u` parameter.
+ :ivar tuple gamma2_range: The interpolation range of :math:`\\gamma^2` parameter.
+ :ivar dict raw_data: Dictionary containing the raw data.
+ """
+
+ def __init__(self, object u, object gamma2, object gaunt_factor):
+
+ u = np.array(u, dtype=np.float64)
+ u.flags.writeable = False
+ gamma2 = np.array(gamma2, dtype=np.float64)
+ gamma2.flags.writeable = False
+ gaunt_factor = np.array(gaunt_factor, dtype=np.float64)
+ gaunt_factor.flags.writeable = False
+
+ self.raw_data = {'u': u, 'gamma2': gamma2, 'gaunt_factor': gaunt_factor}
+
+ self._u_min = u.min()
+ self._u_max = u.max()
+ self._gamma2_min = gamma2.min()
+ self._gamma2_max = gamma2.max()
+
+ self.u_range = (self._u_min, self._u_max)
+ self.gamma2_range = (self._gamma2_min, self._gamma2_max)
+
+ self._gaunt_factor = Interpolator2DArray(np.log10(u), np.log10(gamma2), gaunt_factor, 'cubic', 'none', 0, 0)
+
+ @cython.cdivision(True)
+ cpdef double evaluate(self, double z, double temperature, double wavelength) except? -1e999:
+ """
+ Returns the temperature-averaged free-free Gaunt factor for the supplied parameters.
+
+ :param double z: Species charge or effective plasma charge.
+ :param double temperature: Electron temperature in eV.
+ :param double wavelength: Spectral wavelength.
+
+ :return: free-free Gaunt factor
+ """
+
+ cdef:
+ double u, gamma2
+
+ if z == 0:
+
+ return 0
+
+ gamma2 = z * z * RYDBERG_CONSTANT_EV / temperature
+ u = PH_TO_EV_FACTOR / (temperature * wavelength)
+
+ # classical limit
+ if u >= self._u_max or gamma2 >= self._gamma2_max:
+
+ return 1
+
+ # Born approximation limit
+ if u < self._u_min or gamma2 < self._gamma2_min:
+
+ return sqrt(3) / M_PI * (log(4 / u) - EULER_GAMMA)
+
+ return self._gaunt_factor.evaluate(log10(u), log10(gamma2))
+
+
+cdef class MaxwellianFreeFreeGauntFactor(InterpolatedFreeFreeGauntFactor):
+ r"""
+ The Maxwellian-averaged free-free Gaunt factor interpolated over the data from Table A.1 in
+ M.A. de Avillez and D. Breitschwerdt, "Temperature-averaged and total free-free Gaunt factors
+ for κ and Maxwellian distributions of electrons", 2015, Astron. & Astrophys. 580,
+ `A124 `_.
+
+ The Born approximation is used outside the interpolation range.
+ """
+
+ def __init__(self):
+
+ with open(path.join(path.dirname(__file__), "data/maxwellian_free_free_gaunt_factor.json")) as f:
+ data = json.load(f)
+
+ super().__init__(data['u'], data['gamma2'], data['gaunt_factor'])
diff --git a/cherab/core/atomic/interface.pxd b/cherab/core/atomic/interface.pxd
index b072bd1a..f6b9b914 100644
--- a/cherab/core/atomic/interface.pxd
+++ b/cherab/core/atomic/interface.pxd
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -19,6 +19,7 @@
from cherab.core.atomic.elements cimport Element
from cherab.core.atomic.line cimport Line
from cherab.core.atomic.zeeman cimport ZeemanStructure
+from cherab.core.atomic.gaunt cimport FreeFreeGauntFactor
from cherab.core.atomic.rates cimport *
@@ -58,3 +59,5 @@ cdef class AtomicData:
cpdef ZeemanStructure zeeman_structure(self, Line line, object b_field=*)
+ cpdef FreeFreeGauntFactor free_free_gaunt_factor(self)
+
diff --git a/cherab/core/atomic/interface.pyx b/cherab/core/atomic/interface.pyx
index 1a9702b6..cc96fb4e 100644
--- a/cherab/core/atomic/interface.pyx
+++ b/cherab/core/atomic/interface.pyx
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -16,6 +16,8 @@
# See the Licence for the specific language governing permissions and limitations
# under the Licence.
+from .gaunt import MaxwellianFreeFreeGauntFactor
+
cdef class AtomicData:
"""
@@ -95,3 +97,14 @@ cdef class AtomicData:
cpdef ZeemanStructure zeeman_structure(self, Line line, object b_field=None):
raise NotImplementedError("The zeeman_structure() virtual method is not implemented for this atomic data source.")
+
+ cpdef FreeFreeGauntFactor free_free_gaunt_factor(self):
+ """
+ Returns the Maxwellian-averaged free-free Gaunt factor interpolated over the data
+ from Table A.1 in M.A. de Avillez and D. Breitschwerdt, 2015, Astron. & Astrophys. 580,
+ `A124 `_.
+
+ The Born approximation is used outside the interpolation range.
+ """
+
+ return MaxwellianFreeFreeGauntFactor()
diff --git a/cherab/core/laser/__init__.pxd b/cherab/core/laser/__init__.pxd
new file mode 100644
index 00000000..2760a2ea
--- /dev/null
+++ b/cherab/core/laser/__init__.pxd
@@ -0,0 +1,4 @@
+from cherab.core.laser.node cimport Laser
+from cherab.core.laser.model cimport LaserModel
+from cherab.core.laser.laserspectrum cimport LaserSpectrum
+from cherab.core.laser.profile cimport LaserProfile
\ No newline at end of file
diff --git a/cherab/core/laser/__init__.py b/cherab/core/laser/__init__.py
new file mode 100644
index 00000000..911a64b1
--- /dev/null
+++ b/cherab/core/laser/__init__.py
@@ -0,0 +1,4 @@
+from .node import Laser
+from .model import LaserModel
+from .laserspectrum import LaserSpectrum
+from .profile import LaserProfile
\ No newline at end of file
diff --git a/cherab/core/laser/laserspectrum.pxd b/cherab/core/laser/laserspectrum.pxd
new file mode 100644
index 00000000..a00945eb
--- /dev/null
+++ b/cherab/core/laser/laserspectrum.pxd
@@ -0,0 +1,47 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function1D
+
+from cherab.core.utility.constants cimport SPEED_OF_LIGHT, PLANCK_CONSTANT
+
+from numpy cimport ndarray
+
+
+cdef class LaserSpectrum(Function1D):
+
+ cdef:
+ double _min_wavelength, _max_wavelength, _delta_wavelength
+ int _bins
+ ndarray _power, _power_spectral_density, _wavelengths # power_spectral_density [w/nm]
+ double[::1] power_mv, power_spectral_density_mv, wavelengths_mv
+
+ cpdef double evaluate_integral(self, double lower_limit, double upper_limit)
+
+ cpdef void _update_cache(self)
+
+ cpdef double get_min_wavelenth(self)
+
+ cpdef double get_max_wavelenth(self)
+
+ cpdef int get_spectral_bins(self)
+
+ cpdef double get_delta_wavelength(self)
+
+ cpdef double _get_bin_power_spectral_density(self, double wavelength_lower, double wavelength_upper)
\ No newline at end of file
diff --git a/cherab/core/laser/laserspectrum.pyx b/cherab/core/laser/laserspectrum.pyx
new file mode 100644
index 00000000..e196fba1
--- /dev/null
+++ b/cherab/core/laser/laserspectrum.pyx
@@ -0,0 +1,192 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function1D
+from raysect.optical cimport Point3D, Vector3D
+
+from cherab.core.utility import Notifier
+from cherab.core.utility.constants cimport SPEED_OF_LIGHT, PLANCK_CONSTANT
+
+import numpy as np
+cimport numpy as np
+
+
+cdef class LaserSpectrum(Function1D):
+ """
+ Laser spectrum base class.
+
+ This is an abstract class and cannot be used for observing.
+
+ A 1D function holding information about the spectral properties
+ of a laser. The scattered spectrum is calculated as an iteration
+ over the laser spectrum.
+
+
+ .. warning::
+ When adding a LaserSpectrum, a special care should be given
+ to the integral power of the laser spectrum. During the
+ scattering calculation, the spectral power can be multiplied
+ by the power spatial distribution [W * m ** -3] of the laser
+ power from the LaserProfile. If the integral power
+ of the LaserSpectrum is not 1, unexpected values
+ might be obtained.
+
+ .. note::
+ It is expected that majority of the fusion applications can
+ neglect the influence of the spectral shape of the
+ laser and can use laser spectrum with a single
+ bin, which approximates an infinitely narrow laser spectrum.
+
+ :param float min_wavelength: The minimum wavelength of the laser
+ spectrum in nm.
+ :param float max_wavelength: The maximum wavelength of the laser
+ spectrum in nm.
+ :param int bins: The number of spectral bins of the laser spectrum.
+ :ivar float min_wavelength: The minimum wavelength of the laser
+ spectrum in nm.
+ :ivar float max_wavelength: The maximum wavelength of the laser
+ spectrum in nm.
+ :ivar int bins: The number of specral bins of the laser spectrum
+ :ivar ndarray wavelengths: The wavelengt coordinate vector in nm.
+ :ivar ndarray power_spectral_density: The values of the power
+ spectral density in W / nm.
+ :ivar float delta_wavelength: Spectral width of the bins in nm.
+ """
+
+ def __init__(self, double min_wavelength, double max_wavelength, int bins):
+
+ super().__init__()
+
+ self._check_wavelength_validity(min_wavelength, max_wavelength)
+
+ self._min_wavelength = min_wavelength
+ self._max_wavelength = max_wavelength
+
+ self.bins = bins
+
+ @property
+ def min_wavelength(self):
+ return self._min_wavelength
+
+ @min_wavelength.setter
+ def min_wavelength(self, double value):
+
+ self._check_wavelength_validity(value, self.max_wavelength)
+ self._min_wavelength = value
+ self._update_cache()
+
+ @property
+ def max_wavelength(self):
+ return self._max_wavelength
+
+ @max_wavelength.setter
+ def max_wavelength(self, double value):
+
+ self._check_wavelength_validity(self.min_wavelength, value)
+ self._max_wavelength = value
+ self._update_cache()
+
+ @property
+ def bins(self):
+ return self._bins
+
+ @bins.setter
+ def bins(self, int value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0")
+
+ self._bins = value
+ self._update_cache()
+
+ @property
+ def wavelengths(self):
+ return self._wavelengths
+
+ @property
+ def power_spectral_density(self):
+ return self._power_spectral_density
+
+ @property
+ def delta_wavelength(self):
+ return self._delta_wavelength
+
+ def _check_wavelength_validity(self, min_wavelength, max_wavelength):
+
+ if min_wavelength <= 0:
+ raise ValueError("min_wavelength has to be larger than 0, but {} passed.".format(min_wavelength))
+ if max_wavelength <= 0:
+ raise ValueError("min_wavelength has to be larger than 0, but {} passed.".format(max_wavelength))
+
+ if min_wavelength >= max_wavelength:
+ raise ValueError("min_wavelength has to be smaller than max_wavelength: min_wavelength={} > max_wavelength={}".format(min_wavelength, max_wavelength))
+
+ cpdef double get_min_wavelenth(self):
+ return self._min_wavelength
+
+ cpdef double get_max_wavelenth(self):
+ return self._min_wavelength
+
+ cpdef int get_spectral_bins(self):
+ return self._bins
+
+ cpdef double get_delta_wavelength(self):
+ return self._delta_wavelength
+
+ cpdef void _update_cache(self):
+
+ cdef:
+ Py_ssize_t index
+ double delta_wvl_half, wvl_lower, wvl_upper, wvl
+
+ self._delta_wavelength = (self._max_wavelength - self._min_wavelength) / self._bins
+ self._wavelengths = np.zeros(self.bins, dtype=np.double)
+ self.wavelengths_mv = self._wavelengths
+
+ for index in range(self._bins):
+ self._wavelengths[index] = self._min_wavelength + (0.5 + index) * self._delta_wavelength
+
+ self._power_spectral_density = np.zeros(self._bins, dtype=np.double) # power spectral density (PSD)
+ self.power_spectral_density_mv = self._power_spectral_density
+
+ self._power = np.zeros(self._bins, dtype=np.double) # power in a spectral bin (PSD * delta wavelength)
+ self.power_mv = self._power
+
+ delta_wvl_half = self._delta_wavelength * 0.5
+ wvl_lower = self.wavelengths_mv[0] - delta_wvl_half
+
+ for index in range(self._bins):
+ wvl = wvl_lower + delta_wvl_half
+ wvl_upper = wvl_lower + self._delta_wavelength
+
+ self.power_spectral_density_mv[index] = self._get_bin_power_spectral_density(wvl_lower, wvl_upper)
+ self.power_mv[index] = self.power_spectral_density_mv[index] * self._delta_wavelength # power in the spectral bin for scattering calculations
+
+ wvl_lower = wvl_upper
+
+ cpdef double evaluate_integral(self, double lower_limit, double upper_limit):
+ raise NotImplementedError('Virtual method must be implemented in a sub-class.')
+
+ cpdef double _get_bin_power_spectral_density(self, double wavelength_lower, double wavelength_upper):
+ """
+ Returns the power spectral density in a bin.
+
+ This method can be overidden if a better precision is needed.
+ For example for distributions with known cumulative distribution function.
+ """
+ return 0.5 * (self.evaluate(wavelength_lower) + self.evaluate(wavelength_upper))
diff --git a/cherab/core/laser/material.pxd b/cherab/core/laser/material.pxd
new file mode 100644
index 00000000..24695146
--- /dev/null
+++ b/cherab/core/laser/material.pxd
@@ -0,0 +1,35 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core cimport Primitive
+from raysect.core.math cimport AffineMatrix3D
+from raysect.optical.material.emitter cimport InhomogeneousVolumeEmitter
+
+from cherab.core.laser.node cimport Laser
+
+
+cdef class LaserMaterial(InhomogeneousVolumeEmitter):
+
+ cdef:
+ AffineMatrix3D _laser_to_plasma, _laser_segment_to_laser_node
+ Primitive _primitive
+ Laser _laser
+ list _models
+
+ cdef void _cache_transforms(self)
\ No newline at end of file
diff --git a/cherab/core/laser/material.pyx b/cherab/core/laser/material.pyx
new file mode 100644
index 00000000..75cc46a6
--- /dev/null
+++ b/cherab/core/laser/material.pyx
@@ -0,0 +1,82 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core cimport Primitive
+from raysect.optical cimport World, Primitive, Ray, Spectrum, Point3D, Vector3D, AffineMatrix3D
+from raysect.optical.material.emitter cimport InhomogeneousVolumeEmitter
+from raysect.optical.material.emitter.inhomogeneous cimport VolumeIntegrator
+
+from cherab.core.laser.node cimport Laser
+from cherab.core.laser.model cimport LaserModel
+
+
+cdef class LaserMaterial(InhomogeneousVolumeEmitter):
+
+ def __init__(self, Laser laser not None, Primitive laser_segment not None, list models, VolumeIntegrator integrator not None):
+
+ super().__init__(integrator)
+
+ self._laser = laser
+ self._primitive = laser_segment
+ self.importance = laser.importance
+
+ #validate and set models
+ for model in models:
+ if not isinstance(model, LaserModel):
+ raise TypeError("Model supplied to laser are not LaserMaterial is not LaserModel")
+ model.plasma = laser.plasma
+ model.laser_profile = laser.laser_profile
+ model.laser_spectrum = laser.laser_spectrum
+
+ self._models = models
+
+ cpdef Spectrum emission_function(self, Point3D point, Vector3D direction, Spectrum spectrum,
+ World world, Ray ray, Primitive primitive,
+ AffineMatrix3D to_local, AffineMatrix3D to_world):
+
+ cdef:
+ Point3D point_plasma, point_laser
+ Vector3D direction_plasma, direction_laser
+ LaserModel model
+
+ # cache the important transforms
+ if self._laser_segment_to_laser_node is None or self._laser_to_plasma is None:
+ self._cache_transforms()
+
+ point_laser = point.transform(self._laser_segment_to_laser_node)
+ direction_laser = direction.transform(self._laser_segment_to_laser_node) # observation vector in the laser frame
+ point_plasma = point.transform(self._laser_to_plasma)
+ direction_plasma = direction.transform(self._laser_to_plasma)
+
+ for model in self._models:
+ spectrum = model.emission(point_plasma, direction_plasma, point_laser, direction_laser, spectrum)
+
+ return spectrum
+
+ cdef void _cache_transforms(self):
+ """
+ cache transforms from laser primitive to laser and plasma
+ """
+
+ # if transforms are cached, the material should be used only for one primitive for safety
+ if not len(self.primitives) == 1:
+ raise ValueError("LaserMaterial must be attached to exactly one primitive.")
+
+ self._laser_segment_to_laser_node = self._primitive.to(self._laser)
+ self._laser_to_plasma = self._primitive.to(self._laser.get_plasma())
diff --git a/cherab/core/laser/model.pxd b/cherab/core/laser/model.pxd
new file mode 100644
index 00000000..71cdf9a8
--- /dev/null
+++ b/cherab/core/laser/model.pxd
@@ -0,0 +1,37 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.optical cimport Vector3D, Point3D
+from raysect.optical.spectrum cimport Spectrum
+
+from cherab.core cimport Plasma
+from cherab.core.laser.profile cimport LaserProfile
+from cherab.core.laser.laserspectrum cimport LaserSpectrum
+
+
+cdef class LaserModel:
+ cdef:
+ Plasma _plasma
+ LaserSpectrum _laser_spectrum
+ LaserProfile _laser_profile
+
+ cpdef Spectrum emission(self, Point3D point_plasma, Vector3D observation_plasma, Point3D point_laser,
+ Vector3D observation_laser, Spectrum spectrum)
+
+ cdef object __weakref__
diff --git a/cherab/core/laser/model.pyx b/cherab/core/laser/model.pyx
new file mode 100644
index 00000000..c7d76cae
--- /dev/null
+++ b/cherab/core/laser/model.pyx
@@ -0,0 +1,78 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.optical cimport Vector3D, Point3D
+from raysect.optical.spectrum cimport Spectrum
+
+from cherab.core cimport Plasma
+from cherab.core.laser.profile cimport LaserProfile
+from cherab.core.laser.laserspectrum cimport LaserSpectrum
+
+
+cdef class LaserModel:
+ """
+ Laser spectrum base class.
+
+ This is an abstract class and cannot be used for observing.
+
+ Calculates the contribution to a spectrum caused by a laser.
+
+ :param laser_profile: LaserProfile object
+ :param plasma: Plasma object
+ :param laser_spectrum: LaserSpectrum object
+
+ :ivar laser_profile: LaserProfile object
+ :ivar plasma: Plasma object
+ :ivar laser_spectrum: LaserSpectrum object
+ """
+ def __init__(self, LaserProfile laser_profile=None, LaserSpectrum laser_spectrum=None, Plasma plasma=None):
+
+ self._laser_profile = laser_profile
+ self._laser_spectrum = laser_spectrum
+ self._plasma = plasma
+
+ cpdef Spectrum emission(self, Point3D point_plasma, Vector3D observation_plasma, Point3D point_laser, Vector3D observation_laser,
+ Spectrum spectrum):
+
+ raise NotImplementedError('Virtual method must be implemented in a sub-class.')
+
+ @property
+ def laser_profile(self):
+ return self._laser_profile
+
+ @laser_profile.setter
+ def laser_profile(self, LaserProfile value):
+ self._laser_profile = value
+
+ @property
+ def plasma(self):
+ return self._plasma
+
+ @plasma.setter
+ def plasma(self, Plasma value):
+ self._plasma = value
+
+ @property
+ def laser_spectrum(self):
+ return self._laser_spectrum
+
+ @laser_spectrum.setter
+ def laser_spectrum(self, LaserSpectrum value):
+
+ self._laser_spectrum = value
diff --git a/cherab/core/laser/node.pxd b/cherab/core/laser/node.pxd
new file mode 100644
index 00000000..8fec6821
--- /dev/null
+++ b/cherab/core/laser/node.pxd
@@ -0,0 +1,57 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.optical cimport Point3D, Vector3D, Node, Spectrum, Primitive
+from raysect.optical.material.emitter.inhomogeneous cimport VolumeIntegrator
+from raysect.primitive cimport Cylinder
+
+from cherab.core.plasma cimport Plasma
+from cherab.core.laser.profile cimport LaserProfile
+from cherab.core.laser.laserspectrum cimport LaserSpectrum
+from cherab.core.laser.model cimport LaserModel
+
+
+cdef class ModelManager:
+
+ cdef:
+ list _models
+ readonly object notifier
+
+ cpdef object set(self, object models)
+
+ cpdef object add(self, LaserModel model)
+
+ cpdef object clear(self)
+
+
+cdef class Laser(Node):
+
+ cdef:
+ readonly object notifier
+ double _importance
+ Plasma _plasma
+ ModelManager _models
+ LaserProfile _laser_profile
+ LaserSpectrum _laser_spectrum
+ list _geometry
+ VolumeIntegrator _integrator
+
+ cdef object __weakref__
+
+ cdef Plasma get_plasma(self)
\ No newline at end of file
diff --git a/cherab/core/laser/node.pyx b/cherab/core/laser/node.pyx
new file mode 100644
index 00000000..9475fb69
--- /dev/null
+++ b/cherab/core/laser/node.pyx
@@ -0,0 +1,267 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.primitive cimport Cylinder
+from raysect.optical cimport World, AffineMatrix3D, Primitive, Ray
+from raysect.optical.material.emitter.inhomogeneous cimport NumericalIntegrator
+from raysect.core cimport translate, Material
+
+from cherab.core.laser.material cimport LaserMaterial
+from cherab.core.laser.model cimport LaserModel
+from cherab.core.laser.profile import LaserProfile
+from cherab.core.laser.laserspectrum import LaserSpectrum
+from cherab.core.utility import Notifier
+from libc.math cimport M_PI
+
+from math import ceil
+
+cdef double DEGREES_TO_RADIANS = (M_PI / 180)
+
+
+cdef class ModelManager:
+
+ def __init__(self):
+ self._models = []
+ self.notifier = Notifier()
+
+ def __iter__(self):
+ return iter(self._models)
+
+ cpdef object set(self, object models):
+
+ # copy models and test it is an iterable
+ models = list(models)
+
+ # check contents of list are laser models
+ for model in models:
+ if not isinstance(model, LaserModel):
+ raise TypeError('The model list must consist of only LaserModel objects.')
+
+ self._models = models
+ self.notifier.notify()
+
+ cpdef object add(self, LaserModel model):
+
+ if not model:
+ raise ValueError('Model must not be None type.')
+
+ self._models.append(model)
+ self.notifier.notify()
+
+ cpdef object clear(self):
+ self._models = []
+ self.notifier.notify()
+
+
+cdef class Laser(Node):
+ """
+ A scene-graph object representing a laser of laser light.
+
+ The Cherab laser object holds basic information about the laser and connects
+ the components which are needed for the laser description. With specified
+ emission models it can contribute to observed radiation.
+
+ The Laser object is a Raysect scene-graph node and lives in it's own
+ coordinate space. This coordinate space is defined relative to it's parent
+ scene-graph object by an AffineTransform. The beam parameters are defined
+ in the Laser object coordinate space. Models using the beam object must
+ convert any spatial coordinates into beam space before requesting values
+ from the Laser object.
+
+ The main physical properties of the laser are defined by the three
+ attributes laser_spectrum, laser_profile and models. The laser_spectrum
+ has to be an instance of LaserSpectrum and defines the spectral properties
+ of the laser light. The laser_profile has to be an instance of LaserProfile
+ and it holds all the space related definitions as volumetric distribution
+ of laser light energy polarisation direction. In the models a list of LaserModels
+ can be stored, which calculate the contribution of the laser ligth to the observed
+ radiation. The models can cover various applications as for example
+ Thomson scattering. Please see the documentation of individual classes
+ for more detail.
+
+ The shape of the laser (e.g. cylinder) and its parameters (e.g. radius)
+ is controled by the LaserProfile.
+
+ The plasma reference has to be specified to attach the any models.
+
+ :param Node parent: The parent node in the Raysect scene-graph.
+ See the Raysect documentation for more guidance.
+ :param AffineMatrix3D transform: The transform defining the spatial position
+ and orientation of this laser. See the Raysect documentation if you need
+ guidance on how to use AffineMatrix3D transforms.
+ :param str name: The name for this laser object.
+ :ivar Plasma plasma: The plasma instance with which this laser interacts.
+ :ivar float importance: The importance sampling factor.
+ :ivar LaserSpectrum laser_spectrum: The LaserSpectrum instance with which this laser interacts.
+ :ivar LaserProfile laser_profile: The LaserProfile instance with which this laser interacts.
+ :ivar ModelManager models: The manager class that sets and provides access to the
+ emission models for this laser.
+ :ivar VolumeIntegrator integrator: The configurable method for doing
+ volumetric integration through the laser along a Ray's path. Defaults to
+ a numerical integrator with 1mm step size, NumericalIntegrator(step=0.001).
+ """
+
+ def __init__(self, object parent=None, AffineMatrix3D transform=None, str name=None):
+
+ super().__init__(parent, transform, name)
+
+ self._set_init_values()
+
+ self.notifier = Notifier()
+
+ self._models = ModelManager()
+
+ self._integrator = NumericalIntegrator(step=1e-3)
+
+ self._importance = 1.
+
+ def _set_init_values(self):
+ """
+ Sets initial values of the laser shape to avoid errors.
+ """
+ self._importance = 0.
+ self._geometry = []
+
+ @property
+ def plasma(self):
+ return self._plasma
+
+ @plasma.setter
+ def plasma(self, Plasma value not None):
+
+ #unregister from old plasma notifier
+ if self._plasma is not None:
+ self._plasma.notifier.remove(self._plasma_changed)
+
+ self._plasma = value
+ self._plasma.notifier.add(self._plasma_changed)
+
+ self._configure_materials()
+
+ cdef Plasma get_plasma(self):
+ """
+ Fast method to obtain laser's plasma reference.
+ """
+ return self._plasma
+
+ @property
+ def importance(self):
+ return self._importance
+
+ @importance.setter
+ def importance(self, double value):
+
+ self._importance = value
+ self._configure_materials()
+
+ @property
+ def laser_spectrum(self):
+ return self._laser_spectrum
+
+ @laser_spectrum.setter
+ def laser_spectrum(self, LaserSpectrum value):
+ self._laser_spectrum = value
+ self._configure_materials()
+
+ @property
+ def laser_profile(self):
+ return self._laser_profile
+
+ @laser_profile.setter
+ def laser_profile(self, LaserProfile value):
+
+ if self._laser_profile is not None:
+ self._laser_profile.notifier.remove(self.configure_geometry)
+
+ self._laser_profile = value
+ self._laser_profile.notifier.add(self.configure_geometry)
+
+ self.configure_geometry()
+
+ @property
+ def models(self):
+ return list(self._models)
+
+ @models.setter
+ def models(self, value):
+
+ # check necessary data is available
+ if not all([self._plasma, self._laser_profile, self._laser_spectrum]):
+ raise ValueError("The plasma, laser_profile and laser_spectrum must be set before before specifying any models.")
+
+ self._models.set(value)
+ self._configure_materials()
+
+ @property
+ def integrator(self):
+ return self._integrator
+
+ @integrator.setter
+ def integrator(self, VolumeIntegrator value):
+ self._integrator = value
+
+ for i in self._geometry:
+ i.material.integrator = value
+
+ def configure_geometry(self):
+ """
+ Reconfigure the laser primitives and materials.
+ """
+
+ self._build_geometry()
+ self._configure_materials()
+
+ def _build_geometry(self):
+ """
+ Delete and build new laser segments
+ """
+ # remove old laser segments in any case
+ for i in self._geometry:
+ i.parent = None
+ self._geometry = []
+
+ # no point in adding segments if there is no model and profile
+ if self._laser_profile is None:
+ return
+
+ # rebuild geometry
+ self._geometry = self._laser_profile.generate_geometry()
+
+ for i in self._geometry:
+ i.parent = self
+
+ def _configure_materials(self):
+ """
+ Configure laser segment materials
+ """
+ if not list(self._models) or self._plasma is None or self._laser_spectrum is None:
+ return
+
+ for i in self._geometry:
+ i.material = LaserMaterial(self, i, list(self._models), self._integrator)
+
+ def get_geometry(self):
+ return self._geometry
+
+ def _plasma_changed(self):
+ """React to change of plasma and propagate the information."""
+ self._configure_materials()
+
+ def _modified(self):
+ self._configure_materials()
diff --git a/cherab/core/laser/profile.pxd b/cherab/core/laser/profile.pxd
new file mode 100644
index 00000000..c634a2f8
--- /dev/null
+++ b/cherab/core/laser/profile.pxd
@@ -0,0 +1,41 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function3D
+from raysect.core.math.function.vector3d cimport Function3D as VectorFunction3D
+
+from raysect.optical cimport Spectrum, Point3D, Vector3D
+
+from cherab.core.laser.node cimport Laser
+
+
+cdef class LaserProfile:
+
+ cdef:
+ VectorFunction3D _polarization3d, _pointing3d
+ Function3D _energy_density3d
+ readonly object notifier
+
+ cpdef Vector3D get_pointing(self, double x, double y, double z)
+
+ cpdef Vector3D get_polarization(self, double x, double y, double z)
+
+ cpdef double get_energy_density(self, double x, double y, double z)
+
+ cpdef list generate_geometry(self)
\ No newline at end of file
diff --git a/cherab/core/laser/profile.pyx b/cherab/core/laser/profile.pyx
new file mode 100644
index 00000000..6356d1cb
--- /dev/null
+++ b/cherab/core/laser/profile.pyx
@@ -0,0 +1,163 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function3D
+from raysect.core.math.function.vector3d cimport Function3D as VectorFunction3D
+
+from raysect.optical cimport SpectralFunction, Spectrum, InterpolatedSF, Point3D, Vector3D
+
+from cherab.core.laser.node cimport Laser
+from cherab.core.utility import Notifier
+
+
+cdef class LaserProfile:
+ """
+ LaserProfile base class.
+
+ This is an abstract class and cannot be used for observing.
+
+ Provides information about spatial properties of the laser beam:
+ direction of the laser propagation (direction
+ of the Poynting vector), polarisation of the ligth as the direction
+ of the electric component vector and volumetric energy density of
+ the laser light.
+
+ All the laser properties are evaluated in the frame of reference of
+ the laser.
+
+ .. warning::
+ When combining a LaserProfile with a LaserSpectrum for a laser,
+ a special care has to be given to obtain the correct power
+ of the scattered spectrum. Scattering models can multiply
+ both the spectral power density given by the LaserProfile and
+ the volumetric energy density given by the LaserProfile.
+ Combination of incompatible cases may yield incorrect
+ values of scattered power.
+
+ :ivar Laser laser: The Laser scenegraph node the LaserProfile
+ is connected to.
+ """
+
+ def __init__(self):
+
+ self.notifier = Notifier()
+
+ def set_polarization_function(self, VectorFunction3D function):
+ """
+ Assigns the 3D vector function describing the polarisation vector.
+
+ The polarisation is given as the direction of the electric
+ component of the electromagnetic wave.
+
+ The function is specified in the laser space.
+
+ :param VectorFunction3D function: A 3D vector function describing
+ the polarisation vector.
+ """
+ self._polarization3d = function
+
+ def set_pointing_function(self, VectorFunction3D function):
+ """
+ Assings the 3D vector function describing the direction of the laser propagation.
+
+ The direction of the laser light propagation is the direction
+ of the Poynting vector.
+
+ :param VectorFunction3D function: A 3D vector function describing
+ the laser light propagation direction
+ """
+ self._pointing3d = function
+
+ def set_energy_density_function(self, Function3D function):
+ """
+ Assigns the 3D scalar function describing the laser energy distribution.
+
+ The laser power distribution is the value of the volumetric
+ energy density of the laser light.
+ """
+ self._energy_density3d = function
+
+ cpdef Vector3D get_pointing(self, double x, double y, double z):
+ """
+ Returns the laser light propagation direction.
+
+ At the point (x, y, z) in the laser space.
+
+ :param x: x coordinate in meters.
+ :param y: y coordinate in meters.
+ :param z: z coordinate in meters.
+ :return: Intensity in m^-3.
+ """
+
+ return self._pointing3d.evaluate(x, y, z)
+
+ cpdef Vector3D get_polarization(self, double x, double y, double z):
+ """
+ Returns a vector denoting the laser polarisation.
+
+ The polarisation direction is the direction of the electric
+ component of the electromagnetic wave for the point (x, y, z)
+ in the laser space.
+
+ :param x: x coordinate in meters.
+ :param y: y coordinate in meters.
+ :param z: z coordinate in meters.
+ :return: power density in Wm^-3.
+ """
+
+ return self._polarization3d(x, y, z)
+
+ cpdef double get_energy_density(self, double x, double y, double z):
+ """
+ Returns the volumetric energy density of the laser light in W*m^-3.
+
+ At the point (x, y, z) in the laser space.
+
+ :param x: x coordinate in meters in the laser frame.
+ :param y: y coordinate in meters in the laser frame.
+ :param z: z coordinate in meters in the laser frame.
+ :return: power density in W*m^-3.
+ """
+
+ return self._energy_density3d.evaluate(x, y, z)
+
+ cpdef list generate_geometry(self):
+ """
+ returns list of raysect primitives composing the laser geometry
+
+ This method is called from the Laser instance to which the instance
+ of Profile is attached to. The Laser instance will be assigned as
+ the parent to the returned primitives in the Laser._configure method.
+ The Laser._configure method does not change any transforms. This is
+ why the returned primitives have to have their transforms already
+ initialised in the frame of the laser, when returned.
+ """
+
+ raise NotImplementedError("Virtual function density not defined.")
+
+ def _change(self):
+ """
+ Called if the laser properties change.
+
+ If the model caches calculation data that would be invalidated if its
+ source data changes then this method may be overridden to clear the
+ cache.
+ """
+
+ pass
diff --git a/cherab/core/laser/tests/__init__.py b/cherab/core/laser/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/cherab/core/laser/tests/test_laser.py b/cherab/core/laser/tests/test_laser.py
new file mode 100644
index 00000000..f9f85732
--- /dev/null
+++ b/cherab/core/laser/tests/test_laser.py
@@ -0,0 +1,110 @@
+import unittest
+
+from raysect.optical import World
+from raysect.optical.material.emitter.inhomogeneous import NumericalIntegrator
+
+from cherab.core import Plasma
+from cherab.core.laser.node import Laser
+from cherab.core.model.laser.laserspectrum import ConstantSpectrum
+from cherab.core.model.laser.model import SeldenMatobaThomsonSpectrum
+from cherab.core.model.laser.profile import UniformEnergyDensity
+
+
+class TestLaser(unittest.TestCase):
+
+ def test_laser_init(self):
+ """
+ Test correct initialisation of a laser instance.
+ """
+
+ world = World()
+ laser = Laser(parent=world)
+
+ with self.assertRaises(ValueError, msg="Model was attached before Plasma, Profile and LaserSpectrum were specified."):
+ laser.models = [SeldenMatobaThomsonSpectrum()]
+
+ laser.laser_profile = UniformEnergyDensity()
+ with self.assertRaises(ValueError, msg="Model was attached before Plasma, Profile and LaserSpectrum were specified."):
+ laser.models = [SeldenMatobaThomsonSpectrum()]
+
+ laser.laser_spectrum = ConstantSpectrum(min_wavelength=1059, max_wavelength=1061, bins=10)
+ with self.assertRaises(ValueError, msg="Model was attached before Plasma, Profile and LaserSpectrum were specified."):
+ laser.models = [SeldenMatobaThomsonSpectrum()]
+
+ laser.plasma = Plasma(parent=world)
+ laser.models = [SeldenMatobaThomsonSpectrum()]
+
+ def test_reference_change(self):
+
+ world = World()
+
+ laser_profile = UniformEnergyDensity(laser_length=1, laser_radius=0.1)
+ laser_spectrum = ConstantSpectrum(min_wavelength=1059, max_wavelength=1061, bins=10)
+ plasma = Plasma(parent=world)
+ models = [SeldenMatobaThomsonSpectrum()]
+
+ laser_profile2 = UniformEnergyDensity()
+ laser_spectrum2 = ConstantSpectrum(min_wavelength=1059, max_wavelength=1061, bins=10)
+ plasma2 = Plasma(parent=world)
+ models2 = [SeldenMatobaThomsonSpectrum()]
+
+ laser = Laser(parent=world)
+
+ laser.laser_spectrum = laser_spectrum
+ laser.plasma = plasma
+ laser.laser_profile = laser_profile
+ laser.models = models
+
+ for mod in list(laser.models):
+ self.assertIs(mod.laser_profile, laser_profile, msg="laser_profile reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.plasma, plasma, msg="plasma reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.laser_spectrum, laser_spectrum, msg="laser_spectrum reference in emission model"
+ "is not set correctly.")
+
+ laser.laser_spectrum = laser_spectrum2
+ laser.plasma = plasma2
+ laser.laser_profile = laser_profile2
+
+ for mod in list(laser.models):
+ self.assertIs(mod.laser_profile, laser_profile2, msg="laser_profile reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.plasma, plasma2, msg="plasma reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.laser_spectrum, laser_spectrum2, msg="laser_spectrum reference in emission model"
+ "is not set correctly.")
+
+ laser.models = models + models2
+
+ for mod in list(laser.models):
+ self.assertIs(mod.laser_profile, laser_profile2, msg="laser_profile reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.plasma, plasma2, msg="plasma reference in emission model"
+ "is not set correctly.")
+ self.assertIs(mod.laser_spectrum, laser_spectrum2, msg="laser_spectrum reference in emission model"
+ "is not set correctly.")
+
+ def test_integrator_change(self):
+
+ world = World()
+
+ laser_profile = UniformEnergyDensity(laser_length=1, laser_radius=0.1)
+ laser_spectrum = ConstantSpectrum(min_wavelength=1059, max_wavelength=1061, bins=10)
+ plasma = Plasma(parent=world)
+ models = [SeldenMatobaThomsonSpectrum()]
+
+ laser = Laser(parent=world)
+
+ laser.laser_spectrum = laser_spectrum
+ laser.plasma = plasma
+ laser.laser_profile = laser_profile
+ laser.models = models
+
+ integrator = NumericalIntegrator(1e-4)
+
+ laser.integrator = integrator
+
+ for i in laser.get_geometry():
+ self.assertIs(i.material.integrator, integrator, msg="Integrator not updated properly")
+
diff --git a/cherab/core/laser/tests/test_laserspectrum.py b/cherab/core/laser/tests/test_laserspectrum.py
new file mode 100644
index 00000000..6545f5c7
--- /dev/null
+++ b/cherab/core/laser/tests/test_laserspectrum.py
@@ -0,0 +1,64 @@
+import unittest
+import numpy as np
+
+# The evaluate() method is not implemented in the base LaserSpectrum, so importing the simplest subclass.
+from cherab.core.model.laser.laserspectrum import ConstantSpectrum as LaserSpectrum
+from raysect.optical.spectrum import Spectrum
+
+
+class TestLaserSpectrum(unittest.TestCase):
+
+ def test_laserspectrum_init(self):
+ # test min_wavelength boundaries
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise a ValueError with min_wavelength being zero."):
+ LaserSpectrum(0., 100, 200)
+ LaserSpectrum(-1, 100, 200)
+
+ # test max_wavelength boundaries
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise a ValueError with max_wavelength being zero."):
+ LaserSpectrum(10, 0, 200)
+ LaserSpectrum(10, -1, 200)
+
+ # test min_wavelength >= max_wavelength
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise a ValueError with max_wavelength < min_wavelength."):
+ LaserSpectrum(40, 30, 200)
+ LaserSpectrum(30, 30, 200)
+
+ # test bins > 0
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise a ValueError with bins <= 0."):
+ LaserSpectrum(30, 40, 0)
+ LaserSpectrum(30, 40, -1)
+
+ def test_laserspectrum_changes(self):
+ laser_spectrum = LaserSpectrum(100, 200, 100)
+
+ # change min_wavelength to be larger or equal to max_wavelength
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise ValueError for min_wavelength change "
+ "with min_wavelength >= max_wavelength."):
+ laser_spectrum.min_wavelength = 300
+ laser_spectrum.min_wavelength = 200
+
+ # change max_wavelength to be smaller than max_wavelength
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise ValueError for max_wavelength change "
+ "with min_wavelength > max_wavelength."):
+ laser_spectrum.max_wavelength = 50
+ laser_spectrum.max_wavelength = 100
+
+ with self.assertRaises(ValueError,
+ msg="LaserSpectrum did not raise a ValueError with max_wavelength < min_wavelength."):
+ laser_spectrum.bins = -1
+ laser_spectrum.bins = 0
+
+ # laser spectrum should have same behaviour as Spectrum from raysect.optical
+ spectrum = Spectrum(laser_spectrum.min_wavelength, laser_spectrum.max_wavelength, laser_spectrum.bins)
+
+ # test caching of spectrum data, behaviour should be consistent with raysect.optical.spectrum.Spectrum
+ self.assertTrue(np.array_equal(laser_spectrum.wavelengths, spectrum.wavelengths),
+ "LaserSpectrum.wavelengths values are not equal to Spectrum.wavelengths "
+ "with same boundaries and number of bins")
diff --git a/cherab/core/math/__init__.pxd b/cherab/core/math/__init__.pxd
index 99e92fbe..710ee381 100644
--- a/cherab/core/math/__init__.pxd
+++ b/cherab/core/math/__init__.pxd
@@ -25,3 +25,4 @@ from cherab.core.math.clamp cimport *
from cherab.core.math.mappers cimport *
from cherab.core.math.mask cimport *
from cherab.core.math.slice cimport *
+from cherab.core.math.transform cimport *
diff --git a/cherab/core/math/__init__.py b/cherab/core/math/__init__.py
index b3e9a031..85336afa 100644
--- a/cherab/core/math/__init__.py
+++ b/cherab/core/math/__init__.py
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -31,6 +31,11 @@
from .caching import Caching1D, Caching2D, Caching3D
from .clamp import ClampOutput1D, ClampOutput2D, ClampOutput3D
from .clamp import ClampInput1D, ClampInput2D, ClampInput3D
-from .mappers import IsoMapper2D, IsoMapper3D, Swizzle2D, Swizzle3D, AxisymmetricMapper, VectorAxisymmetricMapper
+from .mappers import IsoMapper2D, IsoMapper3D
+from .mappers import Swizzle2D, Swizzle3D
+from .mappers import AxisymmetricMapper, VectorAxisymmetricMapper
from .mask import PolygonMask2D
from .slice import Slice2D, Slice3D
+from .transform import CylindricalTransform, VectorCylindricalTransform
+from .transform import PeriodicTransform1D, PeriodicTransform2D, PeriodicTransform3D
+from .transform import VectorPeriodicTransform1D, VectorPeriodicTransform2D, VectorPeriodicTransform3D
diff --git a/cherab/core/math/integrators/__init__.pxd b/cherab/core/math/integrators/__init__.pxd
new file mode 100644
index 00000000..db06ef43
--- /dev/null
+++ b/cherab/core/math/integrators/__init__.pxd
@@ -0,0 +1,20 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from cherab.core.math.integrators.integrators1d cimport Integrator1D, GaussianQuadrature
+
diff --git a/cherab/core/math/integrators/__init__.py b/cherab/core/math/integrators/__init__.py
new file mode 100644
index 00000000..86b7d58d
--- /dev/null
+++ b/cherab/core/math/integrators/__init__.py
@@ -0,0 +1,19 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from .integrators1d import Integrator1D, GaussianQuadrature
diff --git a/cherab/core/math/integrators/integrators1d.pxd b/cherab/core/math/integrators/integrators1d.pxd
new file mode 100644
index 00000000..c451285f
--- /dev/null
+++ b/cherab/core/math/integrators/integrators1d.pxd
@@ -0,0 +1,39 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from numpy cimport ndarray
+from raysect.core.math.function.float cimport Function1D, Function2D
+
+
+cdef class Integrator1D:
+
+ cdef:
+ Function1D function
+
+ cdef double evaluate(self, double a, double b) except? -1e999
+
+
+cdef class GaussianQuadrature(Integrator1D):
+
+ cdef:
+ int _min_order, _max_order
+ double _rtol
+ ndarray _roots, _weights
+ double[:] _roots_mv, _weights_mv
+
+ cdef _build_cache(self)
diff --git a/cherab/core/math/integrators/integrators1d.pyx b/cherab/core/math/integrators/integrators1d.pyx
new file mode 100644
index 00000000..54ec4059
--- /dev/null
+++ b/cherab/core/math/integrators/integrators1d.pyx
@@ -0,0 +1,223 @@
+# cython: language_level=3
+
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import numpy as np
+from scipy.special import roots_legendre
+
+from raysect.core.math.function.float cimport autowrap_function1d, Constant1D
+
+from libc.math cimport INFINITY
+cimport cython
+
+
+cdef class Integrator1D:
+ """
+ Compute a definite integral of a one-dimensional function.
+
+ :ivar Function1D integrand: A 1D function to integrate.
+ """
+
+ @property
+ def integrand(self):
+ """
+ A 1D function to integrate.
+
+ :rtype: int
+ """
+ return self.function
+
+ @integrand.setter
+ def integrand(self, object func not None):
+
+ self.function = autowrap_function1d(func)
+
+ cdef double evaluate(self, double a, double b) except? -1e999:
+
+ raise NotImplementedError("The evaluate() method has not been implemented.")
+
+ def __call__(self, double a, double b):
+ """
+ Integrates a one-dimensional function over a finite interval.
+
+ :param double a: Lower limit of integration.
+ :param double b: Upper limit of integration.
+
+ :returns: Definite integral of a one-dimensional function.
+ """
+
+ return self.evaluate(a, b)
+
+
+cdef class GaussianQuadrature(Integrator1D):
+ """
+ Compute an integral of a one-dimensional function over a finite interval
+ using fixed-tolerance Gaussian quadrature.
+ (see Scipy `quadrature `).
+
+ :param object integrand: A 1D function to integrate. Default is Constant1D(0).
+ :param double relative_tolerance: Iteration stops when relative error between
+ last two iterates is less than this value. Default is 1.e-5.
+ :param int max_order: Maximum order on Gaussian quadrature. Default is 50.
+ :param int min_order: Minimum order on Gaussian quadrature. Default is 1.
+
+ :ivar Function1D integrand: A 1D function to integrate.
+ :ivar double relative_tolerance: Iteration stops when relative error between
+ last two iterates is less than this value.
+ :ivar int max_order: Maximum order on Gaussian quadrature.
+ :ivar int min_order: Minimum order on Gaussian quadrature.
+ """
+
+ def __init__(self, object integrand=Constant1D(0), double relative_tolerance=1.e-5, int max_order=50, int min_order=1):
+
+ if min_order < 1 or max_order < 1:
+ raise ValueError("Order of Gaussian quadrature must be >= 1.")
+
+ if min_order > max_order:
+ raise ValueError("Minimum order of Gaussian quadrature must be less than or equal to the maximum order.")
+
+ self._min_order = min_order
+ self._max_order = max_order
+ self._build_cache()
+
+ self.integrand = integrand
+
+ self.relative_tolerance = relative_tolerance
+
+ @property
+ def min_order(self):
+ """
+ Minimum order on Gaussian quadrature.
+
+ :rtype: int
+ """
+ return self._min_order
+
+ @min_order.setter
+ def min_order(self, int value):
+
+ if value < 1:
+ raise ValueError("Order of Gaussian quadrature must be >= 1.")
+
+ if value > self._max_order:
+ raise ValueError("Minimum order of Gaussian quadrature must be less than or equal to the maximum order.")
+
+ self._min_order = value
+
+ self._build_cache()
+
+ @property
+ def max_order(self):
+ """
+ Maximum order on Gaussian quadrature.
+
+ :rtype: float
+ """
+ return self._max_order
+
+ @max_order.setter
+ def max_order(self, int value):
+
+ if value < 1:
+ raise ValueError("Order of Gaussian quadrature must be >= 1.")
+
+ if value < self._min_order:
+ raise ValueError("Maximum order of Gaussian quadrature must be greater than or equal to the minimum order.")
+
+ self._max_order = value
+
+ self._build_cache()
+
+ @property
+ def relative_tolerance(self):
+ """
+ Iteration stops when relative error between last two iterates is less than this value.
+
+ :rtype: double
+ """
+ return self._rtol
+
+ @relative_tolerance.setter
+ def relative_tolerance(self, double value):
+
+ if value <= 0:
+ raise ValueError("Relative tolerance must be positive.")
+
+ self._rtol = value
+
+ cdef _build_cache(self):
+ """
+ Caches the roots and weights of the Gauss-Legendre quadrature.
+ """
+
+ cdef:
+ int order, n, i
+
+ n = (self._max_order + self._min_order) * (self._max_order - self._min_order + 1) // 2
+
+ self._roots = np.zeros(n, dtype=np.float64)
+ self._weights = np.zeros(n, dtype=np.float64)
+
+ i = 0
+ for order in range(self._min_order, self._max_order + 1):
+ self._roots[i:i + order], self._weights[i:i + order] = roots_legendre(order)
+ i += order
+
+ self._roots_mv = self._roots
+ self._weights_mv = self._weights
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ @cython.cdivision(True)
+ @cython.initializedcheck(False)
+ cdef double evaluate(self, double a, double b) except? -1e999:
+ """
+ Integrates a one-dimensional function over a finite interval.
+
+ :param double a: Lower limit of integration.
+ :param double b: Upper limit of integration.
+
+ :returns: Gaussian quadrature approximation to integral.
+ """
+
+ cdef:
+ int order, i, ibegin
+ double newval, oldval, error, x, c, d
+
+ oldval = INFINITY
+ ibegin = 0
+ c = 0.5 * (a + b)
+ d = 0.5 * (b - a)
+
+ for order in range(self._min_order, self._max_order + 1):
+ newval = 0
+ for i in range(ibegin, ibegin + order):
+ x = c + d * self._roots_mv[i]
+ newval += self._weights_mv[i] * self.function.evaluate(x)
+ newval *= d
+
+ error = abs(newval - oldval)
+ oldval = newval
+
+ ibegin += order
+
+ if error < self._rtol * abs(newval):
+ break
+
+ return newval
diff --git a/cherab/core/math/mappers.pxd b/cherab/core/math/mappers.pxd
index 5b455d9d..3835e949 100644
--- a/cherab/core/math/mappers.pxd
+++ b/cherab/core/math/mappers.pxd
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -16,8 +16,9 @@
# See the Licence for the specific language governing permissions and limitations
# under the Licence.
-from cherab.core.math.function cimport Function1D, Function2D, Function3D, VectorFunction2D, VectorFunction3D
-from raysect.core cimport Vector3D
+from raysect.core.math.function.float cimport Function1D, Function2D, Function3D
+from raysect.core.math.function.vector3d cimport Function2D as VectorFunction2D
+from raysect.core.math.function.vector3d cimport Function3D as VectorFunction3D
cdef class IsoMapper2D(Function2D):
@@ -26,8 +27,6 @@ cdef class IsoMapper2D(Function2D):
readonly Function1D function1d
readonly Function2D function2d
- cdef double evaluate(self, double x, double y) except? -1e999
-
cdef class IsoMapper3D(Function3D):
@@ -35,15 +34,11 @@ cdef class IsoMapper3D(Function3D):
readonly Function3D function3d
readonly Function1D function1d
- cdef double evaluate(self, double x, double y, double z) except? -1e999
-
cdef class Swizzle2D(Function2D):
cdef readonly Function2D function2d
- cdef double evaluate(self, double x, double y) except? -1e999
-
cdef class Swizzle3D(Function3D):
@@ -51,18 +46,12 @@ cdef class Swizzle3D(Function3D):
readonly Function3D function3d
int shape[3]
- cdef double evaluate(self, double x, double y, double z) except? -1e999
-
cdef class AxisymmetricMapper(Function3D):
cdef readonly Function2D function2d
- cdef double evaluate(self, double x, double y, double z) except? -1e999
-
cdef class VectorAxisymmetricMapper(VectorFunction3D):
cdef readonly VectorFunction2D function2d
-
- cdef Vector3D evaluate(self, double x, double y, double z)
\ No newline at end of file
diff --git a/cherab/core/math/mappers.pyx b/cherab/core/math/mappers.pyx
index 5ff224a3..f1326f12 100644
--- a/cherab/core/math/mappers.pyx
+++ b/cherab/core/math/mappers.pyx
@@ -20,7 +20,9 @@
from libc.math cimport sqrt, atan2, M_PI
-from cherab.core.math.function cimport autowrap_function1d, autowrap_function2d, autowrap_function3d, autowrap_vectorfunction2d
+from raysect.core.math cimport Vector3D
+from raysect.core.math.function.float cimport autowrap_function1d, autowrap_function2d, autowrap_function3d
+from raysect.core.math.function.vector3d cimport autowrap_function2d as autowrap_vectorfunction2d
from raysect.core cimport rotate_z
cimport cython
@@ -251,13 +253,10 @@ cdef class AxisymmetricMapper(Function3D):
def __init__(self, object function2d):
if not callable(function2d):
- raise TypeError("Function3D is not callable.")
+ raise TypeError("Function2D is not callable.")
self.function2d = autowrap_function2d(function2d)
- def __call__(self, double x, double y, double z):
- return self.evaluate(x, y, z)
-
cdef double evaluate(self, double x, double y, double z) except? -1e999:
"""Return the value of function2d when it is y-axis symmetrically
extended to the 3D space."""
@@ -299,13 +298,11 @@ cdef class VectorAxisymmetricMapper(VectorFunction3D):
self.function2d = autowrap_vectorfunction2d(vectorfunction2d)
- def __call__(self, double x, double y, double z):
- return self.evaluate(x, y, z)
-
@cython.cdivision(True)
cdef Vector3D evaluate(self, double x, double y, double z):
"""Return the value of function2d when it is y-axis symmetrically
extended to the 3D space."""
+ cdef double r, phi
# convert to cylindrical coordinates
phi = atan2(y, x) / M_PI * 180
diff --git a/cherab/core/math/tests/test_integrators.py b/cherab/core/math/tests/test_integrators.py
new file mode 100644
index 00000000..fa967165
--- /dev/null
+++ b/cherab/core/math/tests/test_integrators.py
@@ -0,0 +1,80 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from raysect.core.math.function.float import Exp1D, Arg1D
+from cherab.core.math.integrators import GaussianQuadrature
+from math import sqrt, pi
+from scipy.special import erf
+import unittest
+
+
+class TestGaussianQuadrature(unittest.TestCase):
+ """Gaussian quadrature integrator tests."""
+
+ def test_properties(self):
+ """Test property assignment."""
+ min_order = 3
+ max_order = 30
+ reltol = 1.e-6
+ quadrature = GaussianQuadrature(integrand=Arg1D, relative_tolerance=reltol, max_order=max_order, min_order=min_order)
+
+ self.assertEqual(quadrature.relative_tolerance, reltol)
+ self.assertEqual(quadrature.max_order, max_order)
+ self.assertEqual(quadrature.min_order, min_order)
+ self.assertEqual(quadrature.integrand, Arg1D)
+
+ min_order = 0
+ max_order = 2 # < min_order
+ reltol = -1
+
+ with self.assertRaises(ValueError):
+ quadrature.max_order = max_order
+
+ with self.assertRaises(ValueError):
+ quadrature.min_order = min_order
+
+ with self.assertRaises(ValueError):
+ quadrature.relative_tolerance = reltol
+
+ min_order = 1
+ max_order = 20
+ reltol = 1.e-5
+
+ quadrature.relative_tolerance = reltol
+ quadrature.min_order = min_order
+ quadrature.max_order = max_order
+ quadrature.integrand = Exp1D
+
+ self.assertEqual(quadrature.relative_tolerance, reltol)
+ self.assertEqual(quadrature.min_order, min_order)
+ self.assertEqual(quadrature.max_order, max_order)
+ self.assertEqual(quadrature.integrand, Exp1D)
+
+ def test_integrate(self):
+ """Test integration."""
+ quadrature = GaussianQuadrature(relative_tolerance=1.e-8)
+ a = -0.5
+ b = 3.
+ quadrature.integrand = (2 / sqrt(pi)) * Exp1D(- Arg1D() * Arg1D())
+ exact_integral = erf(b) - erf(a)
+
+ self.assertAlmostEqual(quadrature(a, b), exact_integral, places=8)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/cherab/core/math/tests/test_mappers.py b/cherab/core/math/tests/test_mappers.py
index 777a6a85..a1d0eb73 100644
--- a/cherab/core/math/tests/test_mappers.py
+++ b/cherab/core/math/tests/test_mappers.py
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -16,6 +16,7 @@
# See the Licence for the specific language governing permissions and limitations
# under the Licence.
+from raysect.core.math import Vector3D
from cherab.core.math import mappers
import numpy as np
import unittest
@@ -35,6 +36,9 @@ def f2d(x, y): return x*np.sin(y)
def f3d(x, y, z): return x*x*np.exp(y)-2*z*y
self.function3d = f3d
+ def vecf2d(r, z): return Vector3D(0, r, z)
+ self.vectorfunction2d = vecf2d
+
def test_iso_mapper_2d(self):
"""Composition of a 1D and a 2D function."""
@@ -142,5 +146,17 @@ def test_axisymmetric_mapper_invalid_arg(self):
"""An error must be raised if the given argument is not callable."""
self.assertRaises(TypeError, mappers.AxisymmetricMapper, "blah")
+ def test_vector_axisymmetric_mapper(self):
+ """Vector axisymmetric mapper."""
+ symm_func = mappers.VectorAxisymmetricMapper(self.vectorfunction2d)
+ vec1 = symm_func(1., 1., 1.)
+ vec2 = Vector3D(-1., 1., 1.)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ def test_vector_axisymmetric_mapper_invalid_arg(self):
+ """An error must be raised if the given argument is not callable."""
+ self.assertRaises(TypeError, mappers.VectorAxisymmetricMapper, "blah")
+
+
if __name__ == '__main__':
- unittest.main()
\ No newline at end of file
+ unittest.main()
diff --git a/cherab/core/math/tests/test_transform.py b/cherab/core/math/tests/test_transform.py
new file mode 100644
index 00000000..fc3a2445
--- /dev/null
+++ b/cherab/core/math/tests/test_transform.py
@@ -0,0 +1,260 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from raysect.core.math import Vector3D
+from cherab.core.math import transform
+import numpy as np
+import unittest
+
+
+class TestCylindricalTransform(unittest.TestCase):
+ """Cylindrical transform tests."""
+
+ def setUp(self):
+ """Initialisation with functions to map."""
+
+ def f3d(r, phi, z):
+ return r * np.cos(phi) + z
+ self.function3d = f3d
+
+ def vecf3d(r, phi, z):
+ return Vector3D(np.sin(phi), r * z, np.cos(phi))
+ self.vectorfunction3d = vecf3d
+
+ def test_cylindrical_transform(self):
+ """Cylindrical transform."""
+ cyl_func = transform.CylindricalTransform(self.function3d)
+ self.assertAlmostEqual(cyl_func(1., 1., 0.5),
+ self.function3d(np.sqrt(2.), 0.25 * np.pi, 0.5),
+ places=10)
+
+ def test_cylindrical_transform_invalid_arg(self):
+ """An error must be raised if the given argument is not callable."""
+ self.assertRaises(TypeError, transform.CylindricalTransform, "blah")
+
+ def test_vector_cylindrical_transform(self):
+ """Cylindrical transform."""
+ cyl_func = transform.VectorCylindricalTransform(self.vectorfunction3d)
+ vec1 = cyl_func(1., 1., 1.)
+ vec2 = Vector3D(-0.5, 1.5, 1 / np.sqrt(2))
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ def test_vector_cylindrical_transform_invalid_arg(self):
+ """An error must be raised if the given argument is not callable."""
+ self.assertRaises(TypeError, transform.VectorCylindricalTransform, "blah")
+
+
+class TestPeriodicTransform(unittest.TestCase):
+ """Periodic transform tests."""
+
+ def setUp(self):
+ """Initialisation with functions to map."""
+
+ def f1d(x):
+ return x * np.cos(x - 3)
+ self.function1d = f1d
+
+ def f2d(x, y):
+ return x * np.sin(y)
+ self.function2d = f2d
+
+ def f3d(x, y, z):
+ return x * x * np.exp(y) - 2 * z * y
+ self.function3d = f3d
+
+ def vecf1d(x):
+ return Vector3D(x, x**2, x**3)
+ self.vectorfunction1d = vecf1d
+
+ def vecf2d(x, y):
+ return Vector3D(x, y, x * y)
+ self.vectorfunction2d = vecf2d
+
+ def vecf3d(x, y, z):
+ return Vector3D(x + y + z, (x + y) * z, x * y * z)
+ self.vectorfunction3d = vecf3d
+
+ def test_periodic_transform_1d(self):
+ """1D periodic transform"""
+ period_func = transform.PeriodicTransform1D(self.function1d, np.pi)
+ self.assertAlmostEqual(period_func(1.4 * np.pi),
+ self.function1d(0.4 * np.pi),
+ places=10)
+ self.assertAlmostEqual(period_func(-0.4 * np.pi),
+ self.function1d(0.6 * np.pi),
+ places=10)
+
+ def test_periodic_transform_1d_invalid_arg(self):
+ """1D periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.PeriodicTransform1D, "blah", np.pi)
+ # period is not a number
+ self.assertRaises(TypeError, transform.PeriodicTransform1D, self.function1d, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.PeriodicTransform1D, self.function1d, -1)
+
+ def test_periodic_transform_2d(self):
+ """2D periodic transform"""
+ period_func = transform.PeriodicTransform2D(self.function2d, 1, np.pi)
+ self.assertAlmostEqual(period_func(-0.4, 1.4 * np.pi),
+ self.function2d(0.6, 0.4 * np.pi),
+ places=10)
+ # Periodic only along x
+ period_func = transform.PeriodicTransform2D(self.function2d, 1., 0)
+ self.assertAlmostEqual(period_func(-0.4, 1.4 * np.pi),
+ self.function2d(0.6, 1.4 * np.pi),
+ places=10)
+ # Periodic only along y
+ period_func = transform.PeriodicTransform2D(self.function2d, 0, np.pi)
+ self.assertAlmostEqual(period_func(-0.4, 1.4 * np.pi),
+ self.function2d(-0.4, 0.4 * np.pi),
+ places=10)
+
+ def test_periodic_transform_2d_invalid_arg(self):
+ """2D periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.PeriodicTransform2D, "blah", np.pi, np.pi)
+ # period is not a number
+ self.assertRaises(TypeError, transform.PeriodicTransform2D, self.function2d, "blah", np.pi)
+ self.assertRaises(TypeError, transform.PeriodicTransform2D, self.function2d, np.pi, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.PeriodicTransform2D, self.function2d, -1, np.pi)
+ self.assertRaises(ValueError, transform.PeriodicTransform2D, self.function2d, np.pi, -1)
+
+ def test_periodic_transform_3d(self):
+ """3D periodic transform"""
+ period_func = transform.PeriodicTransform3D(self.function3d, 1, 1, 1)
+ self.assertAlmostEqual(period_func(-0.4, 1.4, 2.1),
+ self.function3d(0.6, 0.4, 0.1),
+ places=10)
+ # Periodic only along y and z
+ period_func = transform.PeriodicTransform3D(self.function3d, 0, 1, 1)
+ self.assertAlmostEqual(period_func(-0.4, 1.4, 2.1),
+ self.function3d(-0.4, 0.4, 0.1),
+ places=10)
+ # Periodic only along x and z
+ period_func = transform.PeriodicTransform3D(self.function3d, 1, 0, 1)
+ self.assertAlmostEqual(period_func(-0.4, 1.4, 2.1),
+ self.function3d(0.6, 1.4, 0.1),
+ places=10)
+ # Periodic only along x and y
+ period_func = transform.PeriodicTransform3D(self.function3d, 1, 1, 0)
+ self.assertAlmostEqual(period_func(-0.4, 1.4, 2.1),
+ self.function3d(0.6, 0.4, 2.1),
+ places=10)
+
+ def test_periodic_transform_3d_invalid_arg(self):
+ """3D periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.PeriodicTransform3D, "blah", np.pi, np.pi, np.pi)
+ # period is not a number
+ self.assertRaises(TypeError, transform.PeriodicTransform3D, self.function3d, "blah", np.pi, np.pi)
+ self.assertRaises(TypeError, transform.PeriodicTransform3D, self.function3d, np.pi, "blah", np.pi)
+ self.assertRaises(TypeError, transform.PeriodicTransform3D, self.function3d, np.pi, np.pi, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.PeriodicTransform3D, self.function3d, -1, np.pi, np.pi)
+ self.assertRaises(ValueError, transform.PeriodicTransform3D, self.function3d, np.pi, -1, np.pi)
+ self.assertRaises(ValueError, transform.PeriodicTransform3D, self.function3d, np.pi, np.pi, -1)
+
+ def test_vector_periodic_transform_1d(self):
+ """1D vector periodic transform"""
+ period_func = transform.VectorPeriodicTransform1D(self.vectorfunction1d, 1)
+ vec1 = period_func(1.4)
+ vec2 = Vector3D(0.4, 0.16, 0.064)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ def test_vector_periodic_transform_1d_invalid_arg(self):
+ """1D vector periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform1D, "blah", 1.)
+ # period is not a number
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform1D, self.vectorfunction1d, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform1D, self.vectorfunction1d, -1)
+
+ def test_vector_periodic_transform_2d(self):
+ """2D vector periodic transform"""
+ period_func = transform.VectorPeriodicTransform2D(self.vectorfunction2d, 1, 1)
+ vec1 = period_func(-0.4, 1.6)
+ vec2 = Vector3D(0.6, 0.6, 0.36)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ # Periodic only along x
+ period_func = transform.VectorPeriodicTransform2D(self.vectorfunction2d, 1, 0)
+ vec1 = period_func(-0.4, 1.6)
+ vec2 = Vector3D(0.6, 1.6, 0.96)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ # Periodic only along y
+ period_func = transform.VectorPeriodicTransform2D(self.vectorfunction2d, 0, 1)
+ vec1 = period_func(-0.4, 1.6)
+ vec2 = Vector3D(-0.4, 0.6, -0.24)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ def test_vector_periodic_transform_2d_invalid_arg(self):
+ """2D vector periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform2D, "blah", 1, 1)
+ # period is not a number
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform2D, self.vectorfunction2d, "blah", 1)
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform2D, self.vectorfunction2d, 1, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform2D, self.vectorfunction2d, -1, 1)
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform2D, self.vectorfunction2d, 1, -1)
+
+ def test_vector_periodic_transform_3d(self):
+ """3D vector periodic transform"""
+ period_func = transform.VectorPeriodicTransform3D(self.vectorfunction3d, 1, 1, 1)
+ vec1 = period_func(-0.4, 1.6, 1.2)
+ vec2 = Vector3D(1.4, 0.24, 0.072)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ # Periodic along y and z
+ period_func = transform.VectorPeriodicTransform3D(self.vectorfunction3d, 0, 1, 1)
+ vec1 = period_func(-0.4, 1.6, 1.2)
+ vec2 = Vector3D(0.4, 0.04, -0.048)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ # Periodic along x and z
+ period_func = transform.VectorPeriodicTransform3D(self.vectorfunction3d, 1, 0, 1)
+ vec1 = period_func(-0.4, 1.6, 1.2)
+ vec2 = Vector3D(2.4, 0.44, 0.192)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ # Periodic along x and y
+ period_func = transform.VectorPeriodicTransform3D(self.vectorfunction3d, 1, 1, 0)
+ vec1 = period_func(-0.4, 1.6, 1.2)
+ vec2 = Vector3D(2.4, 1.44, 0.432)
+ np.testing.assert_almost_equal([vec1.x, vec1.y, vec1.z], [vec2.x, vec2.y, vec2.z], decimal=10)
+
+ def test_vector_periodic_transform_3d_invalid_arg(self):
+ """3D vector periodic transform. Invalid arguments."""
+ # 1st argument is not callable
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform3D, "blah", 1, 1, 1)
+ # period is not a number
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, "blah", 1, 1)
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, 1, "blah", 1)
+ self.assertRaises(TypeError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, 1, 1, "blah")
+ # period is negative
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, -1, 1, 1)
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, 1, -1, 1)
+ self.assertRaises(ValueError, transform.VectorPeriodicTransform3D, self.vectorfunction3d, 1, 1, -1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/cherab/core/math/transform/__init__.pxd b/cherab/core/math/transform/__init__.pxd
new file mode 100644
index 00000000..3ce39b6b
--- /dev/null
+++ b/cherab/core/math/transform/__init__.pxd
@@ -0,0 +1,20 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from cherab.core.math.transform.periodic cimport *
+from cherab.core.math.transform.cylindrical cimport *
\ No newline at end of file
diff --git a/cherab/core/math/transform/__init__.py b/cherab/core/math/transform/__init__.py
new file mode 100644
index 00000000..168bb305
--- /dev/null
+++ b/cherab/core/math/transform/__init__.py
@@ -0,0 +1,21 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from .cylindrical import CylindricalTransform, VectorCylindricalTransform
+from .periodic import PeriodicTransform1D, PeriodicTransform2D, PeriodicTransform3D
+from .periodic import VectorPeriodicTransform1D, VectorPeriodicTransform2D, VectorPeriodicTransform3D
diff --git a/cherab/core/math/transform/cylindrical.pxd b/cherab/core/math/transform/cylindrical.pxd
new file mode 100644
index 00000000..504b2fd5
--- /dev/null
+++ b/cherab/core/math/transform/cylindrical.pxd
@@ -0,0 +1,30 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from raysect.core.math.function.float cimport Function3D
+from raysect.core.math.function.vector3d cimport Function3D as VectorFunction3D
+
+
+cdef class CylindricalTransform(Function3D):
+
+ cdef readonly Function3D function3d
+
+
+cdef class VectorCylindricalTransform(VectorFunction3D):
+
+ cdef readonly VectorFunction3D function3d
diff --git a/cherab/core/math/transform/cylindrical.pyx b/cherab/core/math/transform/cylindrical.pyx
new file mode 100644
index 00000000..cd716cad
--- /dev/null
+++ b/cherab/core/math/transform/cylindrical.pyx
@@ -0,0 +1,128 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from libc.math cimport sqrt, atan2, M_PI
+
+from raysect.core.math cimport Vector3D
+from raysect.core.math.function.float cimport autowrap_function3d
+from raysect.core.math.function.vector3d cimport autowrap_function3d as autowrap_vectorfunction3d
+from raysect.core cimport rotate_z
+cimport cython
+
+cdef class CylindricalTransform(Function3D):
+ """
+ Converts Cartesian coordinates to cylindrical coordinates and calls a 3D function
+ defined in cylindrical coordinates, f(r, :math:`\\phi`, z).
+
+ The angular coordinate is given in radians.
+
+ Positive angular coordinate is measured counterclockwise from the xz plane.
+
+ :param Function3D function3d: The function to be mapped. Must be defined
+ in the interval (:math:`-\\pi`, :math:`\\pi`]
+ on the angular axis.
+
+ .. code-block:: pycon
+
+ >>> from math import sqrt, cos
+ >>> from cherab.core.math import CylindricalTransform
+ >>>
+ >>> def my_func(r, phi, z):
+ >>> return r * cos(phi)
+ >>>
+ >>> f = CylindricalTransform(my_func)
+ >>>
+ >>> f(1, 0, 0)
+ 1.0
+ >>> f(0.5 * sqrt(3), 0.5, 0)
+ 0.8660254037844385
+ """
+
+ def __init__(self, object function3d):
+
+ if not callable(function3d):
+ raise TypeError("Function3D is not callable.")
+
+ self.function3d = autowrap_function3d(function3d)
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+ """
+ Converts to cylindrical coordinates and evaluates the function
+ defined in cylindrical coordinates.
+ """
+ cdef double r, phi
+
+ r = sqrt(x * x + y * y)
+ phi = atan2(y, x)
+
+ return self.function3d.evaluate(r, phi, z)
+
+
+cdef class VectorCylindricalTransform(VectorFunction3D):
+ """
+ Converts Cartesian coordinates to cylindrical coordinates, calls
+ a 3D vector function defined in cylindrical coordinates, f(r, :math:`\\phi`, z),
+ then converts the returned 3D vector to Cartesian coordinates.
+
+ The angular coordinate is given in radians.
+
+ Positive angular coordinate is measured counterclockwise from the xz plane.
+
+ :param VectorFunction3D function3d: The function to be mapped. Must be defined
+ in the interval (:math:`-\\pi`, :math:`\\pi`]
+ on the angular axis.
+
+ .. code-block:: pycon
+
+ >>> from math import sqrt, cos
+ >>> from raysect.core.math import Vector3D
+ >>> from cherab.core.math import VectorCylindricalTransform
+ >>>
+ >>> def my_vec_func(r, phi, z):
+ >>> v = Vector3D(0, 1, 0)
+ >>> v.length = r * abs(cos(phi))
+ >>> return v
+ >>>
+ >>> f = VectorCylindricalTransform(my_vec_func)
+ >>>
+ >>> f(1, 0, 0)
+ Vector3D(0.0, 1.0, 0.0)
+ >>> f(1/sqrt(2), 1/sqrt(2), 0)
+ Vector3D(-0.5, 0.5, 0.0)
+ """
+
+ def __init__(self, object function3d):
+
+ if not callable(function3d):
+ raise TypeError("Function3D is not callable.")
+
+ self.function3d = autowrap_vectorfunction3d(function3d)
+
+ @cython.cdivision(True)
+ cdef Vector3D evaluate(self, double x, double y, double z):
+ """
+ Converts to cylindrical coordinates, evaluates the vector function
+ defined in cylindrical coordinates and rotates the resulting vector
+ around z-axis.
+ """
+ cdef double r, phi
+
+ r = sqrt(x * x + y * y)
+ phi = atan2(y, x)
+
+ return self.function3d.evaluate(r, phi, z).transform(rotate_z(phi / M_PI * 180))
diff --git a/cherab/core/math/transform/periodic.pxd b/cherab/core/math/transform/periodic.pxd
new file mode 100644
index 00000000..e97e4602
--- /dev/null
+++ b/cherab/core/math/transform/periodic.pxd
@@ -0,0 +1,72 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from libc.math cimport fmod
+from raysect.core.math.function.float cimport Function1D, Function2D, Function3D
+from raysect.core.math.function.vector3d cimport Function1D as VectorFunction1D
+from raysect.core.math.function.vector3d cimport Function2D as VectorFunction2D
+from raysect.core.math.function.vector3d cimport Function3D as VectorFunction3D
+
+
+cdef inline double remainder(double x1, double x2) nogil:
+ if x2 == 0:
+ return x1
+ x1 = fmod(x1, x2)
+ return x1 + x2 if (x1 < 0) else x1
+
+
+cdef class PeriodicTransform1D(Function1D):
+
+ cdef:
+ readonly Function1D function1d
+ readonly double period
+
+
+cdef class PeriodicTransform2D(Function2D):
+
+ cdef:
+ readonly Function2D function2d
+ double period_x, period_y
+
+
+cdef class PeriodicTransform3D(Function3D):
+
+ cdef:
+ readonly Function3D function3d
+ readonly double period_x, period_y, period_z
+
+
+cdef class VectorPeriodicTransform1D(VectorFunction1D):
+
+ cdef:
+ readonly VectorFunction1D function1d
+ readonly double period
+
+
+cdef class VectorPeriodicTransform2D(VectorFunction2D):
+
+ cdef:
+ readonly VectorFunction2D function2d
+ readonly double period_x, period_y
+
+
+cdef class VectorPeriodicTransform3D(VectorFunction3D):
+
+ cdef:
+ readonly VectorFunction3D function3d
+ readonly double period_x, period_y, period_z
diff --git a/cherab/core/math/transform/periodic.pyx b/cherab/core/math/transform/periodic.pyx
new file mode 100644
index 00000000..13869458
--- /dev/null
+++ b/cherab/core/math/transform/periodic.pyx
@@ -0,0 +1,352 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from raysect.core.math cimport Vector3D
+from raysect.core.math.function.float cimport autowrap_function1d, autowrap_function2d, autowrap_function3d
+from raysect.core.math.function.vector3d cimport autowrap_function1d as autowrap_vectorfunction1d
+from raysect.core.math.function.vector3d cimport autowrap_function2d as autowrap_vectorfunction2d
+from raysect.core.math.function.vector3d cimport autowrap_function3d as autowrap_vectorfunction3d
+
+
+cdef class PeriodicTransform1D(Function1D):
+ """
+ Extends a periodic 1D function to an infinite 1D space.
+
+ :param Function1D function1d: The periodic 1D function defined
+ in the [0, period) interval.
+ :param double period: The period of the function.
+
+ .. code-block:: pycon
+
+ >>> from cherab.core.math import PeriodicTransform1D
+ >>>
+ >>> def f1(x):
+ >>> return x
+ >>>
+ >>> f2 = PeriodicTransform1D(f1, 1.)
+ >>>
+ >>> f2(1.5)
+ 0.5
+ >>> f2(-0.3)
+ 0.7
+ """
+
+ def __init__(self, object function1d, double period):
+
+ if not callable(function1d):
+ raise TypeError("function1d is not callable.")
+
+ self.function1d = autowrap_function1d(function1d)
+
+ if period <= 0:
+ raise ValueError("Argument period must be positive.")
+
+ self.period = period
+
+ cdef double evaluate(self, double x) except? -1e999:
+ """Return the value of periodic function."""
+
+ return self.function1d.evaluate(remainder(x, self.period))
+
+
+cdef class PeriodicTransform2D(Function2D):
+ """
+ Extends a periodic 2D function to an infinite 2D space.
+
+ Set period_x/period_y to 0 if the function is not periodic along x/y axis.
+
+ :param Function2D function2d: The periodic 2D function defined
+ in the ([0, period_x), [0, period_y)) intervals.
+ :param double period_x: The period of the function along x-axis.
+ 0 if not periodic.
+ :param double period_y: The period of the function along y-axis.
+ 0 if not periodic.
+
+ .. code-block:: pycon
+
+ >>> from cherab.core.math import PeriodicTransform2D
+ >>>
+ >>> def f1(x, y):
+ >>> return x * y
+ >>>
+ >>> f2 = PeriodicTransform2D(f1, 1., 1.)
+ >>>
+ >>> f2(1.5, 1.5)
+ 0.25
+ >>> f2(-0.3, -1.3)
+ 0.49
+ >>>
+ >>> f3 = PeriodicTransform2D(f1, 1., 0)
+ >>>
+ >>> f3(1.5, 1.5)
+ 0.75
+ >>> f3(-0.3, -1.3)
+ -0.91
+ """
+
+ def __init__(self, object function2d, double period_x, double period_y):
+
+ if not callable(function2d):
+ raise TypeError("function2d is not callable.")
+
+ self.function2d = autowrap_function2d(function2d)
+
+ if period_x < 0:
+ raise ValueError("Argument period_x must be >= 0.")
+ if period_y < 0:
+ raise ValueError("Argument period_y must be >= 0.")
+
+ self.period_x = period_x
+ self.period_y = period_y
+
+ cdef double evaluate(self, double x, double y) except? -1e999:
+ """Return the value of periodic function."""
+
+ x = remainder(x, self.period_x)
+ y = remainder(y, self.period_y)
+
+ return self.function2d.evaluate(x, y)
+
+
+cdef class PeriodicTransform3D(Function3D):
+ """
+ Extends a periodic 3D function to an infinite 3D space.
+
+ Set period_x/period_y/period_z to 0 if the function is not periodic along x/y/z axis.
+
+ :param Function3D function3d: The periodic 3D function defined in the
+ ([0, period_x), [0, period_y), [0, period_z)) intervals.
+ :param double period_x: The period of the function along x-axis.
+ 0 if not periodic.
+ :param double period_y: The period of the function along y-axis.
+ 0 if not periodic.
+ :param double period_z: The period of the function along z-axis.
+ 0 if not periodic.
+
+ .. code-block:: pycon
+
+ >>> from cherab.core.math import PeriodicTransform3D
+ >>>
+ >>> def f1(x, y, z):
+ >>> return x * y * z
+ >>>
+ >>> f2 = PeriodicTransform3D(f1, 1., 1., 1.)
+ >>>
+ >>> f2(1.5, 1.5, 1.5)
+ 0.125
+ >>> f2(-0.3, -1.3, -2.3)
+ 0.343
+ >>>
+ >>> f3 = PeriodicTransform3D(f1, 0, 1., 0)
+ >>>
+ >>> f3(1.5, 1.5, 1.5)
+ 1.125
+ >>> f3(-0.3, -1.3, -0.3)
+ 0.063
+ """
+
+ def __init__(self, object function3d, double period_x, double period_y, double period_z):
+
+ if not callable(function3d):
+ raise TypeError("function2d is not callable.")
+
+ self.function3d = autowrap_function3d(function3d)
+
+ if period_x < 0:
+ raise ValueError("Argument period_x must be >= 0.")
+ if period_y < 0:
+ raise ValueError("Argument period_y must be >= 0.")
+ if period_z < 0:
+ raise ValueError("Argument period_z must be >= 0.")
+
+ self.period_x = period_x
+ self.period_y = period_y
+ self.period_z = period_z
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+ """Return the value of periodic function."""
+
+ x = remainder(x, self.period_x)
+ y = remainder(y, self.period_y)
+ z = remainder(z, self.period_z)
+
+ return self.function3d.evaluate(x, y, z)
+
+
+cdef class VectorPeriodicTransform1D(VectorFunction1D):
+ """
+ Extends a periodic 1D vector function to an infinite 1D space.
+
+ :param VectorFunction1D function1d: The periodic 1D vector function
+ defined in the [0, period) interval.
+ :param double period: The period of the function.
+
+ .. code-block:: pycon
+
+ >>> from raysect.core.math import Vector3D
+ >>> from cherab.core.math import VectorPeriodicTransform1D
+ >>>
+ >>> def f1(x):
+ >>> return Vector3D(x, 0, 0)
+ >>>
+ >>> f2 = VectorPeriodicTransform1D(f1, 1.)
+ >>>
+ >>> f2(1.5)
+ Vector3D(0.5, 0, 0)
+ >>> f2(-0.3)
+ Vector3D(0.7, 0, 0)
+ """
+
+ def __init__(self, object function1d, double period):
+
+ if not callable(function1d):
+ raise TypeError("function1d is not callable.")
+
+ self.function1d = autowrap_vectorfunction1d(function1d)
+
+ if period <= 0:
+ raise ValueError("Argument period must be positive.")
+
+ self.period = period
+
+ cdef Vector3D evaluate(self, double x):
+ """Return the value of periodic function."""
+
+ return self.function1d.evaluate(remainder(x, self.period))
+
+
+cdef class VectorPeriodicTransform2D(VectorFunction2D):
+ """
+ Extends a periodic 2D vector function to an infinite 2D space.
+
+ Set period_x/period_y to 0 if the function is not periodic along x/y axis.
+
+ :param VectorFunction2D function2d: The periodic 2D vector function defined in
+ the ([0, period_x), [0, period_y)) intervals.
+ :param double period_x: The period of the function along x-axis.
+ 0 if not periodic.
+ :param double period_y: The period of the function along y-axis.
+ 0 if not periodic.
+
+ .. code-block:: pycon
+
+ >>> from cherab.core.math import VectorPeriodicTransform2D
+ >>>
+ >>> def f1(x, y):
+ >>> return Vector3D(x, y, 0)
+ >>>
+ >>> f2 = VectorPeriodicTransform2D(f1, 1., 1.)
+ >>>
+ >>> f2(1.5, 1.5)
+ Vector3D(0.5, 0.5, 0)
+ >>> f2(-0.3, -1.3)
+ Vector3D(0.7, 0.7, 0)
+ >>>
+ >>> f3 = VectorPeriodicTransform2D(f1, 1., 0)
+ >>>
+ >>> f3(1.5, 1.5)
+ Vector3D(0.5, 1.5, 0)
+ >>> f3(-0.3, -1.3)
+ Vector3D(0.7, -1.3, 0)
+ """
+
+ def __init__(self, object function2d, double period_x, double period_y):
+
+ if not callable(function2d):
+ raise TypeError("function2d is not callable.")
+
+ self.function2d = autowrap_vectorfunction2d(function2d)
+
+ if period_x < 0:
+ raise ValueError("Argument period_x must be >= 0.")
+ if period_y < 0:
+ raise ValueError("Argument period_y must be >= 0.")
+
+ self.period_x = period_x
+ self.period_y = period_y
+
+ cdef Vector3D evaluate(self, double x, double y):
+ """Return the value of periodic function."""
+
+ x = remainder(x, self.period_x)
+ y = remainder(y, self.period_y)
+
+ return self.function2d.evaluate(x, y)
+
+
+cdef class VectorPeriodicTransform3D(VectorFunction3D):
+ """
+ Extends a periodic 3D vector function to an infinite 3D space.
+
+ Set period_x/period_y/period_z to 0 if the function is not periodic along x/y/z axis.
+
+ :param VectorFunction3D function3d: The periodic 3D vector function defined in the
+ ([0, period_x), [0, period_y), [0, period_z)) intervals.
+ :param double period_x: The period of the function along x-axis.
+ 0 if not periodic.
+ :param double period_y: The period of the function along y-axis.
+ 0 if not periodic.
+ :param double period_z: The period of the function along z-axis.
+ 0 if not periodic.
+
+ .. code-block:: pycon
+
+ >>> from cherab.core.math import PeriodicTransform3D
+ >>>
+ >>> def f1(x, y, z):
+ >>> return Vector3D(x, y, z)
+ >>>
+ >>> f2 = VectorPeriodicTransform3D(f1, 1., 1., 1.)
+ >>>
+ >>> f2(1.5, 1.5, 1.5)
+ Vector3D(0.5, 0.5, 0.5)
+ >>> f2(-0.3, -1.3, -2.3)
+ Vector3D(0.7, 0.7, 0.7)
+ >>>
+ >>> f3 = VectorPeriodicTransform3D(f1, 0, 1., 0)
+ >>>
+ >>> f3(1.5, 0.5, 1.5)
+ Vector3D(1.5, 0.5, 1.5)
+ """
+
+ def __init__(self, object function3d, double period_x, double period_y, double period_z):
+
+ if not callable(function3d):
+ raise TypeError("function2d is not callable.")
+
+ self.function3d = autowrap_vectorfunction3d(function3d)
+
+ if period_x < 0:
+ raise ValueError("Argument period_x must be >= 0.")
+ if period_y < 0:
+ raise ValueError("Argument period_y must be >= 0.")
+ if period_z < 0:
+ raise ValueError("Argument period_z must be >= 0.")
+
+ self.period_x = period_x
+ self.period_y = period_y
+ self.period_z = period_z
+
+ cdef Vector3D evaluate(self, double x, double y, double z):
+ """Return the value of periodic function."""
+
+ x = remainder(x, self.period_x)
+ y = remainder(y, self.period_y)
+ z = remainder(z, self.period_z)
+
+ return self.function3d.evaluate(x, y, z)
diff --git a/cherab/core/model/beam/charge_exchange.pxd b/cherab/core/model/beam/charge_exchange.pxd
index 4d9220e5..cd0b48db 100644
--- a/cherab/core/model/beam/charge_exchange.pxd
+++ b/cherab/core/model/beam/charge_exchange.pxd
@@ -21,6 +21,7 @@ from raysect.optical cimport Node, World, Primitive, Ray, Spectrum, SpectralFunc
from cherab.core cimport Species, Plasma, Beam, Line, AtomicData, BeamCXPEC
from cherab.core.beam cimport BeamModel
+from cherab.core.model.lineshape cimport LineShapeModel
cdef class BeamCXLine(BeamModel):
@@ -31,6 +32,8 @@ cdef class BeamCXLine(BeamModel):
double _wavelength
BeamCXPEC _ground_beam_rate
list _excited_beam_data
+ LineShapeModel _lineshape
+ object _lineshape_class, _lineshape_args, _lineshape_kwargs
cdef double _composite_cx_rate(self, double x, double y, double z, double interaction_energy,
Vector3D donor_velocity, double receiver_temperature, double receiver_density) except? -1e999
diff --git a/cherab/core/model/beam/charge_exchange.pyx b/cherab/core/model/beam/charge_exchange.pyx
index 5cefa3d6..295d5f5f 100644
--- a/cherab/core/model/beam/charge_exchange.pyx
+++ b/cherab/core/model/beam/charge_exchange.pyx
@@ -1,8 +1,8 @@
# cython: language_level=3
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2023 Euratom
+# Copyright 2016-2023 United Kingdom Atomic Energy Authority
+# Copyright 2016-2023 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -28,7 +28,7 @@ cimport cython
from raysect.optical.material.emitter.inhomogeneous import NumericalIntegrator
from cherab.core cimport Species, Plasma, Beam, Element, BeamPopulationRate
-from cherab.core.model.lineshape cimport doppler_shift, thermal_broadening, add_gaussian_line
+from cherab.core.model.lineshape cimport GaussianLine
from cherab.core.utility.constants cimport RECIP_4_PI, ELEMENTARY_CHARGE, ATOMIC_MASS
cdef double RECIP_ELEMENTARY_CHARGE = 1 / ELEMENTARY_CHARGE
@@ -44,24 +44,58 @@ cdef double ms_to_evamu(double x):
cdef class BeamCXLine(BeamModel):
- """Calculates CX emission for a beam.
-
- :param line:
- :param step: integration step in meters
- :return:
+ """
+ Calculates emission produced by charge-exchange of plasma ions
+ with beam species.
+
+ :param Line line: The emission line object.
+ :param Beam beam: The beam object.
+ :param Plasma plasma: The emitting plasma object.
+ :param AtomicData atomic_data: The atomic data provider.
+ :param object lineshape: The spectral line shape class. Must be a subclass of `LineShapeModel`.
+ Defaults to `GaussianLine`.
+ :param object lineshape_args: The arguments of spectral line shape class. Defaults is None.
+ :param object lineshape_kwargs: The keyword arguments of spectral line shape class.
+ Defaults is None.
+
+ :ivar Line line: The emission line object.
+
+ .. code-block:: pycon
+ >>> from cherab.core.model import BeamCXLine
+ >>> from cherab.core.atomic import carbon
+ >>> from cherab.core.model import ParametrisedZeemanTriplet
+ >>>
+ >>> cVI_8_7 = Line(carbon, 5, (8, 7)) # emission line
+ >>> # define plasma, beam and atomic data, plasma mast contain C6+ ions.
+ >>> ...
+ >>> # here we override default line shape class, GaussianLine,
+ >>> # with ParametrisedZeemanTriplet to take into account Zeeman splitting.
+ >>> beam_cx_line = BeamCXLine(cVI_8_7, lineshape=ParametrisedZeemanTriplet)
+ >>> beam.models = [beam_cx_line]
"""
- def __init__(self, Line line not None, Beam beam=None, Plasma plasma=None, AtomicData atomic_data=None):
+ def __init__(self, Line line not None, Beam beam=None, Plasma plasma=None, AtomicData atomic_data=None,
+ object lineshape=None, object lineshape_args=None, object lineshape_kwargs=None):
super().__init__(beam, plasma, atomic_data)
self._line = line
- # initialise cache to empty
- self._target_species = None
- self._wavelength = 0.0
- self._ground_beam_rate = None
- self._excited_beam_data = None
+ self._lineshape_class = lineshape or GaussianLine
+ if not issubclass(self._lineshape_class, LineShapeModel):
+ raise TypeError("The attribute lineshape must be a subclass of LineShapeModel.")
+
+ if lineshape_args:
+ self._lineshape_args = lineshape_args
+ else:
+ self._lineshape_args = []
+ if lineshape_kwargs:
+ self._lineshape_kwargs = lineshape_kwargs
+ else:
+ self._lineshape_kwargs = {}
+
+ # ensure that cache is initialised
+ self._change()
@property
def line(self):
@@ -85,9 +119,9 @@ cdef class BeamCXLine(BeamModel):
cdef:
double x, y, z
double donor_density
- double receiver_temperature, receiver_density, receiver_ion_mass, interaction_speed, interaction_energy, emission_rate
+ double receiver_temperature, receiver_density, interaction_speed, interaction_energy, emission_rate
Vector3D receiver_velocity, donor_velocity, interaction_velocity
- double natural_wavelength, central_wavelength, radiance, sigma
+ double radiance
# cache data on first run
if self._target_species is None:
@@ -116,7 +150,6 @@ cdef class BeamCXLine(BeamModel):
return spectrum
receiver_velocity = self._target_species.distribution.bulk_velocity(x, y, z)
- receiver_ion_mass = self._target_species.element.atomic_weight
donor_velocity = beam_direction.normalise().mul(evamu_to_ms(self._beam.get_energy()))
@@ -127,20 +160,16 @@ cdef class BeamCXLine(BeamModel):
# calculate the composite charge-exchange emission coefficient
emission_rate = self._composite_cx_rate(x, y, z, interaction_energy, donor_velocity, receiver_temperature, receiver_density)
- # calculate emission line central wavelength, doppler shifted along observation direction
- natural_wavelength = self._wavelength
- central_wavelength = doppler_shift(natural_wavelength, observation_direction, receiver_velocity)
-
# spectral line emission in W/m^3/str
radiance = RECIP_4_PI * donor_density * receiver_density * emission_rate
- sigma = thermal_broadening(natural_wavelength, receiver_temperature, receiver_ion_mass)
- return add_gaussian_line(radiance, central_wavelength, sigma, spectrum)
+
+ return self._lineshape.add_line(radiance, plasma_point, observation_direction, spectrum)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cdef double _composite_cx_rate(self, double x, double y, double z, double interaction_energy,
- Vector3D donor_velocity, double receiver_temperature, double receiver_density) except? -1e999:
+ Vector3D donor_velocity, double receiver_temperature, double receiver_density) except? -1e999:
"""
Performs a beam population weighted average of the effective cx rates.
@@ -328,6 +357,10 @@ cdef class BeamCXLine(BeamModel):
# link each rate with its population data
self._excited_beam_data.append((rate, population_data))
+ # instance line shape renderer
+ self._lineshape = self._lineshape_class(self._line, self._wavelength, self._target_species, self._plasma,
+ *self._lineshape_args, **self._lineshape_kwargs)
+
def _change(self):
# clear cache to force regeneration on first use
@@ -335,4 +368,3 @@ cdef class BeamCXLine(BeamModel):
self._wavelength = 0.0
self._ground_beam_rate = None
self._excited_beam_data = None
-
diff --git a/cherab/core/model/laser/__init__.pxd b/cherab/core/model/laser/__init__.pxd
new file mode 100644
index 00000000..3b0e3818
--- /dev/null
+++ b/cherab/core/model/laser/__init__.pxd
@@ -0,0 +1,4 @@
+from cherab.core.model.laser.laserspectrum import ConstantSpectrum, GaussianSpectrum
+from cherab.core.model.laser.profile import UniformEnergyDensity, ConstantAxisymmetricGaussian
+from cherab.core.model.laser.profile import ConstantBivariateGaussian, TrivariateGaussian, GaussianBeamAxisymmetric
+from cherab.core.model.laser.model import SeldenMatobaThomsonSpectrum
\ No newline at end of file
diff --git a/cherab/core/model/laser/__init__.py b/cherab/core/model/laser/__init__.py
new file mode 100644
index 00000000..930b55a7
--- /dev/null
+++ b/cherab/core/model/laser/__init__.py
@@ -0,0 +1,4 @@
+from .laserspectrum import ConstantSpectrum, GaussianSpectrum
+from .profile import UniformEnergyDensity, ConstantAxisymmetricGaussian
+from .profile import ConstantBivariateGaussian, TrivariateGaussian, GaussianBeamAxisymmetric
+from .model import SeldenMatobaThomsonSpectrum
diff --git a/cherab/core/model/laser/laserspectrum.pxd b/cherab/core/model/laser/laserspectrum.pxd
new file mode 100644
index 00000000..e21d36fb
--- /dev/null
+++ b/cherab/core/model/laser/laserspectrum.pxd
@@ -0,0 +1,34 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from cherab.core.laser cimport LaserSpectrum
+
+
+cdef class ConstantSpectrum(LaserSpectrum):
+
+ cdef double evaluate(self, double x) except? -1e999
+
+
+cdef class GaussianSpectrum(LaserSpectrum):
+
+ cdef:
+ double _stddev, _recip_stddev, _normalisation, _mean
+ double _norm_cdf
+
+ cdef double evaluate(self, double x) except? -1e999
diff --git a/cherab/core/model/laser/laserspectrum.pyx b/cherab/core/model/laser/laserspectrum.pyx
new file mode 100644
index 00000000..58c1cada
--- /dev/null
+++ b/cherab/core/model/laser/laserspectrum.pyx
@@ -0,0 +1,133 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from cherab.core.laser cimport LaserSpectrum
+from libc.math cimport sqrt, exp, M_PI, erf, M_SQRT2
+
+
+cdef class ConstantSpectrum(LaserSpectrum):
+ """
+ A laser spectrum with constant power.
+
+ Has a constant, non-zero distribution of power spectral density
+ between the min_wavelength and max_wavelength. The integral value
+ of the power is 1 W.
+
+ .. note::
+ The ConstantSpectrum class is suitable for approximation
+ of an infinitely thin laser spectrum, e.g.:
+ ConstantSpectrum(1063.9, 1064.1, 1)
+ """
+
+ def __init__(self, double min_wavelength, double max_wavelength, int bins):
+
+ super().__init__(min_wavelength, max_wavelength, bins)
+
+ cdef double evaluate(self, double x) except? -1e999:
+ """
+ Returns the spectral power density for the given wavelength.
+
+ :param float x: Wavelength in nm.
+
+ :return: Power spectral density in W/nm.
+ """
+
+ cdef:
+ double spectrum_width
+ int index
+
+ if self._min_wavelength <= x <= self._max_wavelength:
+ return 1.0 / (self._max_wavelength - self._min_wavelength)
+ else:
+ return 0
+
+
+cdef class GaussianSpectrum(LaserSpectrum):
+ """
+ A laser spectrum with a normally distributed power spectral density.
+
+ Has a Gaussian-like spectral shape. The inegral value of power is 1 W.
+
+ :param float mean: The mean value of the Gaussian distribution
+ of the laser spectrum in nm, can be thought of as the central
+ wavelength of the laser.
+ :param float stddev: Standard deviation of the Gaussian
+ distribution of the laser spectrum.
+
+ :ivar float stddev: Standard deviation of the Gaussian
+ distribution of the laser spectrum.
+ :ivar float mean: The mean value of the Gaussian distribution
+ of the laser spectrum in nm, can be thought of as the central
+ wavelength of the laser.
+ """
+
+ def __init__(self, double min_wavelength, double max_wavelength, int bins, double mean, double stddev):
+
+ self.stddev = stddev
+ self.mean = mean
+ super().__init__(min_wavelength, max_wavelength, bins)
+
+ @property
+ def stddev(self):
+ return self._stddev
+
+ @stddev.setter
+ def stddev(self, value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0")
+
+ self._stddev = value
+ self._recip_stddev = 1 / value
+ self._normalisation = 1 / (value * sqrt(2 * M_PI))
+ self._norm_cdf = 1 / (value * M_SQRT2)
+
+ @property
+ def mean(self):
+ return self._mean
+
+ @mean.setter
+ def mean(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0")
+
+ self._mean = value
+
+ cdef double evaluate(self, double x) except? -1e999:
+ """
+ Returns the spectral power density for the given wavelength.
+
+ :param float x: Wavelength in nm.
+
+ :return: Power spectral density in W/nm.
+ """
+ return self._normalisation * exp(-0.5 * ((x - self._mean) * self._recip_stddev) ** 2)
+
+ cpdef double _get_bin_power_spectral_density(self, double wavelength_lower, double wavelength_upper):
+ """
+ Returns the power spectral density in a bin.
+
+ Overrides the parent method to deliver better precision.
+ """
+
+ cdef:
+ double val_lower, val_upper
+
+ val_lower = erf((wavelength_lower - self._mean) * self._norm_cdf)
+ val_upper = erf((wavelength_upper - self._mean) * self._norm_cdf)
+ return 0.5 * (val_upper - val_lower) / self._delta_wavelength
\ No newline at end of file
diff --git a/cherab/core/model/laser/math_functions.pxd b/cherab/core/model/laser/math_functions.pxd
new file mode 100644
index 00000000..08827094
--- /dev/null
+++ b/cherab/core/model/laser/math_functions.pxd
@@ -0,0 +1,48 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function3D
+
+cdef class ConstantAxisymmetricGaussian3D(Function3D):
+
+ cdef:
+ double _stddev, _normalisation, _kr
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999
+
+
+cdef class ConstantBivariateGaussian3D(Function3D):
+
+ cdef:
+ double _stddev_x, _stddev_y, _kx, _ky, _normalisation
+
+
+cdef class TrivariateGaussian3D(Function3D):
+
+ cdef:
+ double _mean_z, _stddev_x, _stddev_y, _stddev_z, _kx, _ky
+ double _kz, _normalisation
+
+
+cdef class GaussianBeamModel(Function3D):
+
+ cdef:
+ double _waist_z, _stddev_waist, _stddev_waist2, _wavelength, _rayleigh_range
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999
diff --git a/cherab/core/model/laser/math_functions.pyx b/cherab/core/model/laser/math_functions.pyx
new file mode 100644
index 00000000..1ed73a61
--- /dev/null
+++ b/cherab/core/model/laser/math_functions.pyx
@@ -0,0 +1,304 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+cimport cython
+
+from raysect.core.math.function.float cimport Function3D
+from raysect.core.math.cython.utility cimport find_index
+
+from libc.math cimport sqrt, exp, pi
+
+
+cdef class ConstantAxisymmetricGaussian3D(Function3D):
+ """
+ A function with a 2D Gaussian in the x-y plane and equal standard deviations in x and y directions.
+
+ .. math::
+ F(x, y, z) = \\frac{1}{2 * \\pi \\sigma^2} exp\\left(-\\frac{x^2 + y^2}{2 * \\sigma^2}\\right)
+
+ The function value has a Gaussian shape in the x-y plane with the standard deviations in
+ x and y direction being equal. The integral over an x-y plane is equal to 1
+ and the mean values in x and y directions are equal to 0.
+
+ :param float stddev: The standard deviation in both the x and y directions.
+ """
+
+ def __init__(self, stddev):
+
+ super().__init__()
+
+ self.stddev = stddev
+
+ @property
+ def stddev(self):
+
+ return self._stddev
+
+ @stddev.setter
+ def stddev(self, value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev = value
+ self._kr = -1 / (2 * value ** 2)
+ self._normalisation = 1 / (2 * pi * value ** 2)
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+ cdef:
+ double r2
+ r2 = x ** 2 + y ** 2
+ return self._normalisation * exp(r2 * self._kr)
+
+
+cdef class ConstantBivariateGaussian3D(Function3D):
+ """
+ A function with a 2D Gaussian in the x-y plane.
+
+ .. math::
+ F(x, y, z) = \\frac{1}{2 * \\pi \\sigma_x \\sigma_y} exp\\left(-\\frac{x^2 + y^2}{2 * \\sigma_x \\sigma_y}\\right)
+
+ The function value has a Gaussian shape in the x-y plane. The integral over an x-y plane is equal to 1
+ and the mean values in x and y directions are equal to 0.
+ The correlation between the standard deviations in x and y directions is equal to 0.
+
+ :param float stddev_x: The standard deviation in the x directions.
+ :param float stddev_y: The standard deviation in the y directions.
+ """
+
+ def __init__(self, stddev_x, stddev_y):
+
+ super().__init__()
+ self._init_params()
+
+ self.stddev_x = stddev_x
+ self.stddev_y = stddev_y
+
+ def _init_params(self):
+ self._stddev_x = 1
+ self._stddev_y = 1
+
+ @property
+ def stddev_x(self):
+ return self._stddev_x
+
+ @stddev_x.setter
+ def stddev_x(self, value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev_x = value
+
+ self._cache_constants()
+
+ @property
+ def stddev_y(self):
+ return self._stddev_y
+
+ @stddev_y.setter
+ def stddev_y(self, value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev_y = value
+
+ self._cache_constants()
+
+ def _cache_constants(self):
+ self._kx = -1 / (2 * self._stddev_x ** 2)
+ self._ky = -1 / (2 * self._stddev_y ** 2)
+ self._normalisation = 1 / (2 * pi * self._stddev_x * self._stddev_y)
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+ return self._normalisation * exp(x ** 2 * self._kx +
+ y ** 2 * self._ky)
+
+
+cdef class TrivariateGaussian3D(Function3D):
+ """
+ A function with a 3D Gaussian shape.
+
+ .. math::
+ F(x, y, z) = \\frac{1}{\\sqrt{2 \\pi^3} \\sigma_x \\sigma_y \\sigma_z} exp\\left(-\\frac{x^2}{2 \\sigma_x^2} -\\frac{y^2}{2 \\sigma_y^2} - \\frac{(z - \\mu_z)^2}{2 \\sigma_z^2}\\right)
+
+ The integral over the whole 3D space is equal to 1.The correlation between the standard deviations in x and y directions is equal to 0. The mean value in the
+ x and y directions are equal to 0.
+
+ :param float mean_z: Mean value in the z direction.
+ :param float stddev_x: The standard deviation in the x directions.
+ :param float stddev_y: The standard deviation in the y directions.
+ :param float stddev_z: The standard deviation in the z directions.
+ """
+
+ def __init__(self, mean_z, stddev_x, stddev_y, stddev_z):
+
+ super().__init__()
+ self._init_params()
+
+ self.stddev_x = stddev_x
+ self.stddev_y = stddev_y
+ self.stddev_z = stddev_z
+ self.mean_z = mean_z
+
+ def _init_params(self):
+ self._mean_z = 1
+ self._stddev_x = 1
+ self._stddev_y = 1
+ self._stddev_z = 1
+
+ @property
+ def stddev_x(self):
+ return self._stddev_x
+
+ @stddev_x.setter
+ def stddev_x(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev_x = value
+
+ self._cache_constants()
+
+ @property
+ def stddev_y(self):
+ return self._stddev_y
+
+ @stddev_y.setter
+ def stddev_y(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev_y = value
+
+ self._cache_constants()
+
+ @property
+ def stddev_z(self):
+ return self._stddev_z
+
+ @stddev_z.setter
+ def stddev_z(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._stddev_z = value
+
+ self._cache_constants()
+
+ @property
+ def mean_z(self):
+ return self._mean_z
+
+ @mean_z.setter
+ def mean_z(self, double value):
+ self._mean_z = value
+
+ def _cache_constants(self):
+ self._kx = -1 / (2 * self._stddev_x ** 2)
+ self._ky = -1 / (2 * self._stddev_y ** 2)
+ self._kz = -1 / (2 * self._stddev_z ** 2)
+ self._normalisation = 1 / (sqrt((2 * pi) ** 3) * self._stddev_x * self._stddev_y * self._stddev_z)
+
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+ return self._normalisation * exp(x ** 2 * self._kx +
+ y ** 2 * self._ky +
+ (z - self._mean_z) ** 2 * self._kz)
+
+
+cdef class GaussianBeamModel(Function3D):
+ """
+ A Gaussian beam function (https://en.wikipedia.org/wiki/Gaussian_beam)
+
+ .. math::
+ F(x, y, z) = \\frac{1}{2 \\pi \\sigma^2_z} exp\\left( -\\frac{x^2 + y^2}{2 \\sigma_z(z)^2 }\\right)
+
+ where the standard deviation in the z direction
+
+ .. math::
+ \\sigma_z(z) = \\sigma_0 \\sqrt{1 + \\left(\\frac{z - z_0}{z_R}\\right)^2}
+
+ is a function of position and the
+
+ .. math::
+ z_R = \\frac{\\pi \\omega_0^2 n}{\\lambda_l}
+
+ is the Rayleigh range.
+ """
+
+ def __init__(self, double wavelength, double waist_z, double stddev_waist):
+
+ # preset default values
+ self._wavelength = 1e3
+ self._waist_z = 0
+ self._stddev_waist = 1e-3
+
+ self.wavelength = wavelength
+ self.waist_z = waist_z
+ self.stddev_waist = stddev_waist
+
+ @property
+ def wavelength(self):
+ return self._wavelength
+
+ @wavelength.setter
+ def wavelength(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0, but {0} passed.".format(value))
+
+ self._wavelength = value
+ self._cache_constants()
+
+ @property
+ def waist_z(self):
+ return self._waist_z
+
+ @waist_z.setter
+ def waist_z(self, double value):
+ self._waist_z = value
+
+ @property
+ def stddev_waist(self):
+ return self._stddev_waist
+
+ @stddev_waist.setter
+ def stddev_waist(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0, but {0} passed.".format(value))
+
+ self._stddev_waist = value
+ self._stddev_waist2 = self._stddev_waist ** 2
+ self._cache_constants()
+
+ def _cache_constants(self):
+
+ n = 1 # refractive index of vacuum
+ self._rayleigh_range = 2 * pi * n * self._stddev_waist2 / self._wavelength / 1e-9
+
+ @cython.cdivision(True)
+ cdef double evaluate(self, double x, double y, double z) except? -1e999:
+
+ cdef:
+ double r2, stddev_z2, z_prime
+
+ # shift to correct gaussiam beam model coords, it works with waist at z=0
+ z_prime = z - self._waist_z
+
+ r2 = x ** 2 + y ** 2
+ stddev_z2 = self._stddev_waist2 * (1 + ((z_prime) / self._rayleigh_range) ** 2)
+
+ return 1 / (2 * pi * stddev_z2) * exp(r2 / (-2 * stddev_z2))
diff --git a/cherab/core/model/laser/model.pxd b/cherab/core/model/laser/model.pxd
new file mode 100644
index 00000000..27e0230f
--- /dev/null
+++ b/cherab/core/model/laser/model.pxd
@@ -0,0 +1,40 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.optical cimport Vector3D, Point3D
+from raysect.optical.spectrum cimport Spectrum
+
+from cherab.core.laser cimport Laser, LaserModel, LaserSpectrum, LaserProfile
+
+
+cdef class SeldenMatobaThomsonSpectrum(LaserModel):
+
+ cdef:
+ double _CONST_ALPHA, _RATE_TS, _RECIP_M_PI
+
+ cpdef Spectrum emission(self, Point3D point_plasma, Vector3D observation_plasma, Point3D point_laser,
+ Vector3D observation_laser, Spectrum spectrum)
+
+ cdef double seldenmatoba_spectral_shape(self, double epsilon, double cos_theta, double alpha)
+
+ cdef Spectrum _add_spectral_contribution(self, double ne, double te, double laser_energy, double angle_pointing,
+ double angle_polarization, double laser_wavelength, Spectrum spectrum)
+
+ cpdef Spectrum calculate_spectrum(self, double ne, double te, double laser_energy_density, double laser_wavelength,
+ double observation_angle, double angle_polarization, Spectrum spectrum)
\ No newline at end of file
diff --git a/cherab/core/model/laser/model.pyx b/cherab/core/model/laser/model.pyx
new file mode 100644
index 00000000..dbab8803
--- /dev/null
+++ b/cherab/core/model/laser/model.pyx
@@ -0,0 +1,220 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from libc.math cimport exp, sqrt, cos, M_PI, sin
+cimport cython
+
+from raysect.optical cimport Vector3D, Point3D
+from raysect.optical.spectrum cimport Spectrum
+
+from cherab.core cimport Plasma
+from cherab.core.laser cimport LaserModel, LaserProfile, LaserSpectrum
+from cherab.core.utility.constants cimport DEGREES_TO_RADIANS
+from cherab.core.utility.constants cimport SPEED_OF_LIGHT, ELECTRON_CLASSICAL_RADIUS, ELECTRON_REST_MASS, ELEMENTARY_CHARGE
+
+
+cdef class SeldenMatobaThomsonSpectrum(LaserModel):
+ """
+ Thomson Scattering based on Selden-Matoba.
+
+ The class calculates Thomson scattering of the laser to the spectrum. The model of the scattered spectrum used is based on
+ the semi-empirical model by Selden and the Thomson scattering cross-section is taken from Matoba articles. The spectral contribution
+ of the scattered laser light c is calculated as a sum of contributions of all laser wavelengths
+
+ .. math::
+ c(\lambda) = c r_e^2 n_e cos^2\\theta \\sum_{\\lambda_L} \\frac{E_L(\\lambda_l) S(\\frac{\\lambda}{\\lambda_L} - 1, \\varphi, T_e)}{\\lambda_L},
+
+
+ where :math:`\\lambda` is the spectrum's wavelength, :math:`r_e` is the classical electron radius, :math:`n_e` is the electron delsity,
+ :math:`\\theta` is the angle between the laser polarisation and scattering vectors, :math:`c` is the vacuum speed of light
+ :math:`\\lambda_L` is the laser wavelength, :math:`E_L` is the laser energy density, :math:`\\varphi` is the scattering angle and :math:`T_e` is the electron
+ temperature. The scattering function S is taken from the Matoba article. The multiplication by the speed of light is added to transfer the Thomson scattering
+ cross section into a reaction rate.
+
+ .. seealso::
+ The Prunty article provides a thorough introduction into the phyiscs of Thomson scattering. The articles by Selden and Matoba were used to build
+ this model.
+
+ :Selden: `Selden, A.C., 1980. Simple analytic form of the relativistic Thomson scattering spectrum. Physics Letters A, 79(5-6), pp.405-406.`
+ :Matoba: `Matoba, T., et al., 1979. Analytical approximations in the theory of relativistic Thomson scattering for high temperature fusion plasma.
+ Japanese Journal of Applied Physics, 18(6), p.1127.`
+ :Prunty: `Prunty, S.L., 2014. A primer on the theory of Thomson scattering for high-temperature fusion plasmas. Physica Scripta, 89(12), p.128001.`
+
+ """
+
+ def __init__(self, LaserProfile laser_profile=None, LaserSpectrum laser_spectrum=None, Plasma plasma=None):
+
+ super().__init__(laser_profile, laser_spectrum, plasma)
+
+ # Selden, A.C., 1980. Simple analytic form of the relativistic Thomson scattering spectrum. Physics Letters A, 79(5-6), pp.405-406.
+ self._CONST_ALPHA = ELECTRON_REST_MASS * SPEED_OF_LIGHT ** 2 / (2 * ELEMENTARY_CHARGE) #constant alpha, rewritten for Te in eV
+
+ # from: Prunty, S. L. "A primer on the theory of Thomson scattering for high-temperature fusion plasmas."
+ # TS cross section equiation ~ 3.28 or
+ # Matoba, T., et al., 1979. Analytical approximations in the theory of relativistic Thomson scattering for high temperature fusion plasma.
+ # Japanese Journal of Applied Physics, 18(6), p.1127., TS cross section equiation 18
+ # speed of light for correct normalisation of the scattered intensity calculation (from x-section to rate constant)
+ self._RATE_TS = ELECTRON_CLASSICAL_RADIUS ** 2 * SPEED_OF_LIGHT
+
+ self._RECIP_M_PI = 1 / M_PI
+
+ @cython.cdivision(True)
+ cdef double seldenmatoba_spectral_shape(self, double epsilon, double const_theta, double alpha):
+
+ cdef:
+ double c, a, b
+
+ # const_theta is 2 * (1 - cos(theta))
+
+ c = sqrt(alpha * self._RECIP_M_PI) * (1 - 15. / (16. * alpha) + 345. / (512. * alpha ** 2))
+ a = (1 + epsilon) ** 3 * sqrt(const_theta * (1 + epsilon) + epsilon ** 2)
+ b = sqrt(1 + epsilon ** 2 / (const_theta * (1 + epsilon))) - 1
+
+ return c / a * exp(-2 * alpha * b)
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ cpdef Spectrum emission(self, Point3D point_plasma, Vector3D observation_plasma, Point3D point_laser,
+ Vector3D observation_laser, Spectrum spectrum):
+ cdef:
+ double angle_scattering, angle_pointing, angle_polarization
+ double te, ne, laser_energy_density, laser_energy
+ double plasma_x, plasma_y, plasma_z, laser_x, laser_y, laser_z
+ double[::1] laser_wavelength_mv, laser_spectrum_power_mv
+ int bins
+ Vector3D pointing_vector, polarisation_vector
+ Py_ssize_t index
+
+ plasma_x = point_plasma.x
+ plasma_y = point_plasma.y
+ plasma_z = point_plasma.z
+
+ # get electron parameters for the plasma point
+ te = self._plasma.get_electron_distribution().effective_temperature(plasma_x, plasma_y, plasma_z)
+
+ #terminate early if electron temperature is 0
+ if te <= 0:
+ return spectrum
+
+ ne = self._plasma.get_electron_distribution().density(plasma_x, plasma_y, plasma_z)
+
+ #terminate early if electron density is 0
+ if ne <= 0:
+ return spectrum
+
+ laser_x = point_laser.x
+ laser_y = point_laser.y
+ laser_z = point_laser.z
+
+ #get laser volumetric power
+ laser_energy_density = self._laser_profile.get_energy_density(laser_x, laser_y, laser_z)
+
+ #terminate early if laser power is 0
+ if laser_energy_density == 0:
+ return spectrum
+
+ pointing_vector = self._laser_profile.get_pointing(laser_x, laser_y, laser_z)
+
+ #angle between observation and pointing vector
+ angle_pointing = observation_laser.angle(pointing_vector) # angle between observation and pointing vector of laser
+
+ angle_scattering = (180. - angle_pointing) # scattering direction is the opposite to obervation direction
+
+ # angle between polarisation and observation
+ polarisation_vector = self._laser_profile.get_polarization(laser_x, laser_y, laser_z)
+ angle_polarization = observation_laser.angle(polarisation_vector) # scattering direction is the opposite to obervation direction
+
+ laser_wavelength_mv = self._laser_spectrum.wavelengths_mv
+ laser_spectrum_power_mv = self._laser_spectrum.power_mv # power in spectral bins (PSD * delta wavelength)
+ bins = self._laser_spectrum.get_spectral_bins()
+
+ for index in range(bins):
+ laser_energy = laser_spectrum_power_mv[index] * laser_energy_density
+ if laser_energy > 0:
+ spectrum = self._add_spectral_contribution(ne, te, laser_energy, angle_scattering,
+ angle_polarization, laser_wavelength_mv[index], spectrum)
+
+ return spectrum
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ @cython.cdivision(True)
+ cdef Spectrum _add_spectral_contribution(self, double ne, double te, double laser_energy, double angle_scattering,
+ double angle_polarization, double laser_wavelength, Spectrum spectrum):
+
+ cdef:
+ int index, nbins
+ double alpha, epsilon, cos_anglescat, wavelength, min_wavelength, delta_wavelength
+ double const_theta, recip_laser_wavelength, scattered_power, spectrum_norm
+ double sin2_angle_pol
+
+ alpha = self._CONST_ALPHA / te
+ # scattering angle of the photon = pi - observation_angle
+ cos_anglescat = cos(angle_scattering * DEGREES_TO_RADIANS)
+
+ # pre-calculate constants for Selden-Matoba shape
+ const_theta = 2 * (1 - cos_anglescat)
+
+ nbins = spectrum.bins
+ min_wavelength = spectrum.min_wavelength
+ delta_wavelength = spectrum.delta_wavelength
+ recip_laser_wavelength = 1 / laser_wavelength
+
+ # dipole radiation has a cos ** 2 characteristic, here angle shifted by 90 deg
+ sin2_angle_pol = sin(angle_polarization * DEGREES_TO_RADIANS) ** 2
+
+ #from d_lambda to d_epsilon:d_epsilon = d_lambda / laser_wavelength
+ scattered_power = ne * self._RATE_TS * laser_energy * recip_laser_wavelength * sin2_angle_pol
+ for index in range(nbins):
+ wavelength = min_wavelength + (0.5 + index) * delta_wavelength
+ epsilon = (wavelength * recip_laser_wavelength) - 1
+ spectrum_norm = self.seldenmatoba_spectral_shape(epsilon, const_theta, alpha)
+ spectrum.samples_mv[index] += spectrum_norm * scattered_power
+
+ return spectrum
+
+ cpdef Spectrum calculate_spectrum(self, double ne, double te, double laser_energy_density, double laser_wavelength,
+ double observation_angle, double angle_polarization, Spectrum spectrum):
+ """
+ Calculates scattered spectrum for the given parameters.
+
+ The method returns the Thomson scattered spectrum given the plasma parameters, without the need of specifying
+ plasma or laser.
+
+ :param float ne: Plasma electron density in m**-3
+ :param float te: Plasma electron temperature in eV
+ :param float laser_energy_density: Energy density of the laser light in J * m**-3
+ :param float laser_wavelength: The laser light wavelength in nm
+ :param float observation_angle: The angle of observation is the angle between the observation direction and the direction
+ of the Poynting vector.
+ :param float angle_polarization: The angle between the observation direction and the polarisation direction of the laser light.
+
+ :return: Spectrum
+ """
+ # check for nonzero laser power, ne, te, wavelength
+ if ne <= 0 or te <= 0 or not laser_energy_density > 0:
+ return spectrum
+ if laser_wavelength <= 0:
+ raise ValueError("laser wavelength has to be larger than 0")
+
+ angle_scattering = (180. - observation_angle) # scattering direction is the opposite to obervation direction
+
+ return self._add_spectral_contribution(ne, te, laser_energy_density, angle_scattering, angle_polarization, laser_wavelength, spectrum)
+
+
\ No newline at end of file
diff --git a/cherab/core/model/laser/profile.pxd b/cherab/core/model/laser/profile.pxd
new file mode 100644
index 00000000..12379335
--- /dev/null
+++ b/cherab/core/model/laser/profile.pxd
@@ -0,0 +1,57 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+from raysect.core.math.function.float cimport Function3D
+from raysect.optical cimport Spectrum, Point3D, Vector3D
+
+from cherab.core.laser cimport LaserProfile
+
+
+cdef class UniformEnergyDensity(LaserProfile):
+
+ cdef:
+ double _energy_density, _laser_length, _laser_radius
+
+
+cdef class ConstantAxisymmetricGaussian(LaserProfile):
+
+ cdef:
+ double _stddev, _pulse_energy, _pulse_length, _laser_length, _laser_radius
+ Function3D _distribution
+
+
+cdef class ConstantBivariateGaussian(LaserProfile):
+
+ cdef:
+ double _stddev_x, _stddev_y, _pulse_energy, _pulse_length, _laser_length, _laser_radius
+ Function3D _distribution
+
+
+cdef class TrivariateGaussian(LaserProfile):
+
+ cdef:
+ double _stddev_x, _stddev_y, _stddev_z, _mean_z, _pulse_energy, _pulse_length, _laser_length, _laser_radius
+ Function3D _distribution
+
+
+cdef class GaussianBeamAxisymmetric(LaserProfile):
+
+ cdef:
+ double _pulse_energy, _pulse_length, _stddev_waist, _waist_z, _laser_wavelength, _laser_length, _laser_radius
+ Function3D _distribution
diff --git a/cherab/core/model/laser/profile.pyx b/cherab/core/model/laser/profile.pyx
new file mode 100644
index 00000000..82376980
--- /dev/null
+++ b/cherab/core/model/laser/profile.pyx
@@ -0,0 +1,765 @@
+from raysect.core.math.function.float import Constant3D
+from raysect.core.math.function.vector3d cimport Constant3D as ConstantVector3D
+from raysect.primitive import Cylinder
+from raysect.optical cimport Spectrum, Vector3D, translate
+
+from cherab.core.laser cimport Laser, LaserProfile
+from cherab.core.model.laser.math_functions cimport ConstantAxisymmetricGaussian3D, ConstantBivariateGaussian3D, TrivariateGaussian3D, GaussianBeamModel
+
+from cherab.core.utility.constants cimport SPEED_OF_LIGHT
+
+from libc.math cimport M_PI, sqrt, exp
+
+
+cdef class UniformEnergyDensity(LaserProfile):
+ """
+ LaserProfile with a constant volumetric energy density.
+
+ Returns a laser with a cylindrical shape within which the laser volumentric energy density is constant.
+ The laser starts at z=0 and extends in the positive z direction.
+
+ .. note:
+ The methods get_pointing, get_polarization and get_energy_density are not limited to the inside
+ of the laser cylinder. If called alone for position (x, y, z) outisde the laser cylinder,
+ they will still return non-zero values.
+
+ In the following example, a laser of length of 2 m (extending from z=0 to z=2 m) with a radius of 3 cm
+ and volumetric energy density of 5 J*m^-3 and polarisation in the y direction is created:
+
+ .. code-block:: pycon
+
+ >>> from raysect.core import Vector3D
+ >>> from cherab.core.model.laser import UniformEnergyDensity
+
+ >>> energy = 5 # energy density in J
+ >>> radius = 3e-2 # laser radius in m
+ >>> length = 2 # laser length in m
+ >>> polarisation = Vector3D(0, 1, 0) # polarisation direction
+
+ # create the laser profile
+ >>> laser_profile = UniformEnergyDensity(energy, radius, length, polarisation)
+
+ :param float energy_density: The volumetric energy density of the laser light.
+ :param float laser_length: The length of the laser cylinder.
+ :param float laser_radius: The radius of the laser cylinder.
+ :param Vector3D polarization: The direction of the laser polarization:
+
+ :ivar float energy_density: The volumetric energy density of the laser light.
+ :ivar float laser_radius: The radius of the laser cylinder.
+ :ivar float laser_length: The length of the laser cylinder.
+ """
+
+ def __init__(self, double energy_density=1., double laser_length=1., double laser_radius=0.05, Vector3D polarization=Vector3D(0, 1, 0)):
+ super().__init__()
+
+ self.set_polarization(polarization)
+ self.set_pointing_function(ConstantVector3D(Vector3D(0, 0, 1)))
+ self.energy_density = energy_density
+
+ self._laser_radius = 0.05
+ self._laser_length = 1.
+
+ self.laser_radius = laser_radius
+ self.laser_length = laser_length
+
+ def set_polarization(self, Vector3D value):
+ value = value.normalise()
+ self.set_polarization_function(ConstantVector3D(value))
+
+ @property
+ def laser_length(self):
+ return self._laser_length
+
+ @laser_length.setter
+ def laser_length(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser length has to be larger than 0.")
+
+ self._laser_length = value
+ self.notifier.notify()
+
+ @property
+ def laser_radius(self):
+ return self._laser_radius
+
+ @laser_radius.setter
+ def laser_radius(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser radius has to be larger than 0.")
+
+ self._laser_radius = value
+ self.notifier.notify()
+
+ @property
+ def energy_density(self):
+ return self._energy_density
+
+ @energy_density.setter
+ def energy_density(self, value):
+ if value <= 0:
+ raise ValueError("Laser power density has to be larger than 0.")
+
+ self._energy_density = value
+ funct = Constant3D(value)
+ self.set_energy_density_function(funct)
+
+ cpdef list generate_geometry(self):
+
+ return generate_segmented_cylinder(self.laser_radius, self.laser_length)
+
+
+cdef class ConstantBivariateGaussian(LaserProfile):
+ """
+ LaserProfile with a Gaussian-shaped volumetric energy density distribution in the xy plane
+ and constant pulse intensity.
+
+ Returns a laser with a cylindrical shape and the propagation of the laser light in the positive z direction.
+
+ The model imitates a laser beam with a uniform power output within a single pulse. This results
+ in the distribution of the energy density along the propagation direction of the laser (z-axis) to be also
+ uniform. The integral value of laser energy Exy in an x-y plane is given by
+
+ .. math::
+ E_{xy} = \\frac{E_p}{(c * \\tau)},
+
+ where Ep is the energy of the laser pulse, tau is the temporal pulse length and c is the speed of light in vacuum.
+ In an x-y plane, the volumetric energy density follows a bivariate Gaussian with a zero correlation:
+
+ .. math::
+ E(x, y) = \\frac{E_{xy}}{2 \\pi \\sigma_x \\sigma_y} exp\\left(-\\frac{x^2 + y^2}{2 \\sigma_x \\sigma_y}\\right).
+
+ The sigma_x and sigma_y are standard deviations in x and y directions, respectively.
+
+ .. note::
+ The height of the cylinder, forming the laser beam, is given by the laser_length and is independent from the
+ temporal length of the laser pulse given by pulse_length. This gives the possibility to independently control
+ the size of the laser primitive and the value of the volumetric energy density.
+
+ The methods get_pointing, get_polarization and get_energy_density are not limited to the inside
+ of the laser cylinder. If called for position (x, y, z) outisde the laser cylinder, they can still
+ return non-zero values.
+
+
+ The following example shows how to create a laser with sigma_x= 1 cm and sigma_y=2 cm, which makes the laser
+ profile in x-y plane to be elliptical. The pulse energy is 5 J and the laser temporal pulse length is 10 ns:
+
+ .. code-block:: pycon
+
+ >>> from raysect.core import Vector3D
+ >>> from cherab.core.model.laser import ConstantBivariateGaussian
+
+ >>> radius = 3e-2 # laser radius in m
+ >>> length = 2 # laser length in m
+ >>> polarisation = Vector3D(0, 1, 0) # polarisation direction
+ >>> pulse_energy = 5 # energy in a laser pulse in J
+ >>> pulse_length = 1e-8 # pulse length in s
+ >>> width_x = 1e-2 # standard deviation in x direction in m
+ >>> width_y = 2e-2 # standard deviation in y direction in m
+
+ # create the laser profile
+ >>> laser_profile = ConstantBivariateGaussian(pulse_energy, pulse_length, radius, length, width_x, width_y, polarisation)
+
+ :param float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :param float pulse_length: The temporal length of the laser pulse in seconds.
+ :param float laser_length: The length of the laser cylinder.
+ :param float laser_radius: The radius of the laser cylinder.
+ :param float stddev_x: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the x axis in meters.
+ :param float stddev_y: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the y axis in meters.
+ :param Vector3D polarization: The direction of the laser polarization:
+
+ :ivar float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :ivar float pulse_length: The temporal length of the laser pulse in seconds.
+ :ivar float laser_radius: The radius of the laser cylinder.
+ :ivar float laser_length: The length of the laser cylinder.
+ :ivar float stddev_x: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the x axis in meters.
+ :ivar float stddev_y: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the y axis in meters.
+ """
+ def __init__(self, double pulse_energy=1, double pulse_length=1, double laser_radius=0.05, double laser_length=1.,
+ double stddev_x=0.01, double stddev_y=0.01, Vector3D polarization=Vector3D(0, 1, 0)):
+
+ super().__init__()
+ # set initial values
+ self._pulse_energy = 1
+ self._pulse_length = 1
+ self._stddev_x = 0.1
+ self._stddev_y = 0.1
+
+ self._laser_radius = 0.05
+ self._laser_length = 1
+
+ self.laser_radius = laser_radius
+ self.laser_length = laser_length
+
+ self.set_polarization(polarization)
+ self.set_pointing_function(ConstantVector3D(Vector3D(0, 0, 1)))
+
+ self.stddev_x = stddev_x
+ self.stddev_y = stddev_y
+
+ self.pulse_energy = pulse_energy
+ self.pulse_length = pulse_length
+
+ # set laser constants
+ self.set_polarization(polarization)
+
+ def set_polarization(self, Vector3D value):
+ value = value.normalise()
+ self.set_polarization_function(ConstantVector3D(value))
+
+ @property
+ def laser_length(self):
+ return self._laser_length
+
+ @laser_length.setter
+ def laser_length(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser length has to be larger than 0.")
+
+ self._laser_length = value
+ self.notifier.notify()
+
+ @property
+ def laser_radius(self):
+ return self._laser_radius
+
+ @laser_radius.setter
+ def laser_radius(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser radius has to be larger than 0.")
+
+ self._laser_radius = value
+ self.notifier.notify()
+
+ @property
+ def pulse_energy(self):
+ return self._pulse_energy
+
+ @pulse_energy.setter
+ def pulse_energy(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_energy = value
+ self.notifier.notify()
+
+ @property
+ def pulse_length(self):
+ return self._pulse_length
+
+ @pulse_length.setter
+ def pulse_length(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_length = value
+ self._function_changed()
+
+ @property
+ def stddev_x(self):
+ return self._stddev_x
+
+ @stddev_x.setter
+ def stddev_x(self, value):
+ if value <= 0:
+ raise ValueError("Standard deviation of the laser power has to be larger than 0.")
+
+ self._stddev_x = value
+ self._function_changed()
+
+ @property
+ def stddev_y(self):
+ return self._stddev_y
+
+ @stddev_y.setter
+ def stddev_y(self, value):
+ if value <= 0:
+ raise ValueError("Standard deviation of the laser power has to be larger than 0.")
+
+ self._stddev_y = value
+ self._function_changed()
+
+ def _function_changed(self):
+ """
+ Energy density should be returned in units [J/m ** 3]. Energy shape in xy
+ plane is defined by normal distribution (integral over xy plane for
+ constant z is 1). The units of such distribution are [m ** -2].
+ In the z axis direction (direction of laser propagation),
+ the laser_energy is spread along the z axis using the velocity
+ of light SPEED_OF_LIGHT and the temporal duration of the pulse:
+ length = SPEED_OF_LIGTH * pulse_length. Combining the normal distribution with the normalisation
+ pulse_energy / length gives the units [J / m ** 3].
+ """
+ self._distribution = ConstantBivariateGaussian3D(self._stddev_x, self._stddev_y)
+
+ length = SPEED_OF_LIGHT * self._pulse_length # convert from temporal to spatial length of pulse
+ normalisation = self._pulse_energy / length # normalisation to have correct spatial energy density [J / m**3]
+
+ function = normalisation * self._distribution
+ self.set_energy_density_function(function)
+
+ cpdef list generate_geometry(self):
+
+ return generate_segmented_cylinder(self.laser_radius, self.laser_length)
+
+
+cdef class TrivariateGaussian(LaserProfile):
+ """
+ LaserProfile with a trivariate Gaussian-shaped volumetric energy density.
+
+ Returns a laser with a cylindrical shape and the propagation of the laser light in the positive z direction.
+ This model imitates a laser beam with a Gaussian distribution of power output within a single pulse frozen in time:
+
+ .. math::
+ E(x, y, z) = \\frac{E_p}{\\sqrt{2 \\pi^3} \\sigma_x \\sigma_y \\sigma_z} exp\\left(-\\frac{x^2}{2 \\sigma_x^2} -\\frac{y^2}{2 \\sigma_y^2} -\\frac{(z - \\mu_z)^2}{2 \\sigma_z^2}\\right).
+
+
+ The sigma_x and sigma_y are standard deviations in x and y directions, respectively, and E_p is the energy deliverd by laser in a
+ single laser pulse. The mu_z is the mean of the distribution in the z direction and controls th position of the laser pulse along the z direction.
+ The standard deviation in z direction sigma_z is calculated from the pulse length tau_p, which is the
+ standard deviation of the Gaussian distributed ouput power of the laser within a single pulse:
+
+ .. math::
+ \\sigma_z = \\tau_p c.
+
+ The c stands for the speed of light in vacuum.
+
+ .. note::
+ The height of the cylinder, forming the laser beam, is given by the laser_length and is independent from the
+ temporal length of the laser pulse given by pulse_length. This gives the possibility to independently control
+ the size of the laser primitive and the value of the volumetric energy density.
+
+ The methods get_pointing, get_polarization and get_energy_density are not limited to the inside
+ of the laser cylinder. If called alone for position (x, y, z) outisde the laser cylinder, they can still
+ return non-zero values.
+
+
+ The following example shows how to create a laser with sigma_x = 1 cm and sigma_y = 2 cm, which makes the laser
+ profile in an x-y plane to be elliptical. The pulse energy is 5 J and the laser temporal pulse length is 10 ns.
+ The position of the laser pulse maximum mean_z is set to 0.5:
+
+ .. code-block:: pycon
+
+ >>> from raysect.core import Vector3D
+ >>> from cherab.core.model.laser import ConstantBivariateGaussian
+
+ >>> radius = 3e-2 # laser radius in m
+ >>> length = 2 # laser length in m
+ >>> polarisation = Vector3D(0, 1, 0) # polarisation direction
+ >>> pulse_energy = 5 # energy in a laser pulse in J
+ >>> pulse_length = 1e-8 # pulse length in s
+ >>> pulse_z = 0.5 # position of the pulse mean
+ >>> width_x = 1e-2 # standard deviation in x direction in m
+ >>> width_y = 2e-2 # standard deviation in y direction in m
+
+ # create the laser profile
+ >>> laser_profile = ConstantBivariateGaussian(pulse_energy, pulse_length, pulse_z, radius, length, width_x, width_y, polarisation)
+
+
+ :param float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :param float pulse_length: The standard deviation of the laser pulse length in the temporal domain.
+ :param float mean_z: Position of the mean value of the laser pulse in the z direction. Can be used to control the
+ position of the laser pulse along the laser propagation.
+ :param float laser_length: The length of the laser cylinder.
+ :param float laser_radius: The radius of the laser cylinder.
+ :param float stddev_x: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the x axis in meters.
+ :param float stddev_y: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the y axis in meters.
+ :param Vector3D polarization: The direction of the laser polarization.
+
+ :ivar float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :ivar float pulse_length: The standard deviation of the laser pulse length in the temporal domain.
+ :ivar float mean_z: Position of the mean value of the laser pulse in the z direction.
+ Can be used to control the position of the laser pulse along the laser propagation.
+ :ivar float laser_radius: The radius of the laser cylinder.
+ :ivar float laser_length: The length of the laser cylinder.
+ :ivar float stddev_x: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the x axis in meters.
+ :ivar float stddev_y: The standard deviation of the bivariate Gaussian distribution of the volumetric energy
+ density distribution of the laser light in the y axis in meters.
+ """
+ def __init__(self, double pulse_energy=1, double pulse_length=1, double mean_z=0,
+ double laser_length=1., double laser_radius=0.05,
+ double stddev_x=0.01, double stddev_y=0.01,
+ Vector3D polarization=Vector3D(0, 1, 0)):
+
+ super().__init__()
+ # set initial values
+ self._pulse_energy = 1
+ self._pulse_length = 1
+ self._stddev_x = 0.1
+ self._stddev_y = 0.1
+ self._stddev_z = 1
+ self._laser_radius = 0.05
+ self._laser_length = 1
+ self._mean_z = mean_z
+
+
+ self.laser_radius = laser_radius
+ self.laser_length = laser_length
+ self.stddev_x = stddev_x
+ self.stddev_y = stddev_y
+ self.mean_z = mean_z
+
+ self.pulse_energy = pulse_energy
+ self.pulse_length = pulse_length
+
+ self.set_polarization(polarization)
+ self.set_pointing_function(ConstantVector3D(Vector3D(0, 0, 1)))
+
+ def set_polarization(self, Vector3D value):
+ value = value.normalise()
+ self.set_polarization_function(ConstantVector3D(value))
+
+ @property
+ def laser_length(self):
+ return self._laser_length
+
+ @laser_length.setter
+ def laser_length(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser length has to be larger than 0.")
+
+ self._laser_length = value
+ self.notifier.notify()
+
+ @property
+ def laser_radius(self):
+ return self._laser_radius
+
+ @laser_radius.setter
+ def laser_radius(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser radius has to be larger than 0.")
+
+ self._laser_radius = value
+ self.notifier.notify()
+
+ @property
+ def pulse_energy(self):
+ return self._pulse_energy
+
+ @pulse_energy.setter
+ def pulse_energy(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_energy = value
+ self._function_changed()
+
+ @property
+ def pulse_length(self):
+ return self._pulse_length
+
+ @pulse_length.setter
+ def pulse_length(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_length = value
+ self._stddev_z = self._pulse_length * SPEED_OF_LIGHT
+ self._function_changed()
+
+ @property
+ def stddev_x(self):
+ return self._stddev_x
+
+ @stddev_x.setter
+ def stddev_x(self, value):
+ if value <= 0:
+ raise ValueError("Standard deviation of the laser power has to be larger than 0.")
+
+ self._stddev_x = value
+ self._function_changed()
+
+ @property
+ def stddev_y(self):
+ return self._stddev_y
+
+ @stddev_y.setter
+ def stddev_y(self, value):
+ if value <= 0:
+ raise ValueError("Standard deviation of the laser power has to be larger than 0.")
+
+ self._stddev_y = value
+ self._function_changed()
+
+ @property
+ def mean_z(self):
+ return self._mean_z
+
+ @mean_z.setter
+ def mean_z(self, double value):
+ self._mean_z = value
+ self._function_changed()
+
+ def _function_changed(self):
+ """
+ Energy density should be returned in units [J/m ** 3]. The integral value of the _distribution
+ is 1, thus multiplying _distribution by _pulse_energy gives correct values.
+ """
+
+ self._distribution = TrivariateGaussian3D(self._mean_z, self._stddev_x, self._stddev_y,
+ self._stddev_z)
+
+ normalisation = self._pulse_energy
+
+ function = normalisation * self._distribution
+ self.set_energy_density_function(function)
+
+ cpdef list generate_geometry(self):
+
+ return generate_segmented_cylinder(self.laser_radius, self.laser_length)
+
+cdef class GaussianBeamAxisymmetric(LaserProfile):
+ """
+ LaserProfile with volumetric energy density following the Gaussian beam model.
+
+ Returns a laser with a cylindrical shape and the propagation of the laser light in the positive z direction. This model implements
+ the axisymmetrical Gaussian beam model. It immitates a focused axis symmetrical laser beam with a uniform power ouput in a laser pulse.
+ The volumetric energy density is given by
+
+ .. math::
+ E(x, y, z) = \\frac{E_{xy}}{2 \\pi \\sigma^2(z)} exp\\left( -\\frac{x^2 + y^2}{2 \\sigma^2(z) }\\right) \\\\
+
+ where the sigma is the standard deviation of the Gaussian shape in the xy plane and is given by
+
+ .. math::
+ sigma(z) = \\sigma_0 \\sqrt{1 + \\left(\\frac{z - z_0}{z_R}\\right)^2}.
+
+ The z_0 is the position of the beam focus and z_R is the Rayleigh length
+
+ .. math::
+ z_R = \\frac{\\pi \\omega_0^2 n}{\\lambda_l}
+
+ where the omega_0 is the standard deviation in the xy plane in the focal point (beam waist) and lambda_l is the central wavelength of
+ the laser. The E_xy stand for the laser energy in an xy plane and is calculated as:
+
+ .. math::
+ E_{xy} = \\frac{E_p}{(c * \\tau)},
+
+ where the E_p is the energy in a single laser pulse and tau is the temporal pulse length.
+
+ .. note::
+ For more information about the Gaussian beam model see https://en.wikipedia.org/wiki/Gaussian_beam
+
+ The methods get_pointing, get_polarization and get_energy_density are not limited to the inside
+ of the laser cylinder. If called alone for position (x, y, z) outisde the laser cylinder, they can still
+ return non-zero values.
+
+ The following example shows how to create a laser with pulse energy 5J, pulse length 10 ns and with the laser cylinder primitive
+ being 2m long with 5 cm in diameter. The the standard deviation of the beam in the focal point (waist) is 5mm and the position of the
+ waist is z=50 cm. The laser wavelength is 1060 nm.
+
+ .. code-block:: pycon
+
+ >>> from raysect.core import Vector3D
+ >>> from cherab.core.model.laser import GaussianBeamAxisymmetric
+
+ >>> radius = 5e-2 # laser radius in m
+ >>> length = 2 # laser length in m
+ >>> polarisation = Vector3D(0, 1, 0) # polarisation direction
+ >>> pulse_energy = 5 # energy in a laser pulse in J
+ >>> pulse_length = 1e-8 # pulse length in s
+ >>> waist_width = 5e-3 # standard deviation in the waist
+ >>> waist_z = 0.5 # position of the pulse mean
+ >>> width_x = 1e-2 # standard deviation in x direction in m
+ >>> width_y = 2e-2 # standard deviation in y direction in m
+ >>> laser_wlen = 1060 # laser wavelength in nm
+
+ # create the laser profile
+ >>> laser_profile = GaussianBeamAxisymmetric(pulse_energy, pulse_length, length, radius, waist_z, waist_width, laser_wlen)
+
+ :param float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :param float pulse_length: The temporal length of the laser pulse in seconds.
+ :param float laser_length: The length of the laser cylinder in meters.
+ :param float laser_radius: The radius of the laser cylinder in meters.
+ :param float waist_z: Position of the laser waist along the z axis in m.
+ :param float stddev_waist: The standard deviation of the laser width in the focal point (waist) in m.
+ :param float laser_wavelength: The central wavelength of the laser light in nanometers.
+ :param Vector3D polarization: The direction of the laser polarization.
+
+ :ivar float pulse_energy: The energy of the laser in Joules delivered in a single laser pulse.
+ :ivar float pulse_length: The temporal length of the laser pulse in seconds.
+ :ivar float laser_length: The length of the laser cylinder in meters.
+ :ivar float laser_radius: The radius of the laser cylinder in meters.
+ :ivar float waist_z: Position of the laser waist along the z axis in m.
+ :ivar float stddev_waist: The standard deviation of the laser width in the focal point (waist) in m.
+ :ivar float laser_wavelength: The central wavelength of the laser light in nanometers.
+ :ivar Vector3D polarization: The direction of the laser polarization.
+ """
+
+ def __init__(self, double pulse_energy=1, double pulse_length=1,
+ double laser_length=1., double laser_radius=0.05,
+ double waist_z=0, double stddev_waist=0.01,
+ double laser_wavelength=1e3, Vector3D polarization=Vector3D(0, 1, 0)):
+
+ super().__init__()
+ # set initial values
+ self._pulse_energy = 1
+ self._pulse_length = 1
+ self._stddev_waist = 0.1
+ self._waist_z = waist_z
+ self._laser_wavelength = 1e3
+ self._laser_radius = 0.05
+ self._laser_length = 1
+
+ self.laser_length = laser_length
+ self.laser_radius = laser_radius
+
+ self.set_polarization(polarization)
+ self.set_pointing_function(ConstantVector3D(Vector3D(0, 0, 1)))
+
+ self.stddev_waist = stddev_waist
+ self.waist_z = waist_z
+
+ self.pulse_energy = pulse_energy
+ self.pulse_length = pulse_length
+ self.laser_wavelength = laser_wavelength
+
+ def set_polarization(self, Vector3D value):
+ value = value.normalise()
+ self.set_polarization_function(ConstantVector3D(value))
+
+ @property
+ def laser_length(self):
+ return self._laser_length
+
+ @laser_length.setter
+ def laser_length(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser length has to be larger than 0.")
+
+ self._laser_length = value
+ self.notifier.notify()
+
+ @property
+ def laser_radius(self):
+ return self._laser_radius
+
+ @laser_radius.setter
+ def laser_radius(self, value):
+
+ if value <= 0:
+ raise ValueError("Laser radius has to be larger than 0.")
+
+ self._laser_radius = value
+ self.notifier.notify()
+
+ @property
+ def pulse_energy(self):
+ return self._pulse_energy
+
+ @pulse_energy.setter
+ def pulse_energy(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_energy = value
+ self._function_changed()
+
+ @property
+ def pulse_length(self):
+ return self._pulse_length
+
+ @pulse_length.setter
+ def pulse_length(self, double value):
+ if value <= 0:
+ raise ValueError("Value has to be larger than 0.")
+
+ self._pulse_length = value
+ self._function_changed()
+
+ @property
+ def waist_z(self):
+ return self._waist_z
+
+ @waist_z.setter
+ def waist_z(self, double value):
+ self._waist_z = value
+ self._function_changed()
+
+ @property
+ def stddev_waist(self):
+ return self._stddev_waist
+
+ @stddev_waist.setter
+ def stddev_waist(self, double value):
+ self._stddev_waist = value
+ self._function_changed()
+
+ @property
+ def laser_wavelength(self):
+ return self._laser_wavelength
+
+ @laser_wavelength.setter
+ def laser_wavelength(self, double value):
+ self._laser_wavelength = value
+ self._function_changed()
+
+ def _function_changed(self):
+ """
+ Energy density should be returned in units [J/m ** 3]. Energy shape in xy
+ plane is defined by normal distribution (integral over xy plane for
+ constant z is 1). The units of such distribution are [m ** -2].
+ In the z axis direction (direction of laser propagation),
+ the laser_energy is spread along the z axis using the velocity
+ of light SPEED_OF_LIGHT and the temporal duration of the pulse:
+ length = SPEED_OF_LIGTH * pulse_length. Combining the normal distribution with the normalisation
+ pulse_energy / length gives the units [J / m ** 3].
+ """
+
+ self._distribution = GaussianBeamModel(self._laser_wavelength, self._waist_z, self._stddev_waist)
+ # calculate volumetric power dentiy
+ length = SPEED_OF_LIGHT * self._pulse_length # convert from temporal to spatial length of pulse
+ normalisation = self._pulse_energy / length # normalisation to have correct spatial energy density [J / m**3]
+
+ function = normalisation * self._distribution
+ self.set_energy_density_function(function)
+
+ cpdef list generate_geometry(self):
+
+ return generate_segmented_cylinder(self.laser_radius, self.laser_length)
+
+
+def generate_segmented_cylinder(radius, length):
+ """
+ Generates a segmented cylindrical laser geometry
+
+ Approximates a long cylinder with a cylindrical segments to optimize
+ targetted and importance sampling. The height of a cylinder segments is roughly
+ 2 * cylinder radius.
+
+ :return: List of cylinders
+ """
+
+ n_segments = int(length // (2 * radius)) # number of segments
+ geometry = []
+
+ #length of segment is either length / n_segments if length > radius or length if length < radius
+ if n_segments > 1:
+ segment_length = length / n_segments
+ for i in range(n_segments):
+ segment = Cylinder(name="Laser segment {0:d}".format(i), radius=radius, height=segment_length,
+ transform=translate(0, 0, i * segment_length))
+
+ geometry.append(segment)
+ elif 0 <= n_segments < 2:
+ segment = Cylinder(name="Laser segment {0:d}".format(0), radius=radius, height=length)
+
+ geometry.append(segment)
+ else:
+ raise ValueError("Incorrect number of segments calculated.")
+
+ return geometry
\ No newline at end of file
diff --git a/cherab/core/model/laser/tests/__init__.py b/cherab/core/model/laser/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/cherab/core/model/laser/tests/test_laserspectrum.py b/cherab/core/model/laser/tests/test_laserspectrum.py
new file mode 100644
index 00000000..1f72e666
--- /dev/null
+++ b/cherab/core/model/laser/tests/test_laserspectrum.py
@@ -0,0 +1,46 @@
+import unittest
+from scipy.integrate import nquad
+
+from cherab.core.model.laser.laserspectrum import GaussianSpectrum, ConstantSpectrum
+
+class TestLaserSpectrum(unittest.TestCase):
+
+ def test_constantspectrum(self):
+ """
+ Laser spectrum should be normalized, i.e. integral from minuns inf. to inf. should be one.
+ :return:
+ """
+ min_wavelength = 1039.9
+ max_wavelength = 1040.1
+ bins = 10
+
+ spectrum = ConstantSpectrum(min_wavelength, max_wavelength, bins)
+
+ # check if the power_spectral density is normalized
+
+ integral = spectrum.power_spectral_density.sum() * spectrum.delta_wavelength
+ self.assertTrue(integral == 1, msg="Power spectral density is not normalised.")
+
+ def test_gaussian_spectrum(self):
+ """
+ Laser spectrum should be normalized, i.e. integral from minuns inf. to inf. should be one.
+ :return:
+ """
+ min_wavelength = 1035
+ max_wavelength = 1045
+ bins = 100
+ mean = 1040
+ stddev = 0.5
+
+ spectrum = GaussianSpectrum(min_wavelength, max_wavelength, bins, mean, stddev)
+ integral = nquad(spectrum, [(min_wavelength, max_wavelength)])[0]
+
+ # check if the power_spectral density is normalized
+ self.assertAlmostEqual(integral, 1., 8, msg="Power spectral density function is not normalised.")
+
+ psd = spectrum.power_spectral_density
+ integral = 0
+ for index in range(0, spectrum.bins - 1):
+ integral += (psd[index] + psd[index + 1]) / 2 * spectrum.delta_wavelength
+
+ self.assertAlmostEqual(integral, 1, 8, msg="Power spectral density is not normalised.")
diff --git a/cherab/core/model/laser/tests/test_model.py b/cherab/core/model/laser/tests/test_model.py
new file mode 100644
index 00000000..992d5d52
--- /dev/null
+++ b/cherab/core/model/laser/tests/test_model.py
@@ -0,0 +1,104 @@
+import unittest
+import numpy as np
+from math import cos, sin, sqrt, radians, exp
+from scipy.constants import pi, c, e, m_e, epsilon_0
+
+from raysect.optical import World, Point3D, Vector3D, translate, Ray
+
+from cherab.core.laser import Laser
+from cherab.core.model.laser import ConstantSpectrum, SeldenMatobaThomsonSpectrum, UniformEnergyDensity
+
+from cherab.tools.plasmas.slab import build_constant_slab_plasma
+
+class TestScatteringModel(unittest.TestCase):
+ laser_wavelength = 1040
+ wavelength = np.linspace(600, 1200, 800)
+ scatangle = 45
+
+ def test_selden_matoba_scattered_spectrum(self):
+
+ # calculate TS cross section and constants
+ r_e = e ** 2 / (4 * pi * epsilon_0 * m_e * c ** 2) # classical electron radius
+
+ # re ** 2 is the cross section, c transforms xsection into rate constant
+ scat_const = r_e ** 2 * c
+
+ ray_origin = Point3D(0, 0, 0)
+
+ # angle of scattering
+ observation_angle = [45, 90, 135]
+ for obsangle in observation_angle:
+
+ # pointing vector is in +z direction, angle of observation is 180 - obsangle
+ z = cos((obsangle) / 180 * pi)
+ x = sin((obsangle) / 180 * pi)
+ ray_direction = Vector3D(x, 0, z).normalise()
+
+ # ray spectrum properties
+ min_wavelength = 600
+ max_wavelength = 1200
+ bins = 800
+
+ # plasma properties
+ e_density = 8e19
+ t_e = [100, 1e3, 1e4]
+
+ for vte in t_e:
+ # setup scene
+ world = World()
+ plasma = build_constant_slab_plasma(length=1, width=1, height=1, electron_density=e_density,
+ electron_temperature=vte, plasma_species=[], parent=world)
+
+ # setup laser
+ laser_spectrum = ConstantSpectrum(1059, 1061, 1)
+ laser_profile = UniformEnergyDensity(laser_length=1, laser_radius=0.015)
+ scattering_model = SeldenMatobaThomsonSpectrum()
+ laser = Laser()
+ laser.parent = world
+ laser.transform = translate(0.05, 0, -0.5)
+ laser.laser_profile = laser_profile
+ laser.laser_spectrum = laser_spectrum
+ laser.plasma = plasma
+ laser.models = [scattering_model]
+
+ # trace a single ray through the laser
+ ray = Ray(origin=ray_origin, direction=ray_direction, min_wavelength=min_wavelength,
+ max_wavelength=max_wavelength, bins=bins)
+ traced_spectrum = ray.trace(world)
+
+
+ # calculate spectrum ray-tracing should deliver
+ dl = 2 * laser_profile.laser_radius / sin((obsangle) / 180 * pi) # ray-laser cross section length
+ intensity_test = np.zeros_like(traced_spectrum.wavelengths)
+
+ for vl in laser.laser_spectrum.wavelengths:
+ intensity_const = scat_const * e_density / vl * dl
+ for iwvl, vwvl in enumerate(traced_spectrum.wavelengths):
+ intensity_test[iwvl] += _selden_matoba_shape(vwvl, vte, obsangle, vl) * intensity_const
+
+ for index, (vtest, vray) in enumerate(zip(intensity_test, traced_spectrum.samples)):
+ # skip the test for too low values of power spectral density, max is approx. 3e-5
+ if vray > 1e-30:
+ rel_error = np.abs((vtest - vray) / vray)
+ self.assertLess(rel_error, 1e-7,
+ msg="Traced and test spectrum value do not match: "
+ "scattering angle = {0} deg, Te = {1} eV, wavelength = {2} nm."
+ .format(180 - obsangle, vte, traced_spectrum.wavelengths[index]))
+
+
+def _selden_matoba_shape(wavelength, te, obsangle, laser_wavelength):
+ """
+ Returns Selden-Matoba Spectral shape
+ """
+ epsilon = wavelength / laser_wavelength - 1
+
+ alpha = m_e * c ** 2 / (2 * e * te)
+
+ scat_angle = 180 - obsangle
+ cos_scat = cos(radians(scat_angle))
+
+ const_c = sqrt(alpha / pi) * (1 - 15 / 16 / alpha + 345 / 512 / alpha ** 2)
+ const_a = (1 + epsilon) ** 3 * sqrt(2 * (1 - cos_scat) * (1 + epsilon) + epsilon ** 2)
+ const_b = sqrt(1 + epsilon ** 2 / (2 * (1 - cos_scat) * (1 + epsilon))) - 1
+
+ return const_c / const_a * exp(-2 * alpha * const_b)
diff --git a/cherab/core/model/laser/tests/test_profiles.py b/cherab/core/model/laser/tests/test_profiles.py
new file mode 100644
index 00000000..6f2c9fc3
--- /dev/null
+++ b/cherab/core/model/laser/tests/test_profiles.py
@@ -0,0 +1,198 @@
+import unittest
+import numpy as np
+from math import exp, sqrt
+
+from raysect.core import Vector3D
+
+from cherab.core.model.laser.profile import UniformEnergyDensity, ConstantBivariateGaussian
+from cherab.core.model.laser.profile import TrivariateGaussian, GaussianBeamAxisymmetric, generate_segmented_cylinder
+
+from scipy.integrate import nquad
+from scipy.constants import c, pi
+
+class TestSegmentedCylinder(unittest.TestCase):
+
+ def test_number_of_primitives(self):
+
+ # for r > l there should be 1 cylinder segment only
+ primitives = generate_segmented_cylinder(radius=1, length=0.5)
+ self.assertEqual(len(primitives), 1, msg="Wrong nuber of laser segments, expected 1.")
+
+ # for r < l tehre should be length // (2 * radius) segments
+ primitives = generate_segmented_cylinder(radius=0.5, length=10)
+ self.assertEqual(len(primitives), 10, msg="Wrong nuber of laser segments, expected 20.")
+
+
+class TestLaserProfile(unittest.TestCase):
+
+ def test_uniform_energy_density(self):
+ polarisation = Vector3D(1, 3, 8).normalise()
+ energy_density = 2
+ model = UniformEnergyDensity(energy_density=energy_density, polarization=polarisation)
+
+ # test polarisation
+ pol_model = model.get_polarization(1, 1, 1)
+ self.assertEqual(pol_model.x, polarisation.x,
+ msg="Model polarization x vector component does not agreee with input value.")
+ self.assertEqual(pol_model.y, polarisation.y,
+ msg="Model polarization y vector component does not agreee with input value.")
+ self.assertEqual(pol_model.z, polarisation.z,
+ msg="Model polarization z vector component does not agreee with input value.")
+
+ # test power
+ self.assertEqual(model.get_energy_density(3, 4, 1), energy_density,
+ msg="Model power density distribution does not agree with input.")
+
+ def test_bivariate_gaussian(self):
+
+ pulse_energy = 2
+ pulse_length = 1e-8
+ stddev_x = 0.03
+ stddev_y = 0.06
+ polarisation = Vector3D(2, 3, 4).normalise()
+ model = ConstantBivariateGaussian(pulse_energy=pulse_energy, pulse_length=pulse_length, stddev_x=stddev_x,
+ stddev_y=stddev_y, polarization=polarisation)
+
+ # test polarisation
+ pol_model = model.get_polarization(1, 1, 1)
+ self.assertEqual(pol_model.x, polarisation.x,
+ msg="Model polarization x vector component does not agreee with input value.")
+ self.assertEqual(pol_model.y, polarisation.y,
+ msg="Model polarization y vector component does not agreee with input value.")
+ self.assertEqual(pol_model.z, polarisation.z,
+ msg="Model polarization z vector component does not agreee with input value.")
+
+ # Integrate over laser volume to check energy
+ xlim = [-5 * stddev_x, 5 * stddev_x]
+ ylim = [-5 * stddev_y, 5 * stddev_y]
+ zlim = [0, pulse_length * c]
+ energy_integrated = nquad(model.get_energy_density, [xlim, ylim, zlim])[0]
+ self.assertTrue(np.isclose(energy_integrated / pulse_energy, 1, 1e-3),
+ msg="Integrated laser energy of the model does not give results close to input energy")
+
+ # Check laser power density profile
+ x = np.linspace(-3 * stddev_x, 3 * stddev_x, 30)
+ y = np.linspace(-3 * stddev_y, 3 * stddev_y, 30)
+ for vx in x:
+ for vy in y:
+ tmp = _constant_bivariate_gaussian2d(vx, vy, pulse_energy, pulse_length, stddev_x, stddev_y)
+ tmp2 = model.get_energy_density(vx, vy, 0)
+ self.assertTrue(np.isclose(tmp, tmp2, 1e-9),
+ msg="Model power density distribution for ({},{},{}) does not agree with input.".format(
+ vx, vy, 0))
+
+ def test_trivariate_gaussian(self):
+
+ pulse_energy = 2
+ pulse_length = 1e-8
+ mean_z = 0
+ stddev_x = 0.03
+ stddev_y = 0.06
+ polarisation = Vector3D(2, 3, 4).normalise()
+ model = TrivariateGaussian(pulse_energy=pulse_energy, pulse_length=pulse_length, mean_z=mean_z,
+ stddev_x=stddev_x, stddev_y=stddev_y, polarization=polarisation)
+
+ # test polarisation
+ pol_model = model.get_polarization(1, 1, 1)
+ self.assertEqual(pol_model.x, polarisation.x,
+ msg="Model polarization x vector component does not agreee with input value.")
+ self.assertEqual(pol_model.y, polarisation.y,
+ msg="Model polarization y vector component does not agreee with input value.")
+ self.assertEqual(pol_model.z, polarisation.z,
+ msg="Model polarization z vector component does not agreee with input value.")
+
+ # Integrate over laser volume to check energy
+ xlim = [-5 * stddev_x, 5 * stddev_x]
+ ylim = [-5 * stddev_y, 5 * stddev_y]
+ zlim = [mean_z - 5 * pulse_length * c, mean_z + 5 * pulse_length * c]
+ energy_integrated = nquad(model.get_energy_density, [xlim, ylim, zlim])[0]
+
+ self.assertTrue(np.isclose(energy_integrated / pulse_energy, 1, 1e-3),
+ msg="Integrated laser energy of the model does not give results close to input energy")
+
+ # Check laser power density profile
+ x = np.linspace(-3 * stddev_x, 3 * stddev_x, 30)
+ y = np.linspace(-3 * stddev_y, 3 * stddev_y, 30)
+ z = np.linspace(-3 * pulse_length * c, 3 * pulse_length * c, 30)
+
+ for vx in x:
+ for vy in y:
+ for vz in z:
+ tmp = _constant_trivariate_gaussian3d(vx, vy, vz, pulse_energy, pulse_length, mean_z, stddev_x,
+ stddev_y)
+ tmp2 = model.get_energy_density(vx, vy, vz)
+ self.assertTrue(np.isclose(tmp, tmp2, 1e-9),
+ msg="Model power density distribution for ({},{},{})"
+ " does not agree with input.".format(vx, vy, vz))
+
+ def test_gaussianbeam(self):
+
+ pulse_energy = 2
+ pulse_length = 1e-9
+ waist_z = 0
+ stddev_waist = 0.003
+ laser_wavelength = 1040
+ polarisation = Vector3D(2, 3, 4).normalise()
+
+ model = GaussianBeamAxisymmetric(pulse_energy=pulse_energy, pulse_length=pulse_length, waist_z=waist_z,
+ stddev_waist=stddev_waist, laser_wavelength=laser_wavelength,
+ polarization=polarisation)
+
+ # test polarisation
+ pol_model = model.get_polarization(1, 1, 1)
+ self.assertEqual(pol_model.x, polarisation.x,
+ msg="Model polarization x vector component does not agreee with input value.")
+ self.assertEqual(pol_model.y, polarisation.y,
+ msg="Model polarization y vector component does not agreee with input value.")
+ self.assertEqual(pol_model.z, polarisation.z,
+ msg="Model polarization z vector component does not agreee with input value.")
+
+ # Integrate over laser volume to check energy
+ xlim = [-20 * stddev_waist, 20 * stddev_waist]
+ zlim = [-1 * pulse_length / 2 * c, pulse_length / 2 * c]
+ energy_integrated = nquad(model.get_energy_density, [xlim, xlim, zlim])[0]
+
+ self.assertTrue(np.isclose(energy_integrated / pulse_energy, 1, 1e-3),
+ msg="Integrated laser energy of the model does not give results close to input energy")
+
+ # Check laser power density profile
+ x = np.linspace(-3 * stddev_waist, 3 * stddev_waist, 30)
+ y = np.linspace(-3 * stddev_waist, 3 * stddev_waist, 30)
+ z = np.linspace(-3 * pulse_length * c, 3 * pulse_length * c, 30)
+
+ for vx in x:
+ for vy in y:
+ for vz in z:
+ tmp = _gaussian_beam_model(vx, vy, vz, pulse_energy, pulse_length, waist_z, stddev_waist,
+ laser_wavelength * 1e-9)
+ tmp2 = model.get_energy_density(vx, vy, vz)
+ self.assertTrue(np.isclose(tmp, tmp2, 1e-9),
+ msg="Model power density distribution for ({},{},{}) "
+ "does not agree with input.".format(vx, vy, vz))
+
+
+def _gaussian_beam_model(x, y, z, pulse_energy, pulse_length, waist_z, stddev_waist, wavelength):
+ laser_power_axis = pulse_energy / (pulse_length * c)
+
+ n = 1 # refractive index
+ rayleigh_distance = 2 * pi * stddev_waist ** 2 * n / wavelength
+
+ z_prime = z - waist_z
+
+ stddev_z2 = stddev_waist ** 2 * (1 + (z_prime / rayleigh_distance) ** 2)
+
+ r2 = x ** 2 + y ** 2
+
+ return laser_power_axis / (2 * pi * stddev_z2) * exp(r2 / (-2 * stddev_z2))
+
+
+def _constant_trivariate_gaussian3d(x, y, z, pulse_energy, pulse_length, mean_z, stddev_x, stddev_y):
+ stddev_z = pulse_length * c
+ return (pulse_energy / (sqrt((2 * pi) ** 3) * stddev_x * stddev_y * stddev_z) *
+ exp(-1 / 2 * ((x / stddev_x) ** 2 + (y / stddev_y) ** 2 + ((z - mean_z) / stddev_z) ** 2)))
+
+
+def _constant_bivariate_gaussian2d(x, y, pulse_energy, pulse_length, stddev_x, stddev_y):
+ length = pulse_length * c
+ normalisation = pulse_energy / length
+ return normalisation / (stddev_x * stddev_y * 2 * pi) * exp(-1 / 2 * ((x / stddev_x) ** 2 + (y / stddev_y) ** 2))
diff --git a/cherab/core/model/lineshape.pxd b/cherab/core/model/lineshape.pxd
index 711475b5..2591efe3 100644
--- a/cherab/core/model/lineshape.pxd
+++ b/cherab/core/model/lineshape.pxd
@@ -24,6 +24,7 @@ cimport numpy as np
from raysect.optical cimport Spectrum, Point3D, Vector3D
from cherab.core cimport Line, Species, Plasma, Beam
from cherab.core.math cimport Function1D, Function2D
+from cherab.core.math.integrators cimport Integrator1D
from cherab.core.atomic.zeeman cimport ZeemanStructure
@@ -41,6 +42,7 @@ cdef class LineShapeModel:
double wavelength
Species target_species
Plasma plasma
+ Integrator1D integrator
cpdef Spectrum add_line(self, double radiance, Point3D point, Vector3D direction, Spectrum spectrum)
diff --git a/cherab/core/model/lineshape.pyx b/cherab/core/model/lineshape.pyx
index 5e346175..69278560 100644
--- a/cherab/core/model/lineshape.pyx
+++ b/cherab/core/model/lineshape.pyx
@@ -19,13 +19,17 @@
# under the Licence.
import numpy as np
+from scipy.special import hyp2f1
+
cimport numpy as np
from libc.math cimport sqrt, erf, M_SQRT2, floor, ceil, fabs
from raysect.optical.spectrum cimport new_spectrum
+from raysect.core.math.function.float cimport Function1D
from cherab.core cimport Plasma
from cherab.core.atomic.elements import hydrogen, deuterium, tritium, helium, helium3, beryllium, boron, carbon, nitrogen, oxygen, neon
from cherab.core.math.function cimport autowrap_function1d, autowrap_function2d
+from cherab.core.math.integrators cimport GaussianQuadrature
from cherab.core.utility.constants cimport ATOMIC_MASS, ELEMENTARY_CHARGE, SPEED_OF_LIGHT
cimport cython
@@ -78,8 +82,6 @@ cpdef double thermal_broadening(double wavelength, double temperature, double at
# the number of standard deviations outside the rest wavelength the line is considered to add negligible value (including a margin for safety)
DEF GAUSSIAN_CUTOFF_SIGMA = 10.0
-DEF LORENZIAN_CUTOFF_GAMMA = 50.0
-
@cython.cdivision(True)
@cython.initializedcheck(False)
@@ -146,14 +148,17 @@ cdef class LineShapeModel:
:param float wavelength: The rest wavelength for this emission line.
:param Species target_species: The target plasma species that is emitting.
:param Plasma plasma: The emitting plasma object.
+ :param Integrator1D integrator: Integrator1D instance to integrate the line shape
+ over the spectral bin. Default is None.
"""
- def __init__(self, Line line, double wavelength, Species target_species, Plasma plasma):
+ def __init__(self, Line line, double wavelength, Species target_species, Plasma plasma, Integrator1D integrator=None):
self.line = line
self.wavelength = wavelength
self.target_species = target_species
self.plasma = plasma
+ self.integrator = integrator
cpdef Spectrum add_line(self, double radiance, Point3D point, Vector3D direction, Spectrum spectrum):
raise NotImplementedError('Child lineshape class must implement this method.')
@@ -289,6 +294,38 @@ cdef class MultipletLineShape(LineShapeModel):
return spectrum
+DEF LORENZIAN_CUTOFF_GAMMA = 50.0
+
+
+cdef class StarkFunction(Function1D):
+ """
+ Normalised Stark function for the StarkBroadenedLine line shape.
+ """
+
+ cdef double _a, _x0, _norm
+
+ STARK_NORM_COEFFICIENT = 4 * LORENZIAN_CUTOFF_GAMMA * hyp2f1(0.4, 1, 1.4, -(2 * LORENZIAN_CUTOFF_GAMMA)**2.5)
+
+ def __init__(self, double wavelength, double lambda_1_2):
+
+ if wavelength <= 0:
+ raise ValueError("Argument 'wavelength' must be positive.")
+
+ if lambda_1_2 <= 0:
+ raise ValueError("Argument 'lambda_1_2' must be positive.")
+
+ self._x0 = wavelength
+ self._a = (0.5 * lambda_1_2)**2.5
+ # normalise, so the integral over x is equal to 1 in the limits
+ # (_x0 - LORENZIAN_CUTOFF_GAMMA * lambda_1_2, _x0 + LORENZIAN_CUTOFF_GAMMA * lambda_1_2)
+ self._norm = (0.5 * lambda_1_2)**1.5 / self.STARK_NORM_COEFFICIENT
+
+ @cython.cdivision(True)
+ cdef double evaluate(self, double x) except? -1e999:
+
+ return self._norm / ((fabs(x - self._x0))**2.5 + self._a)
+
+
cdef class StarkBroadenedLine(LineShapeModel):
"""
Parametrised Stark broadened line shape based on the Model Microfield Method (MMM).
@@ -308,6 +345,9 @@ cdef class StarkBroadenedLine(LineShapeModel):
:param dict stark_model_coefficients: Alternative model coefficients in the form
{line_ij: (c_ij, a_ij, b_ij), ...}.
If None, the default model parameters will be used.
+ :param Integrator1D integrator: Integrator1D instance to integrate the line shape
+ over the spectral bin. Default is `GaussianQuadrature()`.
+
"""
STARK_MODEL_COEFFICIENTS_DEFAULT = {
@@ -352,7 +392,8 @@ cdef class StarkBroadenedLine(LineShapeModel):
Line(tritium, 0, (9, 3)): (5.588e-15, 0.7165, 0.033)
}
- def __init__(self, Line line, double wavelength, Species target_species, Plasma plasma, dict stark_model_coefficients=None):
+ def __init__(self, Line line, double wavelength, Species target_species, Plasma plasma,
+ dict stark_model_coefficients=None, integrator=GaussianQuadrature()):
stark_model_coefficients = stark_model_coefficients or self.STARK_MODEL_COEFFICIENTS_DEFAULT
@@ -371,7 +412,7 @@ cdef class StarkBroadenedLine(LineShapeModel):
except IndexError:
raise ValueError('Stark broadening coefficients for {} is not currently available.'.format(line))
- super().__init__(line, wavelength, target_species, plasma)
+ super().__init__(line, wavelength, target_species, plasma, integrator)
def show_supported_transitions(self):
""" Prints all supported transitions."""
@@ -384,11 +425,13 @@ cdef class StarkBroadenedLine(LineShapeModel):
@cython.cdivision(True)
cpdef Spectrum add_line(self, double radiance, Point3D point, Vector3D direction, Spectrum spectrum):
- cdef double ne, te, lambda_1_2, lambda_5_2, wvl
- cdef double cutoff_lower_wavelength, cutoff_upper_wavelength
- cdef double lower_value, lower_wavelength, upper_value, upper_wavelength
- cdef int start, end, i
- cdef Spectrum raw_lineshape
+ cdef:
+ double ne, te, lambda_1_2, lambda_5_2, wvl
+ double cutoff_lower_wavelength, cutoff_upper_wavelength
+ double lower_wavelength, upper_wavelength
+ double bin_integral
+ int start, end, i
+ Spectrum raw_lineshape
ne = self.plasma.get_electron_distribution().density(point.x, point.y, point.z)
if ne <= 0.0:
@@ -400,6 +443,8 @@ cdef class StarkBroadenedLine(LineShapeModel):
lambda_1_2 = self._cij * ne**self._aij / (te**self._bij)
+ self.integrator.function = StarkFunction(self.wavelength, lambda_1_2)
+
# calculate and check end of limits
cutoff_lower_wavelength = self.wavelength - LORENZIAN_CUTOFF_GAMMA * lambda_1_2
if spectrum.max_wavelength < cutoff_lower_wavelength:
@@ -413,28 +458,16 @@ cdef class StarkBroadenedLine(LineShapeModel):
start = max(0, floor((cutoff_lower_wavelength - spectrum.min_wavelength) / spectrum.delta_wavelength))
end = min(spectrum.bins, ceil((cutoff_upper_wavelength - spectrum.min_wavelength) / spectrum.delta_wavelength))
- # TODO - replace with cumulative integrals
# add line to spectrum
- raw_lineshape = spectrum.new_spectrum()
+ lower_wavelength = spectrum.min_wavelength + start * spectrum.delta_wavelength
- lower_wavelength = raw_lineshape.min_wavelength + start * raw_lineshape.delta_wavelength
- lower_value = 1 / ((fabs(lower_wavelength - self.wavelength))**2.5 + (0.5 * lambda_1_2)**2.5)
for i in range(start, end):
+ upper_wavelength = spectrum.min_wavelength + spectrum.delta_wavelength * (i + 1)
- upper_wavelength = raw_lineshape.min_wavelength + raw_lineshape.delta_wavelength * (i + 1)
- upper_value = 1 / ((fabs(upper_wavelength - self.wavelength))**2.5 + (0.5 * lambda_1_2)**2.5)
-
- raw_lineshape.samples_mv[i] += 0.5 * (upper_value + lower_value)
+ bin_integral = self.integrator.evaluate(lower_wavelength, upper_wavelength)
+ spectrum.samples_mv[i] += radiance * bin_integral / spectrum.delta_wavelength
lower_wavelength = upper_wavelength
- lower_value = upper_value
-
- # perform normalisation
- raw_lineshape.div_scalar(raw_lineshape.total())
-
- for i in range(start, end):
- # Radiance ???
- spectrum.samples_mv[i] += radiance * raw_lineshape.samples_mv[i]
return spectrum
diff --git a/cherab/core/model/plasma/bremsstrahlung.pxd b/cherab/core/model/plasma/bremsstrahlung.pxd
index 4da3422f..44025c8c 100644
--- a/cherab/core/model/plasma/bremsstrahlung.pxd
+++ b/cherab/core/model/plasma/bremsstrahlung.pxd
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -18,16 +18,28 @@
# cython: language_level=3
-from cherab.core.atomic cimport Line
+from numpy cimport ndarray
+from cherab.core.math cimport Function1D
+from cherab.core.math.integrators cimport Integrator1D
+from cherab.core.atomic cimport FreeFreeGauntFactor
from cherab.core.plasma cimport PlasmaModel
-from cherab.core.species cimport Species
+
+
+cdef class BremsFunction(Function1D):
+
+ cdef:
+ double ne, te
+ FreeFreeGauntFactor gaunt_factor
+ ndarray species_density, species_charge
+ double[::1] species_density_mv
+ double[::1] species_charge_mv
cdef class Bremsstrahlung(PlasmaModel):
cdef:
- Line _line
- double _wavelength
- Species _target_species
+ BremsFunction _brems_func
+ bint _user_provided_gaunt_factor
+ Integrator1D _integrator
- cdef double _bremsstrahlung(self, double wvl, double te, double ne, double zeff)
+ cdef int _populate_cache(self) except -1
diff --git a/cherab/core/model/plasma/bremsstrahlung.pyx b/cherab/core/model/plasma/bremsstrahlung.pyx
index 18f4e19d..404750a2 100644
--- a/cherab/core/model/plasma/bremsstrahlung.pyx
+++ b/cherab/core/model/plasma/bremsstrahlung.pyx
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -18,15 +18,76 @@
# cython: language_level=3
+import numpy as np
from raysect.optical cimport Spectrum, Point3D, Vector3D
-from cherab.core.utility.constants cimport RECIP_4_PI, ELEMENTARY_CHARGE, SPEED_OF_LIGHT, PLANCK_CONSTANT
-from libc.math cimport sqrt, log, exp
+from cherab.core cimport Plasma, AtomicData
+from cherab.core.math.integrators cimport GaussianQuadrature
+from cherab.core.species cimport Species
+from cherab.core.utility.constants cimport RECIP_4_PI, ELEMENTARY_CHARGE, SPEED_OF_LIGHT, PLANCK_CONSTANT, ELECTRON_REST_MASS, VACUUM_PERMITTIVITY
+from libc.math cimport sqrt, log, exp, M_PI
cimport cython
-cdef double PH_TO_J_FACTOR = PLANCK_CONSTANT * SPEED_OF_LIGHT * 1e9
+cdef double EXP_FACTOR = PLANCK_CONSTANT * SPEED_OF_LIGHT * 1e9 / ELEMENTARY_CHARGE
-cdef double EXP_FACTOR = PH_TO_J_FACTOR / ELEMENTARY_CHARGE
+cdef double BREMS_CONST = (ELEMENTARY_CHARGE**2 * RECIP_4_PI / VACUUM_PERMITTIVITY)**3
+BREMS_CONST *= 32 * M_PI**2 / (3 * sqrt(3) * ELECTRON_REST_MASS**2 * SPEED_OF_LIGHT**3)
+BREMS_CONST *= sqrt(2 * ELECTRON_REST_MASS / (M_PI * ELEMENTARY_CHARGE))
+BREMS_CONST *= SPEED_OF_LIGHT * 1e9 * RECIP_4_PI
+
+
+cdef class BremsFunction(Function1D):
+ """
+ Calculates bremsstrahlung spectrum.
+
+ :param FreeFreeGauntFactor gaunt_factor: Free-free Gaunt factor as a function of Z, Te and
+ wavelength.
+ :param object species_density: Array-like object wiyh ions' density in m-3.
+ :param object species_charge: Array-like object wiyh ions' charge.
+ :param double ne: Electron density in m-3.
+ :param double te: Electron temperature in eV.
+ """
+
+ def __init__(self, FreeFreeGauntFactor gaunt_factor, object species_density, object species_charge, double ne, double te):
+
+ if ne <= 0:
+ raise ValueError("Argument ne must be positive.")
+ self.ne = ne
+
+ if te <= 0:
+ raise ValueError("Argument te must be positive.")
+ self.te = te
+
+ self.gaunt_factor = gaunt_factor
+ self.species_density = np.asarray(species_density, dtype=np.float64) # copied if type does not match
+ self.species_density_mv = self.species_density
+ self.species_charge = np.asarray(species_charge, dtype=np.float64) # copied if type does not match
+ self.species_charge_mv = self.species_charge
+
+ @cython.cdivision(True)
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ cdef double evaluate(self, double wvl) except? -1e999:
+ """
+ :param double wvl: Wavelength in nm.
+ :return:
+ """
+
+ cdef double ni_gff_z2, radiance, pre_factor, ni, z
+ cdef int i
+
+ ni_gff_z2 = 0
+ for i in range(self.species_charge_mv.shape[0]):
+ z = self.species_charge_mv[i]
+ ni = self.species_density_mv[i]
+ if ni > 0:
+ ni_gff_z2 += ni * self.gaunt_factor.evaluate(z, self.te, wvl) * z * z
+
+ # bremsstrahlung equation W/m^3/str/nm
+ pre_factor = BREMS_CONST / (sqrt(self.te) * wvl * wvl) * self.ne * ni_gff_z2
+ radiance = pre_factor * exp(- EXP_FACTOR / (self.te * wvl))
+
+ return radiance
# todo: doppler shift?
@@ -34,15 +95,70 @@ cdef class Bremsstrahlung(PlasmaModel):
"""
Emitter that calculates bremsstrahlung emission from a plasma object.
- The bremmstrahlung formula implemented is equation 2 from M. Beurskens,
- et. al., 'ITER LIDAR performance analysis', Rev. Sci. Instrum. 79, 10E727 (2008),
+ The bremmstrahlung formula implemented is equation 5.3.40
+ from I. H. Hutchinson, 'Principles of Plasma Diagnostics', second edition,
+ Cambridge University Press, 2002, ISBN: 9780511613630,
+ https://doi.org/10.1017/CBO9780511613630
- .. math::
- \\epsilon (\\lambda) = \\frac{0.95 \\times 10^{-19}}{\\lambda 4 \\pi} g_{ff} n_e^2 Z_{eff} T_e^{-1/2} \\times \\exp{\\frac{-hc}{\\lambda T_e}},
+ Note that in eq. 5.3.40, the emissivity :math:`j(\\nu)` is given in (W/m^3/sr/Hz) with respect
+ to frequency, :math:`\\nu`. Here, the emissivity :math:`\\epsilon_{\\mathrm{ff}}(\\lambda)`
+ is given in (W/m^3/nm/sr) with respect to wavelength, :math:`\\lambda = \\frac{10^{9} c}{\\nu}`,
+ and taking into account that :math:`d\\nu=-\\frac{10^{9} c}{\\lambda^2}d\\lambda`.
- where the emission :math:`\\epsilon (\\lambda)` is in units of radiance (ph/s/sr/m^3/nm).
+ .. math::
+ \\epsilon_{\\mathrm{ff}}(\\lambda) = \\left( \\frac{e^2}{4 \\pi \\varepsilon_0} \\right)^3
+ \\frac{32 \\pi^2}{3 \\sqrt{3} m_\\mathrm{e}^2 c^3}
+ \\sqrt{\\frac{2 m_\\mathrm{e}^3}{\\pi e T_\\mathrm{e}}}
+ \\frac{10^{9} c}{4 \\pi \\lambda^2}
+ n_\\mathrm{e} \\sum_i \\left( n_\\mathrm{i} g_\\mathrm{ff} (Z_\\mathrm{i}, T_\\mathrm{e}, \\lambda) Z_\\mathrm{i}^2 \\right)
+ \\mathrm{e}^{-\\frac{10^9 hc}{e T_\\mathrm{e} \\lambda}}\\,,
+
+ where :math:`T_\\mathrm{e}` is in eV and :math:`\\lambda` is in nm.
+
+ :math:`g_\\mathrm{ff} (Z_\\mathrm{i}, T_\\mathrm{e}, \\lambda)` is the free-free Gaunt factor.
+
+ :ivar Plasma plasma: The plasma to which this emission model is attached. Default is None.
+ :ivar AtomicData atomic_data: The atomic data provider for this model. Default is None.
+ :ivar FreeFreeGauntFactor gaunt_factor: Free-free Gaunt factor as a function of Z, Te and
+ wavelength. If not provided,
+ the `atomic_data` is used.
+ :ivar Integrator1D integrator: Integrator1D instance to integrate Bremsstrahlung radiation
+ over the spectral bin. Default is `GaussianQuadrature`.
"""
+ def __init__(self, Plasma plasma=None, AtomicData atomic_data=None, FreeFreeGauntFactor gaunt_factor=None, Integrator1D integrator=None):
+
+ super().__init__(plasma, atomic_data)
+
+ self._brems_func = BremsFunction.__new__(BremsFunction)
+ self.gaunt_factor = gaunt_factor
+ self.integrator = integrator or GaussianQuadrature()
+
+ # ensure that cache is initialised
+ self._change()
+
+ @property
+ def gaunt_factor(self):
+
+ return self._brems_func.gaunt_factor
+
+ @gaunt_factor.setter
+ def gaunt_factor(self, value):
+
+ self._brems_func.gaunt_factor = value
+ self._user_provided_gaunt_factor = True if value else False
+
+ @property
+ def integrator(self):
+
+ return self._integrator
+
+ @integrator.setter
+ def integrator(self, Integrator1D value not None):
+
+ self._integrator = value
+ self._integrator.function = self._brems_func
+
def __repr__(self):
return ''
@@ -53,55 +169,77 @@ cdef class Bremsstrahlung(PlasmaModel):
cpdef Spectrum emission(self, Point3D point, Vector3D direction, Spectrum spectrum):
cdef:
- double ne, te, z_effective
- double lower_wavelength, upper_wavelength
- double lower_sample, upper_sample
+ double ne, te
+ double lower_wavelength, upper_wavelength, bin_integral
+ Species species
int i
+ # cache data on first run
+ if self._brems_func.species_charge is None:
+ self._populate_cache()
+
ne = self._plasma.get_electron_distribution().density(point.x, point.y, point.z)
- if ne == 0:
+ if ne <= 0:
return spectrum
te = self._plasma.get_electron_distribution().effective_temperature(point.x, point.y, point.z)
- if te == 0:
- return spectrum
- z_effective = self._plasma.z_effective(point.x, point.y, point.z)
- if z_effective == 0:
+ if te <= 0:
return spectrum
- # numerically integrate using trapezium rule
- # todo: add sub-sampling to increase numerical accuracy
+ self._brems_func.ne = ne
+ self._brems_func.te = te
+
+ # collect densities of charged species
+ i = 0
+ for species in self._plasma.get_composition():
+ if species.charge > 0:
+ self._brems_func.species_density_mv[i] = species.distribution.density(point.x, point.y, point.z)
+ i += 1
+
+ # add bremsstrahlung to spectrum
lower_wavelength = spectrum.min_wavelength
- lower_sample = self._bremsstrahlung(lower_wavelength, te, ne, z_effective)
for i in range(spectrum.bins):
-
upper_wavelength = spectrum.min_wavelength + spectrum.delta_wavelength * (i + 1)
- upper_sample = self._bremsstrahlung(upper_wavelength, te, ne, z_effective)
- spectrum.samples_mv[i] += 0.5 * (lower_sample + upper_sample)
+ bin_integral = self._integrator.evaluate(lower_wavelength, upper_wavelength)
+ spectrum.samples_mv[i] += bin_integral / spectrum.delta_wavelength
lower_wavelength = upper_wavelength
- lower_sample = upper_sample
return spectrum
- @cython.cdivision(True)
- cdef double _bremsstrahlung(self, double wvl, double te, double ne, double zeff):
- """
- :param wvl: in nm
- :param te: in eV
- :param ne: in m^-3
- :param zeff: a.u.
- :return:
- """
+ cdef int _populate_cache(self) except -1:
- cdef double gaunt_factor, radiance, pre_factor
+ cdef list species_charge
+ cdef Species species
- # gaunt factor
- gaunt_factor = max(1., 0.6183 * log(te) - 0.0821)
+ if self._plasma is None:
+ raise RuntimeError("The emission model is not connected to a plasma object.")
- # bremsstrahlung equation W/m^3/str/nm
- pre_factor = 0.95e-19 * RECIP_4_PI * gaunt_factor * ne * ne * zeff / (sqrt(te) * wvl)
- radiance = pre_factor * exp(- EXP_FACTOR / (te * wvl)) * PH_TO_J_FACTOR
+ if self._brems_func.gaunt_factor is None:
+ if self._atomic_data is None:
+ raise RuntimeError("The emission model is not connected to an atomic data source.")
+
+ # initialise Gaunt factor on first run using the atomic data
+ self._brems_func.gaunt_factor = self._atomic_data.free_free_gaunt_factor()
+
+ species_charge = []
+ for species in self._plasma.get_composition():
+ if species.charge > 0:
+ species_charge.append(species.charge)
+
+ # Gaunt factor takes Z as double to support Zeff, so caching Z as float64
+ self._brems_func.species_charge = np.array(species_charge, dtype=np.float64)
+ self._brems_func.species_charge_mv = self._brems_func.species_charge
+
+ self._brems_func.species_density = np.zeros_like(self._brems_func.species_charge)
+ self._brems_func.species_density_mv = self._brems_func.species_density
+
+ def _change(self):
- # convert to W/m^3/str/nm
- return radiance / wvl
+ # clear cache to force regeneration on first use
+ if not self._user_provided_gaunt_factor:
+ self._brems_func.gaunt_factor = None
+ self._brems_func.species_charge = None
+ self._brems_func.species_charge_mv = None
+ self._brems_func.species_density = None
+ self._brems_func.species_density_mv = None
diff --git a/cherab/core/tests/test_beamcxline.py b/cherab/core/tests/test_beamcxline.py
new file mode 100644
index 00000000..6de8ad58
--- /dev/null
+++ b/cherab/core/tests/test_beamcxline.py
@@ -0,0 +1,165 @@
+# Copyright 2016-2023 Euratom
+# Copyright 2016-2023 United Kingdom Atomic Energy Authority
+# Copyright 2016-2023 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import unittest
+
+import numpy as np
+
+from raysect.core import Point3D, Vector3D, translate
+from raysect.optical import World, Spectrum, Ray
+
+from cherab.core import Beam
+from cherab.core.atomic import Line, AtomicData, BeamCXPEC, BeamStoppingRate
+from cherab.core.atomic import deuterium
+from cherab.tools.plasmas.slab import build_constant_slab_plasma
+from cherab.core.model import SingleRayAttenuator, BeamCXLine, GaussianLine, ZeemanTriplet
+
+
+class ConstantBeamCXPEC(BeamCXPEC):
+ """
+ Constant beam CX PEC for test purpose.
+ """
+
+ def __init__(self, donor_metastable, value):
+ self.donor_metastable = donor_metastable
+ self.value = value
+
+ def evaluate(self, energy, temperature, density, z_effective, b_field):
+
+ return self.value
+
+
+class ConstantBeamStoppingRate(BeamStoppingRate):
+ """
+ Constant beam CX PEC for test purpose.
+ """
+
+ def __init__(self, donor_metastable, value):
+ self.donor_metastable = donor_metastable
+ self.value = value
+
+ def evaluate(self, energy, density, temperature):
+
+ return self.value
+
+
+class TestAtomicData(AtomicData):
+ """Fake atomic data for test purpose."""
+
+ def beam_cx_pec(self, donor_ion, receiver_ion, receiver_charge, transition):
+
+ return [ConstantBeamCXPEC(1, 3.4e-34)]
+
+ def beam_stopping_rate(self, beam_ion, plasma_ion, charge):
+
+ return ConstantBeamStoppingRate(1, 0)
+
+ def wavelength(self, ion, charge, transition):
+
+ return 656.104
+
+
+class TestBeamCXLine(unittest.TestCase):
+
+ world = World()
+
+ atomic_data = TestAtomicData()
+
+ plasma_species = [(deuterium, 1, 1.e19, 200., Vector3D(0, 0, 0))]
+ plasma = build_constant_slab_plasma(length=1, width=1, height=1, electron_density=1e19, electron_temperature=200.,
+ plasma_species=plasma_species, b_field=Vector3D(0, 10., 0))
+ plasma.atomic_data = atomic_data
+ plasma.parent = world
+
+ beam = Beam(transform=translate(0.5, 0, 0))
+ beam.atomic_data = atomic_data
+ beam.plasma = plasma
+ beam.attenuator = SingleRayAttenuator(clamp_to_zero=True)
+ beam.energy = 50000
+ beam.power = 1e6
+ beam.temperature = 10
+ beam.element = deuterium
+ beam.parent = world
+
+ def test_default_lineshape(self):
+ # setting up the model
+ line = Line(deuterium, 0, (3, 2)) # D-alpha line
+ self.beam.models = [BeamCXLine(line)]
+
+ # observing
+ origin = Point3D(1.5, 0, 0)
+ direction = Vector3D(-1, 0, 0)
+ ray = Ray(origin=origin, direction=direction,
+ min_wavelength=655.1, max_wavelength=657.1, bins=512)
+ cx_spectrum = ray.trace(self.world)
+
+ # validating
+ dx = self.beam.integrator.step
+ rate = self.atomic_data.beam_cx_pec(deuterium, deuterium, 1, (3, 2))[0].value
+ ni = self.plasma.ion_density(0.5, 0, 0) # constant slab
+ nd_beam = 0 # beam density
+ for i in range(-int(0.5 / dx), int(0.5 / dx)):
+ x = dx * (i + 0.5)
+ nd_beam += self.beam.density(x, 0, 0) # in internal beam coordinates
+ radiance = 0.25 * rate * ni * nd_beam * dx / np.pi
+
+ target_species = self.plasma.composition.get(line.element, line.charge + 1)
+ wavelength = self.atomic_data.wavelength(line.element, line.charge, line.transition)
+ gaussian_line = GaussianLine(line, wavelength, target_species, self.plasma)
+ spectrum = Spectrum(ray.min_wavelength, ray.max_wavelength, ray.bins)
+ spectrum = gaussian_line.add_line(radiance, Point3D(0.5, 0, 0), direction, spectrum)
+
+ for i in range(ray.bins):
+ self.assertAlmostEqual(cx_spectrum.samples[i], spectrum.samples[i], delta=1e-8,
+ msg='BeamCXLine model gives a wrong value at {} nm.'.format(spectrum.wavelengths[i]))
+
+ def test_custom_lineshape(self):
+ # setting up the model
+ line = Line(deuterium, 0, (3, 2)) # D-alpha line
+ self.beam.models = [BeamCXLine(line, lineshape=ZeemanTriplet)]
+
+ # observing
+ origin = Point3D(1.5, 0, 0)
+ direction = Vector3D(-1, 0, 0)
+ ray = Ray(origin=origin, direction=direction,
+ min_wavelength=655.1, max_wavelength=657.1, bins=512)
+ cx_spectrum = ray.trace(self.world)
+
+ # validating
+ dx = self.beam.integrator.step
+ rate = self.atomic_data.beam_cx_pec(deuterium, deuterium, 1, (3, 2))[0].value
+ ni = self.plasma.ion_density(0.5, 0, 0) # constant slab
+ nd_beam = 0 # beam density
+ for i in range(-int(0.5 / dx), int(0.5 / dx)):
+ x = dx * (i + 0.5)
+ nd_beam += self.beam.density(x, 0, 0) # in internal beam coordinates
+ radiance = 0.25 * rate * ni * nd_beam * dx / np.pi
+
+ target_species = self.plasma.composition.get(line.element, line.charge + 1)
+ wavelength = self.atomic_data.wavelength(line.element, line.charge, line.transition)
+ zeeman_line = ZeemanTriplet(line, wavelength, target_species, self.plasma)
+ spectrum = Spectrum(ray.min_wavelength, ray.max_wavelength, ray.bins)
+ spectrum = zeeman_line.add_line(radiance, Point3D(0.5, 0, 0), direction, spectrum)
+
+ for i in range(ray.bins):
+ self.assertAlmostEqual(cx_spectrum.samples[i], spectrum.samples[i], delta=1e-8,
+ msg='BeamCXLine model gives a wrong value at {} nm.'.format(spectrum.wavelengths[i]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/cherab/core/tests/test_bremsstrahlung.py b/cherab/core/tests/test_bremsstrahlung.py
new file mode 100644
index 00000000..5373776b
--- /dev/null
+++ b/cherab/core/tests/test_bremsstrahlung.py
@@ -0,0 +1,94 @@
+# Copyright 2016-2023 Euratom
+# Copyright 2016-2023 United Kingdom Atomic Energy Authority
+# Copyright 2016-2023 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import unittest
+
+import numpy as np
+
+from raysect.core import Point3D, Vector3D
+from raysect.optical import World, Ray
+
+from cherab.core.atomic import AtomicData, MaxwellianFreeFreeGauntFactor
+from cherab.core.math.integrators import GaussianQuadrature
+from cherab.core.atomic import deuterium, nitrogen
+from cherab.tools.plasmas.slab import build_constant_slab_plasma
+from cherab.core.model import Bremsstrahlung
+
+import scipy.constants as const
+
+
+class TestBremsstrahlung(unittest.TestCase):
+
+ world = World()
+
+ plasma_species = [(deuterium, 1, 1.e19, 2000., Vector3D(0, 0, 0)), (nitrogen, 7, 1.e18, 2000., Vector3D(0, 0, 0))]
+ plasma = build_constant_slab_plasma(length=1, width=1, height=1, electron_density=1e19, electron_temperature=2000.,
+ plasma_species=plasma_species)
+ plasma.parent = world
+ plasma.atomic_data = AtomicData()
+
+ def test_bremsstrahlung_model(self):
+ # setting up the model
+ gaunt_factor = MaxwellianFreeFreeGauntFactor()
+ bremsstrahlung = Bremsstrahlung(gaunt_factor=gaunt_factor)
+ self.plasma.models = [bremsstrahlung]
+
+ # observing
+ origin = Point3D(1.5, 0, 0)
+ direction = Vector3D(-1, 0, 0)
+ ray = Ray(origin=origin, direction=direction,
+ min_wavelength=400., max_wavelength=800., bins=128)
+ brems_spectrum = ray.trace(self.world)
+
+ # validating
+ brems_const = (const.e**2 * 0.25 / np.pi / const.epsilon_0)**3
+ brems_const *= 32 * np.pi**2 / (3 * np.sqrt(3) * const.m_e**2 * const.c**3)
+ brems_const *= np.sqrt(2 * const.m_e / (np.pi * const.e))
+ brems_const *= const.c * 1e9 * 0.25 / np.pi
+ exp_factor = const.h * const.c * 1.e9 / const. e
+
+ ne = self.plasma.electron_distribution.density(0.5, 0, 0)
+ te = self.plasma.electron_distribution.effective_temperature(0.5, 0, 0)
+
+ def brems_func(wvl):
+ ni_gff_z2 = 0
+ for species in self.plasma.composition:
+ z = species.charge
+ ni = self.plasma.composition[(species.element, species.charge)].distribution.density(0.5, 0, 0)
+ ni_gff_z2 += ni * gaunt_factor(z, te, wvl) * z * z
+
+ return brems_const * ni_gff_z2 * ne / (np.sqrt(te) * wvl * wvl) * np.exp(- exp_factor / (te * wvl))
+
+ integrator = GaussianQuadrature(brems_func)
+
+ test_samples = np.zeros(brems_spectrum.bins)
+ delta_wavelength = (brems_spectrum.max_wavelength - brems_spectrum.min_wavelength) / brems_spectrum.bins
+ lower_wavelength = brems_spectrum.min_wavelength
+ for i in range(brems_spectrum.bins):
+ upper_wavelength = brems_spectrum.min_wavelength + delta_wavelength * (i + 1)
+ bin_integral = integrator(lower_wavelength, upper_wavelength)
+ test_samples[i] = bin_integral / delta_wavelength
+ lower_wavelength = upper_wavelength
+
+ for i in range(brems_spectrum.bins):
+ self.assertAlmostEqual(brems_spectrum.samples[i], test_samples[i], delta=1e-10,
+ msg='BeamCXLine model gives a wrong value at {} nm.'.format(brems_spectrum.wavelengths[i]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/cherab/core/tests/test_lineshapes.py b/cherab/core/tests/test_lineshapes.py
index c29f1f2e..da4dc41d 100644
--- a/cherab/core/tests/test_lineshapes.py
+++ b/cherab/core/tests/test_lineshapes.py
@@ -18,17 +18,17 @@
import unittest
-import os
import numpy as np
-from scipy.special import erf
+from scipy.special import erf, hyp2f1
+from scipy.integrate import quadrature
from raysect.core import Point3D, Vector3D
from raysect.core.math.function.float import Arg1D, Constant1D
from raysect.optical import Spectrum
from cherab.core import Line
+from cherab.core.math.integrators import GaussianQuadrature
from cherab.core.atomic import deuterium, nitrogen, ZeemanStructure
-from cherab.openadas import OpenADAS
from cherab.tools.plasmas.slab import build_constant_slab_plasma
from cherab.core.model import GaussianLine, MultipletLineShape, StarkBroadenedLine, ZeemanTriplet, ParametrisedZeemanTriplet, ZeemanMultiplet
@@ -116,7 +116,7 @@ def test_multiplet_line_shape(self):
for i in range(bins):
self.assertAlmostEqual(multi_gaussian[i], spectrum.samples[i], delta=1e-10,
- msg='GaussianLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
+ msg='MultipletLineShape.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
def test_zeeman_triplet(self):
# setting up a line shape model
@@ -167,7 +167,7 @@ def test_zeeman_triplet(self):
for pol in ('no', 'pi', 'sigma'):
for i in range(bins):
self.assertAlmostEqual(tri_gaussian[pol][i], spectrum[pol].samples[i], delta=1e-10,
- msg='GaussianLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
+ msg='ZeemanTriplet.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
def test_parametrised_zeeman_triplet(self):
# setting up a line shape model
@@ -219,7 +219,7 @@ def test_parametrised_zeeman_triplet(self):
for pol in ('no', 'pi', 'sigma'):
for i in range(bins):
self.assertAlmostEqual(tri_gaussian[pol][i], spectrum[pol].samples[i], delta=1e-10,
- msg='GaussianLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
+ msg='ParametrisedZeemanTriplet.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
def test_zeeman_multiplet(self):
# setting up a line shape model
@@ -277,14 +277,15 @@ def test_zeeman_multiplet(self):
for pol in ('no', 'pi', 'sigma'):
for i in range(bins):
self.assertAlmostEqual(tri_gaussian[pol][i], spectrum[pol].samples[i], delta=1e-10,
- msg='GaussianLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
+ msg='ZeemanMultiplet.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
def test_stark_broadened_line(self):
# setting up a line shape model
line = Line(deuterium, 0, (6, 2)) # D-delta line
target_species = self.plasma.composition.get(line.element, line.charge)
wavelength = 656.104
- stark_line = StarkBroadenedLine(line, wavelength, target_species, self.plasma)
+ integrator = GaussianQuadrature(relative_tolerance=1.e-5)
+ stark_line = StarkBroadenedLine(line, wavelength, target_species, self.plasma, integrator=integrator)
# spectrum parameters
min_wavelength = wavelength - 0.2
@@ -304,14 +305,19 @@ def test_stark_broadened_line(self):
te = self.plasma.electron_distribution.effective_temperature(point.x, point.y, point.z)
lambda_1_2 = cij * ne**aij / (te**bij)
+ lorenzian_cutoff_gamma = 50
+ stark_norm_coeff = 4 * lorenzian_cutoff_gamma * hyp2f1(0.4, 1, 1.4, -(2 * lorenzian_cutoff_gamma)**2.5)
+ norm = (0.5 * lambda_1_2)**1.5 / stark_norm_coeff
+
wavelengths, delta = np.linspace(min_wavelength, max_wavelength, bins + 1, retstep=True)
- stark_lineshape = 1 / ((np.abs(wavelengths - wavelength))**2.5 + (0.5 * lambda_1_2)**2.5)
- stark_lineshape = 0.5 * (stark_lineshape[1:] + stark_lineshape[:-1])
- stark_lineshape /= stark_lineshape.sum() * delta
+
+ def stark_lineshape(x):
+ return norm / ((np.abs(x - wavelength))**2.5 + (0.5 * lambda_1_2)**2.5)
for i in range(bins):
- self.assertAlmostEqual(stark_lineshape[i], spectrum.samples[i], delta=1e-10,
- msg='GaussianLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
+ stark_bin = quadrature(stark_lineshape, wavelengths[i], wavelengths[i + 1], rtol=integrator.relative_tolerance)[0] / delta
+ self.assertAlmostEqual(stark_bin, spectrum.samples[i], delta=1e-9,
+ msg='StarkBroadenedLine.add_line() method gives a wrong value at {} nm.'.format(wavelengths[i]))
if __name__ == '__main__':
diff --git a/cherab/core/utility/constants.pxd b/cherab/core/utility/constants.pxd
index fd3fa568..4c59b4a8 100644
--- a/cherab/core/utility/constants.pxd
+++ b/cherab/core/utility/constants.pxd
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -29,3 +29,5 @@ cdef:
double PLANCK_CONSTANT
double ELECTRON_CLASSICAL_RADIUS
double ELECTRON_REST_MASS
+ double RYDBERG_CONSTANT_EV
+ double VACUUM_PERMITTIVITY
diff --git a/cherab/core/utility/constants.pyx b/cherab/core/utility/constants.pyx
index 348e28c3..d36b99f9 100644
--- a/cherab/core/utility/constants.pyx
+++ b/cherab/core/utility/constants.pyx
@@ -1,6 +1,6 @@
-# Copyright 2016-2018 Euratom
-# Copyright 2016-2018 United Kingdom Atomic Energy Authority
-# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -31,4 +31,5 @@ cdef:
double PLANCK_CONSTANT = 6.62607015e-34
double ELECTRON_CLASSICAL_RADIUS = 2.8179403262e-15
double ELECTRON_REST_MASS = 9.1093837015e-31
-
+ double RYDBERG_CONSTANT_EV = 13.605693122994
+ double VACUUM_PERMITTIVITY = 8.8541878128e-12
diff --git a/cherab/generomak/plasma/__init__.py b/cherab/generomak/plasma/__init__.py
index 8a28ab1a..7cccf703 100644
--- a/cherab/generomak/plasma/__init__.py
+++ b/cherab/generomak/plasma/__init__.py
@@ -1,2 +1,3 @@
-from .plasma import get_edge_distributions, get_edge_interpolators, get_edge_plasma
-from .plasma import get_core_distributions, get_core_plasma
\ No newline at end of file
+from .plasma import get_2d_distributions, get_edge_interpolators, get_edge_plasma
+from .plasma import get_core_distributions, get_core_plasma
+from .plasma import get_full_profiles, get_plasma
diff --git a/cherab/generomak/plasma/data/core/carbon0.json b/cherab/generomak/plasma/data/core/carbon0.json
new file mode 100644
index 00000000..d8763cf4
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon0.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.5297458338687,
+ 2782.7582301214393,
+ 2762.5950477966007,
+ 2735.8851983639343,
+ 2703.411010968356,
+ 2665.8945476185836,
+ 2624.0003243064125,
+ 2578.338228519893,
+ 2529.466541110544,
+ 2477.8949930363638,
+ 2424.08780488189,
+ 2368.4666705053005,
+ 2311.4136566031007,
+ 2253.2739981035534,
+ 2194.3587756195216,
+ 2134.9474661044947,
+ 2075.290361665309,
+ 2015.6108544256936,
+ 1956.107587588782,
+ 1896.9564745570865,
+ 1838.3125892477842,
+ 1780.3119316786645,
+ 1723.0730735666177,
+ 1666.6986891326694,
+ 1611.2769765905086,
+ 1556.8829759454748,
+ 1503.5797887772371,
+ 1451.4197056453777,
+ 1400.4452466615378,
+ 1350.6901206300427,
+ 1302.1801079829825,
+ 1254.9338725355856,
+ 1208.9637068710047,
+ 1164.2762159367799,
+ 1120.8729432030323,
+ 1078.7509434988951,
+ 1037.903306411775,
+ 998.3196339061595,
+ 959.986475596583,
+ 922.8877248943963,
+ 887.004979041061,
+ 852.3178658425425,
+ 818.8043397302939,
+ 786.4409495946626,
+ 755.2030806662577,
+ 725.0651725599275,
+ 696.0009154442936,
+ 667.9834261571025,
+ 640.9854059526704,
+ 614.9792814421413,
+ 589.9373301697594,
+ 565.8317921585761,
+ 542.6349686565285,
+ 520.3193092183391,
+ 498.8574881697798,
+ 478.22247141812255,
+ 458.3875744958107,
+ 439.3265126530432,
+ 421.0134437488174,
+ 403.4230046287076,
+ 386.5303416208766,
+ 370.3111357293156,
+ 354.74162305475744,
+ 339.79861092883743,
+ 325.4594902056625,
+ 311.70224411672444,
+ 298.5054540598485,
+ 285.84830266038824,
+ 273.71057441296176,
+ 262.0726541844933,
+ 250.91552383399323,
+ 240.22075718122792,
+ 229.97051353503508,
+ 220.14752997240066,
+ 210.73511254139078,
+ 201.7171265444924,
+ 193.07798604378416,
+ 184.80264271546582,
+ 176.8765741685898,
+ 169.28577183121658,
+ 162.01672849659778,
+ 155.05642561229888,
+ 148.39232038631826,
+ 142.01233277619647,
+ 135.90483241974619,
+ 130.05862555934604,
+ 124.46294200564746,
+ 119.10742218101434,
+ 113.98210427798426,
+ 109.07741156349235,
+ 104.38413985546642,
+ 99.89344519467129,
+ 95.59683173130277,
+ 91.48613984279793,
+ 87.55353449656745,
+ 83.79149386891429,
+ 80.19279822915814,
+ 76.7505190960298,
+ 73.4580086716009,
+ 70.30888955644176,
+ 67.29704474828924,
+ 64.41660792525342,
+ 61.66195401348148,
+ 59.027690038231896,
+ 56.508646256439604,
+ 54.09986756812256,
+ 51.79660520330721,
+ 49.59430868060964,
+ 47.488618033112196,
+ 45.4753562967661,
+ 43.55052225621492,
+ 41.710283442635344,
+ 39.95096937796647,
+ 38.26906505970934,
+ 36.66120468032837,
+ 35.12416557519362,
+ 33.65486239291572,
+ 32.25034148188933,
+ 30.907775486848166,
+ 29.624458149229337,
+ 28.39779930519129,
+ 27.225320075155384,
+ 26.104648238820975,
+ 25.033513789664312,
+ 24.009744663032187,
+ 23.03126263202616,
+ 22.09607936549286,
+ 21.20229264253159,
+ 20.348082718071975,
+ 19.531708834175102,
+ 18.751505871858317,
+ 18.005881138361524,
+ 17.29331128491523,
+ 16.612339350196027,
+ 15.961571924800158,
+ 15.339676432189938,
+ 14.745378521713246,
+ 14.17745956942282,
+ 13.634754282558198,
+ 13.116148403687774,
+ 12.62057651063149,
+ 12.147019908417766,
+ 11.694504609655857,
+ 11.262099399819382,
+ 10.848913984069997,
+ 10.454097212357015,
+ 10.076835379651857,
+ 9.716350598285864,
+ 9.37189923947122,
+ 9.042770441189758,
+ 8.728284679739293,
+ 8.427792402331782,
+ 8.140672718228085,
+ 7.866332145997564,
+ 7.604203414576368,
+ 7.353744315892651,
+ 7.114436606910324,
+ 6.88578495902669,
+ 6.66731595284398,
+ 6.458577116405904,
+ 6.259136005074808,
+ 6.068579321290205,
+ 5.886512072521773,
+ 5.712556765802551,
+ 5.546352637286773,
+ 5.387554915341459,
+ 5.235834115747535,
+ 5.09087536763343,
+ 4.952377768832103,
+ 4.820053769398764,
+ 4.693628582080498,
+ 4.572839618581702,
+ 4.457435950513924,
+ 4.347177793965752,
+ 4.241836016675181,
+ 4.1411916668281155,
+ 4.045035522543728,
+ 3.953167661156071,
+ 3.8653970474291826,
+ 3.7815411398866017,
+ 3.701425514464914,
+ 3.624883504742671,
+ 3.5517558580176334,
+ 3.4818904065449097,
+ 3.4151417532737645,
+ 3.3513709714494597,
+ 3.2904453174754256,
+ 3.23223795645469,
+ 3.176627699856822,
+ 3.1234987547774122,
+ 3.0727404842841777,
+ 3.0242471783623297,
+ 2.9779178349937,
+ 2.933655950925356,
+ 2.8913693217009238,
+ 2.850969850548094,
+ 2.8123733657334666,
+ 2.7754994460091185,
+ 2.7402712537980722,
+ 2.706615375774928,
+ 2.6744616705174318,
+ 2.6437431229153345,
+ 2.6143957050402027,
+ 2.586358243189803,
+ 2.5595722908346312,
+ 2.5339820072055117,
+ 2.509534041273594,
+ 2.4861774208836924,
+ 2.4638634468137517,
+ 2.442545591541203,
+ 2.4221794025087373,
+ 2.4027224096911914,
+ 2.384134037270308,
+ 2.366375519239019,
+ 2.3494098187571737,
+ 2.3332015510957254,
+ 2.3177169100087984,
+ 2.302923597380779,
+ 2.288790756005567,
+ 2.2752889053561534,
+ 2.2623898802136084,
+ 2.250066772028685,
+ 2.23829387289304,
+ 2.2270466220056035,
+ 2.21630155452372,
+ 2.2060362526908253,
+ 2.196229299141507,
+ 2.1868602322873785,
+ 2.1779095036891287,
+ 2.1693584373282744,
+ 2.1611891906943277,
+ 2.1533847176048013,
+ 2.145928732682899,
+ 2.1388056774176825,
+ 2.1320006877379507,
+ 2.125499563030551,
+ 2.1192887365398065,
+ 2.113355247087553,
+ 2.1076867120526006,
+ 2.1022713015558105,
+ 2.0970977137961215,
+ 2.092155151486069,
+ 2.0874332993384708,
+ 2.082922302556797,
+ 2.0786127462849016,
+ 2.0744956359735283,
+ 2.070562378622614,
+ 2.0668047648594987,
+ 2.0632149518174363,
+ 2.059785446777764,
+ 2.0565090915410997,
+ 2.05337904749653,
+ 2.050388781356637,
+ 2.0475320515291053,
+ 1.9864209304153415
+ ],
+ "density": [
+ 0.04048744608721366,
+ 0.040991967564575016,
+ 0.041600133540233744,
+ 0.04226815318206501,
+ 0.04300976853695856,
+ 0.04382292413886765,
+ 0.044710990818178135,
+ 0.04566084382265294,
+ 0.04668132671587653,
+ 0.04778384269676666,
+ 0.04894347040181093,
+ 0.050217658359466025,
+ 0.05155120707621356,
+ 0.05298459045905281,
+ 0.05451328150461624,
+ 0.05613579339020678,
+ 0.05786886344594796,
+ 0.05971555622426197,
+ 0.06168940973780461,
+ 0.06379299848100341,
+ 0.06604924274633829,
+ 0.06845688699486069,
+ 0.07104012824009528,
+ 0.07381877203820006,
+ 0.07680888578177371,
+ 0.07999015982750216,
+ 0.0834079665219863,
+ 0.08705720329088246,
+ 0.09096350307186839,
+ 0.09519183101684933,
+ 0.09977767252368747,
+ 0.10473300929035899,
+ 0.1101772697322425,
+ 0.11612224522135849,
+ 0.12263233516381865,
+ 0.12965535501683825,
+ 0.13730843623793318,
+ 0.1456718556947092,
+ 0.15482815214674314,
+ 0.1649193448672138,
+ 0.17609578865161815,
+ 0.18843317970688814,
+ 0.20225092445258935,
+ 0.21769147208669645,
+ 0.235057725643753,
+ 0.25450284419119984,
+ 0.27607481059071376,
+ 0.3001968017285936,
+ 0.32721833903790154,
+ 0.35788158051591024,
+ 0.3927201787927346,
+ 0.3419825951457436,
+ 4.4007276393775686e-05,
+ 2.118242147089871e-06,
+ 9.990808414127548e-06,
+ 2.1760842922898868e-05,
+ 1.0701015086025121e-05,
+ 2.0686100893291997e-05,
+ 1.4102252243972512e-05,
+ 1.6341843536751136e-05,
+ 5.920055478903454e-05,
+ 3.1202822019714874e-05,
+ 7.006577902969221e-06,
+ 3.0485999375746203e-110,
+ 1.351046152877299e-05,
+ 3.723317857953726e-05,
+ 1.4621524348837632e-05,
+ 8.234384469567877e-05,
+ 4.724949485563587e-07,
+ 1.3234130610459686e-05,
+ 1.1250023529740069e-06,
+ 3.40650350246754e-05,
+ 8.61113675417637e-05,
+ 3.4544273659392032e-06,
+ 1.115441842931324e-05,
+ 6.750427753043206e-05,
+ 0.000101851956735232,
+ 4.1417751607125216e-07,
+ 1.733113479346441e-05,
+ 0.00014160026465313052,
+ 0.00017297702950056632,
+ 0.00026253696716014923,
+ 0.0003314571871220419,
+ 0.0006750813370322345,
+ 0.0011644314857210615,
+ 0.0019017827396563996,
+ 0.0032704725357429448,
+ 0.006078302645905549,
+ 0.010855190117619993,
+ 0.01953392347223397,
+ 1.8680620540029122e-05,
+ 7.144970850284283e-05,
+ 5.542912364767046e-06,
+ 7.435691322796886e-05,
+ 0.00016143391343427039,
+ 0.00020306133691749687,
+ 0.00028544558695254034,
+ 0.0008743656306073129,
+ 0.0024050292905490136,
+ 0.005775071597051694,
+ 0.0005348662947240205,
+ 0.0006539565495507168,
+ 0.0010281871631532197,
+ 0.0013522734276574968,
+ 0.0018752787770719434,
+ 0.0022794719905617836,
+ 0.0032833530457091267,
+ 0.001990519405536644,
+ 0.005452626266015973,
+ 0.00677493232228747,
+ 0.008864117251803522,
+ 0.011092803666997013,
+ 0.013852370395545835,
+ 0.0172470165417693,
+ 0.020371187929570215,
+ 0.025505315179375047,
+ 0.031074048340423287,
+ 0.037995782307585234,
+ 0.0465310460856086,
+ 0.05631424807984447,
+ 0.06745275939537863,
+ 0.08017572144032707,
+ 0.09451365752132886,
+ 0.11074564103118154,
+ 0.12885395814665107,
+ 0.1495571109436204,
+ 0.17305975617364092,
+ 0.19900124477774955,
+ 0.22795492765149622,
+ 0.26016815091843437,
+ 0.29558301290421074,
+ 0.335098447301964,
+ 0.3787529583978551,
+ 0.42680395334454346,
+ 0.47905611444170587,
+ 0.5362824136346813,
+ 0.5985500572439016,
+ 0.6662418422094794,
+ 0.7392810015960789,
+ 0.8192667858555257,
+ 0.9041791387661262,
+ 0.9967330727340975,
+ 1.0961554182560838,
+ 1.202232925311796,
+ 1.3149305765995665,
+ 1.435581443569537,
+ 1.5641755524988206,
+ 1.6995539260866523,
+ 1.8438087576258209,
+ 1.9952089389535912,
+ 2.1548842155881163,
+ 2.3225752489437097,
+ 2.497782026083675,
+ 2.6799685020901842,
+ 2.8702102138142576,
+ 3.067718277784516,
+ 3.272652118255717,
+ 3.4841842881068805,
+ 3.70264957750554,
+ 3.9265053166806303,
+ 4.157418486084073,
+ 4.391689392465598,
+ 4.632972611931735,
+ 4.8774029454280745,
+ 5.12689907629093,
+ 5.380601479886791,
+ 5.635293049863927,
+ 5.894617217838846,
+ 6.15540931208811,
+ 6.41854607357553,
+ 6.681319307917702,
+ 6.9455701730729045,
+ 7.20987457968002,
+ 7.475425480246554,
+ 7.738667122716035,
+ 8.00131956130091,
+ 8.26244637126789,
+ 8.522348348950743,
+ 8.779348920756686,
+ 9.032914882475161,
+ 9.284651592551567,
+ 9.532433301321392,
+ 9.777230760031252,
+ 10.0174789157339,
+ 10.254100706292657,
+ 10.487234177305957,
+ 10.71545840617981,
+ 10.939496800352414,
+ 11.158697017879582,
+ 11.37314606319091,
+ 11.58237151830138,
+ 11.786714430857282,
+ 11.98677813625825,
+ 12.1808353928344,
+ 12.369922844931047,
+ 12.55375159835506,
+ 12.733137363800198,
+ 12.905822998243242,
+ 13.074456274693999,
+ 13.237236622767275,
+ 13.396079440071818,
+ 13.55086631379442,
+ 13.69892325592837,
+ 13.84289554141327,
+ 13.981971275333507,
+ 14.117407405854768,
+ 14.246818740400403,
+ 14.37203389084361,
+ 14.493587620099008,
+ 14.609735497673544,
+ 14.723242173478098,
+ 14.831297504428605,
+ 14.935912532356166,
+ 15.037379352591227,
+ 15.133755168376675,
+ 15.226465373590704,
+ 15.31670960797513,
+ 15.402724885287265,
+ 15.486363892362997,
+ 15.566439939250113,
+ 15.642186731562068,
+ 15.717136638192025,
+ 15.787527775619653,
+ 15.85536956371587,
+ 15.919950135878985,
+ 15.982642593928864,
+ 16.043113366621782,
+ 16.09989366562893,
+ 16.15516174675919,
+ 16.207812578733854,
+ 16.259269128589985,
+ 16.308251288450823,
+ 16.354604739329357,
+ 16.39882478129081,
+ 16.441254777863826,
+ 16.482492572267855,
+ 16.52136186970244,
+ 16.559074281078065,
+ 16.594586374436723,
+ 16.62951333749602,
+ 16.662596876693172,
+ 16.693809896725444,
+ 16.723989679209343,
+ 16.75356267510578,
+ 16.779924132332624,
+ 16.807121709533483,
+ 16.831205414235242,
+ 16.856245388846574,
+ 16.878685435533402,
+ 16.901672493576328,
+ 16.92253181927624,
+ 16.94316073854124,
+ 16.9612022642688,
+ 16.979916247897123,
+ 16.997137492131074,
+ 17.325004601219867
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 0
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon1.json b/cherab/generomak/plasma/data/core/carbon1.json
new file mode 100644
index 00000000..b2d5c389
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon1.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 0.48421585057396443,
+ 0.4902687240676583,
+ 0.49744711278943604,
+ 0.5051954006896824,
+ 0.5136620119549894,
+ 0.5228114951520789,
+ 0.5326752171258001,
+ 0.5430889205581807,
+ 0.5541504144444251,
+ 0.5659869467934964,
+ 0.5782948447729008,
+ 0.5917437089789345,
+ 0.6056712485911827,
+ 0.620542945043669,
+ 0.6362922713807064,
+ 0.6528879784388633,
+ 0.670509736386118,
+ 0.6891758543862906,
+ 0.7090235821831914,
+ 0.7300618223316414,
+ 0.7525298929070332,
+ 0.7763877953370656,
+ 0.8018826318051548,
+ 0.8292062565837163,
+ 0.8585038018336258,
+ 0.889508177208562,
+ 0.9226832625401263,
+ 0.9579291559694979,
+ 0.9954837795225133,
+ 1.0360065994185788,
+ 1.0798223982450068,
+ 1.1269947674435963,
+ 1.1787338800321392,
+ 1.2350760742733788,
+ 1.2966027474529238,
+ 1.3626536962098275,
+ 1.4343556208152823,
+ 1.5124235977441491,
+ 1.597576238405414,
+ 1.691121912675909,
+ 1.7944189321292177,
+ 1.9080331127816117,
+ 2.0349641993946186,
+ 2.176361663537031,
+ 2.3349380858639535,
+ 2.5118452848013555,
+ 2.707159678115966,
+ 2.9246174853883784,
+ 3.1671420854781687,
+ 3.4413506012389776,
+ 3.751694445122891,
+ 3.2477798067270536,
+ 0.006362863907386773,
+ 0.007372973669191416,
+ 0.009216593289128903,
+ 0.011548156028595503,
+ 0.014242714795831715,
+ 0.01786146488055299,
+ 0.022262162510133958,
+ 0.027939765134883766,
+ 0.03551634957985896,
+ 0.04443958387088995,
+ 0.055958579944039195,
+ 0.07088116012661974,
+ 0.09018659935564127,
+ 0.11496387559603737,
+ 0.14633834787935424,
+ 0.1875802388118898,
+ 0.23936517945868985,
+ 0.30754162306911564,
+ 0.3958068353549918,
+ 0.5112101892350656,
+ 0.6620966618289457,
+ 0.858660078735121,
+ 1.1181241421419907,
+ 1.46073435693994,
+ 1.911282430745415,
+ 2.5029504245674246,
+ 3.2846111449205577,
+ 4.318608003844665,
+ 5.687666141161567,
+ 7.506630045311503,
+ 9.92851137619441,
+ 13.163696880564427,
+ 17.493477080108423,
+ 23.303174917833566,
+ 31.091974173382223,
+ 41.45633739453835,
+ 55.267703371244075,
+ 73.72690488904475,
+ 98.20863422520927,
+ 131.2870853869013,
+ 175.83683138019174,
+ 235.99204766064628,
+ 316.38571854740593,
+ 421.7539328588253,
+ 559.4357994437013,
+ 738.9164751802173,
+ 972.3391869076578,
+ 1275.153777920394,
+ 1666.7711728749346,
+ 2171.6699589645095,
+ 2819.988751814856,
+ 3648.7031646271603,
+ 4702.668366138428,
+ 6035.779233963542,
+ 7686.47757537614,
+ 9663.067856260159,
+ 12007.31337433541,
+ 14768.024487039194,
+ 18001.483822967057,
+ 21772.849505706734,
+ 26157.550424254878,
+ 31242.376433647383,
+ 37126.23247711799,
+ 43920.55849586252,
+ 51749.31820504792,
+ 60748.85541615466,
+ 71036.10519259654,
+ 82505.25321944867,
+ 95172.6035262625,
+ 109100.32854050657,
+ 124351.58313892053,
+ 140991.89397504224,
+ 159090.80831541793,
+ 178723.66872728983,
+ 199973.32015148445,
+ 222931.63069035482,
+ 247704.87774357302,
+ 274402.6314683522,
+ 303149.57485778275,
+ 334081.81511881127,
+ 367346.4298088521,
+ 403095.30458799424,
+ 441271.5467435238,
+ 481872.1263701006,
+ 525005.3743482265,
+ 570775.3503247264,
+ 619280.1323497095,
+ 670610.2296256337,
+ 724847.0330594878,
+ 782061.4947899283,
+ 842312.7805629332,
+ 905647.1583655913,
+ 972096.9884098681,
+ 1041679.8789890977,
+ 1114397.9704522684,
+ 1190237.4178496636,
+ 1269168.0928057458,
+ 1351143.3680309465,
+ 1436100.2152481882,
+ 1523959.3923222842,
+ 1614625.8637893011,
+ 1707989.3899476596,
+ 1803925.2961875116,
+ 1902295.3488111356,
+ 2002948.8264528697,
+ 2105723.6679099784,
+ 2210447.758156687,
+ 2316940.2461408074,
+ 2425012.996869253,
+ 2534471.9531783885,
+ 2645118.713026125,
+ 2756751.8441781844,
+ 2869168.440277809,
+ 2982165.4309753384,
+ 3095540.9198091724,
+ 3209095.535627261,
+ 3322633.485232032,
+ 3435963.746723633,
+ 3548904.406828813,
+ 3661274.607561598,
+ 3772901.237685582,
+ 3883621.082668308,
+ 3993279.51143659,
+ 4101731.027144971,
+ 4208839.542291893,
+ 4314478.668059076,
+ 4418531.841795906,
+ 4520892.427679443,
+ 4621463.716299819,
+ 4720158.78415636,
+ 4816900.409340878,
+ 4911620.80796254,
+ 5004261.422094195,
+ 5094772.583239676,
+ 5183113.162616801,
+ 5269250.234491738,
+ 5353158.645119106,
+ 5434820.618175021,
+ 5514225.314109624,
+ 5591368.407651634,
+ 5666251.643182443,
+ 5738882.3707925305,
+ 5809273.161495088,
+ 5877441.340120579,
+ 5943408.591682677,
+ 6007200.515329759,
+ 6068846.311127089,
+ 6128378.312740362,
+ 6185831.708189282,
+ 6241244.1418844825,
+ 6294655.385905712,
+ 6346107.111966662,
+ 6395642.518902035,
+ 6443306.118805427,
+ 6489143.4314059075,
+ 6533200.829506674,
+ 6575525.270986898,
+ 6616164.092233446,
+ 6655164.89427008,
+ 6692575.279163696,
+ 6728442.694407392,
+ 6762814.329286974,
+ 6795737.335340715,
+ 6827258.228432123,
+ 6857422.965645077,
+ 6886276.833068685,
+ 6913864.435669005,
+ 6940229.566958312,
+ 6965415.187144678,
+ 6989463.413916613,
+ 7012415.368759321,
+ 7034311.272954711,
+ 7055190.338080873,
+ 7075090.793272931,
+ 7094049.833290375,
+ 7112103.614543278,
+ 7129287.29681578,
+ 7145634.973864277,
+ 7161179.732926623,
+ 7175953.608746651,
+ 7189987.629596161,
+ 7203311.823403726,
+ 7215955.222910218,
+ 7227945.884573181,
+ 7239310.885176149,
+ 7250076.380752132,
+ 7260267.580029734,
+ 7269908.81296078,
+ 7279023.497225329,
+ 7287634.200202345,
+ 7295762.6574449,
+ 7303429.782592609,
+ 7310655.664301383,
+ 7317459.684297547,
+ 7323860.396159016,
+ 7329875.705663031,
+ 7335522.739642086,
+ 7340818.009363841,
+ 7345777.309661405,
+ 7350415.843108907,
+ 7354748.154845227,
+ 7358788.250898356,
+ 7362549.51046329,
+ 7180737.62151424
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 1
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon2.json b/cherab/generomak/plasma/data/core/carbon2.json
new file mode 100644
index 00000000..c7f6d89a
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon2.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 51.7269475194356,
+ 51.746952820624216,
+ 52.12388596214026,
+ 52.940163304633074,
+ 54.24294247848471,
+ 56.07509778838055,
+ 58.48625229633952,
+ 61.5368349714206,
+ 65.3030344598767,
+ 69.8785578386221,
+ 75.37529754084595,
+ 81.93078413627545,
+ 89.70164187223259,
+ 98.87428659903192,
+ 109.65942092421292,
+ 122.2933234051085,
+ 137.035367139739,
+ 154.16006793143808,
+ 173.94684809895617,
+ 196.66154529962796,
+ 222.53238297052988,
+ 251.7134046195229,
+ 284.2420121677726,
+ 319.983444861121,
+ 358.5598123137554,
+ 398.9683223412675,
+ 440.76433555850025,
+ 484.2490374594113,
+ 530.1044415099693,
+ 579.4915040302302,
+ 634.1713927433501,
+ 696.6820796978036,
+ 770.6142544227597,
+ 860.9672258522206,
+ 970.0620403589148,
+ 1099.2314423795724,
+ 1252.1185630618302,
+ 1432.9887166910512,
+ 1646.7948934705498,
+ 1899.2398766520157,
+ 2196.8166107464817,
+ 2546.8186480837194,
+ 2957.3244606006606,
+ 3437.1830720402863,
+ 3995.651317855098,
+ 4645.819288446255,
+ 5408.159661965817,
+ 6304.394233890673,
+ 7360.988631169922,
+ 8610.408235852314,
+ 10092.612861174073,
+ 11853.166711872651,
+ 13944.655327903243,
+ 16470.555060218794,
+ 19507.094824911295,
+ 23149.859879749787,
+ 27528.59209934883,
+ 32805.44146433598,
+ 39181.431974834195,
+ 46906.5301364389,
+ 56292.49024857901,
+ 67729.29859868562,
+ 81704.69552439438,
+ 98758.342767045,
+ 119563.79546648111,
+ 145008.98972599223,
+ 176209.22723183295,
+ 214569.82314126665,
+ 261867.1097143878,
+ 320353.5889126574,
+ 392894.6330259606,
+ 483146.86838287814,
+ 595791.405155585,
+ 736839.602081546,
+ 914034.8394921427,
+ 1137314.4676054649,
+ 1417795.5431438887,
+ 1770046.1195692741,
+ 2213501.0254945313,
+ 2773182.8952475805,
+ 3481388.8206957136,
+ 4379900.14495483,
+ 5522876.267226655,
+ 6980639.120267879,
+ 8844609.797864616,
+ 11234098.954064578,
+ 14292249.250883874,
+ 18171268.57400767,
+ 23102344.070654884,
+ 29391183.874651648,
+ 37439200.11924598,
+ 47773938.07168198,
+ 61088401.78943633,
+ 78290898.38971062,
+ 100252654.95122445,
+ 127678619.24781525,
+ 161848156.43389606,
+ 204348916.72694722,
+ 257122494.6832895,
+ 322522738.08793396,
+ 403373666.46606535,
+ 503023672.34567523,
+ 625393056.5647471,
+ 775013474.5069699,
+ 957060449.3713105,
+ 1177383070.8421464,
+ 1437802639.9565027,
+ 1734246225.369133,
+ 2068654420.0998182,
+ 2443569577.2558446,
+ 2862029131.1002626,
+ 3327664301.685319,
+ 3844746919.3145304,
+ 4418179733.538788,
+ 5053433114.860162,
+ 5756438161.127043,
+ 6533452755.5666065,
+ 7390922881.304381,
+ 8331837423.650323,
+ 9334354678.472628,
+ 10392166684.043266,
+ 11504279057.327274,
+ 12669790141.968946,
+ 13888035317.62539,
+ 15158729343.112686,
+ 16482091274.303825,
+ 17858939920.92599,
+ 19290752420.740105,
+ 20779851078.546913,
+ 22328898303.12378,
+ 23941318873.556976,
+ 25621068937.484055,
+ 27372541721.972637,
+ 29200132814.888065,
+ 31095452170.414516,
+ 33054347498.016705,
+ 35079589851.19578,
+ 37173581351.618835,
+ 39338307423.93913,
+ 41575301929.46964,
+ 43885622896.80891,
+ 46269837046.91366,
+ 48728011738.553474,
+ 51259713312.86814,
+ 53864011077.12315,
+ 56539486357.443695,
+ 59284246173.27229,
+ 62095941159.639656,
+ 64971787396.43695,
+ 67908591808.401474,
+ 70902780790.1204,
+ 73950431683.65508,
+ 77047306712.3454,
+ 80188888946.12115,
+ 83370419851.9303,
+ 86586937966.57417,
+ 89833318223.03227,
+ 93104311461.33716,
+ 96394583667.15906,
+ 99698754499.39764,
+ 103011434697.43271,
+ 106327261990.32256,
+ 109640935175.03737,
+ 112947246068.6951,
+ 116241109095.60986,
+ 119517588310.54092,
+ 122771921715.4813,
+ 125999542772.99667,
+ 129196099063.11314,
+ 132357468080.74841,
+ 135479838062.1428,
+ 138559536495.15198,
+ 141593161723.4288,
+ 144577614224.11197,
+ 147510062820.63623,
+ 150387945085.9323,
+ 153208965707.6481,
+ 155971093006.19897,
+ 158672553796.7852,
+ 161311826790.89548,
+ 163887634728.62924,
+ 166398935429.4681,
+ 168844911944.07657,
+ 171224961977.36823,
+ 173538686747.2005,
+ 175785879428.2105,
+ 177966513320.9635,
+ 180080729873.50775,
+ 182128826668.6315,
+ 184111245479.87717,
+ 186028560485.09735,
+ 187881466715.82117,
+ 189670768808.52518,
+ 191397370113.5591,
+ 193062262208.28482,
+ 194666514849.56927,
+ 196211266395.00525,
+ 197697714711.99057,
+ 199127108590.06726,
+ 200500739660.8907,
+ 201819934831.14236,
+ 203086049222.54807,
+ 204300459614.14108,
+ 205464558376.57272,
+ 206579747883.16934,
+ 207647435385.08353,
+ 208669028330.83698,
+ 209645930113.7524,
+ 210579536224.9345,
+ 211471230792.85892,
+ 212322383488.85797,
+ 213134346775.05908,
+ 213908449029.64093,
+ 214645996841.59247,
+ 215348286616.73877,
+ 216016580696.22003,
+ 216652114874.8826,
+ 217256097283.5322,
+ 217829707477.1932,
+ 218374095710.14105,
+ 218890382383.57236,
+ 219379657649.66318,
+ 219842981155.79706,
+ 220281381919.172,
+ 220695858314.53354,
+ 221087378166.2643,
+ 221456878931.67258,
+ 221805267966.18643,
+ 222133422860.92596,
+ 222442191842.04816,
+ 222732394226.20602,
+ 223004820922.12497,
+ 223260234973.31854,
+ 223499372134.43323,
+ 223722941475.72876,
+ 223931626010.58966,
+ 224126083341.021,
+ 224306946317.5971,
+ 224474823708.58456,
+ 224630300876.42337,
+ 224773940456.65158,
+ 224906283038.34857,
+ 225027847842.1965,
+ 225139133394.53152,
+ 225240618195.1795,
+ 225332761378.8069,
+ 225416003364.91315,
+ 225490766500.28265,
+ 225557455686.99042,
+ 225616459000.8862,
+ 225668148294.455,
+ 225712879788.01535,
+ 225750994644.923,
+ 225782819533.8887,
+ 225808667174.40283,
+ 214533479339.8047
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 2
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon3.json b/cherab/generomak/plasma/data/core/carbon3.json
new file mode 100644
index 00000000..d561f286
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon3.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 1696833.2929320585,
+ 1695585.5346261703,
+ 1703034.1483737943,
+ 1721256.0083039757,
+ 1751174.826856844,
+ 1793462.9777274628,
+ 1848789.2681748066,
+ 1917932.0502929946,
+ 2001843.1487110062,
+ 2101691.8507644087,
+ 2218901.8049322264,
+ 2355187.4339219616,
+ 2512593.5720948935,
+ 2693541.143056974,
+ 2900880.7853058777,
+ 3137956.567619743,
+ 3408681.8389850566,
+ 3717629.590246343,
+ 4070140.147236769,
+ 4472449.503360834,
+ 4931842.339843194,
+ 5456834.574082767,
+ 6057391.4069654485,
+ 6745188.043835769,
+ 7533894.08882723,
+ 8438040.68619504,
+ 9474927.617135428,
+ 10666144.076443244,
+ 12037269.181392074,
+ 13618691.263185747,
+ 15446615.360481534,
+ 17564303.70763869,
+ 20023607.824385516,
+ 22886777.35580498,
+ 26222719.857324515,
+ 30112198.083528586,
+ 34654282.723995,
+ 39966924.52730038,
+ 46190732.40796578,
+ 53493550.959011845,
+ 62076004.239125356,
+ 72178217.79676005,
+ 84087979.04679102,
+ 98153684.12489405,
+ 114790268.27579233,
+ 134480496.8088131,
+ 157796732.52584448,
+ 185454477.7662331,
+ 218321063.70239368,
+ 257449759.17177022,
+ 304122403.0477343,
+ 359902414.63618606,
+ 426700895.5275371,
+ 506859421.1661952,
+ 603150803.3245813,
+ 718665327.1439896,
+ 857491337.6972063,
+ 1024713797.2305741,
+ 1226629970.51637,
+ 1471064146.446006,
+ 1767770494.5111785,
+ 2128950440.3712964,
+ 2569871178.013945,
+ 3107483535.2911277,
+ 3762666980.8892303,
+ 4562658718.166039,
+ 5541407710.59275,
+ 6741327176.803194,
+ 8215528044.0905075,
+ 10030670665.17434,
+ 12270612334.574423,
+ 15041080240.00464,
+ 18475666848.57919,
+ 22743531642.40487,
+ 28059304890.69837,
+ 34694130667.19102,
+ 42949504729.17792,
+ 53215803474.32276,
+ 66005843073.27365,
+ 81970232639.91074,
+ 101935947429.07399,
+ 126955857114.0498,
+ 158372211099.3084,
+ 197897781357.9156,
+ 247719125699.63535,
+ 310636487052.79944,
+ 389922612130.1703,
+ 488927829361.61676,
+ 612743572971.3516,
+ 767966754305.5444,
+ 963061978933.3938,
+ 1208880863704.0518,
+ 1519300911417.147,
+ 1911986213718.501,
+ 2402412088320.5693,
+ 3001219151011.2773,
+ 3730120534876.667,
+ 4615158784849.36,
+ 5686907738665.593,
+ 6980763900484.745,
+ 8537026859965.436,
+ 10400699753349.402,
+ 12620966467453.045,
+ 15250350343992.717,
+ 18343622207917.098,
+ 21956583495935.363,
+ 26064693092269.617,
+ 30544136400340.87,
+ 35377753295293.17,
+ 40555945070609.02,
+ 46074045244408.83,
+ 51933029405493.94,
+ 58139222942210.87,
+ 64703130552471.7,
+ 71637626192466.19,
+ 78955815493426.89,
+ 86668917902746.72,
+ 94784516303177.33,
+ 103263931645205.48,
+ 111787224185099.47,
+ 120246770335232.78,
+ 128605747496359.89,
+ 136833759942592.23,
+ 144907844298562.9,
+ 152813152835414.7,
+ 160543211765841.1,
+ 168099722187906.75,
+ 175491935454603.38,
+ 182735876734993.4,
+ 189852619551918.88,
+ 196867432542592.47,
+ 203808284935431.44,
+ 210704581917170.66,
+ 217583961405604.62,
+ 224394192250872.2,
+ 231116082117766.88,
+ 237773792771364.6,
+ 244387675489041.34,
+ 250974441603543.8,
+ 257547405498000.12,
+ 264116767501773.88,
+ 270689913774420.62,
+ 277271717683311.97,
+ 283864832683560.44,
+ 290469970659869.75,
+ 297086162435741.6,
+ 303710998999869.2,
+ 310340853188191.1,
+ 316971082286105.75,
+ 323596212423999.56,
+ 330210105837718.44,
+ 336806112130098.3,
+ 343377204653890.2,
+ 349916103076979.94,
+ 356415383111422.3,
+ 362867574303987.75,
+ 369265246706052.7,
+ 375601087170428.94,
+ 381867965963014.5,
+ 388058994328742.4,
+ 394167573613298.7,
+ 400187436512475.75,
+ 406112680998405.06,
+ 411937797455005.75,
+ 417657689540276.8,
+ 423267689282113.25,
+ 428763566902546.94,
+ 434141535854502.4,
+ 439398253542820.25,
+ 444530818187850.8,
+ 449536811414876.2,
+ 454414150553507.06,
+ 459161179124996.75,
+ 463776666728802.44,
+ 468259765082445.1,
+ 472609990374218.7,
+ 476827204446105.7,
+ 480911595099409.4,
+ 484863655789798.3,
+ 488684164954596.6,
+ 492374165189189.6,
+ 495934942466422.6,
+ 499368005568998.6,
+ 502675065882530.7,
+ 505858017676230.6,
+ 508918918977704.56,
+ 511859973130526.25,
+ 514683511105241.2,
+ 517391974619713.7,
+ 519987900109775.94,
+ 522473903578741.44,
+ 524852666342586.44,
+ 527126921677870.1,
+ 529299442370347.3,
+ 531373029154628.2,
+ 533350500028981.56,
+ 535234680423608.1,
+ 537028394196253.75,
+ 538734455425684.3,
+ 540355660970247.06,
+ 541894783756889.0,
+ 543354566764333.56,
+ 544737717663353.94,
+ 546046904076213.9,
+ 547284749417582.06,
+ 548453829279530.9,
+ 549556668323423.5,
+ 550595737642856.25,
+ 551573452562394.7,
+ 552492170838372.0,
+ 553354191229003.4,
+ 554161752403094.4,
+ 554917020632621.5,
+ 555622101348608.25,
+ 556279072705655.25,
+ 556889927902278.8,
+ 557456598671095.75,
+ 557980955650210.25,
+ 558464808917578.9,
+ 558909908669404.6,
+ 559317946024909.9,
+ 559690553941324.56,
+ 560029308223890.9,
+ 560335728617201.25,
+ 560611279965183.6,
+ 560857373428226.7,
+ 561075367746842.94,
+ 561266570542317.8,
+ 561432239645791.94,
+ 561573584447694.25,
+ 561691767260778.06,
+ 561787904690278.2,
+ 561863069005538.4,
+ 561918289508186.7,
+ 561954553892423.7,
+ 561972809593324.8,
+ 561973965120028.06,
+ 561958891370560.56,
+ 561928422925964.1,
+ 561883359321281.1,
+ 561824466291756.2,
+ 561752476992557.2,
+ 561668093190769.7,
+ 561571986428726.75,
+ 561464799157707.44,
+ 561347145841483.9,
+ 561219614029419.6,
+ 561082765398626.2,
+ 560937136765227.25,
+ 560783241064650.5,
+ 560621568301310.75,
+ 560452586467449.8,
+ 560276742431891.2,
+ 560094462798939.7,
+ 559906154737711.9,
+ 519569650787351.1
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 3
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon4.json b/cherab/generomak/plasma/data/core/carbon4.json
new file mode 100644
index 00000000..47ad77e9
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon4.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 46350405566.4054,
+ 46284237625.31838,
+ 46377376549.137474,
+ 46670924446.71948,
+ 47180482713.78791,
+ 47915138259.74194,
+ 48882300889.21657,
+ 50089810565.15369,
+ 51547022732.33509,
+ 53265438570.25678,
+ 55259122012.65607,
+ 57545021624.12109,
+ 60143260320.84436,
+ 63077429051.469345,
+ 66374906777.00613,
+ 70067221925.64133,
+ 74190466880.22955,
+ 78785775449.38242,
+ 83899872865.75154,
+ 89585708209.65178,
+ 95903180036.86243,
+ 102919967269.99362,
+ 110712479034.47878,
+ 119366939061.52307,
+ 128980381012.53004,
+ 139650356255.3698,
+ 151493758818.3758,
+ 164655600080.99313,
+ 179302730877.29105,
+ 195627523788.2097,
+ 213852271426.5203,
+ 234234433172.45392,
+ 257072908865.32074,
+ 282714170388.7059,
+ 311476125733.1768,
+ 343728268938.59607,
+ 379948809932.3586,
+ 420690633544.8943,
+ 466594150949.36475,
+ 518402716039.77686,
+ 576981020112.0531,
+ 643337087885.5581,
+ 718648637928.0991,
+ 804309566656.8345,
+ 901936517731.6887,
+ 1013174699432.6936,
+ 1139774935542.7197,
+ 1284159542010.1714,
+ 1449192365214.294,
+ 1638263013716.838,
+ 1855394300765.4873,
+ 2105373695410.4524,
+ 2393914584397.565,
+ 2727854650178.9463,
+ 3114672632419.614,
+ 3561244443333.942,
+ 4078057118720.018,
+ 4678093148887.286,
+ 5377140773975.816,
+ 6194475953440.215,
+ 7153727019705.466,
+ 8283975395893.132,
+ 9620926371866.709,
+ 11198091896859.557,
+ 13056165093226.484,
+ 15251094943219.5,
+ 17851237199403.375,
+ 20940359891494.133,
+ 24621431200712.773,
+ 29021405474548.914,
+ 34297285209370.332,
+ 40643817115878.99,
+ 48303284204591.195,
+ 57577989916903.66,
+ 68846203133507.68,
+ 82575863200086.94,
+ 99191653487398.58,
+ 119279439872784.33,
+ 143654027332428.78,
+ 173346839323390.3,
+ 209668709470650.44,
+ 254291921482299.34,
+ 309357550616115.0,
+ 377616004551139.75,
+ 462610980484455.0,
+ 568935169243997.1,
+ 701805790886232.4,
+ 865973256198488.8,
+ 1069469897938848.2,
+ 1322843184955839.5,
+ 1639752367136081.5,
+ 2037895759219286.5,
+ 2540187857311035.5,
+ 3176220966949160.5,
+ 3974318084294743.5,
+ 4957628931592609.0,
+ 6166621547030046.0,
+ 7649980316205009.0,
+ 9465032414640132.0,
+ 1.167815021201937e+16,
+ 1.4364618692277636e+16,
+ 1.760776889672942e+16,
+ 2.149721890418564e+16,
+ 2.612615968793039e+16,
+ 3.158776631002165e+16,
+ 3.7970969353840856e+16,
+ 4.52687863954724e+16,
+ 5.335944463086585e+16,
+ 6.2229908295669816e+16,
+ 7.186462354298768e+16,
+ 8.224162698271402e+16,
+ 9.333233640328437e+16,
+ 1.051001076547748e+17,
+ 1.1749765655473509e+17,
+ 1.3046371799766349e+17,
+ 1.4391954758695259e+17,
+ 1.5776602862745238e+17,
+ 1.7188219580417078e+17,
+ 1.860924287861691e+17,
+ 2.0000578021076806e+17,
+ 2.1344414086257683e+17,
+ 2.2629718005560486e+17,
+ 2.384692421863735e+17,
+ 2.498824535514498e+17,
+ 2.604788577222335e+17,
+ 2.7022136553746403e+17,
+ 2.7909348028404227e+17,
+ 2.8709791375615872e+17,
+ 2.942534901122749e+17,
+ 3.005948389926677e+17,
+ 3.061667080728738e+17,
+ 3.1102163520002963e+17,
+ 3.1521700349012704e+17,
+ 3.188116802063171e+17,
+ 3.2183961044985395e+17,
+ 3.2435828220173325e+17,
+ 3.264375086754881e+17,
+ 3.2813887595373184e+17,
+ 3.295162754327499e+17,
+ 3.306165604397081e+17,
+ 3.3148025418647725e+17,
+ 3.321422598062225e+17,
+ 3.326325410056661e+17,
+ 3.32976754800993e+17,
+ 3.3319682689075654e+17,
+ 3.333114663703342e+17,
+ 3.333366204791668e+17,
+ 3.332858725073262e+17,
+ 3.331707873420125e+17,
+ 3.3300120975678624e+17,
+ 3.3278552069020934e+17,
+ 3.325308566056332e+17,
+ 3.322432966946062e+17,
+ 3.319280222669887e+17,
+ 3.315894522167183e+17,
+ 3.31231357998432e+17,
+ 3.308569611179469e+17,
+ 3.304690157406602e+17,
+ 3.300698786616609e+17,
+ 3.296615685611911e+17,
+ 3.2924581618800666e+17,
+ 3.288241068686598e+17,
+ 3.2839771652957235e+17,
+ 3.2796774223744435e+17,
+ 3.275351281085987e+17,
+ 3.271006873058874e+17,
+ 3.2666512072974803e+17,
+ 3.2622903291511296e+17,
+ 3.2579294556561664e+17,
+ 3.2535730908884525e+17,
+ 3.249224982684324e+17,
+ 3.244888569206653e+17,
+ 3.2405668223940326e+17,
+ 3.236262244858278e+17,
+ 3.2319769953504006e+17,
+ 3.227712934116456e+17,
+ 3.22347166191095e+17,
+ 3.219254553603287e+17,
+ 3.2150627871695424e+17,
+ 3.210897368740363e+17,
+ 3.2067591542741376e+17,
+ 3.202648868338333e+17,
+ 3.198567120409589e+17,
+ 3.19451441904167e+17,
+ 3.190491184198753e+17,
+ 3.186497758007563e+17,
+ 3.1825344141450534e+17,
+ 3.178601366046735e+17,
+ 3.174698774094042e+17,
+ 3.1708267519167014e+17,
+ 3.166985371926715e+17,
+ 3.1631746701840864e+17,
+ 3.1593946506808256e+17,
+ 3.1556452891173523e+17,
+ 3.151926536235753e+17,
+ 3.1482383207651834e+17,
+ 3.1445805520277523e+17,
+ 3.140953122246476e+17,
+ 3.1373559085913184e+17,
+ 3.1337887749952186e+17,
+ 3.130251573767114e+17,
+ 3.126744147026179e+17,
+ 3.123266327978007e+17,
+ 3.119817942051087e+17,
+ 3.1163988079097114e+17,
+ 3.113008738357073e+17,
+ 3.109647541141207e+17,
+ 3.106315019674411e+17,
+ 3.103010973675901e+17,
+ 3.099735199746016e+17,
+ 3.096487491879422e+17,
+ 3.0932676419239776e+17,
+ 3.0900753972786e+17,
+ 3.0869105054967526e+17,
+ 3.083772840437199e+17,
+ 3.080662189016621e+17,
+ 3.0775783376675834e+17,
+ 3.074521072573213e+17,
+ 3.071490179876445e+17,
+ 3.068485445867482e+17,
+ 3.0655066571506963e+17,
+ 3.0625536007936736e+17,
+ 3.0596260644602336e+17,
+ 3.056723836528408e+17,
+ 3.0538467061958035e+17,
+ 3.050994463572906e+17,
+ 3.048166899765865e+17,
+ 3.0453638069496154e+17,
+ 3.042584978432657e+17,
+ 3.039830208713851e+17,
+ 3.0370992935322266e+17,
+ 3.0343920299108154e+17,
+ 3.0317082161944416e+17,
+ 3.029047652082736e+17,
+ 3.0264101386582874e+17,
+ 3.0237954784109037e+17,
+ 3.021203475258075e+17,
+ 3.018633934561758e+17,
+ 3.0160866631429037e+17,
+ 3.013561469292451e+17,
+ 3.011058162780258e+17,
+ 3.0085765548619405e+17,
+ 3.0061164582834656e+17,
+ 3.003677687284272e+17,
+ 3.0012600575984256e+17,
+ 2.9988633864545626e+17,
+ 2.996487492574651e+17,
+ 2.994132196171548e+17,
+ 2.991797318945194e+17,
+ 2.989482684078314e+17,
+ 2.98718811623132e+17,
+ 2.9849134415361574e+17,
+ 2.982658487589408e+17,
+ 2.980423083445655e+17,
+ 2.9782070596092915e+17,
+ 2.7247030199525245e+17
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 4
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon5.json b/cherab/generomak/plasma/data/core/carbon5.json
new file mode 100644
index 00000000..b62ee60a
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon5.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 161024132134966.47,
+ 160653503219502.1,
+ 160507242359572.56,
+ 160667836607887.75,
+ 161159174288638.38,
+ 161989547325367.2,
+ 163160868851305.97,
+ 164672538431461.94,
+ 166523370342109.3,
+ 168712636114736.53,
+ 171240653439960.9,
+ 174109128869520.62,
+ 177321363766464.66,
+ 180882384938404.34,
+ 184799035962934.97,
+ 189080051019599.56,
+ 193736124830517.1,
+ 198779987453727.56,
+ 204226489773322.7,
+ 210092703809260.47,
+ 216398040979350.88,
+ 223164390920621.16,
+ 230416283256009.7,
+ 238181074678749.84,
+ 246488677361616.25,
+ 255347696083510.9,
+ 264777740351847.78,
+ 274822297666057.56,
+ 285530597548920.0,
+ 296958209680815.56,
+ 309167755802187.0,
+ 322229722682802.0,
+ 336223391977405.75,
+ 351237037130031.44,
+ 367316468989557.44,
+ 384512645316222.44,
+ 402912558128665.9,
+ 422611765562034.25,
+ 443715236374775.9,
+ 466338364535512.5,
+ 490608107464424.5,
+ 516664263896114.6,
+ 544660909569018.25,
+ 574771346195028.4,
+ 607182200712998.2,
+ 641993775762799.1,
+ 679285757098039.9,
+ 719329437626251.1,
+ 762435817884073.2,
+ 808959351131308.6,
+ 859304387830781.4,
+ 913932717589034.6,
+ 973372418549912.6,
+ 1038228266498749.4,
+ 1108965758582219.4,
+ 1185530665811968.8,
+ 1268623485069471.2,
+ 1359148843563016.0,
+ 1458160473424394.8,
+ 1566887347887052.8,
+ 1686765177753372.5,
+ 1819474480244125.5,
+ 1966944277299036.2,
+ 2129644809721581.0,
+ 2308435409989728.5,
+ 2505507727432574.0,
+ 2723405054905318.5,
+ 2965083298551671.5,
+ 3233983555918746.0,
+ 3534118624816150.5,
+ 3870176221435777.5,
+ 4247642221714308.5,
+ 4672947861350066.0,
+ 5153645539587730.0,
+ 5698618664034045.0,
+ 6317959266999076.0,
+ 7015040256490839.0,
+ 7797878657778269.0,
+ 8680238046734384.0,
+ 9678419565046922.0,
+ 1.0811736328238992e+16,
+ 1.2103072275208854e+16,
+ 1.35795351531977e+16,
+ 1.5273210653384718e+16,
+ 1.7222019001933152e+16,
+ 1.9470878411506988e+16,
+ 2.206058988419503e+16,
+ 2.5010246550634016e+16,
+ 2.8374503295553108e+16,
+ 3.221862128793027e+16,
+ 3.6616618204665976e+16,
+ 4.1651074122496936e+16,
+ 4.74120543092295e+16,
+ 5.399462249641901e+16,
+ 6.143726358298171e+16,
+ 6.9713794415034904e+16,
+ 7.88602209992365e+16,
+ 8.889182371626213e+16,
+ 9.979072697762856e+16,
+ 1.1149427025010378e+17,
+ 1.2388317531927544e+17,
+ 1.3677125579435957e+17,
+ 1.4989901351691597e+17,
+ 1.6293374324877622e+17,
+ 1.7547842758551754e+17,
+ 1.8709055180135395e+17,
+ 1.9727096976715142e+17,
+ 2.055969980363844e+17,
+ 2.1184190259838147e+17,
+ 2.1585866802009814e+17,
+ 2.175780909076306e+17,
+ 2.1700505602378323e+17,
+ 2.142110900199348e+17,
+ 2.0932504552875306e+17,
+ 2.02523454416483e+17,
+ 1.940214986495018e+17,
+ 1.8406488653204474e+17,
+ 1.7292237180532278e+17,
+ 1.609070270228471e+17,
+ 1.485192170274923e+17,
+ 1.3607450007252114e+17,
+ 1.2380272018238762e+17,
+ 1.1189501743619742e+17,
+ 1.0050487014189278e+17,
+ 8.974958274849342e+16,
+ 7.971243093411478e+16,
+ 7.04455417952653e+16,
+ 6.197344649530697e+16,
+ 5.42978817655598e+16,
+ 4.7399830330996056e+16,
+ 4.124606771225955e+16,
+ 3.579255597379613e+16,
+ 3.098812762090215e+16,
+ 2.677841934624266e+16,
+ 2.313267459153055e+16,
+ 1.9995837148790244e+16,
+ 1.7299828713764886e+16,
+ 1.498424019897001e+16,
+ 1.2995976233140328e+16,
+ 1.1288719115750174e+16,
+ 9822303083643866.0,
+ 8562060401319240.0,
+ 7478179071658524.0,
+ 6545096357996279.0,
+ 5740941409601873.0,
+ 5047032901085019.0,
+ 4447432774883569.5,
+ 3928554174161130.5,
+ 3478819914604156.5,
+ 3088366959685935.5,
+ 2748792041830096.0,
+ 2452933605216769.0,
+ 2194685492053311.5,
+ 1968838156523490.2,
+ 1770943605623496.8,
+ 1597200692861872.5,
+ 1444357804385388.5,
+ 1309630363135666.2,
+ 1190630927952283.8,
+ 1085309978444810.6,
+ 991905753181653.0,
+ 908901750211121.1,
+ 834990707915531.6,
+ 769044064015345.5,
+ 710086044389402.1,
+ 657271664609963.1,
+ 609868038549173.2,
+ 567238482949368.1,
+ 528828986803599.75,
+ 494156681915552.7,
+ 462801819568105.44,
+ 434394305887636.3,
+ 408610314143343.06,
+ 385166603830043.2,
+ 363814226223222.2,
+ 344334005110715.2,
+ 326532652735273.4,
+ 310239427130823.75,
+ 295303251427072.06,
+ 281590227809429.2,
+ 268981489039979.28,
+ 257371339064654.56,
+ 246665641500495.62,
+ 236780420950391.28,
+ 227640647282167.97,
+ 219179177413892.6,
+ 211335832859303.44,
+ 204056594461261.25,
+ 197292898404320.6,
+ 191001019886732.9,
+ 185141532760857.62,
+ 179678835102545.62,
+ 174580732073686.62,
+ 169818068643664.22,
+ 165364405752635.5,
+ 161195734386968.4,
+ 157290222775333.8,
+ 153627992565845.03,
+ 150190920391755.9,
+ 146962461710962.6,
+ 143927494208912.38,
+ 141072178412878.78,
+ 138383833459875.8,
+ 135850826229914.27,
+ 133462472282759.86,
+ 131208947226407.88,
+ 129081207321019.44,
+ 127070918269517.56,
+ 125170391272622.27,
+ 123372525535675.33,
+ 121670756518192.75,
+ 120059009296409.5,
+ 118531668753453.81,
+ 117083525311571.0,
+ 115709710318728.34,
+ 114405725785893.33,
+ 113167389473178.39,
+ 111990809312097.34,
+ 110872360170072.14,
+ 109808662725540.33,
+ 108796564236592.3,
+ 107833121017659.64,
+ 106915582459347.52,
+ 106041376431703.06,
+ 105208095947617.9,
+ 104413486959420.16,
+ 103655437183194.61,
+ 102931965854681.19,
+ 102241214329040.6,
+ 101581437448067.73,
+ 100950995603730.38,
+ 100348347436377.56,
+ 99772043108404.7,
+ 99220718105874.52,
+ 98693087518270.73,
+ 98187940757455.16,
+ 97704136675393.52,
+ 97240599050432.17,
+ 96796312405593.72,
+ 96370318136411.11,
+ 95961710919354.02,
+ 95569635379466.4,
+ 95193282993472.34,
+ 94831889213877.6,
+ 94484730792535.0,
+ 94151123288018.19,
+ 93830418746832.02,
+ 93522003537859.14,
+ 93225296336143.55,
+ 92939746236089.92,
+ 92664830994011.1,
+ 92400055380555.25,
+ 92144949643312.14,
+ 91899068064388.0,
+ 91661987613690.53,
+ 80088749700966.69
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 5
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/carbon6.json b/cherab/generomak/plasma/data/core/carbon6.json
new file mode 100644
index 00000000..4c824909
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/carbon6.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 4.9983892951576294e+17,
+ 4.983879497133105e+17,
+ 4.967755866140605e+17,
+ 4.9510985466990605e+17,
+ 4.9341581359634624e+17,
+ 4.9170556331941075e+17,
+ 4.89986255096533e+17,
+ 4.8826259422505344e+17,
+ 4.86537891784407e+17,
+ 4.848145870922532e+17,
+ 4.8309453749605005e+17,
+ 4.8137919232444864e+17,
+ 4.796697037214771e+17,
+ 4.7796700064309997e+17,
+ 4.762718401528628e+17,
+ 4.745848440962568e+17,
+ 4.7290652600562976e+17,
+ 4.71237311271517e+17,
+ 4.695775525472951e+17,
+ 4.6792754170000864e+17,
+ 4.6628751920653805e+17,
+ 4.646576816249229e+17,
+ 4.63038187590711e+17,
+ 4.6142916266522874e+17,
+ 4.598307037636062e+17,
+ 4.582429064892481e+17,
+ 4.5666583570714464e+17,
+ 4.5509951511611744e+17,
+ 4.535439474786944e+17,
+ 4.519991158057632e+17,
+ 4.504649841775356e+17,
+ 4.4894149825499296e+17,
+ 4.474285854993411e+17,
+ 4.4592615597774957e+17,
+ 4.4443415477814e+17,
+ 4.42952515097652e+17,
+ 4.414811279853572e+17,
+ 4.400198704534008e+17,
+ 4.3856860516097184e+17,
+ 4.3712717986695616e+17,
+ 4.356954267048369e+17,
+ 4.3427316126968966e+17,
+ 4.3286018150378886e+17,
+ 4.314562255858729e+17,
+ 4.3006107253038886e+17,
+ 4.28674584595776e+17,
+ 4.272966235432586e+17,
+ 4.259268569438572e+17,
+ 4.2456491049926803e+17,
+ 4.23210364386893e+17,
+ 4.218627468670139e+17,
+ 4.205215267547799e+17,
+ 4.191861045425703e+17,
+ 4.178558019143855e+17,
+ 4.165300783172122e+17,
+ 4.152089127552762e+17,
+ 4.138915252178627e+17,
+ 4.1257692847745683e+17,
+ 4.112639828847147e+17,
+ 4.099513696238169e+17,
+ 4.0863755841905824e+17,
+ 4.0732076842764634e+17,
+ 4.059989634281084e+17,
+ 4.046715679784462e+17,
+ 4.0333761021624723e+17,
+ 4.0199477060236544e+17,
+ 4.006403654855438e+17,
+ 3.992712831648083e+17,
+ 3.978839075577596e+17,
+ 3.9647402693668077e+17,
+ 3.950367246761433e+17,
+ 3.935662483399666e+17,
+ 3.920558527100581e+17,
+ 3.9049761151576006e+17,
+ 3.888821916572605e+17,
+ 3.871989618946227e+17,
+ 3.854440535692542e+17,
+ 3.83608792883725e+17,
+ 3.816785306952975e+17,
+ 3.7963586382173274e+17,
+ 3.774600978175744e+17,
+ 3.751266060486219e+17,
+ 3.726060693144332e+17,
+ 3.69863581102174e+17,
+ 3.668576069457651e+17,
+ 3.635385522314936e+17,
+ 3.5986031537030906e+17,
+ 3.557990082407581e+17,
+ 3.5129187163841626e+17,
+ 3.462630238193415e+17,
+ 3.406247132754573e+17,
+ 3.342765850451636e+17,
+ 3.2710558017180826e+17,
+ 3.189869600468432e+17,
+ 3.098538368048117e+17,
+ 2.997091691578431e+17,
+ 2.884763976878227e+17,
+ 2.7609146834775462e+17,
+ 2.6251483616307402e+17,
+ 2.4774269151380362e+17,
+ 2.318189253723286e+17,
+ 2.1484628655656454e+17,
+ 1.9699454486519517e+17,
+ 1.7850310137509254e+17,
+ 1.596756834262952e+17,
+ 1.4086575956198934e+17,
+ 1.2257942351734243e+17,
+ 1.0536119643932915e+17,
+ 8.945080677375304e+16,
+ 7.501077534396101e+16,
+ 6.213221597889738e+16,
+ 5.083876796328754e+16,
+ 4.109548571419219e+16,
+ 3.282073395211112e+16,
+ 2.58991771483556e+16,
+ 2.0194309163133372e+16,
+ 1.5559472132032808e+16,
+ 1.1846815437393852e+16,
+ 8918871356669974.0,
+ 6666488619767974.0,
+ 4952272490160231.0,
+ 3656693545661167.5,
+ 2684245219410593.0,
+ 1959293800683820.2,
+ 1422454462508854.5,
+ 1027495920737416.9,
+ 738735260847582.1,
+ 528869852835632.25,
+ 377246151542587.9,
+ 268208188769288.22,
+ 190158286219365.4,
+ 134519749871650.16,
+ 94999138095081.17,
+ 67016838139886.77,
+ 47388925728580.2,
+ 33655594842202.37,
+ 24010931117580.105,
+ 17211131680797.598,
+ 12397388136261.445,
+ 8975069389548.232,
+ 6531215810353.063,
+ 4778109970512.45,
+ 3514609743151.2197,
+ 2599594904029.761,
+ 1933687843450.649,
+ 1446636619284.179,
+ 1088581422766.1594,
+ 823990834577.6648,
+ 627438327748.4506,
+ 480650770721.95197,
+ 370438747494.49036,
+ 287240088062.0348,
+ 224091191132.38284,
+ 175897776716.16806,
+ 138915940488.82767,
+ 110381427410.77623,
+ 88243745695.27124,
+ 70974708829.00201,
+ 57430010951.75191,
+ 46748736133.543,
+ 38280102857.815254,
+ 31529840224.19217,
+ 26120769367.413773,
+ 21763705170.207542,
+ 18235884795.813892,
+ 15364908451.932526,
+ 13016733283.730207,
+ 11086658506.895058,
+ 9492528928.261642,
+ 8169588216.710768,
+ 7066704039.21469,
+ 6142970302.393482,
+ 5365759572.048553,
+ 4708966109.732259,
+ 4151558497.112541,
+ 3676522729.535672,
+ 3270038222.3734403,
+ 2920833184.218933,
+ 2619678032.075184,
+ 2358985990.8214483,
+ 2132496850.038897,
+ 1935025513.2003684,
+ 1762261779.2242439,
+ 1610609664.5842507,
+ 1477058481.0535715,
+ 1359078978.4888785,
+ 1254538959.6238554,
+ 1161635237.9576263,
+ 1078837828.5027132,
+ 1004844373.7736144,
+ 938543019.4518695,
+ 878981608.3420769,
+ 825342214.7196075,
+ 776920444.1419855,
+ 733107745.1355531,
+ 693376953.2984082,
+ 657270432.3485224,
+ 624389409.1422876,
+ 594385987.3914045,
+ 566955686.755834,
+ 541831025.8088642,
+ 518777281.941817,
+ 497587285.0481517,
+ 478077997.69254464,
+ 460087497.62123114,
+ 443471967.2421416,
+ 428103642.58286554,
+ 413868620.92078733,
+ 400665191.04849786,
+ 388402498.0855996,
+ 376998969.9038688,
+ 366381412.1133349,
+ 356484284.95387477,
+ 347248113.25952405,
+ 338619246.9022559,
+ 330549123.4969663,
+ 322993975.0574306,
+ 315913999.852501,
+ 309273169.99934995,
+ 303038445.91674054,
+ 297179891.09289044,
+ 291670181.76515394,
+ 286484267.6975641,
+ 281599400.4746377,
+ 276994518.5718484,
+ 272650410.9427122,
+ 268549411.96215296,
+ 264675181.73834926,
+ 261012759.79181898,
+ 257548445.94359872,
+ 254269423.21526513,
+ 251163844.2373063,
+ 248220801.75397795,
+ 245430340.81520307,
+ 242782931.8616595,
+ 240269948.92623258,
+ 237883261.9877548,
+ 235615478.3775228,
+ 233459505.95959592,
+ 231408820.5941001,
+ 229457393.87108496,
+ 227599572.65190783,
+ 225830024.39467406,
+ 224143772.6216756,
+ 222536269.81091282,
+ 221003094.60468093,
+ 219540278.05436647,
+ 218143888.0390999,
+ 216810518.66811267,
+ 215536728.0802908,
+ 214319215.59609443,
+ 213155316.59152457,
+ 212042071.98700914,
+ 210976871.09200314,
+ 209957208.5307115,
+ 173744949.17023906
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "carbon",
+ "charge": 6
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/electrons.json b/cherab/generomak/plasma/data/core/electrons.json
new file mode 100644
index 00000000..7b5452e3
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/electrons.json
@@ -0,0 +1,1292 @@
+{
+ "temperature": [
+ 3000.0,
+ 2998.52312403888,
+ 2992.7832506358122,
+ 2982.0621888623136,
+ 2966.1918094687762,
+ 2945.2429393424018,
+ 2919.419338214869,
+ 2889.003692058303,
+ 2854.3254277348515,
+ 2815.7398455505386,
+ 2773.6139136215174,
+ 2728.3163262527637,
+ 2680.2104553864137,
+ 2629.6493480144745,
+ 2576.972213977541,
+ 2522.5020223843676,
+ 2466.5439345047307,
+ 2409.3843734189736,
+ 2351.2905804738834,
+ 2292.5105439306594,
+ 2233.273210983751,
+ 2173.788913597856,
+ 2114.249953285668,
+ 2054.8313013065413,
+ 1995.6913796728331,
+ 1936.972895410661,
+ 1878.803706166504,
+ 1821.2976997951666,
+ 1764.5556742417446,
+ 1708.6662070172113,
+ 1653.7065059997449,
+ 1599.7432352775288,
+ 1546.8333113667693,
+ 1495.024666457186,
+ 1444.3569764096046,
+ 1394.8623520995304,
+ 1346.5659934019332,
+ 1299.4868056747446,
+ 1253.6379790455755,
+ 1209.0275311576331,
+ 1165.6588143030472,
+ 1123.5309880785605,
+ 1082.6394588511619,
+ 1042.9762874292182,
+ 1004.5305664061173,
+ 967.2887686849466,
+ 931.2350687100197,
+ 896.351637928748,
+ 862.6189159894875,
+ 830.0158591507654,
+ 798.5201673375811,
+ 768.1084912334692,
+ 738.7566207447438,
+ 710.4396561172668,
+ 683.1321629276453,
+ 656.8083121109125,
+ 631.4420061264298,
+ 607.0069923036725,
+ 583.4769643502522,
+ 560.8256529464521,
+ 539.0269062941003,
+ 518.0547614329445,
+ 497.88350708511757,
+ 478.4877387378806,
+ 459.84240662666764,
+ 441.9228572346464,
+ 424.7048688815144,
+ 408.16468193306855,
+ 392.2790241242251,
+ 377.0251314515118,
+ 362.3807650566294,
+ 348.3242244903237,
+ 334.83435771552126,
+ 321.890568180333,
+ 309.4728192650518,
+ 297.56163638257,
+ 286.1381069886319,
+ 275.1838787369333,
+ 264.68115599418036,
+ 254.6126949117557,
+ 244.96179723353092,
+ 235.71230300348657,
+ 226.84858232216044,
+ 218.35552628735832,
+ 210.21853724207088,
+ 202.42351844097678,
+ 194.95686323627902,
+ 187.8054438738336,
+ 180.95659998151527,
+ 174.3981268234994,
+ 168.11826338653523,
+ 162.10568035733561,
+ 156.34946804381812,
+ 150.8391242871043,
+ 145.56454240585458,
+ 140.51599920963352,
+ 135.6841431135791,
+ 131.0599823825858,
+ 126.63487352955082,
+ 122.40050988887697,
+ 118.3489103834026,
+ 114.47240850017948,
+ 110.76364148803557,
+ 107.21553978761827,
+ 103.82131670259133,
+ 100.57445831884021,
+ 97.46871367691406,
+ 94.49808520145595,
+ 91.65681939008829,
+ 88.93939776303986,
+ 86.34052807377111,
+ 83.8551357799498,
+ 81.47835577330721,
+ 79.20552436620889,
+ 77.03217153215161,
+ 74.95401339685759,
+ 72.9669449761771,
+ 71.06703315661875,
+ 69.25050991397345,
+ 67.51376576524152,
+ 65.85334344881281,
+ 64.26593182768406,
+ 62.74836001033597,
+ 61.2975916837819,
+ 59.91071965322365,
+ 58.58496058269206,
+ 57.31764993102628,
+ 56.10623707754045,
+ 54.948280631735244,
+ 53.84144392146098,
+ 52.78349065396557,
+ 51.77228074433782,
+ 50.805766305924465,
+ 49.88198779737891,
+ 48.999070321097264,
+ 48.15522006789341,
+ 47.348720902865914,
+ 46.57793108752631,
+ 45.841280133367995,
+ 45.137265782168555,
+ 44.46445110844881,
+ 43.82146173961798,
+ 43.206983189469376,
+ 42.61975830080557,
+ 42.05858479309852,
+ 41.522312911211856,
+ 41.00984317133116,
+ 40.520124200373346,
+ 40.05215066526151,
+ 39.604961288570934,
+ 39.17763694716649,
+ 38.7692988505653,
+ 38.379106795872445,
+ 38.00625749624137,
+ 37.64998297992401,
+ 37.30954905707338,
+ 36.98425385156884,
+ 36.67342639522852,
+ 36.37642528187246,
+ 36.09263737879576,
+ 35.82147659329382,
+ 35.56238269198415,
+ 35.314820170740816,
+ 35.07827717314717,
+ 34.852264455457785,
+ 34.63631439612891,
+ 34.42998004805659,
+ 34.23283423173999,
+ 34.044468667644786,
+ 33.864493146125206,
+ 33.69253473331596,
+ 33.52823701147538,
+ 33.371259352322355,
+ 33.221276221963834,
+ 33.07797651607301,
+ 32.94106292402577,
+ 32.81025132076462,
+ 32.685270185198156,
+ 32.56586004400546,
+ 32.45177293975274,
+ 32.34277192227911,
+ 32.23863056234819,
+ 32.13913248661057,
+ 32.04407093295307,
+ 31.953248325357347,
+ 31.866475867422928,
+ 31.783573153745696,
+ 31.704367798379554,
+ 31.62869507963904,
+ 31.556397600531596,
+ 31.48732496414222,
+ 31.421333463316515,
+ 31.3582857840232,
+ 31.298050721795224,
+ 31.24050291068117,
+ 31.18552256415908,
+ 31.132995227490305,
+ 31.082811541013847,
+ 31.034867013898335,
+ 30.98906180789872,
+ 30.94530053067335,
+ 30.903492038247204,
+ 30.863549246214866,
+ 30.82538894930257,
+ 30.788931648920514,
+ 30.754101388354496,
+ 30.720825595258578,
+ 30.68903493113094,
+ 30.658663147461834,
+ 30.62964694826175,
+ 30.60192585868675,
+ 30.575442099493,
+ 30.550140467063347,
+ 30.52596821875878,
+ 30.502874963360853,
+ 30.480812556378506,
+ 30.459735000005395,
+ 30.439598347523223,
+ 30.420360611949583,
+ 30.401981678749532,
+ 30.384423222424292,
+ 30.36764862680968,
+ 30.35162290891837,
+ 30.336312646168288,
+ 30.321685906848675,
+ 30.307712183679225,
+ 30.294362330325363,
+ 30.28160850073722,
+ 30.26942409119068,
+ 30.257783684906165,
+ 30.246662999132866,
+ 30.23603883458999,
+ 30.225889027158132,
+ 30.21619240172184,
+ 30.206928728068068,
+ 30.19807867874907,
+ 30.18962378882196,
+ 30.181546417381178,
+ 30.17382971080637,
+ 30.16645756764611,
+ 30.159414605066953,
+ 30.15268612679821,
+ 30.146258092504468,
+ 30.1401170885238,
+ 30.13425029990965,
+ 30.128645483719644,
+ 30.123290943494364,
+ 30.118175504875328,
+ 30.113288492308037,
+ 30.108619706785408,
+ 30.104159404583456,
+ 30.09989827694405,
+ 30.095827430664894,
+ 30.091938369554885,
+ 30.08822297671646,
+ 30.00874190034343
+ ],
+ "density": [
+ 5e+19,
+ 4.981243417835291e+19,
+ 4.960402826870333e+19,
+ 4.938876378646617e+19,
+ 4.916988294636239e+19,
+ 4.894895073575541e+19,
+ 4.872689168534975e+19,
+ 4.850431386174099e+19,
+ 4.82816450569505e+19,
+ 4.8059200450545025e+19,
+ 4.783722014076859e+19,
+ 4.761589167152264e+19,
+ 4.739536438387333e+19,
+ 4.7175758996665205e+19,
+ 4.6957174248046666e+19,
+ 4.673969164500353e+19,
+ 4.65233789497414e+19,
+ 4.630829279642529e+19,
+ 4.609448069324508e+19,
+ 4.588198258002084e+19,
+ 4.567083205796747e+19,
+ 4.546105737335663e+19,
+ 4.5252682213529305e+19,
+ 4.504572635781684e+19,
+ 4.484020621485682e+19,
+ 4.463613526993922e+19,
+ 4.443352446035942e+19,
+ 4.423238249261527e+19,
+ 4.403271611221671e+19,
+ 4.383453033457265e+19,
+ 4.3637828643671245e+19,
+ 4.34426131639279e+19,
+ 4.324888480953614e+19,
+ 4.305664341484428e+19,
+ 4.286588784864013e+19,
+ 4.2676616114717884e+19,
+ 4.248882544069383e+19,
+ 4.230251235670968e+19,
+ 4.2117672765396435e+19,
+ 4.193430200425467e+19,
+ 4.175239490142886e+19,
+ 4.157194582570674e+19,
+ 4.1392948731452695e+19,
+ 4.121539719908261e+19,
+ 4.103928447160288e+19,
+ 4.0864603487664456e+19,
+ 4.069134691152288e+19,
+ 4.051950716024378e+19,
+ 4.034907642845002e+19,
+ 4.018004671086943e+19,
+ 4.0012409822910185e+19,
+ 3.984615741946379e+19,
+ 3.968128101211149e+19,
+ 3.951777198489014e+19,
+ 3.935562160875532e+19,
+ 3.919482105486449e+19,
+ 3.903536140678914e+19,
+ 3.887723367175341e+19,
+ 3.872042879098642e+19,
+ 3.856493764926597e+19,
+ 3.841075108372399e+19,
+ 3.82578598919766e+19,
+ 3.810625483963539e+19,
+ 3.795592666725145e+19,
+ 3.780686609673816e+19,
+ 3.765906383731481e+19,
+ 3.751251059100921e+19,
+ 3.736719705775351e+19,
+ 3.7223113940105036e+19,
+ 3.708025194762049e+19,
+ 3.6938601800909865e+19,
+ 3.6798154235393765e+19,
+ 3.665890000478603e+19,
+ 3.652082988432173e+19,
+ 3.638393467374876e+19,
+ 3.6248205200099906e+19,
+ 3.611363232026088e+19,
+ 3.5980206923348574e+19,
+ 3.584791993291257e+19,
+ 3.5716762308972077e+19,
+ 3.55867250498995e+19,
+ 3.545779919416078e+19,
+ 3.532997582192232e+19,
+ 3.5203246056533017e+19,
+ 3.5077601065889927e+19,
+ 3.495303206369484e+19,
+ 3.4829530310609023e+19,
+ 3.470708711531262e+19,
+ 3.4585693835474727e+19,
+ 3.446534187864e+19,
+ 3.434602270303676e+19,
+ 3.422772781831188e+19,
+ 3.4110448786196742e+19,
+ 3.3994177221108638e+19,
+ 3.3878904790691725e+19,
+ 3.376462321630112e+19,
+ 3.3651324273433653e+19,
+ 3.3538999792108577e+19,
+ 3.3427641657201336e+19,
+ 3.331724180873318e+19,
+ 3.320779224211924e+19,
+ 3.3099285008377905e+19,
+ 3.299171221430335e+19,
+ 3.288506602260401e+19,
+ 3.277933865200853e+19,
+ 3.2674522377341583e+19,
+ 3.257060952957118e+19,
+ 3.246759249582918e+19,
+ 3.236546371940678e+19,
+ 3.22642156997264e+19,
+ 3.21638409922914e+19,
+ 3.2064332208615055e+19,
+ 3.1965682016130003e+19,
+ 3.1867883138079457e+19,
+ 3.1770928353391223e+19,
+ 3.1674810496535667e+19,
+ 3.157952245736852e+19,
+ 3.1485057180959785e+19,
+ 3.1391407667409125e+19,
+ 3.129856697164928e+19,
+ 3.1206528203237556e+19,
+ 3.1115284526136713e+19,
+ 3.1024829158485823e+19,
+ 3.093515537236158e+19,
+ 3.0846256493530964e+19,
+ 3.0758125901195686e+19,
+ 3.0670757027729146e+19,
+ 3.058414335840632e+19,
+ 3.049827843112693e+19,
+ 3.0413155836133044e+19,
+ 3.032876921572053e+19,
+ 3.0245112263945794e+19,
+ 3.016217872632765e+19,
+ 3.0079962399544726e+19,
+ 2.9998457131129012e+19,
+ 2.9917656819155902e+19,
+ 2.9837555411930575e+19,
+ 2.9758146907671814e+19,
+ 2.9679425354192785e+19,
+ 2.9601384848579527e+19,
+ 2.9524019536867484e+19,
+ 2.9447323613715747e+19,
+ 2.937129132207994e+19,
+ 2.9295916952883618e+19,
+ 2.922119484468826e+19,
+ 2.9147119383362347e+19,
+ 2.907368500174985e+19,
+ 2.9000886179337527e+19,
+ 2.8928717441922073e+19,
+ 2.885717336127708e+19,
+ 2.878624855481938e+19,
+ 2.8715937685275652e+19,
+ 2.8646235460349194e+19,
+ 2.857713663238656e+19,
+ 2.850863599804493e+19,
+ 2.844072839795962e+19,
+ 2.83734087164125e+19,
+ 2.830667188100075e+19,
+ 2.8240512862306402e+19,
+ 2.8174926673567138e+19,
+ 2.8109908370347393e+19,
+ 2.8045453050210898e+19,
+ 2.798155585239442e+19,
+ 2.7918211957482054e+19,
+ 2.7855416587081368e+19,
+ 2.779316500350069e+19,
+ 2.773145250942718e+19,
+ 2.7670274447607374e+19,
+ 2.7609626200527954e+19,
+ 2.7549503190099005e+19,
+ 2.748990087733828e+19,
+ 2.7430814762057028e+19,
+ 2.7372240382547927e+19,
+ 2.7314173315273884e+19,
+ 2.725660917455944e+19,
+ 2.719954361228283e+19,
+ 2.714297231757104e+19,
+ 2.7086891016495333e+19,
+ 2.7031295471769723e+19,
+ 2.697618148245014e+19,
+ 2.692154488363691e+19,
+ 2.686738154617714e+19,
+ 2.6813687376370782e+19,
+ 2.6760458315677737e+19,
+ 2.67076903404267e+19,
+ 2.665537946152642e+19,
+ 2.660352172417858e+19,
+ 2.65521132075925e+19,
+ 2.65011500247021e+19,
+ 2.645062832188477e+19,
+ 2.6400544278682247e+19,
+ 2.6350894107522163e+19,
+ 2.6301674053443994e+19,
+ 2.625288039382521e+19,
+ 2.620450943810967e+19,
+ 2.6156557527538237e+19,
+ 2.610902103488069e+19,
+ 2.6061896364171543e+19,
+ 2.6015179950445117e+19,
+ 2.5968868259474686e+19,
+ 2.5922957787512246e+19,
+ 2.5877445061031244e+19,
+ 2.5832326636470903e+19,
+ 2.578759909998139e+19,
+ 2.57432590671733e+19,
+ 2.5699303182867214e+19,
+ 2.5655728120845242e+19,
+ 2.561253058360556e+19,
+ 2.5569707302117368e+19,
+ 2.5527255035580244e+19,
+ 2.5485170571182055e+19,
+ 2.544345072386111e+19,
+ 2.54020923360703e+19,
+ 2.5361092277541216e+19,
+ 2.5320447445052424e+19,
+ 2.5280154762197893e+19,
+ 2.5240211179157164e+19,
+ 2.520061367247062e+19,
+ 2.5161359244810146e+19,
+ 2.5122444924759847e+19,
+ 2.5083867766590497e+19,
+ 2.5045624850041692e+19,
+ 2.500771328010387e+19,
+ 2.4970130186799833e+19,
+ 2.493287272497215e+19,
+ 2.489593807406909e+19,
+ 2.485932343793488e+19,
+ 2.482302604459721e+19,
+ 2.478704314606391e+19,
+ 2.475137201811416e+19,
+ 2.471600996009324e+19,
+ 2.4680954294713426e+19,
+ 2.464620236785044e+19,
+ 2.4611751548345704e+19,
+ 2.45775992278063e+19,
+ 2.4543742820412535e+19,
+ 2.451017976272195e+19,
+ 2.447690751347609e+19,
+ 2.444392355341035e+19,
+ 2.4411225385064636e+19,
+ 2.4378810532594893e+19,
+ 2.434667654158714e+19,
+ 2.4314820978872984e+19,
+ 2.4283241432347005e+19,
+ 2.42519355107831e+19,
+ 2.422090084365806e+19,
+ 2.419013508096743e+19,
+ 2.415963589305566e+19,
+ 2.4129400970434146e+19,
+ 2.4099428023610917e+19,
+ 2.406971478291697e+19,
+ 2.4040258998335894e+19,
+ 2.4011058439331717e+19,
+ 2.3982110894683005e+19,
+ 2.395341417231851e+19,
+ 2.0670269989725e+19
+ ],
+ "vtor": [
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10,
+ 1e-10
+ ],
+ "vpol": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/hydrogen0.json b/cherab/generomak/plasma/data/core/hydrogen0.json
new file mode 100644
index 00000000..754940c0
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/hydrogen0.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2240.0,
+ 2236.4504489807964,
+ 2226.309382068473,
+ 2210.299052071184,
+ 2189.0904205810994,
+ 2163.3046865525707,
+ 2133.515194552534,
+ 2100.249595432215,
+ 2063.992162943028,
+ 2025.1861932135298,
+ 1984.2364319190758,
+ 1941.5114877758033,
+ 1897.3462016693657,
+ 1852.0439490190533,
+ 1805.87885942599,
+ 1759.0979426720367,
+ 1711.9231140372276,
+ 1664.5531149286294,
+ 1617.1653271484834,
+ 1569.917480919263,
+ 1522.949258141365,
+ 1476.3837933749978,
+ 1430.3290757822574,
+ 1384.8792557946174,
+ 1340.1158606300705,
+ 1296.1089230088292,
+ 1252.9180275356005,
+ 1210.5932792532092,
+ 1169.1761988453034,
+ 1128.7005488900284,
+ 1089.193095453988,
+ 1050.674309176122,
+ 1013.1590098321976,
+ 976.6569581985458,
+ 941.1733988535289,
+ 906.7095573708474,
+ 873.2630951733505,
+ 840.828525131861,
+ 809.3975908125881,
+ 778.9596121003383,
+ 749.5017997540461,
+ 721.0095412868372,
+ 693.4666604055054,
+ 666.8556520941395,
+ 641.1578952839868,
+ 616.3538449164151,
+ 592.4232050780837,
+ 569.3450847669792,
+ 547.0981377346717,
+ 525.6606877437563,
+ 505.0108404797533,
+ 485.1265832634224,
+ 465.9858736222754,
+ 447.56671769870127,
+ 429.8472393962903,
+ 412.8057410953542,
+ 396.4207567029529,
+ 380.6710977417666,
+ 365.53589312550383,
+ 350.9946232160131,
+ 337.02714870861604,
+ 323.61373484709463,
+ 310.7350714280776,
+ 298.37228901601867,
+ 286.50697175433055,
+ 275.12116712535635,
+ 264.1973929815059,
+ 253.7186421419,
+ 243.66838482307517,
+ 234.0305691485461,
+ 224.78961996016457,
+ 215.93043613409628,
+ 207.4383865857546,
+ 199.29930513103795,
+ 191.4994843556246,
+ 184.02566862976738,
+ 176.86504639289873,
+ 170.00524182033894,
+ 163.43430597337053,
+ 157.14070752386905,
+ 151.113323135452,
+ 145.34142757467652,
+ 139.81468361812196,
+ 134.52313181416025,
+ 129.457180151816,
+ 124.60759368327163,
+ 119.96548414126156,
+ 115.52229958776202,
+ 111.26981412599169,
+ 107.20011770374389,
+ 103.30560603245968,
+ 99.57897064317038,
+ 96.01318909747529,
+ 92.60151536903889,
+ 89.33747040868218,
+ 86.21483290395201,
+ 83.22763024211139,
+ 80.37012968371364,
+ 77.63682975236918,
+ 75.02245184488561,
+ 72.52193206471382,
+ 70.13041328051168,
+ 67.84323741064236,
+ 65.6559379335423,
+ 63.564232623128014,
+ 61.56401650771693,
+ 59.65135505035933,
+ 57.82247754794227,
+ 56.07377074599886,
+ 54.40177266575983,
+ 52.80316663966101,
+ 51.27477555125246,
+ 49.81355627521912,
+ 48.416594313043035,
+ 47.081098619687594,
+ 45.80439661656459,
+ 44.5839293859712,
+ 43.417247042115314,
+ 42.302004273818525,
+ 41.23595605397633,
+ 40.216953510850516,
+ 39.24293995630613,
+ 38.311947066125406,
+ 37.422091207594626,
+ 36.571569909608,
+ 35.75865847061232,
+ 34.98170669978367,
+ 34.23913578692253,
+ 33.52943529662951,
+ 32.85116028243641,
+ 32.20292851664732,
+ 31.583417831760713,
+ 30.99136356943732,
+ 30.425556133091256,
+ 29.88483864028179,
+ 29.36810467119799,
+ 28.87429610962729,
+ 28.40240107291426,
+ 27.951451927516537,
+ 27.52052338687281,
+ 27.108730688404705,
+ 26.715227846572123,
+ 26.33920597900726,
+ 25.979891702853777,
+ 25.636545598528727,
+ 25.30846073823038,
+ 24.994961276600144,
+ 24.69540110104437,
+ 24.409162539308983,
+ 24.13565512198808,
+ 23.874314397731172,
+ 23.624600798996898,
+ 23.385998556284218,
+ 23.15801465884384,
+ 22.940177859954957,
+ 22.73203772492011,
+ 22.533163720006204,
+ 22.343144340625674,
+ 22.161586277118445,
+ 21.988113616562465,
+ 21.822367079097155,
+ 21.664003287311004,
+ 21.51269406729655,
+ 21.36812578003317,
+ 21.229998681815967,
+ 21.098026312495502,
+ 20.971934910344643,
+ 20.851462852421577,
+ 20.736360119335554,
+ 20.626387783375975,
+ 20.521317519002128,
+ 20.420931134733753,
+ 20.32502012552446,
+ 20.233385244735498,
+ 20.145836094864723,
+ 20.06219073622283,
+ 19.982275312781507,
+ 19.90592369444775,
+ 19.832977135057188,
+ 19.763283945401255,
+ 19.696699180637957,
+ 19.633084341458513,
+ 19.572307088415513,
+ 19.51424096883524,
+ 19.45876515576827,
+ 19.40576419845266,
+ 19.355127783786383,
+ 19.30675050832906,
+ 19.26053166037145,
+ 19.21637501163307,
+ 19.174188618164745,
+ 19.133884630054332,
+ 19.09537910954868,
+ 19.05859185722216,
+ 19.023446245839033,
+ 18.989869061570744,
+ 18.957790352245382,
+ 18.927143282320497,
+ 18.897863994281074,
+ 18.86989147618248,
+ 18.843167435065453,
+ 18.817636175985687,
+ 18.79324448640893,
+ 18.769941525736378,
+ 18.747678719732868,
+ 18.726409659641607,
+ 18.706090005778155,
+ 18.686677395406114,
+ 18.668131354704837,
+ 18.650413214648612,
+ 18.633486030623327,
+ 18.617314505615823,
+ 18.60186491681852,
+ 18.587105045495814,
+ 18.573004109970697,
+ 18.55953270159014,
+ 18.546662723539878,
+ 18.53436733238102,
+ 18.522620882187194,
+ 18.51139887116874,
+ 18.500677890671284,
+ 18.49043557644487,
+ 18.480650562082833,
+ 18.471302434532834,
+ 18.46237169158913,
+ 18.453839701278447,
+ 18.445688663053495,
+ 18.437901570715436,
+ 18.430462176988556,
+ 18.423354959672093,
+ 18.416565089300423,
+ 18.41007839824483,
+ 18.403881351191185,
+ 18.39796101693386,
+ 18.392305041426237,
+ 18.386901622033136,
+ 18.381739482930183,
+ 18.376807851599832,
+ 18.372096436376008,
+ 18.367595404988766,
+ 18.36329536406628,
+ 18.359187339550697,
+ 18.355262757987074,
+ 18.351513428646914,
+ 18.34793152644875,
+ 18.344509575640426,
+ 18.341240434209354,
+ 18.338117278988225,
+ 18.335133591424395,
+ 18.3322831439848,
+ 18.329559987167194,
+ 18.326958437090312,
+ 18.324473063638234,
+ 18.32209867913344,
+ 18.319830327515373,
+ 18.271305784128668
+ ],
+ "density": [
+ 204620001816.96503,
+ 203995340626.48117,
+ 203580415549.07077,
+ 203478214247.57297,
+ 203715877183.5095,
+ 204301348415.06805,
+ 205234420738.4918,
+ 206511241598.7883,
+ 208126529002.83133,
+ 210074752469.19244,
+ 212350782448.41467,
+ 214950246524.57938,
+ 217869717181.2876,
+ 221106800859.7011,
+ 224660168985.34265,
+ 228529555375.00076,
+ 232715734933.54498,
+ 237220492826.1153,
+ 242046589785.09818,
+ 247197727005.0989,
+ 252678512684.92447,
+ 258494431389.8997,
+ 264651816845.81558,
+ 271157828420.81525,
+ 278020413999.39655,
+ 285247320715.9104,
+ 292847439717.963,
+ 300831346075.9571,
+ 309210473286.05414,
+ 317997118815.822,
+ 327204455041.3841,
+ 336846543548.0578,
+ 346938352650.2804,
+ 357495722378.11005,
+ 368531748603.2294,
+ 380060992884.0296,
+ 392101369277.8834,
+ 404671758538.71185,
+ 417792030624.14746,
+ 431483075722.2703,
+ 445766837408.0821,
+ 460666347857.28577,
+ 476205765045.6582,
+ 492411668158.4271,
+ 509310082743.527,
+ 526922958785.0509,
+ 545270668436.08124,
+ 564382532826.562,
+ 584289351347.6514,
+ 605023347803.2103,
+ 626618224577.489,
+ 649109218441.2275,
+ 672533157882.3363,
+ 696928521829.5643,
+ 722330392907.0331,
+ 748761752833.0225,
+ 776263316106.7876,
+ 804879690534.3215,
+ 834657513313.9681,
+ 865645526272.6191,
+ 897894651906.1387,
+ 931458069962.6783,
+ 966390478339.3801,
+ 1002713570323.5283,
+ 1040458926521.3761,
+ 1079684516540.4954,
+ 1120450776084.2368,
+ 1162820677057.6262,
+ 1206859796754.8408,
+ 1252636384433.044,
+ 1300221424799.789,
+ 1349688697963.7998,
+ 1401114835449.2217,
+ 1454579371952.6218,
+ 1510164792644.5955,
+ 1567952481060.059,
+ 1627931114636.4526,
+ 1690139925687.1553,
+ 1754669353636.4456,
+ 1821613533247.6384,
+ 1891070371220.4712,
+ 1963141624989.376,
+ 2037932986753.0464,
+ 2115554176680.7764,
+ 2196119050183.666,
+ 2279748776152.387,
+ 2366500641895.066,
+ 2456287369484.3516,
+ 2549234395774.7485,
+ 2645490036768.047,
+ 2745210502439.3457,
+ 2848560231576.2715,
+ 2955712221053.107,
+ 3066848216768.975,
+ 3181983423138.0234,
+ 3300978418418.4097,
+ 3423964172116.361,
+ 3551081532136.3022,
+ 3682471863828.1035,
+ 3818274934361.4946,
+ 3958626240909.5186,
+ 4103653876103.972,
+ 4253475165354.2246,
+ 4408193462719.133,
+ 4567895603650.418,
+ 4732650517791.943,
+ 4902247847002.056,
+ 5076233402000.4795,
+ 5254598646625.475,
+ 5437349446630.464,
+ 5624489405383.76,
+ 5816019959574.812,
+ 6011939258098.727,
+ 6212239938237.438,
+ 6416906050351.422,
+ 6625909469387.242,
+ 6839206174537.927,
+ 7056732786183.625,
+ 7278311975421.752,
+ 7503119857298.018,
+ 7730869714380.9375,
+ 7961427820158.273,
+ 8194643345174.029,
+ 8430349935940.838,
+ 8668367358140.194,
+ 8908503068344.902,
+ 9150553621597.744,
+ 9394305867677.299,
+ 9639552766370.97,
+ 9886049104086.564,
+ 10133557734495.324,
+ 10381834826485.693,
+ 10630630439847.912,
+ 10879678469431.771,
+ 11128195788042.75,
+ 11375596059217.254,
+ 11621622648260.379,
+ 11866019968617.504,
+ 12108534650895.979,
+ 12348916749575.322,
+ 12586920956579.773,
+ 12822307795224.22,
+ 13054844772251.508,
+ 13284307469611.012,
+ 13510480561149.14,
+ 13733158742539.867,
+ 13952147565575.44,
+ 14167264170431.275,
+ 14378337911729.918,
+ 14585210876204.7,
+ 14787738291529.992,
+ 14985788827443.982,
+ 15179244791671.332,
+ 15368002224351.652,
+ 15551970895709.932,
+ 15731074212570.957,
+ 15905249040010.746,
+ 16074445444998.629,
+ 16238626369271.07,
+ 16397767238935.273,
+ 16551855518444.57,
+ 16700890216574.428,
+ 16844881351954.912,
+ 16983849385509.26,
+ 17117824626881.824,
+ 17246846621603.266,
+ 17370963525334.229,
+ 17490231471110.625,
+ 17604713935017.176,
+ 17714481105258.8,
+ 17819608453161.367,
+ 17920177950565.527,
+ 18016276628873.59,
+ 18107995459063.83,
+ 18195429156535.652,
+ 18278675646852.23,
+ 18357835555954.918,
+ 18433011726092.445,
+ 18504308758387.65,
+ 18571832582598.63,
+ 18635690054375.332,
+ 18695988580024.676,
+ 18752835768579.754,
+ 18806339110761.88,
+ 18856605684254.773,
+ 18903741884561.38,
+ 18947853180595.484,
+ 18989043894059.926,
+ 19027417001587.02,
+ 19063073958565.055,
+ 19096114543521.96,
+ 19126636721924.43,
+ 19154736528236.87,
+ 19180507965077.684,
+ 19204042918329.66,
+ 19225431087078.62,
+ 19244759927277.656,
+ 19262114608067.395,
+ 19277577979726.01,
+ 19291230552256.516,
+ 19303150483665.746,
+ 19313413577033.516,
+ 19322093285526.824,
+ 19329260724543.79,
+ 19334984690237.266,
+ 19339331683709.87,
+ 19342365940211.094,
+ 19344149462728.09,
+ 19344742059393.53,
+ 19344201384180.91,
+ 19342582980399.023,
+ 19339940326544.8,
+ 19336324363046.41,
+ 19331784091828.13,
+ 19326368145671.793,
+ 19320122234851.223,
+ 19313090256097.117,
+ 19305314345120.19,
+ 19296834929279.25,
+ 19287690780209.77,
+ 19277919066210.582,
+ 19267555404250.375,
+ 19256633911438.43,
+ 19245187255846.457,
+ 19233246706569.15,
+ 19220842182934.86,
+ 19208002302790.24,
+ 19194754429784.965,
+ 19181124719614.805,
+ 19167138165162.6,
+ 19152818640516.805,
+ 19138188943830.562,
+ 19123270839007.04,
+ 19108085096194.83,
+ 19092651531087.504,
+ 19076989043026.625,
+ 19061115651909.043,
+ 19045048533903.996,
+ 19028804056001.64,
+ 19012397809386.355,
+ 18995844641670.94,
+ 18979158687998.574,
+ 18962353401040.9,
+ 18945441579905.883,
+ 18928435397987.637,
+ 18911346429777.703,
+ 18894185676666.883,
+ 18876963591763.613,
+ 18859690103748.47,
+ 18842374639807.22,
+ 18825026147656.855,
+ 18807653116696.703,
+ 18790263598309.477,
+ 18772865225350.633,
+ 18755465230832.047,
+ 16384843817946.543
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "hydrogen",
+ "charge": 0
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/hydrogen1.json b/cherab/generomak/plasma/data/core/hydrogen1.json
new file mode 100644
index 00000000..a23d3c11
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/hydrogen1.json
@@ -0,0 +1,1294 @@
+{
+ "temperature": [
+ 2800.0,
+ 2795.6140361201715,
+ 2783.083337747409,
+ 2763.3003486616526,
+ 2737.094135213008,
+ 2705.2322750926364,
+ 2668.4232152414806,
+ 2627.3189416606197,
+ 2582.5178419123567,
+ 2534.5676700076638,
+ 2483.96854551181,
+ 2431.1759357517954,
+ 2376.6035832043513,
+ 2320.6263503869714,
+ 2263.5829625419237,
+ 2205.7786346035323,
+ 2147.4875737595085,
+ 2088.955352654985,
+ 2030.4011511730957,
+ 1972.019866937452,
+ 1913.9840963599631,
+ 1856.4459893126868,
+ 1799.5389814222144,
+ 1743.3794086390585,
+ 1688.0680091781107,
+ 1633.691318203845,
+ 1580.3229607811295,
+ 1528.0248486579108,
+ 1476.8482864126447,
+ 1426.8349924056063,
+ 1378.018039834137,
+ 1330.4227230192646,
+ 1284.0673538547676,
+ 1238.963993137122,
+ 1195.1191212721988,
+ 1152.5342526267314,
+ 1111.2064975634503,
+ 1071.1290759712253,
+ 1032.291785877979,
+ 994.6814305162284,
+ 958.2822070001829,
+ 923.0760595703174,
+ 889.0430001669228,
+ 856.1613989086177,
+ 824.4082468755387,
+ 793.759393429837,
+ 764.1897601482588,
+ 735.6735332927431,
+ 708.1843366049751,
+ 681.6953860793737,
+ 656.1796282458071,
+ 631.6098633780208,
+ 607.9588549360606,
+ 585.1994264504128,
+ 563.3045469619041,
+ 542.2474060441687,
+ 522.0014793543342,
+ 502.5405855822321,
+ 483.8389355984452,
+ 465.8711745366052,
+ 448.61241748523827,
+ 432.0382794087496,
+ 416.124899865624,
+ 400.8489630442867,
+ 386.1877135930409,
+ 372.11896867986945,
+ 358.6211266803817,
+ 345.67317285760663,
+ 333.2546823654665,
+ 321.34582087841227,
+ 309.927343122692,
+ 298.9805895598673,
+ 288.4874814503533,
+ 278.4305145037626,
+ 268.79275130356683,
+ 259.5578126759042,
+ 250.7098681561356,
+ 242.23362569190442,
+ 234.11432070782254,
+ 226.33770464446184,
+ 218.89003307292606,
+ 211.75805347586066,
+ 204.92899277624957,
+ 198.39054468665884,
+ 192.13085694367678,
+ 186.13851848507585,
+ 180.40254662065936,
+ 174.91237424177845,
+ 169.65783710907806,
+ 164.62916125309604,
+ 159.8169505178761,
+ 155.21217427370195,
+ 150.80615532139907,
+ 146.59055800733688,
+ 142.55737656528729,
+ 138.69892369858735,
+ 135.00781941365733,
+ 131.47698011372418,
+ 128.09960795968092,
+ 124.86918050324817,
+ 121.77944059606116,
+ 118.82438657692074,
+ 115.99826273821829,
+ 113.29555007145385,
+ 110.71095729082082,
+ 108.23941213297381,
+ 105.87605293038021,
+ 103.6162204549953,
+ 101.45545002847112,
+ 99.38946389462029,
+ 97.41416384945612,
+ 95.52562412379939,
+ 93.72008451315051,
+ 91.99394374930452,
+ 90.34375310799985,
+ 88.7662102467457,
+ 87.25815326688075,
+ 85.81655499383113,
+ 84.43851746950027,
+ 83.12126665071017,
+ 81.86214730760918,
+ 80.65861811600642,
+ 79.5082469376184,
+ 78.408706282292,
+ 77.35776894632689,
+ 76.35330382111951,
+ 75.39327186643368,
+ 74.47572224272074,
+ 73.59878859700572,
+ 72.76068549699494,
+ 71.95970500815942,
+ 71.19421340869229,
+ 70.46264803735373,
+ 69.7635142693571,
+ 69.0953826155724,
+ 68.45688594046604,
+ 67.84671679431725,
+ 67.26362485539421,
+ 66.70641447789761,
+ 66.17394234161189,
+ 65.6651151993376,
+ 65.1788877182984,
+ 64.7142604118468,
+ 64.27027765791827,
+ 63.84602580079542,
+ 63.440631332874815,
+ 63.05325915323381,
+ 62.68311089991544,
+ 62.32942335295714,
+ 61.9914669052981,
+ 61.66854409880293,
+ 61.359988222742814,
+ 61.065161972176995,
+ 60.78345616376737,
+ 60.51428850665944,
+ 60.2571024261477,
+ 60.01136593793548,
+ 59.776570570881596,
+ 59.55223033620793,
+ 59.33788074122536,
+ 59.13307784570519,
+ 58.937397359105915,
+ 58.75043377692946,
+ 58.571799554551646,
+ 58.40112431694312,
+ 58.23805410275451,
+ 58.08225064130303,
+ 57.93339066106313,
+ 57.7911652283102,
+ 57.65527911463285,
+ 57.525450192074885,
+ 57.40140885472106,
+ 57.28289746559213,
+ 57.16966982775895,
+ 57.06149067863122,
+ 56.95813520642253,
+ 56.85938858783372,
+ 56.765045546033065,
+ 56.674909928059456,
+ 56.588794300802036,
+ 56.50651956475268,
+ 56.427914584755875,
+ 56.35281583702141,
+ 56.281067071686564,
+ 56.21251899025332,
+ 56.14702893725086,
+ 56.08446060550164,
+ 56.02468375439783,
+ 55.96757394061782,
+ 55.91301226073971,
+ 55.8608851052287,
+ 55.81108392330204,
+ 55.76350499819346,
+ 55.718049232360165,
+ 55.67462194219673,
+ 55.63313266183696,
+ 55.593494955645,
+ 55.55562623901411,
+ 55.51944760710454,
+ 55.484883671174465,
+ 55.45186240216659,
+ 55.42031498123234,
+ 55.390175656886,
+ 55.361381608497936,
+ 55.333872815845915,
+ 55.307591934457406,
+ 55.282484176486456,
+ 55.258497196881336,
+ 55.23558098460842,
+ 55.21368775870917,
+ 55.19277186897538,
+ 55.17278970103895,
+ 55.153699585681665,
+ 55.13546171217539,
+ 55.11803804547773,
+ 55.101392247108336,
+ 55.08548959954608,
+ 55.070296933989404,
+ 55.05578256132999,
+ 55.04191620619953,
+ 55.028668943950365,
+ 55.01601314044173,
+ 55.003922394507015,
+ 54.99237148298145,
+ 54.98133630817787,
+ 54.970793847702375,
+ 54.96072210650347,
+ 54.951100071057624,
+ 54.941907665596375,
+ 54.93312571028218,
+ 54.9247358812481,
+ 54.91672067241873,
+ 54.90906335903125,
+ 54.90174796278291,
+ 54.8947592185312,
+ 54.888082542479076,
+ 54.881704001777535,
+ 54.87561028548313,
+ 54.869788676811275,
+ 54.86422702662521,
+ 54.858913728107794,
+ 54.85383769256265,
+ 54.84898832629396,
+ 54.8443555085177,
+ 54.83992957025756,
+ 54.83570127418218,
+ 54.83166179534185,
+ 54.82780270276455,
+ 54.824115941872016,
+ 54.82059381768116,
+ 54.81722897875463,
+ 54.81401440186672,
+ 54.81094337735412,
+ 54.80800949511986,
+ 54.80520663126194,
+ 54.7452478101525
+ ],
+ "density": [
+ 4.7000161116838035e+19,
+ 4.682128787215119e+19,
+ 4.662255270837901e+19,
+ 4.6417278208422126e+19,
+ 4.620855584730208e+19,
+ 4.5997877921630495e+19,
+ 4.5786126032580125e+19,
+ 4.557388001473378e+19,
+ 4.536154779862328e+19,
+ 4.514942993087138e+19,
+ 4.4937755363011396e+19,
+ 4.472670293288807e+19,
+ 4.451641505013135e+19,
+ 4.430700683219043e+19,
+ 4.409857243769369e+19,
+ 4.38911895956297e+19,
+ 4.368492293000609e+19,
+ 4.347982645523464e+19,
+ 4.327594548538098e+19,
+ 4.3073318119596106e+19,
+ 4.287197641493933e+19,
+ 4.267194732453969e+19,
+ 4.247325345683865e+19,
+ 4.227591369649927e+19,
+ 4.207994371652285e+19,
+ 4.18853563809563e+19,
+ 4.169216213518003e+19,
+ 4.150036932127918e+19,
+ 4.130998441718659e+19,
+ 4.1121012257462985e+19,
+ 4.093345622347993e+19,
+ 4.074731840811801e+19,
+ 4.056259975913072e+19,
+ 4.037930020368103e+19,
+ 4.019741870571682e+19,
+ 4.001695340964126e+19,
+ 3.983790175600905e+19,
+ 3.966026052904146e+19,
+ 3.948402592421399e+19,
+ 3.930919360878721e+19,
+ 3.91357587761679e+19,
+ 3.896371619490987e+19,
+ 3.879306025305037e+19,
+ 3.862378038885082e+19,
+ 3.8455872756913046e+19,
+ 3.828933304946574e+19,
+ 3.812415434913541e+19,
+ 3.796032969592534e+19,
+ 3.779785195844539e+19,
+ 3.763671385931872e+19,
+ 3.747690800145458e+19,
+ 3.731842689377711e+19,
+ 3.716126297679983e+19,
+ 3.700540864846064e+19,
+ 3.6850856060966724e+19,
+ 3.6697596750521393e+19,
+ 3.6545622931847754e+19,
+ 3.63949269560757e+19,
+ 3.624550126620646e+19,
+ 3.6097338433711747e+19,
+ 3.5950431200155054e+19,
+ 3.580477252521384e+19,
+ 3.5660355599881843e+19,
+ 3.551717212816437e+19,
+ 3.5375214199829737e+19,
+ 3.523447525545721e+19,
+ 3.509494910531205e+19,
+ 3.4956630001189454e+19,
+ 3.4819512721075306e+19,
+ 3.4683592669405524e+19,
+ 3.4548865996283527e+19,
+ 3.44153297397094e+19,
+ 3.4282981995701944e+19,
+ 3.4151822122170814e+19,
+ 3.402185098353278e+19,
+ 3.389307085841355e+19,
+ 3.3765477248415257e+19,
+ 3.36390706526775e+19,
+ 3.3513857808022893e+19,
+ 3.3389848457318638e+19,
+ 3.326705595137885e+19,
+ 3.3145497973701267e+19,
+ 3.3025197409857077e+19,
+ 3.2906183384364196e+19,
+ 3.27884924868037e+19,
+ 3.2672168857369743e+19,
+ 3.2557253870071173e+19,
+ 3.2443771047542505e+19,
+ 3.233178288004695e+19,
+ 3.222136754653978e+19,
+ 3.2112618260038386e+19,
+ 3.2005644930339512e+19,
+ 3.190057544359449e+19,
+ 3.179755610169293e+19,
+ 3.169667413331649e+19,
+ 3.1597941789312086e+19,
+ 3.1501468231219503e+19,
+ 3.1407358392679612e+19,
+ 3.1315701402899493e+19,
+ 3.122655976363501e+19,
+ 3.113995725177193e+19,
+ 3.1055866895317287e+19,
+ 3.0974201050364137e+19,
+ 3.0894806075100783e+19,
+ 3.0817464043937587e+19,
+ 3.074190310163784e+19,
+ 3.0667602748084875e+19,
+ 3.059388912084078e+19,
+ 3.0520502154565943e+19,
+ 3.0447256542588035e+19,
+ 3.0374032039505535e+19,
+ 3.0300769320810455e+19,
+ 3.0227459649422733e+19,
+ 3.0154130399978762e+19,
+ 3.0080828724751536e+19,
+ 3.00076055212318e+19,
+ 2.9934501515846365e+19,
+ 2.986153682499915e+19,
+ 2.9788666487587082e+19,
+ 2.9715601389175697e+19,
+ 2.9642293974170833e+19,
+ 2.9568746794147893e+19,
+ 2.9494953117879144e+19,
+ 2.942090418993194e+19,
+ 2.9346594991144505e+19,
+ 2.927202828423032e+19,
+ 2.919721694348071e+19,
+ 2.912218473740004e+19,
+ 2.9046961655055204e+19,
+ 2.897159522535346e+19,
+ 2.889613573005297e+19,
+ 2.8820638275299803e+19,
+ 2.8745160581640344e+19,
+ 2.866976018562403e+19,
+ 2.859446819509753e+19,
+ 2.8519338651384783e+19,
+ 2.8444437402203193e+19,
+ 2.8369821546424705e+19,
+ 2.8295540143670977e+19,
+ 2.822163499192403e+19,
+ 2.8148141418240123e+19,
+ 2.8075089045501837e+19,
+ 2.800250251202477e+19,
+ 2.7930402131116364e+19,
+ 2.785880448496708e+19,
+ 2.7787722952184242e+19,
+ 2.7717168171436e+19,
+ 2.764714844554494e+19,
+ 2.757767009134292e+19,
+ 2.750873774095989e+19,
+ 2.744035460018579e+19,
+ 2.7372522669268402e+19,
+ 2.730524293109751e+19,
+ 2.7238515511248703e+19,
+ 2.7172339813867467e+19,
+ 2.710671463689212e+19,
+ 2.704163826966439e+19,
+ 2.697710857556336e+19,
+ 2.6913123061929193e+19,
+ 2.684967893921741e+19,
+ 2.678677317103723e+19,
+ 2.6724402516482183e+19,
+ 2.666256356594527e+19,
+ 2.6601252771429528e+19,
+ 2.6540466472208925e+19,
+ 2.648020091656107e+19,
+ 2.642045228018025e+19,
+ 2.6361216681785897e+19,
+ 2.6302490196357964e+19,
+ 2.6244268866366194e+19,
+ 2.6186547167773954e+19,
+ 2.6129321911080337e+19,
+ 2.607258987087877e+19,
+ 2.6016347040942785e+19,
+ 2.596058941784374e+19,
+ 2.5905313005155705e+19,
+ 2.585051381702677e+19,
+ 2.5796187881207525e+19,
+ 2.5742331241620062e+19,
+ 2.568893996053235e+19,
+ 2.563601012039743e+19,
+ 2.5583537825404264e+19,
+ 2.5531519202783388e+19,
+ 2.5479950403901665e+19,
+ 2.5428827605176574e+19,
+ 2.5378147008834527e+19,
+ 2.5327904843536536e+19,
+ 2.5278097364889854e+19,
+ 2.522872085586001e+19,
+ 2.5179771627098292e+19,
+ 2.5131246017196376e+19,
+ 2.5083140392876634e+19,
+ 2.5035451149129798e+19,
+ 2.498817470930402e+19,
+ 2.4941307525154173e+19,
+ 2.4894846076854927e+19,
+ 2.484878687298473e+19,
+ 2.4803126450483405e+19,
+ 2.475786137458537e+19,
+ 2.4712988238736052e+19,
+ 2.466850366448876e+19,
+ 2.462440430138878e+19,
+ 2.4580686826843484e+19,
+ 2.4537347945982157e+19,
+ 2.4494384391507644e+19,
+ 2.445179292353768e+19,
+ 2.4409570329441386e+19,
+ 2.4367713423668306e+19,
+ 2.432621904757395e+19,
+ 2.428508406924054e+19,
+ 2.4244305383293637e+19,
+ 2.420387991071655e+19,
+ 2.4163804063775474e+19,
+ 2.4124074299375776e+19,
+ 2.4084688695258206e+19,
+ 2.4045644275574723e+19,
+ 2.4006938089881907e+19,
+ 2.3968567212948713e+19,
+ 2.393052874455778e+19,
+ 2.3892819809314083e+19,
+ 2.3855437556447207e+19,
+ 2.3818379159616664e+19,
+ 2.378164181671946e+19,
+ 2.374522274969222e+19,
+ 2.3709119204319965e+19,
+ 2.3673328450042348e+19,
+ 2.3637847779761213e+19,
+ 2.3602674509648167e+19,
+ 2.3567805978955555e+19,
+ 2.3533239549825778e+19,
+ 2.349897260710105e+19,
+ 2.346500255813818e+19,
+ 2.3431326832619577e+19,
+ 2.3397942882369196e+19,
+ 2.3364848181166285e+19,
+ 2.333204022456342e+19,
+ 2.3299516529704546e+19,
+ 2.326727463514042e+19,
+ 2.3235312100654547e+19,
+ 2.320362650708015e+19,
+ 2.3172215456123494e+19,
+ 2.3141076570189193e+19,
+ 2.3110207492203815e+19,
+ 2.3079605885444526e+19,
+ 2.3049269433364124e+19,
+ 2.3019195839420236e+19,
+ 2.2989382826907095e+19,
+ 2.295982813878743e+19,
+ 2.293052953752237e+19,
+ 2.290148480490682e+19,
+ 2.287269174190705e+19,
+ 2.2844148168495403e+19,
+ 2.2815851923484787e+19,
+ 2.278780086437519e+19,
+ 2.2759992867188072e+19,
+ 1.9578429198926516e+19
+ ],
+ "vtor": [
+ 100000.0,
+ 99544.32023364124,
+ 98251.15453696062,
+ 96235.68685722632,
+ 93614.68356191639,
+ 90502.18847954353,
+ 87006.32501749854,
+ 83227.06508922808,
+ 79254.813872946,
+ 75169.66123127713,
+ 71041.16042746486,
+ 66928.50919629741,
+ 62881.02482158773,
+ 58938.821939433255,
+ 55133.61820859918,
+ 51489.60808192722,
+ 48024.35830839606,
+ 44749.69035052268,
+ 41672.524623402256,
+ 38795.66945343124,
+ 36118.54407642795,
+ 33637.83003375026,
+ 31348.04917610031,
+ 29242.06933764292,
+ 27311.54077408969,
+ 25547.26782590489,
+ 23939.521110407513,
+ 22478.295982958116,
+ 21153.523137258686,
+ 19955.237120191036,
+ 18873.708284120235,
+ 17899.54334214529,
+ 17023.759270761642,
+ 16237.834851443324,
+ 15533.743681380842,
+ 14903.972031120154,
+ 14341.524495030524,
+ 13839.919977172622,
+ 13393.180184865832,
+ 12995.812467288095,
+ 12642.788537234375,
+ 12329.520349892675,
+ 12051.83418147994,
+ 11805.94375056095,
+ 11588.423053275488,
+ 11396.179437797053,
+ 11226.42732039882,
+ 11076.662842842592,
+ 10944.639685904545,
+ 10828.34618435543,
+ 10725.983832469563,
+ 10635.94722420132,
+ 10556.805436804136,
+ 10487.284839339893,
+ 10426.253286892172,
+ 10372.705646187464,
+ 10325.750587737686,
+ 10284.598572685094,
+ 10248.550958525679,
+ 10216.990146193662,
+ 10189.370691092356,
+ 10165.211302127113,
+ 10144.087655281786,
+ 10125.625951492917,
+ 10109.49715228246,
+ 10095.411830623676,
+ 10083.115578687914,
+ 10072.384918337477,
+ 10063.023664403154,
+ 10054.85969484832,
+ 10047.742085826912,
+ 10041.538573356505,
+ 10036.133306828673,
+ 10031.424862854412,
+ 10027.3244909875,
+ 10023.75456568367,
+ 10020.647221443161,
+ 10017.943150456194,
+ 10015.59054423511,
+ 10013.544162684711,
+ 10011.764515845945,
+ 10010.217145160046,
+ 10008.871992553453,
+ 10007.702846950711,
+ 10006.686858995241,
+ 10005.804115808194,
+ 10005.037268554323,
+ 10004.371206421612,
+ 10003.792771367725,
+ 10003.29050865027,
+ 10002.85444874773,
+ 10002.475916801126,
+ 10002.14736617021,
+ 10001.86223310832,
+ 10001.614809922945,
+ 10001.400134309408,
+ 10001.213892828007,
+ 10001.052336744104,
+ 10000.912208670363,
+ 10000.790678643563,
+ 10000.68528843837,
+ 10000.593903069897,
+ 10000.514668568,
+ 10000.445975221452,
+ 10000.386425591105,
+ 10000.334806679686,
+ 10000.290065723417,
+ 10000.25128913859,
+ 10000.217684215675,
+ 10000.188563205464,
+ 10000.16332948734,
+ 10000.141465549392,
+ 10000.122522544827,
+ 10000.106111219531,
+ 10000.091894031972,
+ 10000.079578309811,
+ 10000.068910307727,
+ 10000.05967004848,
+ 10000.051666844598,
+ 10000.044735411424,
+ 10000.038732493818,
+ 10000.033533939033,
+ 10000.029032157028,
+ 10000.02513391718,
+ 10000.021758437058,
+ 10000.018835724715,
+ 10000.016305140998,
+ 10000.01411415281,
+ 10000.012217252064,
+ 10000.010575018385,
+ 10000.009153306504,
+ 10000.007922541854,
+ 10000.00685710995,
+ 10000.005934827166,
+ 10000.005136482061,
+ 10000.004445437868,
+ 10000.003847288048,
+ 10000.003329557814,
+ 10000.002881445527,
+ 10000.00249359863,
+ 10000.002157919536,
+ 10000.001867397486,
+ 10000.001615962863,
+ 10000.001398361033,
+ 10000.001210043049,
+ 10000.001047070993,
+ 10000.000906036008,
+ 10000.000783987294,
+ 10000.000678370623,
+ 10000.000586975104,
+ 10000.000507887078,
+ 10000.000439450198,
+ 10000.000380230858,
+ 10000.000328988277,
+ 10000.000284648579,
+ 10000.000246282361,
+ 10000.000213085277,
+ 10000.00018436122,
+ 10000.000159507772,
+ 10000.000138003594,
+ 10000.000119397531,
+ 10000.000103299173,
+ 10000.000089370667,
+ 10000.000077319659,
+ 10000.000066893168,
+ 10000.000057872281,
+ 10000.000050067574,
+ 10000.00004331514,
+ 10000.00003747315,
+ 10000.000032418886,
+ 10000.000028046165,
+ 10000.00002426311,
+ 10000.000020990228,
+ 10000.000018158735,
+ 10000.00001570912,
+ 10000.000013589894,
+ 10000.000011756505,
+ 10000.00001017041,
+ 10000.00000879826,
+ 10000.000007611205,
+ 10000.00000658428,
+ 10000.000005695889,
+ 10000.000004927346,
+ 10000.000004262487,
+ 10000.000003687326,
+ 10000.000003189763,
+ 10000.000002759334,
+ 10000.000002386978,
+ 10000.000002064864,
+ 10000.000001786213,
+ 10000.00000154516,
+ 10000.000001336637,
+ 10000.00000115625,
+ 10000.000001000204,
+ 10000.000000865217,
+ 10000.000000748445,
+ 10000.000000647431,
+ 10000.00000056005,
+ 10000.000000484462,
+ 10000.000000419075,
+ 10000.000000362512,
+ 10000.000000313583,
+ 10000.000000271257,
+ 10000.000000234644,
+ 10000.000000202972,
+ 10000.000000175574,
+ 10000.000000151877,
+ 10000.000000131377,
+ 10000.000000113641,
+ 10000.000000098302,
+ 10000.000000085032,
+ 10000.000000073554,
+ 10000.000000063626,
+ 10000.000000055037,
+ 10000.000000047608,
+ 10000.000000041182,
+ 10000.000000035621,
+ 10000.000000030814,
+ 10000.000000026654,
+ 10000.000000023056,
+ 10000.000000019943,
+ 10000.000000017251,
+ 10000.000000014923,
+ 10000.000000012908,
+ 10000.000000011165,
+ 10000.000000009659,
+ 10000.000000008355,
+ 10000.000000007227,
+ 10000.00000000625,
+ 10000.000000005406,
+ 10000.000000004677,
+ 10000.000000004045,
+ 10000.0000000035,
+ 10000.000000003027,
+ 10000.000000002618,
+ 10000.000000002265,
+ 10000.000000001959,
+ 10000.000000001695,
+ 10000.000000001466,
+ 10000.000000001268,
+ 10000.000000001097,
+ 10000.00000000095,
+ 10000.00000000082,
+ 10000.00000000071,
+ 10000.000000000615,
+ 10000.000000000531,
+ 10000.00000000046,
+ 10000.000000000397,
+ 10000.000000000344,
+ 10000.000000000296,
+ 10000.000000000256,
+ 10000.000000000222,
+ 10000.000000000193,
+ 10000.000000000167,
+ 10000.000000000144,
+ 10000.0
+ ],
+ "vpol": [
+ 18462.326927732716,
+ 18514.99979366994,
+ 18565.939231880784,
+ 18615.197379613106,
+ 18662.8251518226,
+ 18708.87224398403,
+ 18753.38713728863,
+ 18796.417106004,
+ 18838.008226787257,
+ 18878.20538975573,
+ 18917.052311132516,
+ 18954.591547296637,
+ 18990.864510079347,
+ 19025.91148315922,
+ 19059.7716394193,
+ 19092.483059139577,
+ 19124.08274890752,
+ 19154.60666113828,
+ 19184.089714104663,
+ 19212.565812384706,
+ 19240.067867642374,
+ 19266.627819663598,
+ 19292.27665757659,
+ 19317.044441191432,
+ 19340.960322399642,
+ 19364.052566579816,
+ 19386.34857396039,
+ 19407.874900895215,
+ 19428.65728101207,
+ 19448.720646198086,
+ 19468.08914739,
+ 19486.78617514046,
+ 19504.834379934928,
+ 19522.2556922367,
+ 19539.07134224024,
+ 19555.301879315663,
+ 19570.96719112952,
+ 19586.08652242914,
+ 19600.678493479918,
+ 19614.761118146518,
+ 19628.351821610984,
+ 19641.467457721887,
+ 19654.124325970388,
+ 19666.33818809011,
+ 19678.124284279074,
+ 19689.497349042842,
+ 19700.47162665909,
+ 19711.060886264648,
+ 19721.278436566783,
+ 19731.137140181316,
+ 19740.649427600623,
+ 19749.827310795343,
+ 19758.68239645382,
+ 19767.225898864108,
+ 19775.4686524434,
+ 19783.421123920307,
+ 19791.093424175622,
+ 19798.49531974744,
+ 19805.63624400677,
+ 19812.52530800986,
+ 19819.171311033715,
+ 19825.582750801284,
+ 19831.76783340299,
+ 19837.73448292125,
+ 19843.49035076469,
+ 19849.042824718887,
+ 19854.399037720275,
+ 19859.565876360022,
+ 19864.549989124593,
+ 19869.357794379575,
+ 19873.99548810352,
+ 19878.469051378208,
+ 19882.78425764191,
+ 19886.946679712015,
+ 19890.961696583312,
+ 19894.83450000816,
+ 19898.570100864654,
+ 19902.173335318803,
+ 19905.64887078662,
+ 19909.00121170188,
+ 19912.234705095303,
+ 19915.353545990587,
+ 19918.361782622906,
+ 19921.263321485007,
+ 19924.061932206263,
+ 19926.76125226966,
+ 19929.36479157172,
+ 19931.875936830187,
+ 19934.297955844206,
+ 19936.634001611572,
+ 19938.887116307546,
+ 19941.060235129582,
+ 19943.156190012254,
+ 19945.17771321644,
+ 19947.12744079687,
+ 19949.00791595186,
+ 19950.821592259108,
+ 19952.570836801166,
+ 19954.25793318425,
+ 19955.885084453774,
+ 19957.454415910102,
+ 19958.967977827684,
+ 19960.427748080827,
+ 19961.835634679162,
+ 19963.193478215824,
+ 19964.503054231183,
+ 19965.76607549503,
+ 19966.984194209857,
+ 19968.159004137942,
+ 19969.292042654735,
+ 19970.384792731096,
+ 19971.438684846682,
+ 19972.455098836952,
+ 19973.435365675872,
+ 19974.380769196654,
+ 19975.29254775252,
+ 19976.1718958196,
+ 19977.019965543906,
+ 19977.83786823432,
+ 19978.6266758034,
+ 19979.38742215782,
+ 19980.121104540183,
+ 19980.828684823875,
+ 19981.511090762506,
+ 19982.169217195635,
+ 19982.80392721215,
+ 19983.41605327286,
+ 19984.006398293674,
+ 19984.575736690727,
+ 19985.124815388765,
+ 19985.654354794107,
+ 19986.165049733347,
+ 19986.657570359053,
+ 19987.132563023555,
+ 19987.590651121973,
+ 19988.03243590553,
+ 19988.458497266216,
+ 19988.869394493737,
+ 19989.265667005842,
+ 19989.647835052798,
+ 19990.01640039704,
+ 19990.371846968832,
+ 19990.714641498744,
+ 19991.045234127785,
+ 19991.36405899601,
+ 19991.67153481026,
+ 19991.968065391884,
+ 19992.254040205054,
+ 19992.52983486641,
+ 19992.795811636643,
+ 19993.05231989471,
+ 19993.299696595244,
+ 19993.538266709777,
+ 19993.768343652326,
+ 19993.9902296899,
+ 19994.2042163385,
+ 19994.410584745023,
+ 19994.60960605568,
+ 19994.801541771343,
+ 19994.986644090288,
+ 19995.165156238767,
+ 19995.33731278991,
+ 19995.503339971237,
+ 19995.66345596134,
+ 19995.817871175987,
+ 19995.96678854407,
+ 19996.110403773815,
+ 19996.248905609486,
+ 19996.38247607898,
+ 19996.511290732687,
+ 19996.6355188738,
+ 19996.75532378048,
+ 19996.870862920143,
+ 19996.98228815611,
+ 19997.089745946923,
+ 19997.1933775386,
+ 19997.29331915003,
+ 19997.389702151813,
+ 19997.482653238705,
+ 19997.572294595982,
+ 19997.65874405985,
+ 19997.74211527218,
+ 19997.822517829743,
+ 19997.90005742811,
+ 19997.974836000485,
+ 19998.046951851553,
+ 19998.11649978661,
+ 19998.183571236077,
+ 19998.248254375594,
+ 19998.31063424184,
+ 19998.370792844253,
+ 19998.42880927274,
+ 19998.4847598016,
+ 19998.538717989708,
+ 19998.590754777182,
+ 19998.64093857857,
+ 19998.68933537273,
+ 19998.736008789543,
+ 19998.78102019351,
+ 19998.824428764387,
+ 19998.866291574945,
+ 19998.906663665974,
+ 19998.945598118597,
+ 19998.983146124054,
+ 19999.019357050955,
+ 19999.054278510157,
+ 19999.087956417356,
+ 19999.120435053414,
+ 19999.151757122556,
+ 19999.181963808518,
+ 19999.21109482865,
+ 19999.239188486128,
+ 19999.26628172031,
+ 19999.292410155274,
+ 19999.317608146655,
+ 19999.34190882679,
+ 19999.36534414829,
+ 19999.387944926013,
+ 19999.409740877607,
+ 19999.430760662537,
+ 19999.451031919776,
+ 19999.470581304155,
+ 19999.489434521372,
+ 19999.5076163618,
+ 19999.525150733072,
+ 19999.54206069153,
+ 19999.558368472495,
+ 19999.57409551955,
+ 19999.58926251268,
+ 19999.603889395497,
+ 19999.61799540144,
+ 19999.63159907907,
+ 19999.644718316464,
+ 19999.657370364694,
+ 19999.669571860562,
+ 19999.681338848437,
+ 19999.69268680136,
+ 19999.703630641383,
+ 19999.7141847592,
+ 19999.72436303305,
+ 19999.73417884697,
+ 19999.743645108418,
+ 19999.752774265195,
+ 19999.76157832185,
+ 19999.770068855447,
+ 19999.778257030794,
+ 19999.78615361512,
+ 19999.793768992236,
+ 19999.801113176174,
+ 19999.808195824375,
+ 19999.815026250366,
+ 19999.82161343603,
+ 19999.827966043387,
+ 19999.834092426012,
+ 19999.84000064,
+ 20000.0
+ ],
+ "vnorm": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "element": "hydrogen",
+ "charge": 1
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/core/psi_norm.json b/cherab/generomak/plasma/data/core/psi_norm.json
new file mode 100644
index 00000000..01760ebf
--- /dev/null
+++ b/cherab/generomak/plasma/data/core/psi_norm.json
@@ -0,0 +1,260 @@
+{
+ "psi_norm": [
+ 0.0,
+ 0.03561162084555414,
+ 0.06995505415186065,
+ 0.10307546213272856,
+ 0.13501639870233162,
+ 0.1658198667493661,
+ 0.19552637337158152,
+ 0.2241749831433214,
+ 0.25180336948611703,
+ 0.27844786420989853,
+ 0.3041435052899555,
+ 0.3289240829424859,
+ 0.35282218405932053,
+ 0.3758692350602538,
+ 0.3980955432193337,
+ 0.41953033651945604,
+ 0.44020180208767157,
+ 0.4601371232617498,
+ 0.47936251533674257,
+ 0.49790326003855345,
+ 0.5157837387698492,
+ 0.5330274646720292,
+ 0.5496571135454165,
+ 0.5656945536683295,
+ 0.581160874554252,
+ 0.5960764146849096,
+ 0.6104607882557274,
+ 0.6243329109688405,
+ 0.637711024907571,
+ 0.6506127225250871,
+ 0.663054969778784,
+ 0.6750541284408158,
+ 0.6866259776141095,
+ 0.6977857344821621,
+ 0.7085480743199009,
+ 0.7189271497919272,
+ 0.7289366095635164,
+ 0.7385896162488508,
+ 0.7478988637200875,
+ 0.7568765938000214,
+ 0.7655346123602946,
+ 0.7738843048463258,
+ 0.7819366512493673,
+ 0.7897022405453866,
+ 0.7971912846197539,
+ 0.8044136316960491,
+ 0.8113787792866483,
+ 0.8180958866821177,
+ 0.8245737869958408,
+ 0.8308209987797164,
+ 0.8368457372262026,
+ 0.842655924971439,
+ 0.8482592025136506,
+ 0.8536629382605364,
+ 0.8588742382188548,
+ 0.8638999553389449,
+ 0.8687466985264773,
+ 0.8734208413332797,
+ 0.8779285303386681,
+ 0.882275693232307,
+ 0.8864680466092238,
+ 0.8905111034872313,
+ 0.8944101805566421,
+ 0.8981704051718096,
+ 0.9017967220936874,
+ 0.9052938999922776,
+ 0.9086665377175137,
+ 0.9119190703468294,
+ 0.915055775017362,
+ 0.9180807765504632,
+ 0.9209980528759103,
+ 0.9238114402629539,
+ 0.9265246383650785,
+ 0.9291412150851113,
+ 0.931664611267077,
+ 0.9340981452209673,
+ 0.9364450170863771,
+ 0.9387083130407426,
+ 0.9408910093577201,
+ 0.9429959763210364,
+ 0.9450259819989626,
+ 0.9469836958843723,
+ 0.9488716924051706,
+ 0.9506924543097125,
+ 0.9524483759316599,
+ 0.954141766338572,
+ 0.9557748523683696,
+ 0.9573497815576658,
+ 0.9588686249658143,
+ 0.960333379898388,
+ 0.9617459725336712,
+ 0.9631082604556176,
+ 0.9644220350966051,
+ 0.9656890240932012,
+ 0.9669108935580351,
+ 0.9680892502707645,
+ 0.9692256437910194,
+ 0.9703215684960996,
+ 0.9713784655461073,
+ 0.9723977247790973,
+ 0.9733806865387387,
+ 0.9743286434368901,
+ 0.9752428420534066,
+ 0.9761244845754142,
+ 0.9769747303782067,
+ 0.9777946975498447,
+ 0.9785854643614604,
+ 0.9793480706852037,
+ 0.9800835193616915,
+ 0.9807927775187607,
+ 0.9814767778432588,
+ 0.9821364198075426,
+ 0.9827725708523005,
+ 0.9833860675272521,
+ 0.9839777165912252,
+ 0.9845482960730585,
+ 0.9850985562947225,
+ 0.9856292208580062,
+ 0.9861409875960662,
+ 0.9866345294910889,
+ 0.9871104955592747,
+ 0.9875695117043048,
+ 0.9880121815404163,
+ 0.9884390871861642,
+ 0.988850790029919,
+ 0.989247831468101,
+ 0.9896307336171266,
+ 0.99,
+ 0.9903561162084555,
+ 0.9906995505415186,
+ 0.9910307546213273,
+ 0.9913501639870234,
+ 0.9916581986674937,
+ 0.9919552637337158,
+ 0.9922417498314332,
+ 0.9925180336948611,
+ 0.992784478642099,
+ 0.9930414350528995,
+ 0.9932892408294248,
+ 0.9935282218405932,
+ 0.9937586923506025,
+ 0.9939809554321933,
+ 0.9941953033651946,
+ 0.9944020180208767,
+ 0.9946013712326175,
+ 0.9947936251533674,
+ 0.9949790326003856,
+ 0.9951578373876985,
+ 0.9953302746467203,
+ 0.9954965711354542,
+ 0.9956569455366833,
+ 0.9958116087455425,
+ 0.9959607641468491,
+ 0.9961046078825573,
+ 0.9962433291096884,
+ 0.9963771102490757,
+ 0.9965061272252509,
+ 0.9966305496977879,
+ 0.9967505412844082,
+ 0.9968662597761411,
+ 0.9969778573448216,
+ 0.997085480743199,
+ 0.9971892714979192,
+ 0.9972893660956351,
+ 0.9973858961624885,
+ 0.9974789886372009,
+ 0.9975687659380003,
+ 0.997655346123603,
+ 0.9977388430484633,
+ 0.9978193665124937,
+ 0.9978970224054539,
+ 0.9979719128461976,
+ 0.9980441363169605,
+ 0.9981137877928665,
+ 0.9981809588668211,
+ 0.9982457378699584,
+ 0.9983082099877971,
+ 0.998368457372262,
+ 0.9984265592497144,
+ 0.9984825920251366,
+ 0.9985366293826053,
+ 0.9985887423821885,
+ 0.9986389995533894,
+ 0.9986874669852648,
+ 0.9987342084133328,
+ 0.9987792853033867,
+ 0.998822756932323,
+ 0.9988646804660922,
+ 0.9989051110348723,
+ 0.9989441018055665,
+ 0.998981704051718,
+ 0.9990179672209368,
+ 0.9990529389999228,
+ 0.9990866653771752,
+ 0.9991191907034683,
+ 0.9991505577501736,
+ 0.9991808077655047,
+ 0.9992099805287591,
+ 0.9992381144026296,
+ 0.9992652463836508,
+ 0.9992914121508512,
+ 0.9993166461126708,
+ 0.9993409814522096,
+ 0.9993644501708637,
+ 0.9993870831304075,
+ 0.9994089100935772,
+ 0.9994299597632104,
+ 0.9994502598199896,
+ 0.9994698369588437,
+ 0.9994887169240517,
+ 0.9995069245430971,
+ 0.9995244837593166,
+ 0.9995414176633857,
+ 0.9995577485236837,
+ 0.9995734978155767,
+ 0.9995886862496581,
+ 0.9996033337989839,
+ 0.9996174597253367,
+ 0.9996310826045561,
+ 0.999644220350966,
+ 0.999656890240932,
+ 0.9996691089355804,
+ 0.9996808925027076,
+ 0.9996922564379102,
+ 0.999703215684961,
+ 0.9997137846554611,
+ 0.9997239772477909,
+ 0.9997338068653874,
+ 0.9997432864343689,
+ 0.999752428420534,
+ 0.9997612448457541,
+ 0.9997697473037821,
+ 0.9997779469754985,
+ 0.9997858546436146,
+ 0.999793480706852,
+ 0.999800835193617,
+ 0.9998079277751876,
+ 0.9998147677784326,
+ 0.9998213641980754,
+ 0.999827725708523,
+ 0.9998338606752725,
+ 0.9998397771659122,
+ 0.9998454829607306,
+ 0.9998509855629473,
+ 0.9998562922085801,
+ 0.9998614098759606,
+ 0.9998663452949109,
+ 0.9998711049555927,
+ 0.999875695117043,
+ 0.9998801218154042,
+ 0.9998843908718617,
+ 0.9998885079002992,
+ 0.999892478314681,
+ 0.9998963073361713,
+ 0.9999,
+ 1.0
+ ]
+}
\ No newline at end of file
diff --git a/cherab/generomak/plasma/data/edge/carbon0.json b/cherab/generomak/plasma/data/edge/carbon0.json
index beee5028..cc58c95c 100644
--- a/cherab/generomak/plasma/data/edge/carbon0.json
+++ b/cherab/generomak/plasma/data/edge/carbon0.json
@@ -36,52 +36,52 @@
0.8826349542181627,
0.8899903230020518,
0.8899903230020518,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7047757257456048,
0.7047757257456048,
0.7072344434153071,
@@ -94,10 +94,10 @@
0.771280502896162,
0.7378957943285048,
0.7378957943285048,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6668202352525383,
0.6668202352525383,
0.6939803492353266,
@@ -114,56 +114,56 @@
0.7550529537931084,
0.6698586018699858,
0.6698586018699858,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.8777104035584131,
0.8777104035584131,
0.8904284769390789,
@@ -232,52 +232,52 @@
0.8826349542181627,
0.8899903230020518,
0.8899903230020518,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7047757257456048,
0.7047757257456048,
0.7072344434153071,
@@ -290,10 +290,10 @@
0.771280502896162,
0.7378957943285048,
0.7378957943285048,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6668202352525383,
0.6668202352525383,
0.6939803492353266,
@@ -310,56 +310,56 @@
0.7550529537931084,
0.6698586018699858,
0.6698586018699858,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.8777104035584131,
0.8777104035584131,
0.8904284769390789,
@@ -428,52 +428,52 @@
0.9488695364408866,
0.9776952595352856,
0.9776952595352856,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7381857748401043,
0.7381857748401043,
0.7252051835877666,
@@ -486,10 +486,10 @@
0.6707223018957097,
0.6653150953392322,
0.6653150953392322,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6712374760547157,
0.6712374760547157,
0.6863147774504369,
@@ -506,62 +506,62 @@
0.7169300660266651,
0.7016922330175489,
0.7016922330175489,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 0.989668471223005,
- 0.989668471223005,
- 0.9084402862412485,
- 0.9084402862412485,
- 0.9888120737628983,
- 0.9888120737628983,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 0.989668471223005,
+ 0.989668471223005,
+ 0.9084402862412485,
+ 0.9084402862412485,
+ 0.9888120737628983,
+ 0.9888120737628983,
0.9238193646007199,
0.9238193646007199,
0.9402302268252902,
@@ -624,52 +624,52 @@
1.0141940442254633,
1.0314660474570372,
1.0314660474570372,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7425897836430437,
0.7425897836430437,
0.7658060128718618,
@@ -682,10 +682,10 @@
0.671465665626478,
0.6819424130985049,
0.6819424130985049,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7291516897755482,
0.7291516897755482,
0.7241049927832115,
@@ -702,56 +702,56 @@
0.7451781374562225,
0.6630318889047037,
0.6630318889047037,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
1.041544898725567,
1.041544898725567,
0.9741726142287506,
@@ -820,52 +820,52 @@
1.0599891197764155,
1.0291050094043501,
1.0291050094043501,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7562683004400875,
0.7562683004400875,
0.7327700174161945,
@@ -878,10 +878,10 @@
0.6702462619986006,
0.7024151245985529,
0.7024151245985529,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.697839411880975,
0.697839411880975,
0.7256309169217358,
@@ -898,56 +898,56 @@
0.7184151082807516,
0.6821155525602305,
0.6821155525602305,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.9521070696129001,
0.9521070696129001,
0.875934444566366,
@@ -1016,52 +1016,52 @@
0.9521600600249424,
0.9985453326739754,
0.9985453326739754,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7107102149886928,
0.7107102149886928,
0.6925560368645347,
@@ -1074,10 +1074,10 @@
0.7163705771532305,
0.7085061508892283,
0.7085061508892283,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6568431829970128,
0.6568431829970128,
0.6666301188861303,
@@ -1094,56 +1094,56 @@
0.6694595197797648,
0.7170387931147423,
0.7170387931147423,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
20.447996996565863,
20.447996996565863,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.9327311785025072,
0.9327311785025072,
0.9597158436652123,
@@ -1212,52 +1212,52 @@
1.0298700935866976,
0.9528687209652565,
0.9528687209652565,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6387338189080094,
0.6387338189080094,
0.6234247702803535,
@@ -1270,10 +1270,10 @@
0.6924896272079825,
0.6741197425302109,
0.6741197425302109,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7490929991929967,
0.7490929991929967,
0.7573533243775917,
@@ -1290,56 +1290,56 @@
0.6863972902004013,
0.7098833398665082,
0.7098833398665082,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
29.736571479671202,
29.736571479671202,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
41.119296463288705,
41.119296463288705,
20.70607715528574,
20.70607715528574,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
20.447996996565863,
20.447996996565863,
11.907214594917132,
11.907214594917132,
11.053179545995052,
11.053179545995052,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.9374114989121731,
0.9374114989121731,
1.0162759619923405,
@@ -1408,52 +1408,52 @@
0.9172602251294597,
1.034558340712888,
1.034558340712888,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7698504483370217,
0.7698504483370217,
0.6974013203590386,
@@ -1466,10 +1466,10 @@
0.7918775452569733,
0.6937161461562047,
0.6937161461562047,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6507337442545676,
0.6507337442545676,
0.6520238017651679,
@@ -1486,60 +1486,60 @@
0.668291795847024,
0.715565672142988,
0.715565672142988,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
29.736571479671202,
29.736571479671202,
28.954414273401518,
28.954414273401518,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
41.119296463288705,
41.119296463288705,
20.70607715528574,
20.70607715528574,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
20.436121901400792,
20.436121901400792,
22.917604227150402,
22.917604227150402,
11.053179545995052,
11.053179545995052,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 1.0904314561361903,
- 1.0904314561361903,
- 1.085821664779066,
- 1.085821664779066,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 1.0904314561361903,
+ 1.0904314561361903,
+ 1.085821664779066,
+ 1.085821664779066,
1.0145245945460468,
1.0145245945460468,
0.9934922693423827,
@@ -1606,50 +1606,50 @@
1.078138055032951,
0.6426753943036221,
0.6426753943036221,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7200699195816633,
0.7200699195816633,
0.755049895453662,
@@ -1662,10 +1662,10 @@
0.6385266008067373,
0.6417090838687141,
0.6417090838687141,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6539603547857009,
0.6539603547857009,
0.6483565406933778,
@@ -1682,30 +1682,30 @@
0.6835863641736272,
0.6922198691857843,
0.6922198691857843,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
29.736571479671202,
29.736571479671202,
28.954414273401518,
28.954414273401518,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
12.009592819963695,
12.009592819963695,
20.87818801631581,
20.87818801631581,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
20.462200798766613,
20.462200798766613,
23.184476175552565,
@@ -1714,22 +1714,22 @@
11.053179545995052,
40.216868497908706,
40.216868497908706,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
47.12362569631633,
47.12362569631633,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
1.271636695208476,
1.271636695208476,
1.077981642815545,
@@ -1802,50 +1802,50 @@
1.6613708772886773,
1.8250934621981263,
1.8250934621981263,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6754564865286883,
0.6754564865286883,
0.6830080259427875,
@@ -1858,10 +1858,10 @@
0.6935655385422379,
0.6392340134452367,
0.6392340134452367,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6822174139883256,
0.6822174139883256,
0.6678244940626191,
@@ -1878,30 +1878,30 @@
0.7375110677091551,
0.6868580384002779,
0.6868580384002779,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
29.736571479671202,
29.736571479671202,
28.954414273401518,
28.954414273401518,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
11.486304075009997,
11.486304075009997,
21.400253425490913,
21.400253425490913,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
20.46202541236162,
20.46202541236162,
28.1268806720096,
@@ -1910,22 +1910,22 @@
11.053179545995052,
40.216868497908706,
40.216868497908706,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
47.12362569631633,
47.12362569631633,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
4.073020328419045,
4.073020328419045,
1.5613878937645274,
@@ -1990,58 +1990,58 @@
1.9632484541651354,
2.1295862313767837,
2.1295862313767837,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6763005882159183,
0.6763005882159183,
0.7898026179802595,
@@ -2054,10 +2054,10 @@
0.6937591501537277,
0.7556495172304454,
0.7556495172304454,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.648692521126856,
0.648692521126856,
0.681328248605578,
@@ -2074,18 +2074,18 @@
0.6840589712407453,
0.7241738366283028,
0.7241738366283028,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
29.736571479671202,
29.736571479671202,
28.592746909327357,
@@ -2110,38 +2110,38 @@
10.298871329064708,
47.12362569631633,
47.12362569631633,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 4.25838478430837,
- 4.25838478430837,
- 2.2399058404942385,
- 2.2399058404942385,
- 1.6997660820960394,
- 1.6997660820960394,
- 1.4481581186260142,
- 1.4481581186260142,
- 1.6029574676720695,
- 1.6029574676720695,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 4.25838478430837,
+ 4.25838478430837,
+ 2.2399058404942385,
+ 2.2399058404942385,
+ 1.6997660820960394,
+ 1.6997660820960394,
+ 1.4481581186260142,
+ 1.4481581186260142,
+ 1.6029574676720695,
+ 1.6029574676720695,
1.4764963798616977,
1.4764963798616977,
1.0559663423477441,
@@ -2180,64 +2180,64 @@
2.054170888626254,
3.687400861196182,
3.687400861196182,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7016610254721765,
0.7016610254721765,
0.7150149213822576,
@@ -2250,10 +2250,10 @@
0.7040376672975498,
0.7555713111217425,
0.7555713111217425,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6900798429694239,
0.6900798429694239,
0.7153411650615797,
@@ -2270,18 +2270,18 @@
0.6640386443184142,
0.6994095259037463,
0.6994095259037463,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
27.739809741851474,
27.739809741851474,
38.84926023705824,
@@ -2306,38 +2306,38 @@
10.298871329064708,
47.12362569631633,
47.12362569631633,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
12.78479636097352,
12.78479636097352,
3.6748473139947193,
@@ -2368,72 +2368,72 @@
3.527400649883651,
19.403170249953853,
19.403170249953853,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.691325710595777,
0.691325710595777,
0.6673680525040038,
@@ -2446,10 +2446,10 @@
0.7359544353459845,
0.6783759523982673,
0.6783759523982673,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6720141694439417,
0.6720141694439417,
0.6500762012735732,
@@ -2466,18 +2466,18 @@
0.6696363417318444,
0.6958262131290076,
0.6958262131290076,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
27.613459752902624,
27.613459752902624,
50.56896491975679,
@@ -2502,42 +2502,42 @@
9.900632466719646,
47.12362569631633,
47.12362569631633,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
12.102842213837954,
12.102842213837954,
1.7662817818874772,
@@ -2564,72 +2564,72 @@
4.423797944365727,
5.186650225483191,
5.186650225483191,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
6.087607566495069,
6.087607566495069,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6851429341217069,
0.6851429341217069,
0.6554378448138072,
@@ -2642,10 +2642,10 @@
0.7649226520925533,
0.6514028964424405,
0.6514028964424405,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.674137093925438,
0.674137093925438,
0.6775360949372078,
@@ -2662,14 +2662,14 @@
0.6772589719343018,
0.6916349149553257,
0.6916349149553257,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
10.416500681534718,
10.416500681534718,
36.59624148531928,
@@ -2700,40 +2700,40 @@
47.12362569631633,
7.919889561939525,
7.919889561939525,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
3.4987177325168757,
3.4987177325168757,
1.6479893314933964,
@@ -2758,74 +2758,74 @@
1.2275594077849972,
5.494688671136869,
5.494688671136869,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
6.087607566495069,
6.087607566495069,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7292143545266557,
0.7292143545266557,
0.6891375623444526,
@@ -2838,10 +2838,10 @@
0.7586520575858056,
0.6745911012955143,
0.6745911012955143,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6433718218861504,
0.6433718218861504,
0.6992843212317127,
@@ -2858,14 +2858,14 @@
0.6969783957041531,
0.7316343748400964,
0.7316343748400964,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
10.685891702999333,
10.685891702999333,
36.59624148531928,
@@ -2896,36 +2896,36 @@
8.577289612376159,
7.137119439478731,
7.137119439478731,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
9.916620092213877,
9.916620092213877,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
6.42574718762251,
6.42574718762251,
3.179734301380406,
@@ -2956,72 +2956,72 @@
2.9325974429358705,
23.358836476453074,
23.358836476453074,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
33.60428485689675,
33.60428485689675,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
6.087607566495069,
6.087607566495069,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
32.071443253865354,
32.071443253865354,
15.43404108838102,
15.43404108838102,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7621497992711334,
0.7621497992711334,
0.7179255867240416,
@@ -3034,10 +3034,10 @@
0.767890115166915,
0.7059415772256232,
0.7059415772256232,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.636204010449949,
0.636204010449949,
0.6790766242069662,
@@ -3054,14 +3054,14 @@
0.6941961806191215,
0.649713319935984,
0.649713319935984,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
12.239578698037612,
12.239578698037612,
19.242109356589207,
@@ -3094,20 +3094,20 @@
5.711142083726083,
6.620745038277721,
6.620745038277721,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
13.11318150205903,
13.11318150205903,
6.593562642107537,
@@ -3156,50 +3156,50 @@
33.669584773135576,
33.49419462323778,
33.49419462323778,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
8.171498524051001,
8.171498524051001,
38.45923270405153,
38.45923270405153,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
15.860288098546818,
15.860288098546818,
32.071443253865354,
@@ -3208,16 +3208,16 @@
15.43404108838102,
18.948368959923304,
18.948368959923304,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7029588848691198,
0.7029588848691198,
0.6739359300879681,
@@ -3230,10 +3230,10 @@
0.7166222347991128,
0.7328946603524116,
0.7328946603524116,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6357189827797727,
0.6357189827797727,
0.6683781783326145,
@@ -3250,14 +3250,14 @@
0.6741188063038498,
0.7088372005305378,
0.7088372005305378,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
12.229961156704775,
12.229961156704775,
18.50145319245743,
@@ -3354,42 +3354,42 @@
30.909596326069007,
27.39453570136138,
27.39453570136138,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
5.20877762345397,
5.20877762345397,
6.623242890209321,
6.623242890209321,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
4.480751652255091,
4.480751652255091,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
9.424871565066152,
9.424871565066152,
25.002127199915215,
@@ -3404,16 +3404,16 @@
15.43404108838102,
18.948368959923304,
18.948368959923304,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
15.397359739550415,
15.397359739550415,
15.397359739550415,
15.397359739550415,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6738766357517608,
0.6738766357517608,
0.6770712897564328,
@@ -3426,10 +3426,10 @@
0.7541213461486544,
0.6783959252273055,
0.6783959252273055,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6463107612640417,
0.6463107612640417,
0.666387511428406,
@@ -3446,14 +3446,14 @@
0.6821862064429534,
0.7122229695430697,
0.7122229695430697,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
23.867441447158193,
23.867441447158193,
18.074834812501706,
@@ -3550,38 +3550,38 @@
27.39453570136138,
35.695627926627225,
35.695627926627225,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
59.91215073481093,
59.91215073481093,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
5.20877762345397,
5.20877762345397,
6.623242890209321,
6.623242890209321,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
6.289243511711331,
6.289243511711331,
6.692733355640737,
@@ -3604,12 +3604,12 @@
24.511241873472486,
8.926741719040699,
8.926741719040699,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6638601995739754,
0.6638601995739754,
0.6726811995187293,
@@ -3622,10 +3622,10 @@
0.7778953790434571,
0.6578610482968759,
0.6578610482968759,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6443494918675741,
0.6443494918675741,
1.0633255808672593,
@@ -3642,12 +3642,12 @@
0.6765483137110837,
0.6952242195787759,
0.6952242195787759,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
5.307164528277598,
5.307164528277598,
20.442098770490496,
@@ -3746,34 +3746,34 @@
1.2827860276983667,
35.69119083782619,
35.69119083782619,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
59.91215073481093,
59.91215073481093,
59.91215073481093,
59.91215073481093,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
5.20877762345397,
5.20877762345397,
6.623242890209321,
6.623242890209321,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
0.6666763684683721,
0.6666763684683721,
0.7227419720315307,
@@ -3802,10 +3802,10 @@
6.311529444012602,
1.1100967036072755,
1.1100967036072755,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6891511064191441,
0.6891511064191441,
0.6774362932071071,
@@ -3818,10 +3818,10 @@
0.7280618598760566,
0.7217131216756966,
0.7217131216756966,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.702498199084334,
0.702498199084334,
0.8427326122145906,
@@ -3838,12 +3838,12 @@
0.6723606980277558,
0.6898971539988143,
0.6898971539988143,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
13.651777548017844,
13.651777548017844,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
7.851858361329716,
7.851858361329716,
18.578210646904243,
@@ -3942,26 +3942,26 @@
1.2281109075268166,
28.424399054118275,
28.424399054118275,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
47.648711995883474,
47.648711995883474,
52.974239043858134,
52.974239043858134,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
38.28753003771493,
38.28753003771493,
7.8610140309910435,
7.8610140309910435,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
0.6666763684683721,
0.6666763684683721,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
33.80948695073779,
33.80948695073779,
5.20877762345397,
@@ -4014,10 +4014,10 @@
0.7272484039983822,
0.6604385418842652,
0.6604385418842652,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6681542954021136,
0.6681542954021136,
0.8068853162416049,
@@ -4154,8 +4154,8 @@
0.6666763684683721,
0.6666763684683721,
0.6666763684683721,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
33.80948695073779,
33.80948695073779,
33.80948695073779,
@@ -4210,10 +4210,10 @@
0.743756196858879,
0.6876543925430885,
0.6876543925430885,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7303031233696048,
0.7303031233696048,
0.7414673730661835,
@@ -4348,8 +4348,8 @@
2.796235137205228,
0.6666763684683721,
0.6666763684683721,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
33.80948695073779,
33.80948695073779,
21.166854066104175,
@@ -4406,10 +4406,10 @@
0.7093227899365309,
0.6636280778514962,
0.6636280778514962,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.726225420661078,
0.726225420661078,
0.703051009543059,
@@ -4602,10 +4602,10 @@
0.7129741351601812,
0.6611613086350877,
0.6611613086350877,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6949256881997445,
0.6949256881997445,
0.6979661769302773,
@@ -4798,10 +4798,10 @@
0.6918136717752184,
0.7215496565530365,
0.7215496565530365,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6959255779534731,
0.6959255779534731,
0.6880125303337811,
@@ -4994,10 +4994,10 @@
0.6835688879482187,
0.7268541902852392,
0.7268541902852392,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6848245547438186,
0.6848245547438186,
0.679257503139944,
@@ -5190,10 +5190,10 @@
0.683777479181487,
0.7169371189319192,
0.7169371189319192,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6898697537739775,
0.6898697537739775,
0.688960740392373,
@@ -5386,10 +5386,10 @@
0.6829814371141303,
0.714735239360631,
0.714735239360631,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6944113878520088,
0.6944113878520088,
0.6889494432609483,
@@ -5582,10 +5582,10 @@
0.6810513128479442,
0.7179132285360741,
0.7179132285360741,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7000713755260022,
0.7000713755260022,
0.6947092950801328,
@@ -5778,10 +5778,10 @@
0.6677305593510484,
0.7192147080082807,
0.7192147080082807,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6944829155460022,
0.6944829155460022,
0.6939876518009437,
@@ -5974,10 +5974,10 @@
0.6723199409734995,
0.7051740588547367,
0.7051740588547367,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6991042536949145,
0.6991042536949145,
0.6833483130175272,
@@ -6170,10 +6170,10 @@
0.6985494459532857,
0.684618210453817,
0.684618210453817,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.6994964077100628,
0.6994964077100628,
0.7044508551982791,
@@ -6366,10 +6366,10 @@
0.6881025953097255,
0.7203669529985169,
0.7203669529985169,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7151509862800808,
0.7151509862800808,
0.747833337831589,
@@ -6562,10 +6562,10 @@
0.6867911294229997,
0.7382354572523369,
0.7382354572523369,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7029822905281491,
0.7029822905281491,
0.7433765258618795,
@@ -6758,10 +6758,10 @@
0.705876852776521,
0.7732053842947257,
0.7732053842947257,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7010752598455384,
0.7010752598455384,
0.7448947105291513,
@@ -6954,10 +6954,10 @@
0.7567317324888662,
0.7563844549239631,
0.7563844549239631,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.7127471938902338,
0.7127471938902338,
0.7629452796026733,
@@ -7150,10 +7150,10 @@
0.7424246333129336,
0.8932101927033845,
0.8932101927033845,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.8063032955204114,
0.8063032955204114,
0.7377027444528318,
@@ -7346,10 +7346,10 @@
0.7424246333129336,
0.8932101927033845,
0.8932101927033845,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
+ 152.00613642203447,
0.8063032955204114,
0.8063032955204114,
0.7377027444528318,
@@ -14901,4 +14901,4 @@
0.0,
0.0
]
-}
\ No newline at end of file
+}
diff --git a/cherab/generomak/plasma/data/edge/hydrogen0.json b/cherab/generomak/plasma/data/edge/hydrogen0.json
index 50252db1..b255b8b3 100644
--- a/cherab/generomak/plasma/data/edge/hydrogen0.json
+++ b/cherab/generomak/plasma/data/edge/hydrogen0.json
@@ -36,22 +36,22 @@
1.972944700927401,
2.1469916156572784,
2.1469916156572784,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 1060.8616203299343,
- 1060.8616203299343,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
237.02952717009856,
237.02952717009856,
510.5159897120308,
@@ -94,10 +94,10 @@
3.2178661145048255,
3.0058149630960105,
3.0058149630960105,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.228549122630633,
4.228549122630633,
4.632909532245744,
@@ -114,8 +114,8 @@
3.701953002018378,
3.344396295820652,
3.344396295820652,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
390.9182712497354,
390.9182712497354,
368.29180845487235,
@@ -160,10 +160,10 @@
327.66094502911096,
224.2842595343954,
224.2842595343954,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.28095818054478,
2.28095818054478,
2.2121432336404925,
@@ -232,22 +232,22 @@
1.972944700927401,
2.1469916156572784,
2.1469916156572784,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 1060.8616203299343,
- 1060.8616203299343,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
237.02952717009856,
237.02952717009856,
510.5159897120308,
@@ -290,10 +290,10 @@
3.2178661145048255,
3.0058149630960105,
3.0058149630960105,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.228549122630633,
4.228549122630633,
4.632909532245744,
@@ -310,8 +310,8 @@
3.701953002018378,
3.344396295820652,
3.344396295820652,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
390.9182712497354,
390.9182712497354,
368.29180845487235,
@@ -356,10 +356,10 @@
327.66094502911096,
224.2842595343954,
224.2842595343954,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.28095818054478,
2.28095818054478,
2.2121432336404925,
@@ -432,14 +432,14 @@
773.3934409631391,
773.3934409631391,
773.3934409631391,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
1060.8616203299343,
1060.8616203299343,
172.10538098510307,
@@ -486,10 +486,10 @@
3.032072679696813,
3.370428818774048,
3.370428818774048,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
5.3896244750752,
5.3896244750752,
4.462110574008034,
@@ -624,14 +624,14 @@
2.147574884680287,
2.194014083967723,
2.194014083967723,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
773.3934409631391,
773.3934409631391,
773.3934409631391,
773.3934409631391,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
298.78233138681514,
298.78233138681514,
59.11285621707551,
@@ -682,10 +682,10 @@
3.1739117848101137,
3.592521996547854,
3.592521996547854,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.050162985962009,
4.050162985962009,
4.408568162903317,
@@ -748,10 +748,10 @@
223.31419795253365,
240.54622431848549,
240.54622431848549,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.3245336506386725,
2.3245336506386725,
2.224360425917933,
@@ -820,10 +820,10 @@
2.2302022287512653,
2.315271438417445,
2.315271438417445,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
69.51090013212614,
69.51090013212614,
492.924708325262,
@@ -878,10 +878,10 @@
2.9181949735012807,
3.2768293386558027,
3.2768293386558027,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.324206553120909,
4.324206553120909,
4.620829840413214,
@@ -946,8 +946,8 @@
156.99101750849775,
232.87885497898233,
232.87885497898233,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.2079833302574556,
2.2079833302574556,
2.2547071423586873,
@@ -1016,10 +1016,10 @@
2.1893738964614062,
2.04235408915594,
2.04235408915594,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
52.38173633232502,
52.38173633232502,
101.12902445436613,
@@ -1074,10 +1074,10 @@
3.4798216262090365,
3.1222993731414017,
3.1222993731414017,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.816413082204519,
4.816413082204519,
4.044458683573587,
@@ -1142,8 +1142,8 @@
92.01574712267337,
270.2239009185301,
270.2239009185301,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.2063231512587396,
2.2063231512587396,
2.1501370865704437,
@@ -1212,8 +1212,8 @@
2.3205649246785858,
2.1310041774083195,
2.1310041774083195,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
100.91711897977912,
100.91711897977912,
44.17568980724506,
@@ -1270,10 +1270,10 @@
2.962358144089624,
2.6885652983502446,
2.6885652983502446,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.510954002590953,
4.510954002590953,
5.1300036622553815,
@@ -1466,10 +1466,10 @@
3.091068609355341,
3.595791860736873,
3.595791860736873,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.758281560358844,
3.758281560358844,
4.7689404762596235,
@@ -1662,10 +1662,10 @@
3.178992185951452,
3.0699698744951243,
3.0699698744951243,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.2251648103863184,
3.2251648103863184,
4.289231195965626,
@@ -1858,10 +1858,10 @@
2.525787178593943,
2.825822761312346,
2.825822761312346,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.9410852499050995,
3.9410852499050995,
3.3806876751642854,
@@ -2054,10 +2054,10 @@
3.019009700524693,
2.3753950839355458,
2.3753950839355458,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.197689853464683,
4.197689853464683,
3.755099077296867,
@@ -2250,10 +2250,10 @@
2.877357840683626,
3.041679111143497,
3.041679111143497,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.5308683699103307,
3.5308683699103307,
3.276232088652468,
@@ -2446,10 +2446,10 @@
2.7262409819915026,
4.0978295780089375,
4.0978295780089375,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.0636950981772966,
3.0636950981772966,
3.487733612772186,
@@ -2642,10 +2642,10 @@
2.8434261886757737,
2.888884534812159,
2.888884534812159,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.965325731994167,
2.965325731994167,
3.2970243030020376,
@@ -2838,10 +2838,10 @@
2.6858381957903403,
2.9947567566386066,
2.9947567566386066,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
2.707415654396568,
2.707415654396568,
3.4228154272283566,
@@ -3034,10 +3034,10 @@
3.1050752422844288,
2.5827768999906664,
2.5827768999906664,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.3679896994428393,
3.3679896994428393,
3.7827563898925267,
@@ -3230,10 +3230,10 @@
3.2214229008659983,
3.112208101269813,
3.112208101269813,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.079169463159205,
4.079169463159205,
4.373918362861358,
@@ -3426,10 +3426,10 @@
3.182294755648022,
3.540194869675025,
3.540194869675025,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.426191958807458,
3.426191958807458,
3.890835422082432,
@@ -3622,10 +3622,10 @@
2.9324045178903795,
3.031484542296727,
3.031484542296727,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.048504929076378,
4.048504929076378,
4.101542214851699,
@@ -3818,10 +3818,10 @@
3.1031142849634143,
3.186577866420189,
3.186577866420189,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
5.138463029164361,
5.138463029164361,
4.226479438221542,
@@ -4014,10 +4014,10 @@
2.9823071305632336,
3.301914899852422,
3.301914899852422,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.230204495667361,
4.230204495667361,
3.7793528325791326,
@@ -4210,10 +4210,10 @@
2.7946538508812133,
3.6766072947235355,
3.6766072947235355,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.347594361434184,
4.347594361434184,
3.2985799991388465,
@@ -4406,10 +4406,10 @@
2.9905828098601517,
3.2936387212347777,
3.2936387212347777,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.6020830522235667,
3.6020830522235667,
3.408852235202427,
@@ -4602,10 +4602,10 @@
2.990016392911645,
2.251912069764962,
2.251912069764962,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.33474979388571,
3.33474979388571,
3.552615972053928,
@@ -4798,10 +4798,10 @@
3.1068532609744706,
2.035272972280783,
2.035272972280783,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.346502929963464,
3.346502929963464,
3.4188598084373263,
@@ -4994,10 +4994,10 @@
3.050768558393544,
2.5736518761388956,
2.5736518761388956,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.719975297055793,
3.719975297055793,
3.6058544216667188,
@@ -5190,10 +5190,10 @@
2.9544671289969644,
2.6266115175413303,
2.6266115175413303,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.621674275397029,
3.621674275397029,
3.7044403682147324,
@@ -5386,10 +5386,10 @@
2.7672878919291497,
2.397112914080858,
2.397112914080858,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.811473760389393,
3.811473760389393,
3.8450036464581223,
@@ -5582,10 +5582,10 @@
2.630605459198078,
2.492375257046721,
2.492375257046721,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.876404241706099,
3.876404241706099,
3.662145218877284,
@@ -5778,10 +5778,10 @@
2.8051830270294658,
2.551368128365802,
2.551368128365802,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.877623582918886,
3.877623582918886,
4.0914143677369355,
@@ -5974,10 +5974,10 @@
2.6751353808596363,
2.908345372861055,
2.908345372861055,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.916432724608066,
3.916432724608066,
4.1287282310971465,
@@ -6170,10 +6170,10 @@
2.6903946222448782,
2.7719752652440692,
2.7719752652440692,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
3.539496944130319,
3.539496944130319,
4.011383928346568,
@@ -6366,10 +6366,10 @@
2.4393379088563094,
2.553484436847679,
2.553484436847679,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.608095663939136,
4.608095663939136,
4.553307572453338,
@@ -6562,10 +6562,10 @@
2.4487560963893076,
2.596682670133111,
2.596682670133111,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.667622184284084,
4.667622184284084,
4.634387022273851,
@@ -6758,10 +6758,10 @@
2.540889570856143,
3.099676149689748,
3.099676149689748,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.975413715838775,
4.975413715838775,
4.372279592238767,
@@ -6954,10 +6954,10 @@
2.8814299260339857,
2.778316014312814,
2.778316014312814,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
4.494170272614275,
4.494170272614275,
4.624706129623908,
@@ -7150,10 +7150,10 @@
3.1383402387080377,
3.087223090784384,
3.087223090784384,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
5.0891368198545335,
5.0891368198545335,
4.804279214073222,
@@ -7346,10 +7346,10 @@
3.1383402387080377,
3.087223090784384,
3.087223090784384,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
- 6241509074460.763,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
+ 1060.8616203299343,
5.0891368198545335,
5.0891368198545335,
4.804279214073222,
@@ -14901,4 +14901,4 @@
0.0,
0.0
]
-}
\ No newline at end of file
+}
diff --git a/cherab/generomak/plasma/plasma.py b/cherab/generomak/plasma/plasma.py
index f06335b4..45c5ed3e 100644
--- a/cherab/generomak/plasma/plasma.py
+++ b/cherab/generomak/plasma/plasma.py
@@ -1,7 +1,7 @@
-# Copyright 2016-2021 Euratom
-# Copyright 2016-2021 United Kingdom Atomic Energy Authority
-# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
#
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
# European Commission - subsequent versions of the EUPL (the "Licence");
@@ -24,7 +24,8 @@
from raysect.core import Vector3D, translate
from raysect.core.math.function.float.function2d.interpolate import Discrete2DMesh
-from raysect.core.math.function.float import Arg1D, Exp1D, Constant1D
+from raysect.core.math.function.float import Arg1D, Exp1D, Constant1D, Interpolator1DArray, Blend2D
+from raysect.core.math.function.vector3d import Constant2D as ConstantVector2D, Blend2D as BlendVector2D
from raysect.primitive import Cylinder, Subtract
from cherab.core import AtomicData, Plasma, Maxwellian, Species
@@ -33,6 +34,8 @@
from cherab.core.math.mappers import AxisymmetricMapper, VectorAxisymmetricMapper
from cherab.core.math.clamp import ClampInput1D
+from cherab.tools.plasmas.ionisation_balance import interpolators1d_from_elementdensity, interpolators1d_match_plasma_neutrality
+
from cherab.openadas import OpenADAS
from cherab.generomak.equilibrium import load_equilibrium
@@ -106,64 +109,65 @@ def get_edge_interpolators():
profiles["mesh"]["triangles"],
profiles["electron"]["temperature"], limit=False)
ne = Discrete2DMesh.instance(te, profiles["electron"]["density"], limit=False)
+ ve = ConstantVector2D(Vector3D(0, 1.e-10, 0)) # avoid zero-length vectors for blending
mesh_interp["electron"]["temperature"] = te
mesh_interp["electron"]["density"] = ne
+ mesh_interp["electron"]["velocity"] = ve
for elem_name, elem_data in profiles["composition"].items():
for stage, stage_data in elem_data.items():
t = Discrete2DMesh.instance(te, stage_data["temperature"], limit=False)
n = Discrete2DMesh.instance(te, stage_data["density"], limit=False)
+ v = ConstantVector2D(Vector3D(0, 1.e-10, 0)) # avoid zero-length vectors for blending
mesh_interp["composition"][elem_name][stage]["temperature"] = t
mesh_interp["composition"][elem_name][stage]["density"] = n
- mesh_interp["composition"][elem_name][stage]["element"] = stage_data["element"]
+ mesh_interp["composition"][elem_name][stage]["velocity"] = v
return mesh_interp.freeze()
-def get_edge_distributions():
+def get_2d_distributions(profiles_2d=None):
"""
- Provides Generomak edge Maxwellian distribution of plasma species
+ Provides Generomak Maxwellian distribution of plasma species for 2d profiles
+ :param profiles_2d: Dictionary with 2D profile interpolators in the shape
+ returned by the get_edge_interpolators() or get_full_profiles() functions.
+ If not specified, will use the value returned by get_edge_interpolators().
:return: Dictionary holding instances of Maxwellian distributions for plasma species.
"""
- mesh_interp = get_edge_interpolators()
-
- zero_vector = Vector3D(0, 0, 0)
+ profiles_2d = profiles_2d or get_edge_interpolators()
dists = RecursiveDict()
- n3d = AxisymmetricMapper(mesh_interp["electron"]["density"])
- t3d = AxisymmetricMapper(mesh_interp["electron"]["temperature"])
+ n3d = AxisymmetricMapper(profiles_2d["electron"]["density"])
+ t3d = AxisymmetricMapper(profiles_2d["electron"]["temperature"])
+ v3d = VectorAxisymmetricMapper(profiles_2d["electron"]["velocity"])
- dists["electron"] = Maxwellian(n3d, t3d, zero_vector, electron_mass)
+ dists["electron"] = Maxwellian(n3d, t3d, v3d, electron_mass)
- for elem_name, elem_data in mesh_interp["composition"].items():
+ for elem_name, elem_data in profiles_2d["composition"].items():
for stage, stage_data in elem_data.items():
- # get element or isotope
- try:
- element = lookup_isotope(elem_name)
- except ValueError:
- element = lookup_element(elem_name)
+ spec_cherab = _get_cherab_element(elem_name)
n3d = AxisymmetricMapper(stage_data["density"])
t3d = AxisymmetricMapper(stage_data["temperature"])
- mass = element.atomic_weight * atomic_mass
- dists["composition"][elem_name][stage]["distribution"] = Maxwellian(n3d, t3d, zero_vector, mass)
- dists["composition"][elem_name][stage]["element"] = element
+ v3d = VectorAxisymmetricMapper(stage_data["velocity"])
+ mass = spec_cherab.atomic_weight * atomic_mass
+ dists["composition"][elem_name][stage] = Maxwellian(n3d, t3d, v3d, mass)
return dists.freeze()
def get_edge_plasma(atomic_data=None, parent=None, name="Generomak edge plasma"):
"""
- Provides Generomak Edge plasma.
+ Provides Generomak default edge plasma.
- :param atomic_data: Instance of AtomicData, default isOpenADAS()
+ :param atomic_data: Instance of AtomicData, default is OpenADAS()
:param parent: parent of the plasma node, defaults None
:param name: name of the plasma node, defaults "Generomak edge plasma"
:return: populated Plasma object
@@ -172,12 +176,8 @@ def get_edge_plasma(atomic_data=None, parent=None, name="Generomak edge plasma")
# load Generomak equilibrium
equilibrium = load_equilibrium()
- # create or check atomic_data
- if atomic_data is not None:
- if not isinstance(atomic_data, AtomicData):
- raise ValueError("atomic_data has to be of type AtomicData")
- else:
- atomic_data = OpenADAS()
+ # get edge distributions
+ distributions = get_2d_distributions()
# base plasma geometry on mesh vertices
profiles_dir = os.path.join(os.path.dirname(__file__), "data/edge")
@@ -188,38 +188,88 @@ def get_edge_plasma(atomic_data=None, parent=None, name="Generomak edge plasma")
vertex_coords = np.asarray(mesh["vertex_coords"])
r_range = (vertex_coords[:, 0].min(), vertex_coords[:, 0].max())
z_range = (vertex_coords[:, 1].min(), vertex_coords[:, 1].max())
- plasma_height = z_range[1] - z_range[0]
- padding = 1e-3 # enlarge for safety
+ return get_plasma(equilibrium=equilibrium, distributions=distributions,
+ r_range=r_range, z_range=z_range, atomic_data=atomic_data,
+ parent=parent, name=name)
- outer_column = Cylinder(radius=r_range[1], height=plasma_height)
- inner_column = Cylinder(radius=r_range[0], height=plasma_height + 2 * padding)
- inner_column.transform = translate(0, 0, -padding)
- plasma_geometry = Subtract(outer_column, inner_column)
- geometry_transform = translate(0, 0, z_range[0])
+def load_core_profiles():
+ """
+ Loads Generomak default core plasma profiles.
- # get distributions
- dists = get_edge_distributions()
+ Return a single dictionary with available core plasma species temperature and
+ density profiles on a magnetic surface coordinate grid.
- # create plasma composition list
- plasma_composition = []
- for elem_data in dists["composition"].values():
+ :return: dictionary with electron and plasma composition profiles
+ """
+ profiles_dir = os.path.join(os.path.dirname(__file__), "data/core")
+
+ core_data = RecursiveDict()
+ path = os.path.join(profiles_dir, "psi_norm.json")
+ with open(path, "r") as fhl:
+ core_data["psi_norm"] = json.load(fhl)["psi_norm"]
+
+ path = os.path.join(profiles_dir, "electrons.json")
+ with open(path, "r") as fhl:
+ core_data["electron"] = json.load(fhl)
+
+ saved_elements = (hydrogen, carbon)
+
+ for element in saved_elements:
+ for chrg in range(element.atomic_number + 1):
+ path = os.path.join(profiles_dir, "{}{:d}.json".format(element.name, chrg))
+
+ with open(path, "r") as fhl:
+ file_data = json.load(fhl)
+ element_name = file_data["element"]
+ charge = file_data["charge"]
+
+ core_data["composition"][element_name][charge] = file_data
+
+ return core_data.freeze()
+
+
+def get_core_interpolators():
+ """
+ Provides 1d interpolators for Generomak default core profiles.
+
+ :return: dictionary holding 1D interpolators of density,
+ temperature and velocity for plasma species
+ """
+
+ profiles = load_core_profiles()
+
+ core_interp = RecursiveDict()
+
+ te = Interpolator1DArray(profiles["psi_norm"], profiles["electron"]["temperature"], 'cubic', 'nearest', 1.e-5)
+ ne = Interpolator1DArray(profiles["psi_norm"], profiles["electron"]["density"], 'cubic', 'nearest', 1.e-5)
+ ve_tor = Interpolator1DArray(profiles["psi_norm"], profiles["electron"]["vtor"], 'cubic', 'nearest', 1.e-5)
+ ve_pol = Interpolator1DArray(profiles["psi_norm"], profiles["electron"]["vpol"], 'cubic', 'nearest', 1.e-5)
+ ve_norm = Interpolator1DArray(profiles["psi_norm"], profiles["electron"]["vnorm"], 'cubic', 'nearest', 1.e-5)
+
+ core_interp["electron"]["f1d_temperature"] = te
+ core_interp["electron"]["f1d_density"] = ne
+ core_interp["electron"]["f1d_vtor"] = ve_tor
+ core_interp["electron"]["f1d_vpol"] = ve_pol
+ core_interp["electron"]["f1d_vnorm"] = ve_norm
+
+ for elem_name, elem_data in profiles["composition"].items():
for stage, stage_data in elem_data.items():
- species = Species(stage_data["element"], stage, stage_data["distribution"])
- plasma_composition.append(species)
- # Populate plasma
- plasma = Plasma(parent=parent)
- plasma.name = name
- plasma.geometry = plasma_geometry
- plasma.atomic_data = atomic_data
- plasma.electron_distribution = dists["electron"]
- plasma.composition = plasma_composition
- plasma.geometry_transform = geometry_transform
- plasma.b_field = VectorAxisymmetricMapper(equilibrium.b_field)
+ t = Interpolator1DArray(profiles["psi_norm"], stage_data["temperature"], 'cubic', 'nearest', 1.e-5)
+ n = Interpolator1DArray(profiles["psi_norm"], stage_data["density"], 'cubic', 'nearest', 1.e-5)
+ vtor = Interpolator1DArray(profiles["psi_norm"], stage_data["vtor"], 'cubic', 'nearest', 1.e-5)
+ vpol = Interpolator1DArray(profiles["psi_norm"], stage_data["vpol"], 'cubic', 'nearest', 1.e-5)
+ vnorm = Interpolator1DArray(profiles["psi_norm"], stage_data["vnorm"], 'cubic', 'nearest', 1.e-5)
- return plasma
+ core_interp["composition"][elem_name][stage]["f1d_temperature"] = t
+ core_interp["composition"][elem_name][stage]["f1d_density"] = n
+ core_interp["composition"][elem_name][stage]["f1d_vtor"] = vtor
+ core_interp["composition"][elem_name][stage]["f1d_vpol"] = vpol
+ core_interp["composition"][elem_name][stage]["f1d_vnorm"] = vnorm
+
+ return core_interp.freeze()
def get_double_parabola(v_min, v_max, convexity, concavity, xmin=0, xmax=1):
@@ -245,7 +295,7 @@ def get_double_parabola(v_min, v_max, convexity, concavity, xmin=0, xmax=1):
:return: Function1D
"""
- x = Arg1D() #the free parameter
+ x = Arg1D() # the free parameter
# funciton for the normalised free variable
x_norm = ClampInput1D((x - xmin) / (xmax - xmin), 0, 1)
@@ -271,7 +321,7 @@ def get_exponential_growth(initial_value, growth_rate, initial_position=1):
:return: Function1D
"""
- x = Arg1D() #the free parameter
+ x = Arg1D() # the free parameter
return initial_value * Exp1D((x - initial_position) * growth_rate)
@@ -288,7 +338,6 @@ def get_maxwellian_distribution(equilibrium, f1d_density, f1d_temperature, f1d_v
:return: Maxwellian distribution
"""
-
# map profiles to 3D
f3d_te = equilibrium.map3d(f1d_temperature)
f3d_ne = equilibrium.map3d(f1d_density)
@@ -308,28 +357,29 @@ def get_edge_profile_values(r, z, edge_interpolators=None):
returned by the get_edge_interpolators function.
:return: Dictionary of edge values at [R, Z]
"""
+
# load edge interpolators if not passed as argument
if edge_interpolators is None:
edge_interp = get_edge_interpolators()
else:
edge_interp = edge_interpolators
# create recursive dictionary to store profile values
- lcfs_values = RecursiveDict()
+ values = RecursiveDict()
# add electron values
- lcfs_values["electron"]["temperature"] = edge_interp["electron"]["temperature"](r, z)
- lcfs_values["electron"]["density"] = edge_interp["electron"]["density"](r, z)
+ values["electron"]["temperature"] = edge_interp["electron"]["temperature"](r, z)
+ values["electron"]["density"] = edge_interp["electron"]["density"](r, z)
# add species values
for spec, desc in edge_interp['composition'].items():
for chrg, chrg_desc in desc.items():
for prop, val in chrg_desc.items():
if prop in ["temperature", "density"]:
- lcfs_values["composition"][spec][chrg][prop] = val(r, z)
+ values["composition"][spec][chrg][prop] = val(r, z)
else:
- lcfs_values["composition"][spec][chrg][prop] = val
+ values["composition"][spec][chrg][prop] = val
- return lcfs_values.freeze()
+ return values.freeze()
def get_core_profiles_arguments(**kwargs):
@@ -347,21 +397,16 @@ def get_core_profiles_arguments(**kwargs):
te_core core: (default 3e3) electron temperature
te_convexity: (default 2.35) convexity of the electron temperature profile
te_concavity: (default 1.26) concavity of the electron temperature profile
- nh_core: (default 5e19) density of H1+
- nh_convexity: (default 1.09) convexity of H1+ density profile
- nh_concavity: (default 0.24) concavity of H1+ density profile
th_core: (default 2.8e3) H1+ temperature
- th_convexity: (default 1) convexity of H1+ temperature profile
- th_concavity: (default 0.82) concavity of H1+ temperature profile
+ th_convexity: (default 2) convexity of H1+ temperature profile
+ th_concavity: (default 1.26) concavity of H1+ temperature profile
th0_fraction: (default 0.8) H0 temperature factor
- nh0_decay decay: (default 20) rate of H0 density profile
- timp_core: (default 2.7e3) core impurity temperature
- timp_convexity: (default 1) convexity of impurity temperature profile
- timp_concavity: (default 0.82) concavity of impurity temperature profile
+ timp_core: (default 2.8e3) core impurity temperature
+ timp_convexity: (default 2) convexity of impurity temperature profile
+ timp_concavity: (default 1.26) concavity of impurity temperature profile
nimp_core: (default 5e17) impurity density
nimp_convexity: (default 1.09) convexity of impurity density profile
nimp_concavity: (default 0.24) concavity of impurity density profile
- nimp_decay: (default 30) decay rate of impurity density profile (except bare nuclei)
vtor_core: (default 1e5) toroidal rotation velocity m/s
vtor_edge: (default 1e4) toroidal rotation velocity at the edge m/s
vtor_convexity: (default 2) convexity of the toroidal rotation profile
@@ -371,26 +416,20 @@ def get_core_profiles_arguments(**kwargs):
:return: dictionary of profile arguments
"""
-
- core_args = {"ne_core": 5e19, "ne_convexity": 1.09,
- "ne_concavity": 0.24, "te_core": 3e3,
- "te_convexity": 2.35, "te_concavity": 1.26,
- "nh_core": 5e19, "nh_convexity": 1.09,
- "nh_concavity": 0.24, "th_core": 2.8e3,
- "th_convexity": 1, "th_concavity": 0.82,
- "th0_fraction": 0.8, "nh0_decay": 20,
- "timp_core": 2.7e3, "timp_convexity": 1,
- "timp_concavity": 0.82, "nimp_core": 5e17,
- "nimp_convexity": 1.09, "nimp_concavity": 0.24,
- "nimp_decay": 30,
- "vtor_core": 1e5, "vtor_edge": 1e4,
- "vtor_convexity": 2, "vtor_concavity": 4,
- "vpol_lcfs": 2e4, "vpol_decay": 0.08}
+
+ core_args = {"ne_core": 5e19, "ne_convexity": 1.09, "ne_concavity": 0.24,
+ "te_core": 3e3, "te_convexity": 2.35, "te_concavity": 1.26,
+ "th_core": 2.8e3, "th_convexity": 2, "th_concavity": 1.26,
+ "th0_fraction": 0.8,
+ "timp_core": 2.8e3, "timp_convexity": 2, "timp_concavity": 1.26,
+ "nimp_core": 5e17, "nimp_convexity": 1.09, "nimp_concavity": 0.24,
+ "vtor_core": 1e5, "vtor_edge": 1e4, "vtor_convexity": 2, "vtor_concavity": 4,
+ "vpol_lcfs": 2e4, "vpol_decay": 0.08}
if not kwargs:
return core_args
- # change passed values of core args
+ # change passed values of core args
for key, item in kwargs.items():
core_args[key] = item
@@ -419,15 +458,18 @@ def get_core_profiles_description(lcfs_values=None, core_args=None):
z = 0
lcfs_values = get_edge_profile_values(r, z)
+ # total carbon impurity density at lcfs
+ nimp_lcfs = sum([value["density"] for _, value in lcfs_values["composition"]["carbon"].items()])
+
if core_args is None:
core_args = get_core_profiles_arguments()
# toroidal rotation profile
f1d_vtor = get_double_parabola(core_args["vtor_edge"], core_args["vtor_core"],
- core_args["vtor_convexity"], core_args["vtor_concavity"])
+ core_args["vtor_convexity"], core_args["vtor_concavity"], xmin=1, xmax=0)
# poloidal rotation profile
- f1d_vpol = get_exponential_growth(core_args["vpol_lcfs"], core_args["vpol_decay"])
+ f1d_vpol = get_exponential_growth(core_args["vpol_lcfs"], core_args["vpol_decay"])
# velocity normal to magnetic surfaces
f1d_vnorm = Constant1D(0)
@@ -442,49 +484,42 @@ def get_core_profiles_description(lcfs_values=None, core_args=None):
profiles["electron"]["f1d_density"] = get_double_parabola(lcfs_values["electron"]["density"],
core_args["ne_core"], core_args["ne_convexity"],
core_args["ne_concavity"], xmin=1, xmax=0)
- profiles["electron"]["f1d_vtor"] = Constant1D(0)
+ profiles["electron"]["f1d_vtor"] = Constant1D(1.e-10) # avoid zero-length vectors for blending
profiles["electron"]["f1d_vpol"] = Constant1D(0)
profiles["electron"]["f1d_vnorm"] = Constant1D(0)
- # Setup H1+ profiles with double parabola shapes
- profiles["composition"]["hydrogen"][1]["f1d_temperature"] = get_double_parabola(lcfs_values["composition"]["hydrogen"][1]["temperature"],
- core_args["th_core"], core_args["th_convexity"], core_args["th_concavity"],
- xmin=1, xmax=0)
- profiles["composition"]["hydrogen"][1]["f1d_density"] = get_double_parabola(lcfs_values["composition"]["hydrogen"][1]["density"],
- core_args["nh_core"], core_args["nh_convexity"],
- core_args["nh_concavity"], xmin=1, xmax=0)
- profiles["composition"]["hydrogen"][1]["f1d_vtor"] = f1d_vtor
- profiles["composition"]["hydrogen"][1]["f1d_vpol"] = f1d_vpol
- profiles["composition"]["hydrogen"][1]["f1d_vnorm"] = f1d_vnorm
-
- # setup H0+ profile shapes with temperature as a fraction of H1+ and density with decaying exponential
- profiles["composition"]["hydrogen"][0]["f1d_temperature"] = core_args["th0_fraction"] * get_double_parabola(lcfs_values["composition"]["hydrogen"][0]["temperature"],
- core_args["th_core"], core_args["th_convexity"],
- core_args["th_concavity"], xmin=1, xmax=0)
- profiles["composition"]["hydrogen"][0]["f1d_density"] = get_exponential_growth(lcfs_values["composition"]["hydrogen"][0]["density"], core_args["nh0_decay"])
- profiles["composition"]["hydrogen"][0]["f1d_vtor"] = f1d_vtor
- profiles["composition"]["hydrogen"][0]["f1d_vpol"] = f1d_vpol
- profiles["composition"]["hydrogen"][0]["f1d_vnorm"] = f1d_vnorm
-
- # setup C6+ profile shapes with double parabolas
- profiles["composition"]["carbon"][6]["f1d_temperature"] = get_double_parabola(lcfs_values["composition"]["carbon"][6]["temperature"],
- core_args["timp_core"], core_args["timp_convexity"], core_args["timp_concavity"],
- xmin=1, xmax=0)
- profiles["composition"]["carbon"][6]["f1d_density"] = get_double_parabola(lcfs_values["composition"]["carbon"][6]["density"], core_args["nimp_core"],
- core_args["nimp_convexity"], core_args["nimp_concavity"], xmin=1, xmax=0)
- profiles["composition"]["carbon"][6]["f1d_vtor"] = f1d_vtor
- profiles["composition"]["carbon"][6]["f1d_vpol"] = f1d_vpol
- profiles["composition"]["carbon"][6]["f1d_vnorm"] = f1d_vnorm
-
- # setup CX+ profile shapes with temperature as double parabolas and density with decaying exponentials
- for chrg in range(6):
- profiles["composition"]["carbon"][chrg]["f1d_temperature"] = get_double_parabola(lcfs_values["composition"]["carbon"][chrg]["temperature"],
- core_args["timp_core"], core_args["timp_convexity"], core_args["timp_concavity"],
+ # total carbon density
+ carbon_total_density = get_double_parabola(nimp_lcfs, core_args["nimp_core"],
+ core_args["nimp_convexity"], core_args["nimp_concavity"], xmin=1, xmax=0)
+
+ # solve ionisation balance
+ openadas = OpenADAS(permit_extrapolation=True)
+ psin_1d = np.append(1. - np.geomspace(1.e-4, 1, 1023)[::-1], [1.]) # density profiles are sharp near psin=1
+ density_profiles = {}
+ density_profiles["carbon"] = interpolators1d_from_elementdensity(openadas, carbon, psin_1d, carbon_total_density,
+ profiles["electron"]["f1d_density"],
+ profiles["electron"]["f1d_temperature"])
+
+ density_profiles["hydrogen"] = interpolators1d_match_plasma_neutrality(openadas, hydrogen, psin_1d, [density_profiles["carbon"]],
+ profiles["electron"]["f1d_density"],
+ profiles["electron"]["f1d_temperature"])
+
+ # Setup ion profiles
+ for element, prefix in ((hydrogen, "h"), (carbon, "imp")):
+ name = element.name
+ for chrg in range(element.atomic_number + 1):
+ profiles["composition"][name][chrg]["f1d_temperature"] = get_double_parabola(lcfs_values["composition"][name][chrg]["temperature"],
+ core_args["t{}_core".format(prefix)],
+ core_args["t{}_convexity".format(prefix)],
+ core_args["t{}_concavity".format(prefix)],
xmin=1, xmax=0)
- profiles["composition"]["carbon"][chrg]["f1d_density"] = get_exponential_growth(lcfs_values["composition"]["carbon"][chrg]["density"], core_args["nimp_decay"])
- profiles["composition"]["carbon"][chrg]["f1d_vtor"] = f1d_vtor
- profiles["composition"]["carbon"][chrg]["f1d_vpol"] = f1d_vpol
- profiles["composition"]["carbon"][chrg]["f1d_vnorm"] = f1d_vnorm
+ profiles["composition"][name][chrg]["f1d_density"] = density_profiles[name][chrg]
+ profiles["composition"][name][chrg]["f1d_vtor"] = f1d_vtor
+ profiles["composition"][name][chrg]["f1d_vpol"] = f1d_vpol
+ profiles["composition"][name][chrg]["f1d_vnorm"] = f1d_vnorm
+
+ # multiply H0 temperature by th0_fraction
+ profiles["composition"]["hydrogen"][0]["f1d_temperature"] *= core_args["th0_fraction"]
return profiles.freeze()
@@ -493,15 +528,17 @@ def get_core_distributions(profiles=None, equilibrium=None):
"""
Returns a dictionary of core plasma species Maxwellian distributions.
- :param profiles: Dictionary of core particle profiles. The dictionary has to have the same form
- as the one returned by the function get_core_profiles_description.
- The default value is the value returned by the call get_core_profiles_description().
+ :param profiles: Dictionary with core interpolators. The dictionary has to have
+ the same form as the one returned by the function
+ get_core_profiles_description or get_core_interpolators.
+ The default value is the value returned by the call
+ get_core_interpolators().
:param equilibrium: an instance of EFITEquilibrium.
:return: dictionary of core plasma species with Maxwellian distribution
"""
# get core profile data if not passed sa argument
if profiles is None:
- profiles = get_core_profiles_description()
+ profiles = get_core_interpolators()
# load plasma equilibrium if not passed as argument
if equilibrium is None:
@@ -510,23 +547,20 @@ def get_core_distributions(profiles=None, equilibrium=None):
# build a dictionary with Maxwellian distributions
species = RecursiveDict()
species["electron"] = get_maxwellian_distribution(equilibrium, rest_mass=electron_mass,
- **profiles["electron"])
+ **profiles["electron"])
for name, spec in profiles["composition"].items():
spec_cherab = _get_cherab_element(name)
for chrg, desc in spec.items():
rest_mass = atomic_mass * spec_cherab.atomic_weight
- species["composition"][name][chrg] = get_maxwellian_distribution(equilibrium, rest_mass=rest_mass, **desc)
+ species["composition"][name][chrg] = get_maxwellian_distribution(equilibrium, rest_mass=rest_mass, **desc)
return species.freeze()
-def get_core_plasma(distributions=None, atomic_data=None, parent=None, name="Generomak core plasma"):
+def get_core_plasma(atomic_data=None, parent=None, name="Generomak core plasma"):
"""
- Provides Generomak core plasma.
+ Provides Generomak default core plasma.
- :param distributions: A dictionary of plasma distributions. Has to have the same format as the
- dictionary returned by get_core_distributions. The default value
- is the value returned by the call get_core_distributions().
:param atomic_data: Instance of AtomicData, default is OpenADAS()
:param parent: parent of the plasma node, defaults None
:param name: name of the plasma node, defaults "Generomak edge plasma"
@@ -536,33 +570,119 @@ def get_core_plasma(distributions=None, atomic_data=None, parent=None, name="Gen
# load Generomak equilibrium
equilibrium = load_equilibrium()
+ # load core distributions
+ distributions = get_core_distributions(equilibrium=equilibrium)
+
+ return get_plasma(equilibrium=equilibrium, distributions=distributions,
+ atomic_data=atomic_data, parent=parent, name=name)
+
+
+def get_full_profiles(equilibrium=None, core_profiles=None, edge_profiles=None, mask=None):
+ """
+ Blends core and edge profiles using the mask function as a modulator.
+
+ :param equilibrium: an instance of EFITEquilibrium. The default value is the value returned by
+ load_equilibrium().
+ :param core_profiles: Dictionary with core interpolators. The dictionary has to have
+ the same form as the one returned by the function
+ get_core_profiles_description or get_core_interpolators.
+ The default value is the value returned by the call
+ get_core_interpolators().
+ :param edge_profiles: Dictionary with edge interpolators in the shape
+ returned by the get_edge_interpolators function.
+ If not specified, will use the value returned by
+ get_edge_interpolators().
+ :param Function2D mask: Scalar 2D function returning a value in the range [0, 1].
+ If not specified, will use core profiles for psi_normal < 0.94,
+ the edge profiles for psi_normal > 1 and a weighted sum of core and
+ edge profiles for 0.94 < psi_normal < 1, with the edge profile weight
+ increasing from 0 to 1 linearly.
+
+ :return: dictionary of blended plasma profiles with the sturcture identical to edge_profiles.
+ """
+
+ equilibrium = equilibrium or load_equilibrium()
+
+ core_profiles = core_profiles or get_core_interpolators()
+
+ edge_profiles = edge_profiles or get_edge_interpolators()
+
+ mask = mask or equilibrium.map2d(Interpolator1DArray([0, 0.94, 1.0, 1.1], [1, 1, 0, 0], 'linear', 'none', 0))
+
+ # blended core and edge profiles
+ blended_profiles = RecursiveDict()
+
+ # map core profiles to 2D using the equilibrium
+ te_core = equilibrium.map2d(core_profiles["electron"]["f1d_temperature"])
+ ne_core = equilibrium.map2d(core_profiles["electron"]["f1d_density"])
+ ve_core = equilibrium.map_vector2d(core_profiles["electron"]["f1d_vtor"],
+ core_profiles["electron"]["f1d_vpol"],
+ core_profiles["electron"]["f1d_vnorm"])
+
+ blended_profiles["electron"]["temperature"] = Blend2D(edge_profiles["electron"]["temperature"], te_core, mask)
+ blended_profiles["electron"]["density"] = Blend2D(edge_profiles["electron"]["density"], ne_core, mask)
+ blended_profiles["electron"]["velocity"] = BlendVector2D(edge_profiles["electron"]["velocity"], ve_core, mask)
+
+ for element, states in core_profiles["composition"].items():
+ for charge, state in states.items():
+ t_core = equilibrium.map2d(state["f1d_temperature"])
+ n_core = equilibrium.map2d(state["f1d_density"])
+ v_core = equilibrium.map_vector2d(state["f1d_vtor"], state["f1d_vpol"], state["f1d_vnorm"])
+
+ edge_state = edge_profiles["composition"][element][charge]
+
+ blended_profiles["composition"][element][charge]["temperature"] = Blend2D(edge_state["temperature"], t_core, mask)
+ blended_profiles["composition"][element][charge]["density"] = Blend2D(edge_state["density"], n_core, mask)
+ blended_profiles["composition"][element][charge]["velocity"] = BlendVector2D(edge_state["velocity"], v_core, mask)
+
+ return blended_profiles.freeze()
+
+
+def get_plasma(equilibrium=None, distributions=None, r_range=None, z_range=None, atomic_data=None, parent=None, name="Generomak plasma"):
+ """
+ Provides Generomak plasma. The full (core + edge) plasma is returned by default.
+
+ :param equilibrium: an instance of EFITEquilibrium. The default value is the value returned by load_equilibrium().
+ :param distributions: A dictionary of plasma distributions. Has to have the same format as the
+ dictionary returned by get_core_distributions or get_2d_distributions.
+ The default value is the value returned by the call:
+ get_2d_distributions(get_full_profiles(equilibrium)).
+ :param r_range: Plasma domain range (min, max) in R direction in meters.
+ :param z_range: Plasma domain range (min, max) in Z direction in meters.
+ :param atomic_data: Instance of AtomicData, default is OpenADAS()
+ :param parent: parent of the plasma node, defaults None
+ :param name: name of the plasma node, defaults "Generomak plasma"
+ :return: populated Plasma object
+ """
+
+ equilibrium = equilibrium or load_equilibrium()
+
+ distributions = distributions or get_2d_distributions(get_full_profiles(equilibrium=equilibrium))
+
+ r_range = r_range or equilibrium.r_range
+ z_range = z_range or equilibrium.z_range
+
# create or check atomic_data
if atomic_data is not None:
if not isinstance(atomic_data, AtomicData):
- raise ValueError("atomic_data has to be of type AtomicData")
+ raise ValueError("atomic_data has to be of type AtomicData")
else:
atomic_data = OpenADAS()
- # construct plasma primitive shape
- padding = 1e-3 #enlarge for safety
- plasma_height = equilibrium.z_range[1] - equilibrium.z_range[0]
- outer_column = Cylinder(radius=equilibrium.r_range[1], height=plasma_height)
- inner_column = Cylinder(radius=equilibrium.r_range[0], height=plasma_height + 2 * padding)
+ # construct plasma primitive shape
+ padding = 1e-3 # enlarge for safety
+ plasma_height = z_range[1] - z_range[0]
+ outer_column = Cylinder(radius=r_range[1], height=plasma_height)
+ inner_column = Cylinder(radius=r_range[0], height=plasma_height + 2 * padding)
inner_column.transform = translate(0, 0, -padding)
plasma_geometry = Subtract(outer_column, inner_column)
# coordinate transform of the plasma frame
- geometry_transform = translate(0, 0, equilibrium.z_range[0])
-
- # load core distributions if needed
- if distributions is None:
- dists = get_core_distributions()
- else:
- dists = distributions
+ geometry_transform = translate(0, 0, z_range[0])
# create plasma composition list
plasma_composition = []
- for elem_name, elem_data in dists["composition"].items():
+ for elem_name, elem_data in distributions["composition"].items():
for stage, stage_data in elem_data.items():
elem = _get_cherab_element(elem_name)
species = Species(elem, stage, stage_data)
@@ -573,7 +693,7 @@ def get_core_plasma(distributions=None, atomic_data=None, parent=None, name="Gen
plasma.name = name
plasma.geometry = plasma_geometry
plasma.atomic_data = atomic_data
- plasma.electron_distribution = dists["electron"]
+ plasma.electron_distribution = distributions["electron"]
plasma.composition = plasma_composition
plasma.geometry_transform = geometry_transform
plasma.b_field = VectorAxisymmetricMapper(equilibrium.b_field)
diff --git a/cherab/openadas/parse/adf15.py b/cherab/openadas/parse/adf15.py
index ec93fbf2..269edd0a 100644
--- a/cherab/openadas/parse/adf15.py
+++ b/cherab/openadas/parse/adf15.py
@@ -67,11 +67,19 @@ def parse_adf15(element, charge, adf_file_path, header_format=None):
# use simple electron configuration structure for hydrogen-like ions
if header_format == 'hydrogen' or element == hydrogen:
config = _scrape_metadata_hydrogen(file, element, charge)
- elif header_format == 'hydrogen-like' or element.atomic_number - charge == 1:
+ elif header_format == 'hydrogen-like':
config = _scrape_metadata_hydrogen_like(file, element, charge)
+ elif element.atomic_number - charge == 1:
+ config = _scrape_metadata_hydrogen_like(file, element, charge)
+ if not config and 'bnd#' in adf_file_path:
+ # ADF15 files with the "bnd" suffix may have metadata in the "hydrogen" format
+ config = _scrape_metadata_hydrogen(file, element, charge)
else:
config = _scrape_metadata_full(file, element, charge)
+ if not config:
+ raise RuntimeError("Unable to parse ADF15 metadata.")
+
# process rate data
rates = RecursiveDict()
for cls in ('excitation', 'recombination', 'thermalcx'):
diff --git a/cherab/tools/inversions/voxels.pyx b/cherab/tools/inversions/voxels.pyx
index 6baaa821..c682e01a 100644
--- a/cherab/tools/inversions/voxels.pyx
+++ b/cherab/tools/inversions/voxels.pyx
@@ -682,7 +682,7 @@ class ToroidalVoxelGrid(VoxelCollection):
patches = []
for voxel in self:
- polygon = Polygon([(v.x, v.y) for v in voxel.vertices], True)
+ polygon = Polygon([(v.x, v.y) for v in voxel.vertices], closed=True)
patches.append(polygon)
p = PatchCollection(patches, cmap=cmap)
diff --git a/cherab/tools/raytransfer/pipelines.py b/cherab/tools/raytransfer/pipelines.py
index b94223ea..e051e3f7 100644
--- a/cherab/tools/raytransfer/pipelines.py
+++ b/cherab/tools/raytransfer/pipelines.py
@@ -34,24 +34,68 @@
from raysect.optical.observer.base import Pipeline0D, Pipeline1D, Pipeline2D, PixelProcessor
-class RayTransferPipeline0D(Pipeline0D):
+class RayTransferPipelineBase():
+
+ def __init__(self, name=None, kind='power'):
+
+ self.name = name
+ self._matrix = None
+ self._samples = 0
+ self._bins = 0
+ self.kind = kind
+
+ @property
+ def kind(self):
+ """
+ The kind of the pipeline. Can be 'power' or 'radiance'.
+ In the case of 'power', the resulting matrix is multiplied by the sensitivity
+ of the detector, and the units of the matrix are [m^3 sr], which gives the units
+ of power [W] for the product of the ray transfer matrix and the emission profile.
+ In case of 'radiance', the sensitivity is not taken into account and
+ the matrix is calculated in [m], which gives the units of radiance [W m^-2 sr^-1]
+ for the product of the ray transfer matrix and the emission profile.
+ """
+ return self._kind
+
+ @kind.setter
+ def kind(self, value):
+ _kind = value.lower()
+ if _kind in ('power', 'radiance'):
+ self._kind = _kind
+ else:
+ raise ValueError("The kind property must be 'power' or 'radiance'.")
+
+ @property
+ def matrix(self):
+ return self._matrix
+
+
+class RayTransferPipeline0D(Pipeline0D, RayTransferPipelineBase):
"""
Simple 0D pipeline for ray transfer matrix (geometry matrix) calculation.
+ :param str name: The name of the pipeline. Default is 'RayTransferPipeline0D'.
+ :param str kind: The kind of the pipeline. Can be 'power' (default) or 'radiance'.
+ In the case of 'power', the resulting matrix is multiplied by the sensitivity
+ of the detector, and the units of the matrix are [m^3 sr], which gives the units
+ of power [W] for the product of the ray transfer matrix and the emission profile.
+ In case of 'radiance', the sensitivity is not taken into account and
+ the matrix is calculated in [m], which gives the units of radiance [W m^-2 sr^-1]
+ for the product of the ray transfer matrix and the emission profile.
+ Note that if the sensitivity of the detector is 1 (e.g. `PinholeCamera`, `VectorCamera`),
+ the 'power' and 'radiance' give the same results.
+
:ivar np.ndarray matrix: Ray transfer matrix, a 1D array of size :math:`N_{bin}`.
.. code-block:: pycon
>>> from cherab.tools.raytransfer import RayTransferPipeline0D
- >>> pipeline = RayTransferPipeline0D()
+ >>> pipeline = RayTransferPipeline0D(kind='radiance')
"""
- def __init__(self, name=None):
+ def __init__(self, name='RayTransferPipeline0D', kind='power'):
- self.name = name or 'RayTransferPipeline0D'
- self._matrix = None
- self._samples = 0
- self._bins = 0
+ RayTransferPipelineBase.__init__(self, name, kind)
def initialise(self, min_wavelength, max_wavelength, spectral_bins, spectral_slices, quiet):
self._samples = 0
@@ -59,7 +103,10 @@ def initialise(self, min_wavelength, max_wavelength, spectral_bins, spectral_sli
self._matrix = np.zeros(spectral_bins)
def pixel_processor(self, slice_id):
- return RayTransferPixelProcessor(self._bins)
+ if self._kind == 'power':
+ return PowerRayTransferPixelProcessor(self._bins)
+ else:
+ return RadianceRayTransferPixelProcessor(self._bins)
def update(self, slice_id, packed_result, pixel_samples):
self._samples += pixel_samples
@@ -68,30 +115,34 @@ def update(self, slice_id, packed_result, pixel_samples):
def finalise(self):
self._matrix /= self._samples
- @property
- def matrix(self):
- return self._matrix
-
-class RayTransferPipeline1D(Pipeline1D):
+class RayTransferPipeline1D(Pipeline1D, RayTransferPipelineBase):
"""
Simple 1D pipeline for ray transfer matrix (geometry matrix) calculation.
+ :param str name: The name of the pipeline. Default is 'RayTransferPipeline0D'.
+ :param str kind: The kind of the pipeline. Can be 'power' (default) or 'radiance'.
+ In the case of 'power', the resulting matrix is multiplied by the sensitivity
+ of the detector, and the units of the matrix are [m^3 sr], which gives the units
+ of power [W] for the product of the ray transfer matrix and the emission profile.
+ In case of 'radiance', the sensitivity is not taken into account and
+ the matrix is calculated in [m], which gives the units of radiance [W m^-2 sr^-1]
+ for the product of the ray transfer matrix and the emission profile.
+ Note that if the sensitivity of the detector is 1 (e.g. `PinholeCamera`, `VectorCamera`),
+ the 'power' and 'radiance' give the same results.
+
:ivar np.ndarray matrix: Ray transfer matrix, a 2D array of shape :math:`(N_{pixel}, N_{bin})`.
.. code-block:: pycon
>>> from cherab.tools.raytransfer import RayTransferPipeline1D
- >>> pipeline = RayTransferPipeline1D()
+ >>> pipeline = RayTransferPipeline1D(kind='radiance')
"""
- def __init__(self, name=None):
+ def __init__(self, name='RayTransferPipeline1D', kind='power'):
- self.name = name or 'RayTransferPipeline1D'
- self._matrix = None
+ RayTransferPipelineBase.__init__(self, name, kind)
self._pixels = None
- self._samples = 0
- self._bins = 0
def initialise(self, pixels, pixel_samples, min_wavelength, max_wavelength, spectral_bins, spectral_slices, quiet):
self._pixels = pixels
@@ -100,7 +151,10 @@ def initialise(self, pixels, pixel_samples, min_wavelength, max_wavelength, spec
self._matrix = np.zeros((pixels, spectral_bins))
def pixel_processor(self, pixel, slice_id):
- return RayTransferPixelProcessor(self._bins)
+ if self._kind == 'power':
+ return PowerRayTransferPixelProcessor(self._bins)
+ else:
+ return RadianceRayTransferPixelProcessor(self._bins)
def update(self, pixel, slice_id, packed_result):
self._matrix[pixel] = packed_result[0] / self._samples
@@ -108,30 +162,34 @@ def update(self, pixel, slice_id, packed_result):
def finalise(self):
pass
- @property
- def matrix(self):
- return self._matrix
-
-class RayTransferPipeline2D(Pipeline2D):
+class RayTransferPipeline2D(Pipeline2D, RayTransferPipelineBase):
"""
Simple 2D pipeline for ray transfer matrix (geometry matrix) calculation.
+ :param str name: The name of the pipeline. Default is 'RayTransferPipeline0D'.
+ :param str kind: The kind of the pipeline. Can be 'power' (default) or 'radiance'.
+ In the case of 'power', the resulting matrix is multiplied by the sensitivity
+ of the detector, and the units of the matrix are [m^3 sr], which gives the units
+ of power [W] for the product of the ray transfer matrix and the emission profile.
+ In case of 'radiance', the sensitivity is not taken into account and
+ the matrix is calculated in [m], which gives the units of radiance [W m^-2 sr^-1]
+ for the product of the ray transfer matrix and the emission profile.
+ Note that if the sensitivity of the detector is 1 (e.g. `PinholeCamera`, `VectorCamera`),
+ the 'power' and 'radiance' give the same results.
+
:ivar np.ndarray matrix: Ray transfer matrix, a 3D array of shape :math:`(N_x, N_y, N_{bin})`.
.. code-block:: pycon
>>> from cherab.tools.raytransfer import RayTransferPipeline2D
- >>> pipeline = RayTransferPipeline2D()
+ >>> pipeline = RayTransferPipeline2D(kind='radiance')
"""
- def __init__(self, name=None):
+ def __init__(self, name='RayTransferPipeline2D', kind='power'):
- self.name = name or 'RayTransferPipeline2D'
- self._matrix = None
+ RayTransferPipelineBase.__init__(self, name, kind)
self._pixels = None
- self._samples = 0
- self._bins = 0
def initialise(self, pixels, pixel_samples, min_wavelength, max_wavelength, spectral_bins, spectral_slices, quiet):
self._pixels = pixels
@@ -140,7 +198,10 @@ def initialise(self, pixels, pixel_samples, min_wavelength, max_wavelength, spec
self._matrix = np.zeros((pixels[0], pixels[1], spectral_bins))
def pixel_processor(self, x, y, slice_id):
- return RayTransferPixelProcessor(self._bins)
+ if self._kind == 'power':
+ return PowerRayTransferPixelProcessor(self._bins)
+ else:
+ return RadianceRayTransferPixelProcessor(self._bins)
def update(self, x, y, slice_id, packed_result):
self._matrix[x, y] = packed_result[0] / self._samples
@@ -148,21 +209,32 @@ def update(self, x, y, slice_id, packed_result):
def finalise(self):
pass
- @property
- def matrix(self):
- return self._matrix
-
-class RayTransferPixelProcessor(PixelProcessor):
+class RayTransferPixelProcessorBase(PixelProcessor):
"""
- PixelProcessor that stores ray transfer matrix for each pixel.
+ Base class for PixelProcessor that stores ray transfer matrix for each pixel.
"""
def __init__(self, bins):
self._matrix = np.zeros(bins)
- def add_sample(self, spectrum, sensitivity):
- self._matrix += spectrum.samples * sensitivity
-
def pack_results(self):
return (self._matrix, 0)
+
+
+class RadianceRayTransferPixelProcessor(RayTransferPixelProcessorBase):
+ """
+ PixelProcessor that stores ray transfer matrix in the units of [m] for each pixel.
+ """
+
+ def add_sample(self, spectrum, sensitivity):
+ self._matrix += spectrum.samples
+
+
+class PowerRayTransferPixelProcessor(RayTransferPixelProcessorBase):
+ """
+ PixelProcessor that stores ray transfer matrix in the units of [m^3 sr] for each pixel.
+ """
+
+ def add_sample(self, spectrum, sensitivity):
+ self._matrix += spectrum.samples * sensitivity
diff --git a/cherab/tools/raytransfer/roughconductor.pyx b/cherab/tools/raytransfer/roughconductor.pyx
index 04edf6f2..faef9cf1 100644
--- a/cherab/tools/raytransfer/roughconductor.pyx
+++ b/cherab/tools/raytransfer/roughconductor.pyx
@@ -18,7 +18,7 @@
# under the Licence.
#
-from raysect.optical cimport Point3D, Vector3D, AffineMatrix3D, World, Ray, Spectrum, new_vector3d
+from raysect.optical cimport Point3D, Vector3D, AffineMatrix3D, World, Ray, Spectrum, new_vector3d, Intersection
from libc.math cimport M_PI, sqrt
from raysect.optical.material cimport RoughConductor
cimport cython
@@ -34,7 +34,8 @@ cdef class RToptimisedRoughConductor(RoughConductor):
@cython.cdivision(True)
cpdef Spectrum evaluate_shading(self, World world, Ray ray, Vector3D s_incoming, Vector3D s_outgoing,
Point3D w_reflection_origin, Point3D w_transmission_origin, bint back_face,
- AffineMatrix3D world_to_surface, AffineMatrix3D surface_to_world):
+ AffineMatrix3D world_to_surface, AffineMatrix3D surface_to_world,
+ Intersection intersection):
cdef:
double n, k
diff --git a/cherab/tools/spectroscopy/__init__.py b/cherab/tools/spectroscopy/__init__.py
new file mode 100644
index 00000000..23bbbe1f
--- /dev/null
+++ b/cherab/tools/spectroscopy/__init__.py
@@ -0,0 +1,22 @@
+
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+from .instrument import SpectroscopicInstrument
+from .polychromator import PolychromatorFilter, TrapezoidalFilter, Polychromator
+from .spectrometer import Spectrometer, CzernyTurnerSpectrometer
diff --git a/cherab/tools/spectroscopy/instrument.py b/cherab/tools/spectroscopy/instrument.py
new file mode 100644
index 00000000..0e0d666c
--- /dev/null
+++ b/cherab/tools/spectroscopy/instrument.py
@@ -0,0 +1,118 @@
+
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+class SpectroscopicInstrument:
+ """
+ Base class for spectroscopic instruments (spectrometers, polychromators, etc.).
+ This is an abstract class.
+
+ :param str name: Instrument name.
+
+ :ivar list pipeline_classes: The list of pipeline classes used with this instrument.
+ :ivar list pipeline_kwargs: The list of dicts with keywords passed to init methods of
+ pipeline classes used with this instrument.
+ :ivar float min_wavelength: Lower wavelength bound for spectral range.
+ :ivar float max_wavelength: Upper wavelength bound for spectral range.
+ :ivar int spectral_bins: The number of spectral samples over the wavelength range.
+ """
+
+ def __init__(self, name=''):
+ self._pipeline_classes = None
+ self.name = name
+ self._clear_spectral_settings()
+
+ @property
+ def name(self):
+ # Instrument name.
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ self._name = str(value)
+ self._pipeline_kwargs = None
+
+ @property
+ def pipeline_classes(self):
+ # The list of pipeline classes used with this instrument.
+ if self._pipeline_classes is None:
+ self._update_pipeline_classes()
+
+ return self._pipeline_classes
+
+ @property
+ def pipeline_kwargs(self):
+ # The list of dicts with keywords passed to init methods of
+ # pipeline classes used with this instrument.
+ if self._pipeline_kwargs is None:
+ self._update_pipeline_kwargs()
+
+ return self._pipeline_kwargs
+
+ def create_pipelines(self):
+ """ Returns a list of new pipelines created according to `pipeline_classes`
+ and keyword arguments."""
+ if self._pipeline_classes is None:
+ self._update_pipeline_classes()
+ if self._pipeline_kwargs is None:
+ self._update_pipeline_kwargs()
+
+ pipelines = []
+ for PipelineClass, kwargs in zip(self._pipeline_classes, self._pipeline_kwargs):
+ pipeline = PipelineClass(**kwargs)
+ pipelines.append(pipeline)
+
+ return pipelines
+
+ @property
+ def min_wavelength(self):
+ # Lower wavelength bound for spectral range.
+ if self._min_wavelength is None:
+ self._update_spectral_settings()
+
+ return self._min_wavelength
+
+ @property
+ def max_wavelength(self):
+ # Upper wavelength bound for spectral range.
+ if self._max_wavelength is None:
+ self._update_spectral_settings()
+
+ return self._max_wavelength
+
+ @property
+ def spectral_bins(self):
+ # The number of spectral samples over the wavelength range.
+ if self._spectral_bins is None:
+ self._update_spectral_settings()
+
+ return self._spectral_bins
+
+ def _clear_spectral_settings(self):
+ self._min_wavelength = None
+ self._max_wavelength = None
+ self._spectral_bins = None
+
+ def _update_spectral_settings(self):
+ raise NotImplementedError("To be defined in subclass.")
+
+ def _update_pipeline_classes(self):
+ raise NotImplementedError("To be defined in subclass.")
+
+ def _update_pipeline_kwargs(self):
+ raise NotImplementedError("To be defined in subclass.")
diff --git a/cherab/tools/spectroscopy/polychromator.py b/cherab/tools/spectroscopy/polychromator.py
new file mode 100644
index 00000000..56fb6e18
--- /dev/null
+++ b/cherab/tools/spectroscopy/polychromator.py
@@ -0,0 +1,221 @@
+
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import numpy as np
+from raysect.optical import InterpolatedSF
+from raysect.optical.observer import RadiancePipeline0D
+
+from .instrument import SpectroscopicInstrument
+
+
+class PolychromatorFilter(InterpolatedSF):
+ """
+ Defines a polychromator filter as a Raysect's InterpolatedSF.
+
+ :param object wavelengths: 1D array of wavelengths in nanometers.
+ :param object samples: 1D array of spectral samples.
+ :param bool normalise: True/false toggle for whether to normalise the
+ spectral function so its integral equals 1.
+ :param str name: Filter name (e.g. "H-alpha filter"). Default is ''.
+
+ :ivar float min_wavelength: Lower wavelength bound of the filter's spectral range in nm.
+ :ivar float max_wavelength: Upper wavelength bound of the filter's spectral range in nm.
+ """
+
+ def __init__(self, wavelengths, samples, normalise=False, name=''):
+
+ wavelengths = np.array(wavelengths, dtype=np.float64)
+ samples = np.array(samples, dtype=np.float64)
+
+ if wavelengths.ndim != 1:
+ raise ValueError("Wavelength array must be 1D.")
+
+ if samples.shape[0] != wavelengths.shape[0]:
+ raise ValueError("Wavelength and sample arrays must be the same length.")
+
+ indices = np.argsort(wavelengths)
+ wavelengths = wavelengths[indices]
+ samples = samples[indices]
+
+ self._min_wavelength = wavelengths[0]
+ self._max_wavelength = wavelengths[-1]
+ self._window = self._max_wavelength - self._min_wavelength
+ self._central_wavelength = 0.5 * (self._max_wavelength + self._min_wavelength)
+
+ # setting the ends of the filter to zero, if they are not
+ if samples[0] != 0:
+ wavelengths = np.insert(wavelengths, 0, wavelengths[0] * (1. - 1.e-15))
+ samples = np.insert(samples, 0, 0)
+ if samples[-1] != 0:
+ wavelengths = np.append(wavelengths, wavelengths[-1] * (1. + 1.e-15))
+ samples = np.append(samples, 0)
+
+ super().__init__(wavelengths, samples, normalise)
+ self._name = str(name)
+
+ @property
+ def name(self):
+ # Filter name.
+ return self._name
+
+ @property
+ def min_wavelength(self):
+ # Lower wavelength bound of the filter's spectral range in nm.
+ return self._min_wavelength
+
+ @property
+ def max_wavelength(self):
+ # Upper wavelength bound of the filter's spectral range in nm.
+ return self._max_wavelength
+
+ @property
+ def window(self):
+ # Size of the filtering window in nm.
+ return self._window
+
+ @property
+ def central_wavelength(self):
+ # Central wavelength of the filter in nm.
+ return self._central_wavelength
+
+
+class TrapezoidalFilter(PolychromatorFilter):
+ """
+ Symmetrical trapezoidal polychromator filter.
+
+ :param float wavelength: Central wavelength of the filter in nm.
+ :param float window: Size of the filtering window in nm. Default is 3.
+ :param float flat_top: Size of the flat top part of the filter in nm.
+ Default is None (equal to window).
+ :param str name: Filter name (e.g. "H-alpha filter"). Default is ''.
+ """
+
+ def __init__(self, central_wavelength, window=3., flat_top=None, name=''):
+
+ if central_wavelength <= 0:
+ raise ValueError("Argument 'central_wavelength' must be positive.")
+
+ if window <= 0:
+ raise ValueError("Argument 'window' must be positive.")
+
+ flat_top = flat_top or window
+
+ if flat_top <= 0:
+ raise ValueError("Argument 'flat_top' must be positive.")
+ if flat_top > window:
+ raise ValueError("Argument 'flat_top' must be less or equal than 'window'.")
+
+ self._flat_top = flat_top
+
+ if flat_top == window:
+ flat_top -= flat_top * 1.e-15
+
+ wavelengths = [central_wavelength - 0.5 * window,
+ central_wavelength - 0.5 * flat_top,
+ central_wavelength + 0.5 * flat_top,
+ central_wavelength + 0.5 * window]
+ samples = [0, 1, 1, 0]
+ super().__init__(wavelengths, samples, normalise=False, name=name)
+
+ @property
+ def flat_top(self):
+ # Size of the flat top part of the filter in nm.
+ return self._flat_top
+
+
+class Polychromator(SpectroscopicInstrument):
+ """
+ A polychromator assembly with a set of different filters.
+
+ :param list filters: List of the `PolychromatorFilter` instances.
+ :param int min_bins_per_window: Minimal number of spectral bins
+ per filtering window. Default is 10.
+ :param str name: Polychromator name.
+
+ .. code-block:: pycon
+
+ >>> from raysect.optical import World
+ >>> from raysect.optical.observer import FibreOptic
+ >>> from cherab.tools.spectroscopy import Polychromator, TrapezoidalFilter
+ >>>
+ >>> world = World()
+ >>> h_alpha_filter = TrapezoidalFilter(656.1, name='H-alpha filter')
+ >>> ciii_465nm_filter = TrapezoidalFilter(464.8, name='CIII 465 nm filter')
+ >>> polychromator = Polychromator([h_alpha_filter, ciii_465nm_filter], name='MyPolychromator')
+ >>> fibreoptic = FibreOptic(name="MyFibreOptic", parent=world)
+ >>> fibreoptic.min_wavelength = polychromator.min_wavelength
+ >>> fibreoptic.max_wavelength = polychromator.max_wavelength
+ >>> fibreoptic.spectral_bins = polychromator.spectral_bins
+ >>> fibreoptic.pipelines = polychromator.create_pipelines()
+ """
+
+ def __init__(self, filters, min_bins_per_window=10, name=''):
+ super().__init__(name)
+ self.min_bins_per_window = min_bins_per_window
+ self.filters = filters
+
+ @property
+ def min_bins_per_window(self):
+ # Minimal number of spectral bins per filtering window.
+ return self._min_bins_per_window
+
+ @min_bins_per_window.setter
+ def min_bins_per_window(self, value):
+ value = int(value)
+ if value <= 0:
+ raise ValueError("Attribute 'min_bins_per_window' must be positive.")
+
+ self._min_bins_per_window = value
+ self._clear_spectral_settings()
+
+ @property
+ def filters(self):
+ # List of the PolychromatorFilter instances.
+ return self._filters
+
+ @filters.setter
+ def filters(self, value):
+ for poly_filter in value:
+ if not isinstance(poly_filter, PolychromatorFilter):
+ raise TypeError('Property filters must contain only PolychromatorFilter instances.')
+
+ self._filters = value
+ self._clear_spectral_settings()
+ self._pipeline_classes = None
+ self._pipeline_kwargs = None
+
+ def _update_pipeline_classes(self):
+ self._pipeline_classes = [RadiancePipeline0D for poly_filter in self._filters]
+
+ def _update_pipeline_kwargs(self):
+ self._pipeline_kwargs = [{'name': self._name + ': ' + poly_filter.name, 'filter': poly_filter} for poly_filter in self._filters]
+
+ def _update_spectral_settings(self):
+
+ min_wavelength = np.inf
+ max_wavelength = 0
+ step = np.inf
+ for poly_filter in self._filters:
+ step = min(step, poly_filter.window / self._min_bins_per_window)
+ min_wavelength = min(min_wavelength, poly_filter.min_wavelength)
+ max_wavelength = max(max_wavelength, poly_filter.max_wavelength)
+
+ self._min_wavelength = min_wavelength
+ self._max_wavelength = max_wavelength
+ self._spectral_bins = int(np.ceil((max_wavelength - min_wavelength) / step))
diff --git a/cherab/tools/spectroscopy/spectrometer.py b/cherab/tools/spectroscopy/spectrometer.py
new file mode 100644
index 00000000..585ac3f4
--- /dev/null
+++ b/cherab/tools/spectroscopy/spectrometer.py
@@ -0,0 +1,351 @@
+
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import numpy as np
+from raysect.optical import Spectrum
+from raysect.optical.observer import SpectralRadiancePipeline0D
+
+from .instrument import SpectroscopicInstrument
+
+
+class Spectrometer(SpectroscopicInstrument):
+ """
+ Spectrometer that can accommodate multiple spectra.
+
+ Spectrometer is initialized with a sequence of calibration arrays (one array per accommodated
+ spectrum) containing the wavelengths of the pixel borders. Namely, the values
+ :math:`w_{k}^{i}` and :math:`w_{k}^{i+1}` define the spectral range of the pixel :math:`p_i`
+ of the `k`-th spectrum. After the spectrum is ray-traced, it can be recalibrated with
+ `spectrometer.calibrate(spectrum)`.
+
+ Note that Raysect cannot raytrace the spectra with non-constant spectral resolution.
+ Thus, the actual number of spectral bins of raytraced spectrum is defined with
+ `min_bins_per_pixel` attribute.
+
+ :param tuple wavelength_to_pixel: Wavelength-to-pixel calibration arrays.
+ :param int min_bins_per_pixel: Minimal number of spectral bins
+ per pixel. Default is 1.
+ :param str name: Spectrometer name.
+
+ :ivar tuple wavelengths: Central wavelengths of the pixels.
+
+ .. code-block:: pycon
+
+ >>> from raysect.optical import World, Spectrum
+ >>> from raysect.optical.observer import FibreOptic
+ >>> from cherab.tools.spectroscopy import Spectrometer
+ >>> from matplotlib import pyplot as plt
+ >>>
+ >>> wavelength_to_pixel = ([400., 400.5, 401.5, 402., 404.],
+ >>> [600., 600.5, 601.5, 602., 604., 607.])
+ >>> spectrometer = Spectrometer(wavelength_to_pixel, min_bins_per_pixel=5,
+ >>> name='MySpectrometer')
+ >>>
+ >>> world = World()
+ >>> fibreoptic = FibreOptic(name="MyFibreOptic", parent=world)
+ >>> fibreoptic.min_wavelength = spectrometer.min_wavelength
+ >>> fibreoptic.max_wavelength = spectrometer.max_wavelength
+ >>> fibreoptic.spectral_bins = spectrometer.spectral_bins
+ >>> fibreoptic.pipelines = spectrometer.create_pipelines()
+ >>> ...
+ >>> fibreoptic.observe()
+ >>> spectrum = Spectrum(fibreoptic.min_wavelength, fibreoptic.max_wavelength, fibreoptic.spectral_bins)
+ >>> spectrum.samples[:] = fibreoptic.pipelines[0].mean
+ >>> calibrated_spectra = spectrometer.calibrate(spectrum)
+ >>> wavelengths = spectrometer.wavelengths
+ >>>
+ >>> plt.plot(wavelengths[0], calibrated_spectra[0])
+ >>> plt.show()
+ """
+
+ def __init__(self, wavelength_to_pixel, min_bins_per_pixel=1, name=''):
+
+ self.min_bins_per_pixel = min_bins_per_pixel
+ self.wavelength_to_pixel = wavelength_to_pixel
+ super().__init__(name)
+
+ @property
+ def wavelength_to_pixel(self):
+ # Wavelength-to-pixel calibration arrays.
+ return self._wavelength_to_pixel
+
+ @wavelength_to_pixel.setter
+ def wavelength_to_pixel(self, value):
+ _wavelength_to_pixel = []
+ _wavelengths = []
+ for wl2pix in value:
+ wl2pix = np.array(wl2pix, dtype=float)
+ if wl2pix.ndim != 1:
+ raise ValueError('Attribute wavelength_to_pixel must only contain one-dimensional arrays.')
+ if wl2pix.size < 2:
+ raise ValueError('Attribute wavelength_to_pixel must only contain arrays of at least 2 elements.')
+ if np.any(np.diff(wl2pix) <= 0):
+ raise ValueError('Attribute wavelength_to_pixel must only contain monotonically increasing arrays.')
+ wl2pix.flags.writeable = False
+ _wavelength_to_pixel.append(wl2pix)
+ wl_center = 0.5 * (wl2pix[1:] + wl2pix[:-1])
+ wl_center.flags.writeable = False
+ _wavelengths.append(wl_center)
+ self._wavelength_to_pixel = tuple(_wavelength_to_pixel)
+ self._wavelengths = tuple(_wavelengths)
+ self._clear_spectral_settings()
+
+ @property
+ def wavelengths(self):
+ # Central wavelengths of the pixels.
+ return self._wavelengths
+
+ @property
+ def min_bins_per_pixel(self):
+ # Minimal number of spectral bins per pixel.
+ return self._min_bins_per_pixel
+
+ @min_bins_per_pixel.setter
+ def min_bins_per_pixel(self, value):
+ value = int(value)
+ if value <= 0:
+ raise ValueError("Attribute 'min_bins_per_pixel' must be positive.")
+
+ self._min_bins_per_pixel = value
+ self._clear_spectral_settings()
+
+ def _update_pipeline_classes(self):
+ self._pipeline_classes = [SpectralRadiancePipeline0D]
+
+ def _update_pipeline_kwargs(self):
+ self._pipeline_kwargs = [{'name': self._name}]
+
+ def _update_spectral_settings(self):
+ self._min_wavelength = min(wl2pix[0] for wl2pix in self._wavelength_to_pixel)
+ self._max_wavelength = max(wl2pix[-1] for wl2pix in self._wavelength_to_pixel)
+ step = min(np.diff(wl2pix).min() for wl2pix in self._wavelength_to_pixel) / self._min_bins_per_pixel
+ self._spectral_bins = int(np.ceil((self._max_wavelength - self._min_wavelength) / step))
+
+ def calibrate(self, spectrum):
+ """
+ Calibrates the spectrum according to the `wavelength_to_pixel` arrays
+ by averaging it over the pixel widths.
+
+ :param Spectrum spectrum: Spectrum to calibrate.
+
+ :returns: A tuple of calibrated spectra as ndarrays.
+ """
+ if not isinstance(spectrum, Spectrum):
+ raise TypeError('Argument spectrum must be a Spectrum instance.')
+ if spectrum.min_wavelength > self.min_wavelength or spectrum.max_wavelength < self.max_wavelength:
+ raise ValueError('Unable to calibrate the spectrum. '
+ 'The spectrum has narrower range ({}, {}) than the spectrometer ({}, {}).'.format(spectrum.min_wavelength,
+ spectrum.max_wavelength,
+ self.min_wavelength,
+ self.max_wavelength))
+ calibrated_spectra = []
+ for wl2pix in self.wavelength_to_pixel:
+ calibrated_spectrum = np.zeros(wl2pix.size - 1)
+ for i in range(wl2pix.size - 1):
+ calibrated_spectrum[i] = spectrum.integrate(wl2pix[i], wl2pix[i + 1]) / (wl2pix[i + 1] - wl2pix[i])
+ calibrated_spectra.append(calibrated_spectrum)
+
+ return calibrated_spectra
+
+
+class CzernyTurnerSpectrometer(Spectrometer):
+ """
+ Czerny-Turner spectrometer.
+
+ The Czerny-Turner spectrometer is initialized with the parameters of the diffraction scheme
+ and a sequence of accommodated spectra, each of which is determined by the lower wavelength
+ bound and the number of pixels.
+
+ This spectrometer automatically fills the wavelength-to-pixel calibration arrays
+ according to the parameters of the diffraction scheme.
+
+ :param int diffraction_order: Diffraction order.
+ :param float grating: Diffraction grating in nm-1.
+ :param float focal_length: Focal length in nm.
+ :param float pixel_spacing: Pixel to pixel spacing on CCD in nm.
+ :param float diffraction_angle: Angle between incident and diffracted light in degrees.
+ :param tuple accommodated_spectra: A sequence of (`min_wavelength`, `pixels`) pairs, specifying
+ the lower wavelength bound and the number of pixels
+ of accommodated spectra.
+ :param int min_bins_per_pixel: Minimal number of spectral bins
+ per pixel. Default is 1.
+ :param str name: Spectrometer name.
+
+ :ivar tuple wavelength_to_pixel: Wavelength-to-pixel calibration arrays.
+
+ .. code-block:: pycon
+
+ >>> from raysect.optical import World
+ >>> from raysect.optical.observer import FibreOptic
+ >>> from cherab.tools.spectroscopy import CzernyTurnerSpectrometer
+ >>>
+ >>> world = World()
+ >>> hires_spectrometer = CzernyTurnerSpectrometer(1, 2.e-3, 1.e9, 2.e4, 10.,
+ >>> ((600., 512), (700., 128)),
+ >>> name='MySpectrometer')
+ >>> fibreoptic = FibreOptic(name="MyFibreOptic", parent=world)
+ >>> fibreoptic.min_wavelength = hires_spectrometer.min_wavelength
+ >>> fibreoptic.max_wavelength = hires_spectrometer.max_wavelength
+ >>> fibreoptic.spectral_bins = hires_spectrometer.spectral_bins
+ >>> fibreoptic.pipelines = hires_spectrometer.create_pipelines()
+ """
+
+ def __init__(self, diffraction_order, grating, focal_length, pixel_spacing, diffraction_angle,
+ accommodated_spectra, min_bins_per_pixel=1, name=''):
+ self._accommodated_spectra = None
+ self.diffraction_order = diffraction_order
+ self.grating = grating
+ self.focal_length = focal_length
+ self.pixel_spacing = pixel_spacing
+ self.diffraction_angle = diffraction_angle
+ self.accommodated_spectra = accommodated_spectra
+ self.min_bins_per_pixel = min_bins_per_pixel
+ self.name = name
+
+ @property
+ def diffraction_order(self):
+ # Diffraction order.
+ return self._diffraction_order
+
+ @diffraction_order.setter
+ def diffraction_order(self, value):
+ value = int(value)
+ if value <= 0:
+ raise ValueError("Attribute 'diffraction_order' must be positive.")
+
+ self._diffraction_order = value
+ # resolution has changed, recalculating wavelength_to_pixel
+ self._update_wavelength_to_pixel()
+
+ @property
+ def grating(self):
+ # Diffraction grating in nm-1.
+ return self._grating
+
+ @grating.setter
+ def grating(self, value):
+ if value <= 0:
+ raise ValueError("Attribute 'grating' must be positive.")
+
+ self._grating = value
+ # resolution has changed, recalculating wavelength_to_pixel
+ self._update_wavelength_to_pixel()
+
+ @property
+ def focal_length(self):
+ # Focal length in nm.
+ return self._focal_length
+
+ @focal_length.setter
+ def focal_length(self, value):
+ if value <= 0:
+ raise ValueError("Attribute 'focal_length' must be positive.")
+
+ self._focal_length = value
+ # resolution has changed, recalculating wavelength_to_pixel
+ self._update_wavelength_to_pixel()
+
+ @property
+ def pixel_spacing(self):
+ # Pixel to pixel spacing on CCD in nm.
+ return self._pixel_spacing
+
+ @pixel_spacing.setter
+ def pixel_spacing(self, value):
+ if value <= 0:
+ raise ValueError("Attribute 'pixel_spacing' must be positive.")
+
+ self._pixel_spacing = value
+ # resolution has changed, recalculating wavelength_to_pixel
+ self._update_wavelength_to_pixel()
+
+ @property
+ def diffraction_angle(self):
+ # Angle between incident and diffracted light in degrees.
+ return np.rad2deg(self._diffraction_angle)
+
+ @diffraction_angle.setter
+ def diffraction_angle(self, value):
+ if value <= 0:
+ raise ValueError("Attribute 'diffraction_angle' must be positive.")
+
+ self._diffraction_angle = np.deg2rad(value)
+ # resolution has changed, recalculating wavelength_to_pixel
+ self._update_wavelength_to_pixel()
+
+ @property
+ def accommodated_spectra(self):
+ return self._accommodated_spectra
+
+ @accommodated_spectra.setter
+ def accommodated_spectra(self, value):
+ for min_wavelength, pixels in value:
+ if min_wavelength <= 0:
+ raise ValueError('The value of min_wavelength in accommodated_spectra must be positive.')
+ if pixels <= 0:
+ raise ValueError('The value of pixels in accommodated_spectra must be positive.')
+ self._accommodated_spectra = value
+ self._update_wavelength_to_pixel()
+
+ def _update_wavelength_to_pixel(self):
+
+ if self._accommodated_spectra is None:
+ return
+
+ _wavelength_to_pixel = []
+ _wavelengths = []
+ for min_wavelength, pixels in self._accommodated_spectra:
+ pixels = int(pixels)
+ wl2pix = np.zeros(pixels + 1)
+ wl2pix[0] = min_wavelength
+ for i in range(1, pixels + 1):
+ wl2pix[i] = wl2pix[i - 1] + self.resolution(wl2pix[i - 1])
+ wl2pix.flags.writeable = False
+ _wavelength_to_pixel.append(wl2pix)
+ wl_center = 0.5 * (wl2pix[1:] + wl2pix[:-1])
+ wl_center.flags.writeable = False
+ _wavelengths.append(wl_center)
+ self._wavelength_to_pixel = tuple(_wavelength_to_pixel)
+ self._wavelengths = tuple(_wavelengths)
+
+ self._clear_spectral_settings()
+
+ @property
+ def wavelength_to_pixel(self):
+ # Wavelength-to-pixel calibration arrays.
+ return self._wavelength_to_pixel
+
+ def resolution(self, wavelength):
+ """
+ Calculates spectral resolution in nm for a given wavelength.
+
+ :param wavelength: Wavelength in nm.
+
+ :returns: Resolution in nm.
+ """
+ grating = self._grating
+ m = self._diffraction_order
+ dxdp = self._pixel_spacing
+ angle = self._diffraction_angle
+ fl = self._focal_length
+
+ p = 0.5 * m * grating * wavelength
+ _resolution = dxdp * (np.sqrt(np.cos(angle)**2 - p * p) - p * np.tan(angle)) / (m * fl * grating)
+
+ return _resolution
diff --git a/cherab/tools/tests/test_raytransfer.py b/cherab/tools/tests/test_raytransfer.py
index 38a5cdcf..76ecd4d4 100644
--- a/cherab/tools/tests/test_raytransfer.py
+++ b/cherab/tools/tests/test_raytransfer.py
@@ -18,9 +18,10 @@
import unittest
import numpy as np
-from raysect.optical import World, Ray, Point3D, Point2D, Vector3D, NumericalIntegrator
+from raysect.optical import World, Ray, Point3D, Point2D, Vector3D, NumericalIntegrator, Spectrum
from raysect.primitive import Box, Cylinder, Subtract
from cherab.tools.raytransfer import RayTransferBox, RayTransferCylinder, CartesianRayTransferEmitter, CylindricalRayTransferEmitter
+from cherab.tools.raytransfer import RayTransferPipeline0D, RayTransferPipeline1D, RayTransferPipeline2D
from cherab.tools.inversions import ToroidalVoxelGrid
@@ -239,3 +240,158 @@ def test_evaluate_function_3d(self):
spectrum_test = np.zeros(12)
spectrum_test[2] = spectrum_test[9] = np.sqrt(2.)
self.assertTrue(np.allclose(spectrum_test, spectrum.samples, atol=0.001))
+
+
+class TestRayTransferPipeline0D(unittest.TestCase):
+ """
+ Test cases for RayTransferPipeline0D class.
+ """
+
+ def test_initialise(self):
+ """
+ Test initialise method.
+ """
+ nbins = 10
+ pipeline = RayTransferPipeline0D('test_pipeline_0D', kind='power')
+ pipeline.initialise(0, 0, nbins, 0, 0)
+
+ self.assertTrue(pipeline.matrix.shape == (nbins,))
+ self.assertTrue(pipeline.name == 'test_pipeline_0D')
+ self.assertTrue(pipeline.kind == 'power')
+
+ self.assertRaises(ValueError, RayTransferPipeline0D, 'test_pipeline_0D', 'blah')
+
+ def test_kind(self):
+ """
+ Test if the 'kind' attribute works properly.
+ """
+ nbins = 10
+ sensitivity = 2.
+ spectral_value = 1.
+ spectrum = Spectrum(1., 2., nbins)
+ spectrum.samples[:] = spectral_value
+
+ pipeline = RayTransferPipeline0D('test_pipeline_0D', kind='power')
+ pipeline.initialise(0, 0, nbins, 0, 0)
+
+ pixel_processor = pipeline.pixel_processor(0)
+
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # multiplied by sensitivity
+ self.assertTrue(np.all(matrix == sensitivity * spectral_value))
+
+ pipeline.kind = 'radiance'
+ pixel_processor = pipeline.pixel_processor(0)
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # not multiplied by sensitivity
+ self.assertTrue(np.all(matrix == spectral_value))
+
+
+class TestRayTransferPipeline1D(unittest.TestCase):
+ """
+ Test cases for RayTransferPipeline1D class.
+ """
+
+ def test_initialise(self):
+ """
+ Test initialise method.
+ """
+ nbins = 10
+ pixels = 20
+ samples = 1
+ pipeline = RayTransferPipeline1D('test_pipeline_1D', kind='radiance')
+ pipeline.initialise(pixels, samples, 0, 0, nbins, 1, 0)
+
+ self.assertTrue(pipeline.matrix.shape == (pixels, nbins))
+ self.assertTrue(pipeline.name == 'test_pipeline_1D')
+ self.assertTrue(pipeline.kind == 'radiance')
+ self.assertTrue(pipeline._samples == samples)
+
+ self.assertRaises(ValueError, RayTransferPipeline1D, 'test_pipeline_1D', 'blah')
+
+ def test_kind(self):
+ """
+ Test if the 'kind' attribute works properly.
+ """
+ nbins = 10
+ pixels = 20
+ samples = 1
+ sensitivity = 2.
+ spectral_value = 1.
+ spectrum = Spectrum(1., 2., nbins)
+ spectrum.samples[:] = spectral_value
+
+ pipeline = RayTransferPipeline1D('test_pipeline_1D', kind='power')
+ pipeline.initialise(pixels, samples, 0, 0, nbins, 1, 0)
+
+ pixel_processor = pipeline.pixel_processor(0, 0)
+
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # multiplied by sensitivity
+ self.assertTrue(np.all(matrix == sensitivity * spectral_value))
+
+ pipeline.kind = 'radiance'
+ pixel_processor = pipeline.pixel_processor(0, 0)
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # not multiplied by sensitivity
+ self.assertTrue(np.all(matrix == spectral_value))
+
+
+class TestRayTransferPipeline2D(unittest.TestCase):
+ """
+ Test cases for RayTransferPipeline2D class.
+ """
+
+ def test_initialise(self):
+ """
+ Test initialise method.
+ """
+ nbins = 10
+ pixels = (20, 5)
+ samples = 1
+ pipeline = RayTransferPipeline2D('test_pipeline_2D', kind='radiance')
+ pipeline.initialise(pixels, samples, 0, 0, nbins, 1, 0)
+
+ self.assertTrue(pipeline.matrix.shape == (pixels[0], pixels[1], nbins))
+ self.assertTrue(pipeline.name == 'test_pipeline_2D')
+ self.assertTrue(pipeline.kind == 'radiance')
+ self.assertTrue(pipeline._samples == samples)
+
+ self.assertRaises(ValueError, RayTransferPipeline2D, 'test_pipeline_2D', 'blah')
+
+ def test_units(self):
+ """
+ Test if the 'kind' attribute works properly.
+ """
+ nbins = 10
+ pixels = (20, 5)
+ samples = 1
+ sensitivity = 2.
+ spectral_value = 1.
+ spectrum = Spectrum(1., 2., nbins)
+ spectrum.samples[:] = spectral_value
+
+ pipeline = RayTransferPipeline2D('test_pipeline_2D', kind='power')
+ pipeline.initialise(pixels, samples, 0, 0, nbins, 1, 0)
+
+ pixel_processor = pipeline.pixel_processor(0, 0, 0)
+
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # multiplied by sensitivity
+ self.assertTrue(np.all(matrix == sensitivity * spectral_value))
+
+ pipeline.kind = 'radiance'
+ pixel_processor = pipeline.pixel_processor(0, 0, 0)
+ pixel_processor.add_sample(spectrum, sensitivity)
+
+ matrix, _ = pixel_processor.pack_results() # not multiplied by sensitivity
+ self.assertTrue(np.all(matrix == spectral_value))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/cherab/tools/tests/test_spectroscopic_instruments.py b/cherab/tools/tests/test_spectroscopic_instruments.py
new file mode 100644
index 00000000..211f7830
--- /dev/null
+++ b/cherab/tools/tests/test_spectroscopic_instruments.py
@@ -0,0 +1,170 @@
+# Copyright 2016-2021 Euratom
+# Copyright 2016-2021 United Kingdom Atomic Energy Authority
+# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+import unittest
+import numpy as np
+
+from raysect.optical import Spectrum
+from raysect.optical.observer.pipeline import RadiancePipeline0D, SpectralRadiancePipeline0D
+from cherab.tools.spectroscopy import TrapezoidalFilter, PolychromatorFilter, Polychromator, CzernyTurnerSpectrometer, Spectrometer
+
+
+class TestPolychromatorFilter(unittest.TestCase):
+ """
+ Test for PolychromatorFilter class.
+ """
+
+ def test_spectrum(self):
+ wavelengths = [658, 654, 656] # unsorted
+ samples = [0.5, 0.5, 1] # non-zero at the ends
+ poly_filter = PolychromatorFilter(wavelengths, samples, name='test_filter')
+ wavelengths = np.linspace(653., 659., 7)
+ spectrum_true = np.array([0, 0.5, 0.75, 1., 0.75, 0.5, 0])
+ spectrum_test = np.array([poly_filter(wvl) for wvl in wavelengths])
+ self.assertTrue(np.all(spectrum_true == spectrum_test))
+
+
+class TestTrapezoidalFilter(unittest.TestCase):
+ """
+ Test for TrapezoidalFilter class.
+ """
+
+ def test_spectrum(self):
+ wavelength = 500.
+ window = 6.
+ flat_top = 2.
+ poly_filter = TrapezoidalFilter(wavelength, window, flat_top, 'test_filter')
+ wavelengths = np.linspace(496., 504., 9)
+ spectrum_true = np.array([0, 0, 0.5, 1., 1., 1., 0.5, 0, 0])
+ spectrum_test = np.array([poly_filter(wvl) for wvl in wavelengths])
+ self.assertTrue(np.all(spectrum_true == spectrum_test))
+
+
+class TestPolychromator(unittest.TestCase):
+ """
+ Test cases for Polychromator class.
+ """
+
+ poly_filters_default = (TrapezoidalFilter(400., 6., 2., 'filter 1'),
+ TrapezoidalFilter(700., 8., 4., 'filter 2'))
+ min_bins_per_window_default = 10
+
+ def test_pipeline_classes(self):
+ polychromator = Polychromator(self.poly_filters_default, self.min_bins_per_window_default, 'test polychromator')
+ pipeline_classes_true = [RadiancePipeline0D, RadiancePipeline0D]
+ self.assertSequenceEqual(pipeline_classes_true, polychromator.pipeline_classes)
+
+ def test_pipeline_kwargs(self):
+ polychromator = Polychromator(self.poly_filters_default, self.min_bins_per_window_default, 'test polychromator')
+ pipeline_kwargs_true = [{'name': 'test polychromator: filter 1', 'filter': self.poly_filters_default[0]},
+ {'name': 'test polychromator: filter 2', 'filter': self.poly_filters_default[1]}]
+ self.assertSequenceEqual(pipeline_kwargs_true, polychromator.pipeline_kwargs)
+
+ def test_spectral_properties(self):
+ polychromator = Polychromator(self.poly_filters_default, self.min_bins_per_window_default)
+ min_wavelength_true = 397.
+ max_wavelength_true = 704.
+ spectral_bins_true = 512
+ self.assertTrue(polychromator.min_wavelength == min_wavelength_true and
+ polychromator.max_wavelength == max_wavelength_true and
+ polychromator.spectral_bins == spectral_bins_true)
+
+ def test_filter_change(self):
+ """ Checks if the spectral properties are updated correctly when the filters are replaced."""
+ polychromator = Polychromator(self.poly_filters_default, self.min_bins_per_window_default)
+ polychromator.min_bins_per_window = 20
+ polychromator.filters = [TrapezoidalFilter(500., 5., 2., 'filter 1'),
+ TrapezoidalFilter(600., 7., 4., 'filter 2')]
+ min_wavelength_true = 497.5
+ max_wavelength_true = 603.5
+ spectral_bins_true = 424
+ self.assertTrue(polychromator.min_wavelength == min_wavelength_true and
+ polychromator.max_wavelength == max_wavelength_true and
+ polychromator.spectral_bins == spectral_bins_true)
+
+
+class TestSpectrometer(unittest.TestCase):
+ """
+ Test cases for Spectrometer class.
+ """
+
+ def test_pipeline_classes(self):
+ wavelength_to_pixel = ([400., 400.5],)
+ spectrometer = Spectrometer(wavelength_to_pixel, name='test spectrometer')
+ self.assertSequenceEqual([SpectralRadiancePipeline0D], spectrometer.pipeline_classes)
+
+ def test_pipeline_kwargs(self):
+ wavelength_to_pixel = ([400., 400.5],)
+ spectrometer = Spectrometer(wavelength_to_pixel, name='test spectrometer')
+ self.assertSequenceEqual([{'name': 'test spectrometer'}], spectrometer.pipeline_kwargs)
+
+ def test_spectral_properties(self):
+ wavelength_to_pixel = ([400., 400.5, 401.5, 402., 404.], [600., 600.5, 601.5, 602., 604., 607.])
+ spectrometer = Spectrometer(wavelength_to_pixel, min_bins_per_pixel=2, name='test spectrometer')
+ min_wavelength_true = 400.
+ max_wavelength_true = 607.
+ spectra_bins_true = 828
+ self.assertTrue(spectrometer.min_wavelength == min_wavelength_true and
+ spectrometer.max_wavelength == max_wavelength_true and
+ spectrometer.spectral_bins == spectra_bins_true)
+
+ def test_calibration(self):
+ wavelength_to_pixel = ([400., 400.5, 401.5, 402., 404.],)
+ spectrometer = Spectrometer(wavelength_to_pixel, name='test spectrometer')
+ spectrum = Spectrum(399, 405, 12)
+ s, ds = np.linspace(0, 6., 13, retstep=True)
+ spectrum.samples[:] = s[:-1] + 0.5 * ds
+ calibrated_spectra = spectrometer.calibrate(spectrum)
+ self.assertTrue(np.all(calibrated_spectra[0] == np.array([1.25, 2., 2.75, 4.])))
+
+
+class TestCzernyTurnerSpectrometer(unittest.TestCase):
+ """
+ Test cases for CzernyTurnerSpectrometer class.
+ """
+
+ diffraction_order = 1
+ grating = 2.e-3
+ focal_length = 1.e9
+ pixel_spacing = 2.e4
+ diffraction_angle = 10.
+ accommodated_spectra = ((400., 64), (500., 32))
+ min_bins_per_pixel = 2
+
+ def test_resolution(self):
+ wavelengths = np.array([350., 550., 750.])
+ resolutions_true = np.array([8.587997e-3, 7.199328e-3, 5.0599164e-3])
+ spectrometer = CzernyTurnerSpectrometer(self.diffraction_order, self.grating, self.focal_length, self.pixel_spacing,
+ self.diffraction_angle, self.accommodated_spectra, name='test spectrometer')
+ resolutions = spectrometer.resolution(wavelengths)
+ self.assertTrue(np.all(np.abs(resolutions / resolutions_true - 1.) < 1.e-7))
+
+ def test_spectral_properties(self):
+ min_wavelength_true = 400
+ max_wavelength_true = 500.24326
+ spectra_bins_true = 26377
+ spectrometer = CzernyTurnerSpectrometer(self.diffraction_order, self.grating, self.focal_length, self.pixel_spacing,
+ self.diffraction_angle, self.accommodated_spectra,
+ min_bins_per_pixel=self.min_bins_per_pixel, name='test spectrometer')
+ self.assertTrue(spectrometer.min_wavelength == min_wavelength_true and
+ spectrometer.spectral_bins == spectra_bins_true and
+ abs(spectrometer.max_wavelength - max_wavelength_true) < 1.e-5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/demos/emission_models/bremsstrahlung.py b/demos/emission_models/bremsstrahlung.py
new file mode 100755
index 00000000..b1da93f6
--- /dev/null
+++ b/demos/emission_models/bremsstrahlung.py
@@ -0,0 +1,84 @@
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+# External imports
+import matplotlib.pyplot as plt
+from scipy.constants import electron_mass, atomic_mass
+from raysect.optical import World, Vector3D, Point3D, Ray
+from raysect.primitive import Sphere
+from raysect.optical.material.emitter.inhomogeneous import NumericalIntegrator
+
+# Cherab imports
+from cherab.core import Species, Maxwellian, Plasma
+from cherab.core.atomic.elements import deuterium, nitrogen
+from cherab.core.model import Bremsstrahlung
+from cherab.openadas import OpenADAS
+from cherab.tools.plasmas import GaussianVolume
+
+
+# tunables
+ion_density = 1e20
+sigma = 1.
+
+# setup scenegraph
+world = World()
+
+# create atomic data source
+adas = OpenADAS(permit_extrapolation=True)
+
+# PLASMA ----------------------------------------------------------------------
+plasma = Plasma(parent=world)
+plasma.atomic_data = adas
+plasma.geometry = Sphere(sigma)
+plasma.geometry_transform = None
+plasma.integrator = NumericalIntegrator(step=0.01 * sigma)
+
+# define basic distributions
+d_density = GaussianVolume(ion_density, sigma)
+n_density = d_density * 0.01
+e_density = GaussianVolume(ion_density, sigma)
+temperature = GaussianVolume(1000, sigma)
+bulk_velocity = Vector3D(0, 0, 0)
+
+deuterium_mass = deuterium.atomic_weight * atomic_mass
+d_distribution = Maxwellian(d_density, temperature, bulk_velocity, deuterium_mass)
+nitrogen_mass = nitrogen.atomic_weight * atomic_mass
+n_distribution = Maxwellian(n_density, temperature, bulk_velocity, nitrogen_mass)
+e_distribution = Maxwellian(e_density, temperature, bulk_velocity, electron_mass)
+
+d1_species = Species(deuterium, 1, d_distribution)
+n1_species = Species(nitrogen, 1, n_distribution)
+
+# define species
+plasma.b_field = Vector3D(1.0, 1.0, 1.0)
+plasma.electron_distribution = e_distribution
+plasma.composition = [d1_species, n1_species]
+
+# add Bremsstrahlung to the plasma
+plasma.models = [Bremsstrahlung()]
+
+# Ray-trace and plot the results
+r = Ray(origin=Point3D(0, 0, -5), direction=Vector3D(0, 0, 1),
+ min_wavelength=380, max_wavelength=800, bins=256)
+s = r.trace(world)
+plt.plot(s.wavelengths, s.samples)
+plt.xlabel('Wavelength (nm)')
+plt.ylabel('Radiance (W/m^2/str/nm)')
+plt.title('Observed Bremsstrahlung spectrum')
+plt.show()
diff --git a/demos/generomak/plasma/plot_2d_plasma.py b/demos/generomak/plasma/plot_2d_plasma.py
new file mode 100755
index 00000000..12f58866
--- /dev/null
+++ b/demos/generomak/plasma/plot_2d_plasma.py
@@ -0,0 +1,128 @@
+
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+"""
+This demo does the same plots as the plot_2d_profiles.py demo, but samples the profiles from the Plasma objects.
+"""
+
+import numpy as np
+from matplotlib.colors import SymLogNorm
+from matplotlib import pyplot as plt
+
+from cherab.core.math import sample3d
+from cherab.core.atomic.elements import hydrogen, carbon
+
+from cherab.generomak.plasma import get_core_plasma, get_edge_plasma, get_plasma
+
+
+def plot_profiles(core_profile, edge_profile, full_profile, r_range, z_range, label):
+
+ # Sample core profile on a regular grid
+ _, _, _, core_profile_samples = sample3d(core_profile, r_range, (0, 0, 1), z_range)
+ core_profile_samples = core_profile_samples.squeeze()
+
+ # Sample edge profile on a regular grid
+ _, _, _, edge_profile_samples = sample3d(edge_profile, r_range, (0, 0, 1), z_range)
+ edge_profile_samples = edge_profile_samples.squeeze()
+
+ # Sample blended profile on a regular grid
+ _, _, _, full_profile_samples = sample3d(full_profile, r_range, (0, 0, 1), z_range)
+ full_profile_samples = full_profile_samples.squeeze()
+
+ fig = plt.figure(figsize=(9.5, 5.), tight_layout=True)
+
+ vmax = full_profile_samples.max()
+ linthresh = 0.01 * min(core_profile_samples.max(), edge_profile_samples.max())
+ color_norm = SymLogNorm(linthresh, vmin=0, vmax=vmax)
+
+ core_profile_samples[core_profile_samples == 0] = np.nan
+ edge_profile_samples[edge_profile_samples == 0] = np.nan
+ full_profile_samples[full_profile_samples == 0] = np.nan
+
+ ax_core = fig.add_subplot(131)
+ ax_core.imshow(core_profile_samples.T, extent=[r_range[0], r_range[1], z_range[0], z_range[1]], origin='lower', norm=color_norm, cmap='gnuplot')
+ ax_core.text(0.99, 0.99, 'Core', ha='right', va='top', transform=ax_core.transAxes)
+ ax_core.set_xlim(r_range[0], r_range[1])
+ ax_core.set_ylim(z_range[0], z_range[1])
+ ax_core.set_xlabel('R, m')
+ ax_core.set_ylabel('Z, m')
+
+ ax_edge = fig.add_subplot(132, sharex=ax_core, sharey=ax_core)
+ img = ax_edge.imshow(edge_profile_samples.T, extent=[r_range[0], r_range[1], z_range[0], z_range[1]], origin='lower', norm=color_norm, cmap='gnuplot')
+ ax_edge.text(0.99, 0.99, 'Edge', ha='right', va='top', transform=ax_edge.transAxes)
+ ax_edge.set_xlabel('R, m')
+
+ ax_blend = fig.add_subplot(133, sharex=ax_core, sharey=ax_core)
+ img = ax_blend.imshow(full_profile_samples.T, extent=[r_range[0], r_range[1], z_range[0], z_range[1]], origin='lower', norm=color_norm, cmap='gnuplot')
+ ax_blend.text(0.99, 0.99, 'Blended', ha='right', va='top', transform=ax_blend.transAxes)
+ ax_blend.set_xlabel('R, m')
+
+ fig.colorbar(img, label=label)
+
+ return fig
+
+
+# get Generomak core plasma
+core_plasma = get_core_plasma()
+
+# get Generomak edge plasma
+edge_plasma = get_edge_plasma()
+
+# get Generomak full plasma (blended core and edge profiles)
+full_plasma = get_plasma()
+
+# plasma domain
+r_range = (0.78, 2.23, 290)
+z_range = (-1.74, 1.49, 647)
+
+# Plotting plasma profiles
+plot_profiles(core_plasma.electron_distribution.density,
+ edge_plasma.electron_distribution.density,
+ full_plasma.electron_distribution.density,
+ r_range, z_range, 'Electron density, m-3')
+
+plot_profiles(core_plasma.electron_distribution.effective_temperature,
+ edge_plasma.electron_distribution.effective_temperature,
+ full_plasma.electron_distribution.effective_temperature,
+ r_range, z_range, 'Electron temperature, eV')
+
+plot_profiles(core_plasma.composition.get(hydrogen, 1).distribution.effective_temperature,
+ edge_plasma.composition.get(hydrogen, 1).distribution.effective_temperature,
+ full_plasma.composition.get(hydrogen, 1).distribution.effective_temperature,
+ r_range, z_range, 'Ion temperature, eV')
+
+for element, charges in ((hydrogen, (0, 1)), (carbon, (0, 1, 2, 3, 4, 5, 6))):
+ for charge in charges:
+ state_str = ' {}+'.format(charge) if charge else ' 0'
+ plot_profiles(core_plasma.composition.get(element, charge).distribution.density,
+ edge_plasma.composition.get(element, charge).distribution.density,
+ full_plasma.composition.get(element, charge).distribution.density,
+ r_range, z_range, '{} density, m-3'.format(element.name + state_str))
+
+plot_profiles(core_plasma.composition.get(hydrogen, 0).distribution.effective_temperature,
+ edge_plasma.composition.get(hydrogen, 0).distribution.effective_temperature,
+ full_plasma.composition.get(hydrogen, 0).distribution.effective_temperature,
+ r_range, z_range, 'neutral hydrogen effective temperature, eV')
+
+plot_profiles(core_plasma.composition.get(carbon, 0).distribution.effective_temperature,
+ edge_plasma.composition.get(carbon, 0).distribution.effective_temperature,
+ full_plasma.composition.get(carbon, 0).distribution.effective_temperature,
+ r_range, z_range, 'neutral carbon effective temperature, eV')
+
+plt.show()
diff --git a/demos/generomak/plasma/plot_2d_profiles.py b/demos/generomak/plasma/plot_2d_profiles.py
new file mode 100755
index 00000000..07fb7683
--- /dev/null
+++ b/demos/generomak/plasma/plot_2d_profiles.py
@@ -0,0 +1,144 @@
+
+# Copyright 2016-2022 Euratom
+# Copyright 2016-2022 United Kingdom Atomic Energy Authority
+# Copyright 2016-2022 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+"""
+This demo plots core, edge and blended Generomak 2D plasma profiles.
+"""
+
+import numpy as np
+from matplotlib.colors import SymLogNorm
+from matplotlib.collections import PolyCollection
+from matplotlib import pyplot as plt
+
+from cherab.core.math import sample2d
+from cherab.core.utility import RecursiveDict
+
+from cherab.generomak.equilibrium import load_equilibrium
+from cherab.generomak.plasma.plasma import get_core_interpolators, load_edge_profiles, get_full_profiles
+
+
+def plot_profiles(core_profile, edge_mesh, edge_data, full_profile, label):
+
+ # get grid parameters
+ vertex_coords = np.asarray(edge_mesh["vertex_coords"])
+ triangles = np.asarray(edge_mesh["triangles"])
+ rl, ru = (vertex_coords[:, 0].min(), vertex_coords[:, 0].max())
+ zl, zu = (vertex_coords[:, 1].min(), vertex_coords[:, 1].max())
+ nr = 288
+ nz = 647
+
+ edge_data = np.asarray(edge_data)
+
+ # Sample core profile on a regular grid
+ _, _, core_profile_samples = sample2d(core_profile, (rl, ru, nr), (zl, zu, nz))
+
+ # Sample blended profile on a regular grid
+ _, _, profile_samples = sample2d(full_profile, (rl, ru, nr), (zl, zu, nz))
+
+ fig = plt.figure(figsize=(9.5, 5.), tight_layout=True)
+
+ vmax = profile_samples.max()
+ linthresh = 0.01 * min(core_profile_samples.max(), edge_data.max())
+ color_norm = SymLogNorm(linthresh, vmin=0, vmax=vmax)
+
+ core_profile_samples[core_profile_samples == 0] = np.nan
+ profile_samples[profile_samples == 0] = np.nan
+
+ ax_core = fig.add_subplot(131)
+ ax_core.imshow(core_profile_samples.T, extent=[rl, ru, zl, zu], origin='lower', norm=color_norm, cmap='gnuplot')
+ ax_core.text(0.99, 0.99, 'Core', ha='right', va='top', transform=ax_core.transAxes)
+ ax_core.set_xlim(rl, ru)
+ ax_core.set_ylim(zl, zu)
+ ax_core.set_xlabel('R, m')
+ ax_core.set_ylabel('Z, m')
+
+ ax_edge = fig.add_subplot(132, sharex=ax_core, sharey=ax_core)
+ collection = PolyCollection(vertex_coords[triangles], norm=color_norm, cmap='gnuplot')
+ collection.set_array(edge_data)
+ ax_edge.add_collection(collection)
+ ax_edge.text(0.99, 0.99, 'Edge', ha='right', va='top', transform=ax_edge.transAxes)
+ ax_edge.set_aspect(1)
+ ax_edge.set_xlabel('R, m')
+
+ ax_blend = fig.add_subplot(133, sharex=ax_core, sharey=ax_core)
+ img = ax_blend.imshow(profile_samples.T, extent=[rl, ru, zl, zu], origin='lower', norm=color_norm, cmap='gnuplot')
+ ax_blend.text(0.99, 0.99, 'Blended', ha='right', va='top', transform=ax_blend.transAxes)
+ ax_blend.set_xlabel('R, m')
+
+ fig.colorbar(img, label=label)
+
+ return fig
+
+
+# load Generomak equilibrium
+equilibrium = load_equilibrium()
+
+# load 1D core profiles, f(psi_norm)
+core_profiles_1d = get_core_interpolators()
+
+# load 2D edge profiles defined on a quadrilateral mesh
+edge_data = load_edge_profiles()
+
+# load 2D plasma profiles covering both core and edge regions
+# see the source code for the get_full_profiles() to learn how to blend core and edge profiles using a mask function
+full_profiles = get_full_profiles(equilibrium, core_profiles_1d)
+
+# map core profiles to 2D using the equilibrium
+core_profiles_2d = RecursiveDict()
+
+core_profiles_2d["electron"]["temperature"] = equilibrium.map2d(core_profiles_1d["electron"]["f1d_temperature"])
+core_profiles_2d["electron"]["density"] = equilibrium.map2d(core_profiles_1d["electron"]["f1d_density"])
+
+for element, states in core_profiles_1d["composition"].items():
+ for charge, state in states.items():
+ core_profiles_2d["composition"][element][charge]["density"] = equilibrium.map2d(state["f1d_density"])
+ core_profiles_2d["composition"][element][charge]["temperature"] = equilibrium.map2d(state["f1d_temperature"])
+
+core_profiles_2d = core_profiles_2d.freeze()
+
+# Plotting plasma profiles
+plot_profiles(core_profiles_2d["electron"]["density"], edge_data["mesh"],
+ edge_data["electron"]["density"], full_profiles["electron"]["density"],
+ 'Electron density, m-3')
+
+plot_profiles(core_profiles_2d["electron"]["temperature"], edge_data["mesh"],
+ edge_data["electron"]["temperature"], full_profiles["electron"]["temperature"],
+ 'Electron temperature, eV')
+
+plot_profiles(core_profiles_2d["composition"]["hydrogen"][1]["temperature"], edge_data["mesh"],
+ edge_data["composition"]["hydrogen"][1]["temperature"],
+ full_profiles["composition"]["hydrogen"][1]["temperature"], 'Ion temperature, eV')
+
+for element, states in core_profiles_2d["composition"].items():
+ for charge, state in states.items():
+ state_str = ' {}+'.format(charge) if charge else ' 0'
+ plot_profiles(state["density"], edge_data["mesh"],
+ edge_data["composition"][element][charge]["density"],
+ full_profiles["composition"][element][charge]["density"],
+ '{} density, m-3'.format(element + state_str))
+
+plot_profiles(core_profiles_2d["composition"]["hydrogen"][0]["temperature"], edge_data["mesh"],
+ edge_data["composition"]["hydrogen"][0]["temperature"],
+ full_profiles["composition"]["hydrogen"][0]["temperature"], 'neutral hydrogen effective temperature, eV')
+
+plot_profiles(core_profiles_2d["composition"]["carbon"][0]["temperature"], edge_data["mesh"],
+ edge_data["composition"]["carbon"][0]["temperature"],
+ full_profiles["composition"]["carbon"][0]["temperature"], 'neutral carbon effective temperature, eV')
+
+plt.show()
diff --git a/demos/generomak/plasma/plot_core_profiles.py b/demos/generomak/plasma/plot_core_profiles.py
index c12f0d5a..23fd4486 100644
--- a/demos/generomak/plasma/plot_core_profiles.py
+++ b/demos/generomak/plasma/plot_core_profiles.py
@@ -22,9 +22,9 @@
import matplotlib.pyplot as plt
from cherab.core.math.samplers import sample1d_points
-from cherab.generomak.plasma.plasma import get_core_profiles_description
+from cherab.generomak.plasma.plasma import get_core_interpolators
-profiles = get_core_profiles_description()
+profiles = get_core_interpolators()
# setup temperature plot
_, ax_t = plt.subplots()
@@ -35,11 +35,12 @@
# setup density plot
_, ax_n = plt.subplots()
ax_n.set_yscale("log")
+ax_n.set_ylim(1.e-1, 1.e21)
ax_n.set_title("Species Core Density Profiles")
ax_n.set_xlabel("psin")
ax_n.set_ylabel("m^-3")
-psin = np.linspace(0, 1, 30)
+psin = np.append(1. - np.geomspace(1.e-4, 1, 127)[::-1], [1.])
# add hydrogen curves
for chrg, desc in profiles["composition"]["hydrogen"].items():
vals = sample1d_points(desc["f1d_temperature"], psin)
diff --git a/demos/laser/laser_profile.py b/demos/laser/laser_profile.py
new file mode 100644
index 00000000..fd5a08ad
--- /dev/null
+++ b/demos/laser/laser_profile.py
@@ -0,0 +1,86 @@
+from random import gauss
+from raysect.core import Vector3D
+
+from cherab.core.math.samplers import sample3d_grid
+from cherab.core.model.laser.profile import (UniformEnergyDensity, ConstantBivariateGaussian,
+ TrivariateGaussian, GaussianBeamAxisymmetric)
+
+import numpy as np
+import matplotlib.pyplot as plt
+
+def plot_profiles(profile, title=""):
+ """Plot the laser profile
+
+ Produces 2d energy density plot in the x-z plane at y=0.
+ Produces plots of energy density profiles along x, y and z
+ directions.
+ """
+
+ # set coordinate grid and zero indices
+ x = np.linspace(-0.01, 0.01, 31)
+ z = np.linspace(-1, 1, 101)
+ x_zero = np.abs(x).argmin()
+ z_zero = np.abs(z).argmin()
+
+ e_xz_profile = sample3d_grid(profile.get_energy_density, x, [0], z)[:, 0, :]
+ e_y_profile = sample3d_grid(profile.get_energy_density, [0], x, [0])[0, :, 0]
+
+ # plot
+ fig = plt.figure(constrained_layout=True)
+ fig.suptitle(title)
+ spec = fig.add_gridspec(4, 3)
+
+ # profile along y at z=0
+ axz = fig.add_subplot(spec[0, 0:2])
+ axz.plot(x, e_y_profile, color="C2", ls="dashed")
+ axz.set_xlabel("y [m]")
+ axz.set_ylabel("Energy [J/m^3]")
+
+ # x-y plane
+ ax2d = fig.add_subplot(spec[1:3, 0:2])
+ im = ax2d.pcolormesh(x, z, e_xz_profile.T)
+ fig.colorbar(im, ax=ax2d, label="Energy [J/m^3]")
+ ax2d.axhline(z[z_zero], color="C0", ls="dashed")
+ ax2d.axvline(x[x_zero], color="C1", ls="dashed")
+ ax2d.plot([x[x_zero]], z[z_zero], marker="x", color="C2")
+ ax2d.set_xlabel("x [m]")
+ ax2d.set_ylabel("z [m]")
+
+ # profile along z at x=0
+ axz = fig.add_subplot(spec[1:3, -1])
+ axz.plot(e_xz_profile[x_zero, :], z, color="C0", ls="dashed")
+ axz.set_ylabel("z [m]")
+ axz.set_xlabel("Energy [J/m^3]")
+
+ # profile along x at z=0
+ axz = fig.add_subplot(spec[-1, 0:2])
+ axz.plot(x, e_xz_profile[:, z_zero].T, color="C1", ls="dashed")
+ axz.set_xlabel("x [m]")
+ axz.set_ylabel("Energy [J/m^3]")
+
+# UniformEnergyDensity profile has constant parameters in the whole x, y, z space
+uniform = UniformEnergyDensity(energy_density=1e3, laser_length=2., laser_radius=0.005,
+ polarization=Vector3D(0, 1, 0))
+plot_profiles(uniform, "Uniform Energy Profile")
+
+# Example of ConstantBivariteGaussian. With energy 2J, pulse temporal length 5 ns
+# and different standard deviations in the x and y plane. The mean value in both
+# dimensions is equal to 0. There is no correlation between x and y.
+
+gauss2d = ConstantBivariateGaussian(pulse_energy=2, pulse_length=5e-9,
+ stddev_x=2e-3, stddev_y=4e-3)
+plot_profiles(gauss2d, "ConstantBivariateGaussian Energy Profile")
+
+# Example of TrivariageGaussian profile. With the pulse mean at z=0.2
+gauss3d = TrivariateGaussian(pulse_energy=2, pulse_length=2e-9,
+ mean_z=0.2, stddev_x=2e-3, stddev_y=4e-3 )
+plot_profiles(gauss3d, "TrivariateGaussian Energy Profile")
+
+# Example of GaussianBeamModel with wavelength 1e4 nm and 1 mm standard deviation
+# in the waist. The wavelength is too high
+# but was selected to produce nice plots in the defined x, y, z dimensions.
+
+gaussbeam = GaussianBeamAxisymmetric(stddev_waist=1e-3, waist_z=0.2, laser_wavelength=1e4)
+plot_profiles(gaussbeam, "GaussianBeam Energy Profile")
+
+plt.show()
\ No newline at end of file
diff --git a/demos/laser/laser_spectrum.py b/demos/laser/laser_spectrum.py
new file mode 100644
index 00000000..7904bbdc
--- /dev/null
+++ b/demos/laser/laser_spectrum.py
@@ -0,0 +1,34 @@
+from cherab.core.model.laser import ConstantSpectrum, GaussianSpectrum
+
+import matplotlib.pyplot as plt
+
+
+# construct a ConstantSpectrum with 10 spectral bins
+constant_wide = ConstantSpectrum(min_wavelength=1059.9, max_wavelength=1060.1, bins=10)
+
+# plot the power_spectral_density attribute of the laser
+_, ax = plt.subplots()
+ax.plot(constant_wide.wavelengths, constant_wide.power_spectral_density)
+
+ax.set_xlabel("Wavelength [nm]")
+ax.set_ylabel("W / nm")
+
+ax.set_title("Energy Spectral Density")
+plt.show()
+
+# construct a narrow laser spectrum
+constant_narrow = ConstantSpectrum(min_wavelength=1059.999, max_wavelength=1060.001, bins=1)
+print("narow spectrum wavelengths: {}, power spectral density: {}".format(constant_narrow.wavelengths,
+ constant_narrow.power_spectral_density))
+
+# construct a GaussianSpectrum with 20 bins
+gaussian = GaussianSpectrum(min_wavelength=1059, max_wavelength=1061, bins=30,
+ mean=1060, stddev=0.3)
+
+_, ax = plt.subplots()
+ax.plot(gaussian.wavelengths, gaussian.power_spectral_density)
+ax.set_xlabel("Wavelength [nm]")
+ax.set_ylabel("W / nm")
+
+ax.set_title("Energy Spectral Density")
+plt.show()
diff --git a/demos/laser/model_seldenmatoba.py b/demos/laser/model_seldenmatoba.py
new file mode 100644
index 00000000..0491cd66
--- /dev/null
+++ b/demos/laser/model_seldenmatoba.py
@@ -0,0 +1,72 @@
+import matplotlib.pyplot as plt
+
+from raysect.optical.spectrum import Spectrum
+
+from cherab.core.model.laser import SeldenMatobaThomsonSpectrum
+from cherab.core.utility import RecursiveDict
+
+
+density = 3e19 # electron density
+temperatures = [100, 2.e3] # electron temperatures in eV
+laser_wavelength = 1060 # wavelength of the laser light in nm
+laser_energy = 1 # energy density of the laser light in J/m^3
+
+# angle between observation direction and electric field
+angles_pol = [90, 45]
+
+# angles between propagation direction and observation direction
+angles_obs = [45, 90, 135, 120]
+
+# define spectrum of observed scattering
+min_wavelength = 650
+max_wavelength = 1300
+bins = 1000
+
+
+# calculate Thomson scattered spectra for the specified combinations of el. properties and observation
+model = SeldenMatobaThomsonSpectrum()
+scattered = RecursiveDict()
+
+for te in temperatures:
+ for ap in angles_pol:
+ for ao in angles_obs:
+ spectrum = Spectrum(min_wavelength, max_wavelength, bins)
+ scattered[te][ap][ao] = model.calculate_spectrum(density, te, laser_energy, laser_wavelength,
+ ao, ap, spectrum).samples
+scattered = scattered.freeze()
+
+wvls = spectrum.wavelengths
+
+# plot temperature influence on scattered spectra
+ap, ao = 90, 90
+_, ax = plt.subplots()
+ax.set_title("Scattered spectrum, pol. angl.={:d}, obs. angl = {:d}".format(ap, ao))
+for te in temperatures:
+ rad = scattered[te][ap][ao]
+ ax.plot(wvls, rad, label="Te = {:3.1f} eV".format(te))
+ax.set_xlabel("Wavelength [nm]")
+ax.set_ylabel("Spectral Radiance [W/m^3/sr]")
+ax.legend()
+
+# plot influence of angle between polarisation and observation on scattered spectra
+te, ao = 100, 90
+_, ax = plt.subplots()
+ax.set_title("Scattered spectrum, te = {:3.1f}, obs. angl = {:d}".format(te, ao))
+for ap in angles_pol:
+ rad = scattered[te][ap][ao]
+ ax.plot(wvls, rad, label="pol. angl. = {:d} deg".format(ap))
+ax.set_xlabel("Wavelength [nm]")
+ax.set_ylabel("Spectral Radiance [W/m^3/sr]")
+ax.legend()
+
+# plot influence of observation angle on scattered spectra
+te, ap = 2e3, 90
+_, ax = plt.subplots()
+ax.set_title("Scattered spectrum, te = {:3.1f}, obs. angl = {:d}".format(te, ao))
+for ao in angles_obs:
+ rad = scattered[te][ap][ao]
+ ax.plot(wvls, rad, label="obs. angl. = {:d} deg".format(ao))
+ax.set_xlabel("Wavelength [nm]")
+ax.set_ylabel("Spectral Radiance [W/m^3/sr]")
+ax.legend()
+plt.show()
diff --git a/demos/laser/thomson_scattering.py b/demos/laser/thomson_scattering.py
new file mode 100644
index 00000000..f9198d8e
--- /dev/null
+++ b/demos/laser/thomson_scattering.py
@@ -0,0 +1,61 @@
+import numpy as np
+
+from raysect.optical import World, translate, Point3D, rotate_basis, Vector3D
+from raysect.optical.observer import FibreOptic
+
+from cherab.core.model.laser import ConstantBivariateGaussian, ConstantSpectrum, SeldenMatobaThomsonSpectrum
+from cherab.core.laser import Laser
+
+from cherab.generomak.plasma import get_core_plasma
+from cherab.generomak.equilibrium import load_equilibrium
+
+import matplotlib.pyplot as plt
+
+world = World()
+
+plasma = get_core_plasma(parent=world)
+equilibrium = load_equilibrium()
+
+# set up the laser
+laser = Laser(name="Thomson Scattering laser", parent=world)
+laser.transform = translate(equilibrium.magnetic_axis[0], 0, -2)
+laser.plasma = plasma
+laser.laser_profile = ConstantBivariateGaussian(pulse_energy=2, pulse_length=1e-8,
+ laser_length=4, laser_radius=1e-2,
+ stddev_x=3e-3, stddev_y=2e-3)
+laser.laser_spectrum = ConstantSpectrum(min_wavelength=1059.9, max_wavelength=1060.1, bins=1)
+laser.models = [SeldenMatobaThomsonSpectrum()]
+
+# generate points on laser in world space to measure on
+laser_points = [Point3D(0, 0, round(z, 2)).transform(laser.to_root()) for z in np.linspace(2, 2.8, 5)]
+te = [plasma.electron_distribution.effective_temperature(*point) for point in laser_points]
+ne = [plasma.electron_distribution.density(*point) for point in laser_points]
+
+# place fibres 0.1m outside sep on lfs
+fibre_position = Point3D(equilibrium.psin_to_r(1) + 0.1, 0, 0)
+
+# generate fibres list and observe
+fibres = {}
+for point in laser_points:
+
+ direction = fibre_position.vector_to(point)
+ transform = translate(*fibre_position) * rotate_basis(direction, Vector3D(0, 0, 1))
+
+ fibre = FibreOptic(radius=1e-3, acceptance_angle=0.25,
+ parent=world, transform=transform,
+ min_wavelength=800, max_wavelength=1200,
+ spectral_bins=1000,
+ pixel_samples=1000)
+
+ fibre.pipelines[0].display_progress = False
+ fibre.observe()
+ fibres[point.z] = fibre
+
+_, ax = plt.subplots()
+for z, fibre in fibres.items():
+ pipeline = fibre.pipelines[0]
+ ax.plot(pipeline.wavelengths, pipeline.samples.mean, label="z={:1.2f}m".format(z))
+ax.set_xlabel("wavelength [nm]")
+ax.set_ylabel("spectral power W/nm")
+ax.legend()
+plt.show()
diff --git a/demos/observers/bolometry/geometry_matrix_with_raytransfer.py b/demos/observers/bolometry/geometry_matrix_with_raytransfer.py
index a9300636..35c525e1 100644
--- a/demos/observers/bolometry/geometry_matrix_with_raytransfer.py
+++ b/demos/observers/bolometry/geometry_matrix_with_raytransfer.py
@@ -240,7 +240,7 @@ def _point3d_to_rz(point):
for camera in cameras:
for foil in camera:
print("Calculating sensitivity for {}...".format(foil.name))
- foil.pipelines = [RayTransferPipeline0D()]
+ foil.pipelines = [RayTransferPipeline0D(kind=foil.units)]
# All objects in world have wavelength-independent material properties,
# so it doesn't matter which wavelength range we use (as long as
# max_wavelength - min_wavelength = 1)
diff --git a/demos/plasmas/analytic_plasma_function_framework.py b/demos/plasmas/analytic_plasma_function_framework.py
new file mode 100644
index 00000000..1459f28e
--- /dev/null
+++ b/demos/plasmas/analytic_plasma_function_framework.py
@@ -0,0 +1,165 @@
+
+# Copyright 2016-2018 Euratom
+# Copyright 2016-2018 United Kingdom Atomic Energy Authority
+# Copyright 2016-2018 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
+#
+# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl5
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the Licence for the specific language governing permissions and limitations
+# under the Licence.
+
+
+import numpy as np
+import matplotlib.pyplot as plt
+from scipy.constants import electron_mass, atomic_mass
+
+from raysect.core.math.function.float import Arg2D, Exp2D, Sqrt2D
+from raysect.primitive import Cylinder
+from raysect.optical import World, translate, Point3D, Vector3D, rotate_basis, Spectrum
+from raysect.optical.observer import PinholeCamera, PowerPipeline2D
+
+from cherab.core import Species, Maxwellian, Plasma, Line
+from cherab.core.math import sample3d, AxisymmetricMapper
+from cherab.core.atomic import deuterium
+from cherab.core.model import ExcitationLine
+from cherab.openadas import OpenADAS
+
+
+def NeutralFunction(peak_value, sigma, magnetic_axis, lcfs_radius=1):
+ """A neutral profile that is constant outside the plasma,
+ then exponentially decays inside the LCFS."""
+ raxis = magnetic_axis[0]
+ zaxis = magnetic_axis[1]
+ radius_from_axis = Sqrt2D((Arg2D('x') - raxis)**2 + (Arg2D('y') - zaxis)**2)
+ scale = Exp2D(-((radius_from_axis - lcfs_radius)**2) / (2 * sigma**2))
+ inside_lcfs = (radius_from_axis <= lcfs_radius)
+ # density = peak * scale * inside_lcfs + peak * (inside_lcfs - 1).
+ # Rearrange so inside_lcfs and scale are only called once each.
+ density = peak_value * (inside_lcfs * (scale - 1) + 1)
+ return AxisymmetricMapper(density)
+
+
+def IonFunction(v_core, v_lcfs, magnetic_axis, p=4, q=3, lcfs_radius=1):
+ """An approximate toroidal plasma profile that follows a double
+ quadratic between the LCFS and magnetic axis."""
+ r_axis = magnetic_axis[0]
+ z_axis = magnetic_axis[1]
+ radius_from_axis = Sqrt2D((Arg2D('x') - r_axis)**2 + (Arg2D('y') - z_axis)**2)
+ density = (v_core - v_lcfs) * (1 - (radius_from_axis / lcfs_radius)**p)**q + v_lcfs
+ inside_lcfs = (radius_from_axis <= lcfs_radius)
+ return AxisymmetricMapper(density * inside_lcfs)
+
+
+# tunables
+peak_density = 1e19
+peak_temperature = 2500
+magnetic_axis = (2.5, 0)
+
+
+# setup scenegraph
+world = World()
+
+
+###################
+# plasma creation #
+
+plasma = Plasma(parent=world)
+plasma.atomic_data = OpenADAS(permit_extrapolation=True)
+plasma.geometry = Cylinder(3.5, 2.2, transform=translate(0, 0, -1.1))
+plasma.geometry_transform = translate(0, 0, -1.1)
+
+# No net velocity for any species
+zero_velocity = Vector3D(0, 0, 0)
+
+# define neutral species distribution
+d0_density = NeutralFunction(peak_density, 0.1, magnetic_axis)
+d0_temperature = 0.5 # constant 0.5eV temperature for all neutrals
+d0_distribution = Maxwellian(d0_density, d0_temperature, zero_velocity,
+ deuterium.atomic_weight * atomic_mass)
+d0_species = Species(deuterium, 0, d0_distribution)
+
+# define deuterium ion species distribution
+d1_density = IonFunction(peak_density, 0, magnetic_axis)
+d1_temperature = IonFunction(peak_temperature, 0, magnetic_axis)
+d1_distribution = Maxwellian(d1_density, d1_temperature, zero_velocity,
+ deuterium.atomic_weight * atomic_mass)
+d1_species = Species(deuterium, 1, d1_distribution)
+
+# define the electron distribution
+e_density = IonFunction(peak_density, 0, magnetic_axis)
+e_temperature = IonFunction(peak_temperature, 0, magnetic_axis)
+e_distribution = Maxwellian(e_density, e_temperature, zero_velocity, electron_mass)
+
+# define species
+plasma.b_field = Vector3D(1.0, 1.0, 1.0)
+plasma.electron_distribution = e_distribution
+plasma.composition = [d0_species, d1_species]
+
+# Add a balmer alpha line for visualisation purposes
+d_alpha_excit = ExcitationLine(Line(deuterium, 0, (3, 2)))
+plasma.models = [d_alpha_excit]
+
+
+####################
+# Visualise Plasma #
+
+# Run some plots to check the distribution functions and emission profile are as expected
+r, _, z, t_samples = sample3d(d1_temperature, (0, 4, 200), (0, 0, 1), (-2, 2, 200))
+plt.imshow(np.transpose(np.squeeze(t_samples)), extent=[0, 4, -2, 2])
+plt.colorbar()
+plt.axis('equal')
+plt.xlabel('r axis')
+plt.ylabel('z axis')
+plt.title("Ion temperature profile in r-z plane")
+
+plt.figure()
+r, _, z, t_samples = sample3d(d1_temperature, (-4, 4, 400), (-4, 4, 400), (0, 0, 1))
+plt.imshow(np.transpose(np.squeeze(t_samples)), extent=[-4, 4, -4, 4])
+plt.colorbar()
+plt.axis('equal')
+plt.xlabel('x axis')
+plt.ylabel('y axis')
+plt.title("Ion temperature profile in x-y plane")
+
+plt.figure()
+r, _, z, t_samples = sample3d(d0_density, (0, 4, 200), (0, 0, 1), (-2, 2, 200))
+plt.imshow(np.transpose(np.squeeze(t_samples)), extent=[0, 4, -2, 2])
+plt.colorbar()
+plt.axis('equal')
+plt.xlabel('r axis')
+plt.ylabel('z axis')
+plt.title("Neutral Density profile in r-z plane")
+
+plt.figure()
+xrange = np.linspace(0, 4, 200)
+yrange = np.linspace(-2, 2, 200)
+d_alpha_rz_intensity = np.zeros((200, 200))
+direction = Vector3D(0, 1, 0)
+for i, x in enumerate(xrange):
+ for j, y in enumerate(yrange):
+ emission = d_alpha_excit.emission(Point3D(x, 0.0, y), direction, Spectrum(650, 660, 1))
+ d_alpha_rz_intensity[j, i] = emission.total()
+plt.imshow(d_alpha_rz_intensity, extent=[0, 4, -2, 2], origin='lower')
+plt.colorbar()
+plt.xlabel('r axis')
+plt.ylabel('z axis')
+plt.title("D-alpha emission in R-Z")
+
+
+camera = PinholeCamera((256, 256), pipelines=[PowerPipeline2D()], parent=world)
+camera.transform = translate(2.5, -4.5, 0)*rotate_basis(Vector3D(0, 1, 0), Vector3D(0, 0, 1))
+camera.pixel_samples = 1
+
+plt.ion()
+camera.observe()
+plt.ioff()
+plt.show()
diff --git a/demos/ray_transfer/1_ray_transfer_box.py b/demos/ray_transfer/1_ray_transfer_box.py
index e4d5e8bb..43461709 100644
--- a/demos/ray_transfer/1_ray_transfer_box.py
+++ b/demos/ray_transfer/1_ray_transfer_box.py
@@ -36,8 +36,8 @@
from raysect.optical.observer import PinholeCamera, FullFrameSampler2D
# RayTransferPipeline2D is optimised for calculation of ray transfer matrices.
-# It's also possible to use SpectralRadiancePipeline2D but for the matrices with >1000 elements
-# the performance will be lower.
+# It's also possible to use SpectralRadiancePipeline2D or SpectralPowerPipeline2D but
+# for the matrices with >1000 elements the performance will be lower.
from cherab.tools.raytransfer import RayTransferPipeline2D, RayTransferBox
# Here we use special materials optimised for calculation of ray transfer matrices.
@@ -66,6 +66,9 @@
rtb.step = 0.2
# creating ray transfer pipeline
+# Be careful when setting the 'kind' attribute of the pipeline to 'power' or 'radiance'.
+# In the case of 'power', the matrix [m] is multiplied by the detector's sensitivity [m^2 sr].
+# For the PinholeCamera this does not matter, because its pixel sensitivity is 1.
pipeline = RayTransferPipeline2D()
# setting up the camera
diff --git a/dev/pypi_notes.md b/dev/pypi_notes.md
new file mode 100644
index 00000000..c79e6fe8
--- /dev/null
+++ b/dev/pypi_notes.md
@@ -0,0 +1,80 @@
+Building wheels for publishing on PyPI
+======================================
+
+Linux wheels published on PyPI must be for one of the manylinux variants.
+This means they should be built inside a manylinux Docker container.
+
+For Cherab versions 1.4 and earlier (which depend on raysect 0.7.1 or earlier),
+the procedure varies slightly depending on whether there is a raysect wheel
+available for the Python version or not.
+
+When Raysect wheels are available
+---------------------------------
+
+1. Retrieve the appropriate manylinux container (we'll use manylinux1 here as
+ an example, but any appropriate version works the same way).
+ ```bash
+ sudo docker run -ti -v :/cherab_core quay.io/pypa/manylinux1_x86_64 /bin/bash
+ ```
+ Or, if using singularity instead of Docker (where sudo rights are not available):
+ ```bash
+ singularity pull docker://quay.io/pypa/manylinux1_x86_64
+ singularity run -B :/cherab_core -W /tmp -c ./manylinux1_x86_64_latest.sif
+ ```
+2. Inside the container, change to the top level directory of this repository.
+ ```bash
+ cd /cherab_core
+ ```
+3. Configure pip to prefer older binary wheels over newer sdists. This is because
+ the manylinux images have very few libraries installed so fail to build many
+ packages.
+ ```bash
+ export PIP_PREFER_BINARY=1
+ ```
+4. (Optional) Configure a cache directory for pip that doesn't have a small quota.
+ This will prevent `No space left on device` errors when collecting dependencies,
+ or when pip does have to build certain packages (Numpy for example does successfully
+ build on certain manylinux versions for certain Python versions).
+ ```bash
+ export PIP_CACHE_DIR=/tmp/pipcache
+ ```
+5. Use PyPA's `build` package to build the sdists and wheels, for each Python version
+ we're building the wheels for. For example, for Python 3.8:
+ ```bash
+ /opt/python/cp38-cp38/bin/python -m build .
+ ```
+ Ensure you've done step 3 above before running this command!
+6. Once the build has finished, repair the wheel to give it the correct manylinux tag.
+ Once again, using Python 3.8 as an example:
+ ```bash
+ auditwheel repair ./dist/cherab-1.4.0rc1-cp38-cp38-linux_x86_64.whl
+ ```
+ This will produce a wheel in the `./wheelhouse` directory which can be uploaded to PyPI.
+
+When Raysect wheels aren't available
+------------------------------------
+
+For Raysect 0.8 and later, the same procedure applies as above.
+For Raysect 0.7.1 and below, a couple of additional steps are required.
+
+1. Follow steps 1-4 above to set up the container environment.
+2. Create a virtual environment for building the wheel. For example, for Python 3.10:
+ ```bash
+ /opt/python/cp310-cp310/bin/python -m venv /tmp/cp310
+ . /tmp/cp310/bin/activate
+ ```
+3. Install build, wheel Cython and the oldest supported Numpy into this environment.
+ ```bash
+ pip install build wheel cython oldest-supported-numpy
+ ```
+4. Install the required Raysect version.
+ ```bash
+ pip install raysect==0.7.1
+ ```
+5. Use PyPA's `build` to build the wheel, but tell it to use this virtual
+ environment rather than creating a new isolated one.
+ ```bash
+ python -m build -n .
+ ```
+6. Run the auditwheel command as given in step 6 above to produce wheels with
+ the correct tag for uploading to PyPI.
diff --git a/docs/source/atomic/atomic_data.rst b/docs/source/atomic/atomic_data.rst
index df3bc2db..650d89b4 100644
--- a/docs/source/atomic/atomic_data.rst
+++ b/docs/source/atomic/atomic_data.rst
@@ -6,3 +6,4 @@ Atomic Data
elements_and_isotopes
emission_lines
rate_coefficients
+ gaunt_factors
diff --git a/docs/source/atomic/gaunt_factors.rst b/docs/source/atomic/gaunt_factors.rst
new file mode 100644
index 00000000..b7950ff9
--- /dev/null
+++ b/docs/source/atomic/gaunt_factors.rst
@@ -0,0 +1,23 @@
+
+Gaunt factors
+-------------
+
+This includes classes for temperature-averaged Gaunt factors used to calculate Bremsstrahlung (free-free Gaunt factor)
+and radiative recombination continuum (bound-free Gaunt factor) emission.
+
+
+Free-free Gaunt factors
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: cherab.core.atomic.gaunt.FreeFreeGauntFactor
+ :members:
+ :special-members: __call__
+
+.. autoclass:: cherab.core.atomic.gaunt.InterpolatedFreeFreeGauntFactor
+ :show-inheritance:
+ :members:
+
+.. autoclass:: cherab.core.atomic.gaunt.MaxwellianFreeFreeGauntFactor
+ :show-inheritance:
+ :members:
+
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 7dfb5f04..d17ec793 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -39,6 +39,7 @@
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.mathjax',
+ 'sphinx_tabs.tabs',
]
# Add any paths that contain templates here, relative to this directory.
@@ -55,16 +56,16 @@
# General information about the project.
project = 'Cherab'
-copyright = '2021, Cherab Team'
+copyright = '2022, Cherab Team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '1.3'
+version = '1.4'
# The full version, including alpha/beta/rc tags.
-release = '1.3.0'
+release = '1.4.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -142,6 +143,7 @@
html_context = {'css_files': [
'_static/theme_overrides.css', # override wide tables in RTD theme
+ '_static/tabs.css',
]
}
diff --git a/docs/source/demonstrations/plasmas/analytic_function_plasma.rst b/docs/source/demonstrations/plasmas/analytic_function_plasma.rst
index e74ba874..627f0c66 100644
--- a/docs/source/demonstrations/plasmas/analytic_function_plasma.rst
+++ b/docs/source/demonstrations/plasmas/analytic_function_plasma.rst
@@ -10,11 +10,25 @@ shows how to use these functions in a plasma and visualises the results.
Note that while it is possible to use pure python functions for development, they are typically
~100 times slower than their cython counterparts. Therefore, for use cases where speed is important
-we recommend moving these functions to cython classes. For an example of a cython function,
-see the `Gaussian `_
-cython class in the demos folder.
+we recommend moving these functions to cython classes. An alternative solution which may not require
+writing and compiling any additional cython code is to use Raysect's
+`function framework `_ to build up
+expressions which will be evaluated like Python functions. These will typically run slightly slower
+than a hand-coded cython implementation but still significantly faster than a pure python
+implementation.
-.. literalinclude:: ../../../../demos/plasmas/analytic_plasma.py
+Two examples are provided, one using a pure python implementation of analytic forms for neutral and
+ion plasma species distributions, and one using objects from Raysect's function framework.
+
+.. tabs::
+
+ .. tab:: Pure python
+
+ .. literalinclude:: ../../../../demos/plasmas/analytic_plasma.py
+
+ .. tab:: Function framework
+
+ .. literalinclude:: ../../../../demos/plasmas/analytic_plasma_function_framework.py
.. figure:: analytic_plasma_slices.png
:align: center
diff --git a/docs/source/installation_and_structure.rst b/docs/source/installation_and_structure.rst
index 3af9d3ad..e9c051bf 100644
--- a/docs/source/installation_and_structure.rst
+++ b/docs/source/installation_and_structure.rst
@@ -82,6 +82,12 @@ line to install the packages under your own user account. Alternatively, conside
`virtual environment `_ to avoid the risk of
conflicting versions of packages in your Python environment.
+By default, pip will install from wheel archives on PyPI. If a binary wheel is not available for
+your version of Python, or if you are installing from source in editable mode for development (see
+below), the package will be compiled locally on your machine. Compilation is done in parallel by
+default, using all available processors, but can be overridden by setting the environment variable
+``CHERAB_NCPU`` to the number of processors to use.
+
Installing from source
^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/source/math/math.rst b/docs/source/math/math.rst
index eab9a1fa..836cbe84 100644
--- a/docs/source/math/math.rst
+++ b/docs/source/math/math.rst
@@ -18,6 +18,7 @@ utilities that Cherab provides for slicing, dicing and projecting these function
function
interpolators
mappers
+ transform
mask
samplers
slice
diff --git a/docs/source/math/transform.rst b/docs/source/math/transform.rst
new file mode 100644
index 00000000..f3d6cfa8
--- /dev/null
+++ b/docs/source/math/transform.rst
@@ -0,0 +1,11 @@
+
+Transformations
+---------------
+
+These functions perform coordinate transformations as wrappers for other functions. Unlike mappers, these wrappers do not change the dimensionality of the wrapped functions.
+
+.. automodule:: cherab.core.math.transform.cylindrical
+ :members:
+
+.. automodule:: cherab.core.math.transform.periodic
+ :members:
diff --git a/docs/source/models/emission_models.rst b/docs/source/models/emission_models.rst
index 73f76cc2..3a2c3b9c 100644
--- a/docs/source/models/emission_models.rst
+++ b/docs/source/models/emission_models.rst
@@ -13,3 +13,4 @@ Cherab contains a number of independent physics models for spectroscopic emissio
brem/bremsstrahlung
basic_line/basic_line_emission
line_shapes/spectral_line_shapes
+ laser/laser
diff --git a/docs/source/models/laser/laser.rst b/docs/source/models/laser/laser.rst
new file mode 100644
index 00000000..da9f7f79
--- /dev/null
+++ b/docs/source/models/laser/laser.rst
@@ -0,0 +1,28 @@
+Laser
+======
+
+Laser Spectrum
+--------------
+
+.. autoclass:: cherab.core.model.laser.laserspectrum.ConstantSpectrum
+ :members:
+.. autoclass:: cherab.core.model.laser.laserspectrum.GaussianSpectrum
+ :members:
+
+Laser Profile
+-------------
+
+.. autoclass:: cherab.core.model.laser.profile.UniformEnergyDensity
+ :members:
+.. autoclass:: cherab.core.model.laser.profile.ConstantBivariateGaussian
+ :members:
+.. autoclass:: cherab.core.model.laser.profile.TrivariateGaussian
+ :members:
+.. autoclass:: cherab.core.model.laser.profile.GaussianBeamAxisymmetric
+ :members:
+
+Laser Model
+-------------
+
+.. autoclass:: cherab.core.model.laser.model.SeldenMatobaThomsonSpectrum
+ :members:
diff --git a/docs/source/plasmas/laser.rst b/docs/source/plasmas/laser.rst
new file mode 100644
index 00000000..6c94c6d8
--- /dev/null
+++ b/docs/source/plasmas/laser.rst
@@ -0,0 +1,20 @@
+Laser
+======
+
+Laser Spectrum
+--------------
+
+.. autoclass:: cherab.core.laser.laserspectrum.LaserSpectrum
+ :members:
+
+Laser Profile
+-------------
+
+.. autoclass:: cherab.core.laser.profile.LaserProfile
+ :members:
+
+Laser Model
+-------------
+
+.. autoclass:: cherab.core.laser.model.LaserModel
+ :members:
diff --git a/docs/source/plasmas/plasmas.rst b/docs/source/plasmas/plasmas.rst
index 07198e71..98e3d9c8 100644
--- a/docs/source/plasmas/plasmas.rst
+++ b/docs/source/plasmas/plasmas.rst
@@ -7,3 +7,4 @@ Plasmas
core_plasma_classes
equilibrium
particle_beams
+ laser
diff --git a/docs/source/tools/observers.rst b/docs/source/tools/observers.rst
index e9a3a7e8..e93e2057 100644
--- a/docs/source/tools/observers.rst
+++ b/docs/source/tools/observers.rst
@@ -146,3 +146,4 @@ Spectroscopic prefix in class name.
.. autoclass:: cherab.tools.observers.SpectroscopicFibreOptic
:members
+
diff --git a/docs/source/tools/spectroscopy.rst b/docs/source/tools/spectroscopy.rst
new file mode 100644
index 00000000..a116dd77
--- /dev/null
+++ b/docs/source/tools/spectroscopy.rst
@@ -0,0 +1,42 @@
+
+Spectroscopy
+============
+
+The tools for plasma spectroscopy.
+
+.. _spectroscopy_instruments:
+
+Spectroscopic instruments
+-------------------------
+
+Spectroscopic instruments such as polychromators and spectrometers
+simplify the setup of properties of the observers and rendering pipelines. The instruments
+are not connected to the scenegraph, so they cannot observe the world. However, the instruments
+have properties, such as `min_wavelength`, `max_wavelength`, `spectral_bins`,
+`pipeline_properties`, with which the observer can be configured.
+The Cherab core package provides base classes for spectroscopic instruments,
+so machine-specific packages can build more advance instruments from them, such as instruments
+with spectral properties based on the actual experimental setup for a given shot/pulse.
+
+.. autoclass:: cherab.tools.spectroscopy.SpectroscopicInstrument
+ :members:
+
+.. autoclass:: cherab.tools.spectroscopy.PolychromatorFilter
+ :members:
+
+.. autoclass:: cherab.tools.spectroscopy.TrapezoidalFilter
+ :show-inheritance:
+ :members:
+
+.. autoclass:: cherab.tools.spectroscopy.Polychromator
+ :show-inheritance:
+ :members:
+
+.. autoclass:: cherab.tools.spectroscopy.Spectrometer
+ :show-inheritance:
+ :members:
+
+.. autoclass:: cherab.tools.spectroscopy.CzernyTurnerSpectrometer
+ :show-inheritance:
+ :members:
+
diff --git a/docs/source/tools/tools.rst b/docs/source/tools/tools.rst
index 3b356121..19f58e95 100644
--- a/docs/source/tools/tools.rst
+++ b/docs/source/tools/tools.rst
@@ -8,6 +8,7 @@ Tools
materials
primitives
observers
+ spectroscopy
tomography
utility
diff --git a/pyproject.toml b/pyproject.toml
index f896f8f0..a4eabed0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,3 @@
[build-system]
-requires = ["setuptools", "wheel", "oldest-supported-numpy", "cython>=0.28", "raysect==0.7.1"]
+requires = ["setuptools>=62.3", "oldest-supported-numpy", "cython>=0.28", "raysect==0.8.1"]
build-backend="setuptools.build_meta"
diff --git a/requirements.txt b/requirements.txt
index 2b5e7b4e..24a9b6e8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,4 +2,4 @@ cython>=0.28
numpy>=1.14
scipy
matplotlib
-raysect==0.7.1
\ No newline at end of file
+raysect==0.8.1
diff --git a/setup.py b/setup.py
index d7810f52..6cf51624 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,11 @@
-from setuptools import setup, find_packages, Extension
+from collections import defaultdict
import sys
-import numpy
import os
import os.path as path
+from pathlib import Path
import multiprocessing
+import numpy
+from setuptools import setup, find_packages, Extension
from Cython.Build import cythonize
multiprocessing.set_start_method('fork')
@@ -31,9 +33,12 @@
source_paths = ["cherab", "demos"]
compilation_includes = [".", numpy.get_include()]
-compilation_args = []
+compilation_args = ["-O3"]
cython_directives = {"language_level": 3}
setup_path = path.dirname(path.abspath(__file__))
+num_processes = int(os.getenv("CHERAB_NCPU", "-1"))
+if num_processes == -1:
+ num_processes = multiprocessing.cpu_count()
if line_profile:
compilation_args.append("-DCYTHON_TRACE=1")
@@ -68,6 +73,16 @@
compiler_directives=cython_directives,
)
+# Include demos in a separate directory in the distribution as data_files.
+demo_parent_path = Path("share/cherab/demos/core")
+data_files = defaultdict(list)
+demos_source = Path("demos")
+for item in demos_source.rglob("*"):
+ if item.is_file():
+ install_dir = demo_parent_path / item.parent.relative_to(demos_source)
+ data_files[str(install_dir)].append(str(item))
+data_files = list(data_files.items())
+
# parse the package version number
with open(path.join(path.dirname(__file__), "cherab/core/VERSION")) as version_file:
version = version_file.read().strip()
@@ -103,12 +118,25 @@
"numpy>=1.14",
"scipy",
"matplotlib",
- "raysect==0.7.1",
+ "raysect==0.8.1",
+ ],
+ extras_require={
+ # Running ./dev/build_docs.sh runs setup.py, which requires cython.
+ "docs": ["cython", "sphinx", "sphinx-rtd-theme", "sphinx-tabs"],
+ },
+ packages=find_packages(include=["cherab*"]),
+ package_data={"": [
+ "**/*.pyx", "**/*.pxd", # Needed to build Cython extensions.
+ "**/*.json", "**/*.cl", "**/*.npy", "**/*.obj", # Supplementary data
],
- packages=find_packages(),
- include_package_data=True,
+ "cherab.core": ["VERSION"], # Used to determine version at run time
+ },
+ data_files=data_files,
zip_safe=False,
ext_modules=extensions,
+ options=dict(
+ build_ext={"parallel": num_processes},
+ ),
)
# setup a rate repository with common rates