Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cherab/core/beam/__init__.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@

from cherab.core.beam.node cimport Beam
from cherab.core.beam.model cimport BeamModel, BeamAttenuator
from cherab.core.beam.distribution cimport BeamDistribution
1 change: 1 addition & 0 deletions cherab/core/beam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@

from .node import Beam
from .model import BeamModel, BeamAttenuator
from cherab.core.beam.distribution import BeamDistribution
34 changes: 34 additions & 0 deletions cherab/core/beam/distribution.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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 Element
from cherab.core.distribution cimport DistributionFunction
from cherab.core.beam.node cimport Beam

cdef class BeamDistribution(DistributionFunction):


cdef:
Beam _beam
Element _element

cdef Element get_element(self)

cpdef Beam get_beam(self)

cpdef list get_geometry(self)
89 changes: 89 additions & 0 deletions cherab/core/beam/distribution.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 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.beam.node cimport Beam
from cherab.core.atomic cimport Element
from cherab.core.distribution cimport DistributionFunction, ZeroDistribution
from cherab.core.utility import Notifier


cdef class BeamDistribution(DistributionFunction):

def __init__(self):

super().__init__()
self._beam = None

@property
def element(self):
return self._element

@element.setter
def element(self, Element value not None):
self._element = value
self._element_changed()
self.notifier.notify()

cdef Element get_element(self):
return self._element

@property
def beam(self):
return self._beam

@beam.setter
def beam(self, Beam value):

self._beam = value
self._beam_changed()

self.notifier.notify()

cpdef Beam get_beam(self):
return self._beam

cpdef list get_geometry(self):
"""
Get list of Primitives forming the beam geometry
"""
raise NotImplementedError('Virtual method must be implemented in a sub-class.')

def _beam_changed(self):
"""
Reaction to _beam changes

Virtual method call.
"""
pass

def _element_changed(self):
"""
Reaction to _element change

Virtual method call.
"""
pass

def _modified(self):
"""
Called when distribution chages

Virtual method call.
"""
self.notifier.notify()
5 changes: 5 additions & 0 deletions cherab/core/beam/material.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
# See the Licence for the specific language governing permissions and limitations
# under the Licence.


from raysect.optical cimport Primitive
from raysect.optical.material.emitter cimport InhomogeneousVolumeEmitter

from cherab.core.plasma cimport Plasma
from cherab.core.beam cimport Beam
from cherab.core.atomic cimport AtomicData
from cherab.core.beam.distribution cimport BeamDistribution


cdef class BeamMaterial(InhomogeneousVolumeEmitter):
Expand All @@ -29,5 +32,7 @@ cdef class BeamMaterial(InhomogeneousVolumeEmitter):
Beam _beam
Plasma _plasma
AtomicData _atomic_data
Primitive _beam_primitive
BeamDistribution _distribution
list _models

23 changes: 15 additions & 8 deletions cherab/core/beam/material.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,27 @@ from raysect.optical cimport World, Primitive, Ray, Spectrum, SpectralFunction,
from raysect.optical.material.emitter cimport InhomogeneousVolumeEmitter
from raysect.optical.material.emitter.inhomogeneous cimport VolumeIntegrator
from cherab.core.beam.model cimport BeamModel
from cherab.core.beam.distribution cimport BeamDistribution


cdef class BeamMaterial(InhomogeneousVolumeEmitter):

def __init__(self, Beam beam not None, Plasma plasma not None, AtomicData atomic_data not None,
list models not None, VolumeIntegrator integrator not None):
def __init__(self,
Beam beam not None,
BeamDistribution distribution not None,
Primitive beam_primitive not None,
Plasma plasma not None,
AtomicData atomic_data not None,
list models not None,
VolumeIntegrator integrator not None):

super().__init__(integrator)

self._beam = beam
self._distribution = distribution
self._plasma = plasma
self._atomic_data = atomic_data
self._beam_primitive = beam_primitive

# validate
for model in models:
Expand All @@ -42,6 +51,7 @@ cdef class BeamMaterial(InhomogeneousVolumeEmitter):
for model in models:
model.beam = beam
model.plasma = plasma
model.distribution = distribution
model.atomic_data = atomic_data

self._models = models
Expand All @@ -53,20 +63,17 @@ cdef class BeamMaterial(InhomogeneousVolumeEmitter):
cdef:
BeamModel model
Point3D plasma_point
Vector3D beam_direction, observation_direction

beam_direction = self._beam.direction(point.x, point.y, point.z)
Vector3D observation_direction

# transform points and directions
# todo: cache this transform and rebuild if beam or plasma notifies
beam_to_plasma = self._beam.to(self._plasma)
beam_to_plasma = self._beam_primitive.to(self._plasma)
plasma_point = point.transform(beam_to_plasma)
beam_direction = beam_direction.transform(beam_to_plasma)
observation_direction = direction.transform(beam_to_plasma)

