Skip to content

Commit

Permalink
Allows reflector to be specified by frequency and polarization
Browse files Browse the repository at this point in the history
  • Loading branch information
mjsandells committed Apr 28, 2020
1 parent b9eef4a commit e8fe307
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 15 deletions.
40 changes: 25 additions & 15 deletions smrt/substrate/reflector.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
# return a perfect absorber / black body.
ref = make_reflector(temperature=260, specular_reflection=0)
# Specify a frequency and polarization dictionary of reflectivity
ref = make_reflector(specular_reflection={(21e9, 'H'): 0.5, (21e9, 'V'): 0.6, (36e9, 'H'): 0.7, (36e9, 'V'): 0.8})
.. note::
the backscatter coefficient argument is not implemented/documented yet.
Expand All @@ -38,13 +41,11 @@
from smrt.core.lib import smrt_matrix



def make_reflector(temperature=None, specular_reflection=None):

""" Construct a reflector or absorber instance.
"""


# create the instance
return Reflector(temperature=temperature, specular_reflection=specular_reflection)
Expand All @@ -58,7 +59,7 @@ class Reflector(Substrate):
def specular_reflection_matrix(self, frequency, eps_1, mu1, npol):

if npol > 2:
raise NotImplementedError("active model is not yet implemented, need modification for the third compunant")
raise NotImplementedError("active model is not yet implemented, need modification for the third component")

if self.backscatter_coefficient is not None:
raise NotImplementedError("backscatter_coefficient to be implemented")
Expand All @@ -67,11 +68,9 @@ def specular_reflection_matrix(self, frequency, eps_1, mu1, npol):
self.specular_reflection = 1

spec_refl_coeff = smrt_matrix.zeros((npol, len(mu1)))
if isinstance(self.specular_reflection, dict): # we have a dictionary with polarization
spec_refl_coeff[0] = self._get_refl(self.specular_reflection['V'], mu1)
spec_refl_coeff[1] = self._get_refl(self.specular_reflection['H'], mu1)
else: # we have a scalar, both polarization are the same
spec_refl_coeff[0] = spec_refl_coeff[1] = self._get_refl(self.specular_reflection, mu1)

spec_refl_coeff[0] = self._get_refl(frequency, 'V', mu1)
spec_refl_coeff[1] = self._get_refl(frequency, 'H', mu1)

return spec_refl_coeff

Expand All @@ -81,18 +80,29 @@ def emissivity_matrix(self, frequency, eps_1, mu1, npol):
self.specular_reflection = 1

if npol > 2:
raise NotImplementedError("active model is not yet implemented, need modification for the third compunant")
raise NotImplementedError("active model is not yet implemented, need modification for the third component")

emissivity = smrt_matrix.zeros((npol, len(mu1)))
if isinstance(self.specular_reflection, dict): # we have a dictionary with polarization
emissivity[0] = 1 - self._get_refl(self.specular_reflection['V'], mu1)
emissivity[1] = 1 - self._get_refl(self.specular_reflection['H'], mu1)
else: # we have a scalar, both polarization are the same
emissivity[0] = emissivity[1] = 1 - self._get_refl(self.specular_reflection, mu1)

emissivity[0] = 1 - self._get_refl(frequency, 'V', mu1)
emissivity[1] = 1 - self._get_refl(frequency, 'H', mu1)

return emissivity

def _get_refl(self, specular_reflection, mu1):
def _get_refl(self, frequency, polarization, mu1):

specular_reflection = self.specular_reflection

# try to get the frequency and/or the polarization if it is a dict
if isinstance(specular_reflection, dict):
for key in [(frequency, polarization), (polarization, frequency), frequency, polarization]:
if key in specular_reflection:
specular_reflection = specular_reflection[key]
break

if isinstance(specular_reflection, dict):
raise SMRTError("The specular_reflection argument must be a scalar or a dict with the frequency and/or polarization as a key. If both, provide frequency and polarization as a tuple key")

if callable(specular_reflection): # we have a function, call it and see what we get
user_refl = specular_reflection(np.arccos(mu1))
if len(user_refl) == len(mu1): # we have only one polarization
Expand Down
49 changes: 49 additions & 0 deletions smrt/substrate/test_reflector.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@


import numpy as np
from nose.tools import raises

from smrt.core.error import SMRTError
from smrt.substrate.reflector import Reflector


Expand Down Expand Up @@ -37,3 +40,49 @@ def refl(theta):

assert np.all(m[0] == 0.5)
assert np.all(m[1] == 0.5)


def test_dict_multifrequency():

refl = Reflector(specular_reflection={21e9: 0.5, 36e9: 0.7})
m1 = refl.specular_reflection_matrix(21e9, None, mu, 2)
m2 = refl.specular_reflection_matrix(36e9, None, mu, 2)

assert np.all(m1[0] == 0.5)
assert np.all(m2[1] == 0.7)


@raises(SMRTError)
def test_missing_frequency_warning():
refl = Reflector(specular_reflection={21e9: 0.5, 36e9: 0.7})
m1 = refl.specular_reflection_matrix(10e9, None, mu, 2)


def test_emissivity_reflectivity_relation():
refl = Reflector(specular_reflection={(21e9, 'H'): 0.5, (21e9, 'V'): 0.6, (36e9, 'H'): 0.7, (36e9, 'V'): 0.8})
r = refl.specular_reflection_matrix(21e9, None, mu, 2)
e = refl.emissivity_matrix(21e9, None, mu, 2)
assert np.all((r + e).values == 1.)


def test_tuple_dict_multifrequency():

refl = Reflector(specular_reflection={(21e9, 'H'): 0.5, (21e9, 'V'): 0.6, (36e9, 'H'): 0.7, (36e9, 'V'): 0.8})
m1 = refl.specular_reflection_matrix(21e9, None, mu, 2)
m2 = refl.specular_reflection_matrix(36e9, None, mu, 2)

assert np.all(m1[1] == 0.5)
assert np.all(m1[0] == 0.6)
assert np.all(m2[1] == 0.7)
assert np.all(m2[0] == 0.8)


def test_inverted_reflector_dictionary():
refl = Reflector(specular_reflection={('H', 21e9): 0.5, ('V', 21e9): 0.6, (36e9, 'H'): 0.7, (36e9, 'V'): 0.8})
m1 = refl.specular_reflection_matrix(21e9, None, mu, 2)
m2 = refl.specular_reflection_matrix(36e9, None, mu, 2)

assert np.all(m1[1] == 0.5)
assert np.all(m1[0] == 0.6)
assert np.all(m2[1] == 0.7)
assert np.all(m2[0] == 0.8)

0 comments on commit e8fe307

Please sign in to comment.