-
Notifications
You must be signed in to change notification settings - Fork 24
Add ThermalCXLine model #386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jacklovell
merged 27 commits into
cherab:development
from
vsnever:feature/thermal_cx_line
Jul 31, 2024
Merged
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
6584c90
Add ThermalCXLine model.
vsnever 7b357e1
Add ThermalCXPEC and update atomic data interface.
vsnever 4a6807f
Update install_adf15() so it could install thermal CX PECs from starn…
vsnever 520abd0
Fixed an error in _thermalcx_adf15_2dto3d_converter.
vsnever b622ba5
Merge branch 'development' into feature/thermal_cx_line
vsnever dc6afce
Added a test for the ExcitationLine model.
vsnever 270241b
Added tests for ExcitationLine, RecombinationLine and ThermalCXLine.
vsnever fb6e549
Fix error in BeamCXLine docstring.
vsnever 7b068c7
Added documentation for line emission models.
vsnever 2599717
Update changelog.
vsnever 0518d72
Remove target species as a donor from cached CX PECs.
vsnever 25428af
Add demo for ThermalCXLine model.
vsnever 74cd1b6
Merge branch 'development' into feature/thermal_cx_line
vsnever e2f3c6d
Undo adding docstrings to ExcitationLine and RecombinationLine as the…
vsnever c78e020
Add comments for atomic rates caching.
vsnever e799a6b
Make ThermalCXPEC to return zero if plasma parameters are <=zero thre…
vsnever 751878f
Pass RecursiveDict as normal dict to functions.
vsnever 4e2d169
Convert docstring for ThermalCXLine to raw string format.
vsnever 6d03432
Moved plasma setup to setUp() function in the unit tests for line emi…
vsnever c04bac7
Replaced zero threshold with 0 in openadas ThermalCXPEC.
vsnever b413c4f
Moved C5+ PEC installation from the demo to populate().
vsnever 76b533f
Removed isdir() check before makedirs because exist_ok is set to True.
vsnever 3644dd4
Merge branch 'development' into feature/thermal_cx_line
vsnever 67128fd
Merge branch 'development' into feature/thermal_cx_line
vsnever b0113d9
Updated CHANGELOG with the info about the C VI lines.
vsnever 941df80
Merge branch 'development' into feature/thermal_cx_line
vsnever 4f1e14a
Merge branch 'development' into feature/thermal_cx_line
vsnever File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # 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. | ||
|
|
||
| from cherab.core.atomic cimport Line | ||
| from cherab.core.plasma cimport PlasmaModel | ||
| from cherab.core.species cimport Species | ||
| from cherab.core.model.lineshape cimport LineShapeModel | ||
|
|
||
|
|
||
| cdef class ThermalCXLine(PlasmaModel): | ||
|
|
||
| cdef: | ||
| Line _line | ||
| double _wavelength | ||
| Species _target_species | ||
| list _rates | ||
| LineShapeModel _lineshape | ||
| object _lineshape_class, _lineshape_args, _lineshape_kwargs | ||
|
|
||
| cdef int _populate_cache(self) except -1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| # 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. | ||
|
|
||
| from raysect.optical cimport Spectrum, Point3D, Vector3D | ||
| from cherab.core cimport Plasma, AtomicData | ||
| from cherab.core.atomic cimport ThermalCXPEC | ||
| from cherab.core.model.lineshape cimport GaussianLine, LineShapeModel | ||
| from cherab.core.utility.constants cimport RECIP_4_PI | ||
|
|
||
|
|
||
| cdef class ThermalCXLine(PlasmaModel): | ||
| r""" | ||
| Emitter that calculates spectral line emission from a plasma object | ||
| as a result of thermal charge exchange of the target species with the donor species. | ||
|
|
||
| .. math:: | ||
| \epsilon_{\mathrm{CX}}(\lambda) = \frac{1}{4 \pi} n_{Z_\mathrm{i} + 1} | ||
| \sum_j{n_{Z_\mathrm{j}} \mathrm{PEC}_{\mathrm{cx}}(n_\mathrm{e}, T_\mathrm{e}, T_{Z_\mathrm{j}})} | ||
| f(\lambda), | ||
|
|
||
| where :math:`n_{Z_\mathrm{i} + 1}` is the receiver species density, | ||
| :math:`n_{Z_\mathrm{j}}` is the donor species density, | ||
| :math:`\mathrm{PEC}_{\mathrm{cx}}` is the thermal CX photon emission coefficient | ||
| for the specified spectral line of the :math:`Z_\mathrm{i}` ion, | ||
| :math:`T_{Z_\mathrm{j}}` is the donor species temperature, | ||
| :math:`f(\lambda)` is the normalised spectral line shape, | ||
|
|
||
| :param Line line: Spectroscopic emission line object. | ||
| :param Plasma plasma: The plasma to which this emission model is attached. Default is None. | ||
| :param AtomicData atomic_data: The atomic data provider for this model. Default is None. | ||
| :param object lineshape: Line shape model class. Default is None (GaussianLine). | ||
| :param object lineshape_args: A list of line shape model arguments. Default is None. | ||
| :param object lineshape_kwargs: A dictionary of line shape model keyword arguments. Default is None. | ||
|
|
||
| :ivar Plasma plasma: The plasma to which this emission model is attached. | ||
| :ivar AtomicData atomic_data: The atomic data provider for this model. | ||
| """ | ||
|
|
||
| def __init__(self, Line line, Plasma plasma=None, AtomicData atomic_data=None, object lineshape=None, | ||
| object lineshape_args=None, object lineshape_kwargs=None): | ||
|
|
||
| super().__init__(plasma, atomic_data) | ||
|
|
||
| self._line = line | ||
|
|
||
| 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() | ||
|
|
||
| def __repr__(self): | ||
| return '<ThermalCXLine: element={}, charge={}, transition={}>'.format(self._line.element.name, self._line.charge, self._line.transition) | ||
|
|
||
| cpdef Spectrum emission(self, Point3D point, Vector3D direction, Spectrum spectrum): | ||
|
|
||
| cdef: | ||
| double ne, te, receiver_density, donor_density, donor_temperature, weighted_rate, radiance | ||
| Species species | ||
| ThermalCXPEC rate | ||
|
|
||
| # cache data on first run | ||
| if self._target_species is None: | ||
| self._populate_cache() | ||
|
|
||
| ne = self._plasma.get_electron_distribution().density(point.x, point.y, point.z) | ||
| if ne <= 0.0: | ||
| return spectrum | ||
|
|
||
| te = self._plasma.get_electron_distribution().effective_temperature(point.x, point.y, point.z) | ||
| if te <= 0.0: | ||
| return spectrum | ||
|
|
||
| receiver_density = self._target_species.distribution.density(point.x, point.y, point.z) | ||
| if receiver_density <= 0.0: | ||
| return spectrum | ||
|
|
||
| # obtain composite CX PEC by iterating over all possible CX donors | ||
| weighted_rate = 0 | ||
| for species, rate in self._rates: | ||
| donor_density = species.distribution.density(point.x, point.y, point.z) | ||
| donor_temperature = species.distribution.effective_temperature(point.x, point.y, point.z) | ||
| weighted_rate += donor_density * rate.evaluate(ne, te, donor_temperature) | ||
|
|
||
| # add emission line to spectrum | ||
| radiance = RECIP_4_PI * weighted_rate * receiver_density | ||
| return self._lineshape.add_line(radiance, point, direction, spectrum) | ||
|
|
||
| cdef int _populate_cache(self) except -1: | ||
|
|
||
| cdef: | ||
| int receiver_charge | ||
| Species species | ||
| ThermalCXPEC rate | ||
|
|
||
| # sanity checks | ||
| if self._plasma is None: | ||
| raise RuntimeError("The emission model is not connected to a plasma object.") | ||
| if self._atomic_data is None: | ||
| raise RuntimeError("The emission model is not connected to an atomic data source.") | ||
|
|
||
| if self._line is None: | ||
| raise RuntimeError("The emission line has not been set.") | ||
|
|
||
| # locate target species | ||
| receiver_charge = self._line.charge + 1 | ||
| try: | ||
| self._target_species = self._plasma.composition.get(self._line.element, receiver_charge) | ||
| except ValueError: | ||
| raise RuntimeError("The plasma object does not contain the ion species for the specified CX line " | ||
| "(element={}, ionisation={}).".format(self._line.element.symbol, receiver_charge)) | ||
|
|
||
| # obtain rate functions | ||
| self._rates = [] | ||
| # iterate over all posible electron donors in plasma composition | ||
| # and for each donor, cache the PEC rate function for the CX reaction with this receiver | ||
| for species in self._plasma.composition: | ||
|
Mateasek marked this conversation as resolved.
|
||
| # exclude the receiver species from the list of donors and omit fully ionised species | ||
| if species != self._target_species and species.charge < species.element.atomic_number: | ||
| rate = self._atomic_data.thermal_cx_pec(species.element, species.charge, # donor | ||
| self._line.element, receiver_charge, # receiver | ||
| self._line.transition) | ||
| self._rates.append((species, rate)) | ||
|
|
||
| # identify wavelength | ||
| self._wavelength = self._atomic_data.wavelength(self._line.element, self._line.charge, self._line.transition) | ||
|
|
||
| # 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 | ||
| self._target_species = None | ||
| self._wavelength = 0.0 | ||
| self._rates = None | ||
| self._lineshape = None | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.