# call each model and accumulate spectrum
for model in self._models:
spectrum = model.emission(point, plasma_point, beam_direction, observation_direction, spectrum)
spectrum = model.emission(point, plasma_point, observation_direction, spectrum)

return spectrum

Expand Down
8 changes: 6 additions & 2 deletions cherab/core/beam/model.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
# See the Licence for the specific language governing permissions and limitations
# under the Licence.

from raysect.core cimport AffineMatrix3D
from raysect.optical cimport Spectrum, Point3D, Vector3D

from cherab.core.plasma.node cimport Plasma
from cherab.core.beam.node cimport Beam
from cherab.core.beam.distribution cimport BeamDistribution
from cherab.core.atomic cimport AtomicData


Expand All @@ -29,19 +31,21 @@ cdef class BeamModel:
Plasma _plasma
Beam _beam
AtomicData _atomic_data
BeamDistribution _distribution

cdef object __weakref__

cpdef Spectrum emission(self, Point3D beam_point, Point3D plasma_point, Vector3D beam_direction, Vector3D observation_direction, Spectrum spectrum)
cpdef Spectrum emission(self, Point3D beam_point, Point3D plasma_point, Vector3D observation_direction, Spectrum spectrum)


cdef class BeamAttenuator:

cdef:
readonly object notifier
Plasma _plasma
Beam _beam
BeamDistribution _distribution
AtomicData _atomic_data
AffineMatrix3D _transform, _transform_inv

cdef object __weakref__

Expand Down
65 changes: 48 additions & 17 deletions cherab/core/beam/model.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# under the Licence.

from cherab.core.utility import Notifier

from raysect.core cimport AffineMatrix3D

cdef class BeamModel:

Expand Down Expand Up @@ -71,6 +71,24 @@ cdef class BeamModel:
# inform model source data has changed
self._change()

@property
def distribution(self):
return self._distribution

@distribution.setter
def distribution(self, BeamDistribution value not None):

# disconnect from previous beam's notifications
if self._distribution:
self._distribution.notifier.remove(self._change)

# attach to beam to inform model of changes to beam properties
self._distribution = value
self._distribution.notifier.add(self._change)

# inform model source data has changed
self._change()

@property
def atomic_data(self):
return self._atomic_data
Expand All @@ -83,7 +101,7 @@ cdef class BeamModel:
# inform model source data has changed
self._change()

cpdef Spectrum emission(self, Point3D beam_point, Point3D plasma_point, Vector3D beam_direction, Vector3D observation_direction, Spectrum spectrum):
cpdef Spectrum emission(self, Point3D beam_point, Point3D plasma_point, Vector3D observation_direction, Spectrum spectrum):
"""
Calculate the emission for a point on the beam in a specified direction.

Expand Down Expand Up @@ -115,23 +133,36 @@ cdef class BeamModel:

cdef class BeamAttenuator:

def __init__(self, Beam beam=None, Plasma plasma=None, AtomicData atomic_data=None):
def __init__(self, BeamDistribution distribution=None, Plasma plasma=None, AtomicData atomic_data=None):

# must notify beam if the attenuator properties change, affecting the density values
# must notify distribution if the attenuator properties change, affecting the density values
self.notifier = Notifier()

# configure
self._beam = beam
self._distribution = distribution
self._plasma = plasma
self._atomic_data = atomic_data
self._transform = AffineMatrix3D()
self._transform_inv = AffineMatrix3D()


# setup property change notifications for plasma
if self._plasma:
self._plasma.notifier.add(self._change)

# setup property change notifications for beam
if self._beam:
self._beam.notifier.add(self._change)
# setup property change notifications for distribution
if self._distribution:
self._distribution.notifier.add(self._change)

@property
def transform(self):
return self._transform

@transform.setter
def transform(self, AffineMatrix3D value):
self._transform = value
self._transform_inv = value.inverse()
self._change()

@property
def plasma(self):
Expand All @@ -152,19 +183,19 @@ cdef class BeamAttenuator:
self._change()

@property
def beam(self):
return self._beam
def distribution(self):
return self._distribution

@beam.setter
def beam(self, Beam value not None):
@distribution.setter
def distribution(self, BeamDistribution value not None):

# disconnect from previous beam's notifications
if self._beam:
self._beam.notifier.remove(self._change)
if self._distribution:
self._distribution.notifier.remove(self._change)

# attach to beam to inform model of changes to beam properties
self._beam = value
self._beam.notifier.add(self._change)
# attach to distribution to inform model of changes to distribution properties
self._distribution = value
self._distribution.notifier.add(self._change)

# inform model source data has changed
self._change()
Expand Down
Loading