From 7961841bfb8484653021c625d54b37b45f11c375 Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:44:01 +0200 Subject: [PATCH 1/7] Fix documentation typos --- src/elli/materials.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index a116d096..1d3c51bc 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -313,7 +313,7 @@ class VCAMaterial(MixtureMaterial): * :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, * :math:`\varepsilon_h` is the permittivity of the host mixture material, * :math:`\varepsilon_g` is the permittivity of the guest mixture material and - * :math:`f` is the volume fraction of material a in the guest material. + * :math:`f` is the volume fraction of the guest in the host material. """ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: @@ -346,7 +346,7 @@ class LooyengaEMA(MixtureMaterial): * :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, * :math:`\varepsilon_h` is the permittivity of the host mixture material, * :math:`\varepsilon_g` is the permittivity of the guest mixture material and - * :math:`f` is the volume fraction of material a in the guest material. + * :math:`f` is the volume fraction of the guest in the host material. References: Looyenga, H. (1965). Physica, 31(3), 401–406. @@ -384,7 +384,7 @@ class MaxwellGarnettEMA(MixtureMaterial): * :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, * :math:`\varepsilon_h` is the permittivity of the host mixture material, * :math:`\varepsilon_g` is the permittivity of the guest mixture material and - * :math:`f` is the volume fraction of material a in the guest material. + * :math:`f` is the volume fraction of the guest in the host material. """ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: @@ -420,14 +420,14 @@ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArr class BruggemanEMA(MixtureMaterial): r"""Mixture Material approximated with the Bruggeman formula - for spherical inclusions. + for isotropic spherical inclusions. Returns one of the two analytical solutions to this quadratic equation: .. math:: 2 \varepsilon_\text{eff}^2 + - \varepsilon_\text{eff} [(3f - 2) \varepsilon_a - + (1 - 3f)\varepsilon_b] - \varepsilon_a \cdot \varepsilon_b = 0 + [(3f - 2) \varepsilon_a + (1 - 3f)\varepsilon_b] \varepsilon_\text{eff} + - \varepsilon_a \cdot \varepsilon_b = 0 where :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, :math:`\varepsilon_a` is the permittivity of the first mixture material, From d148ad1eb66c7ac3138abd967bda7b29273e6de3 Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:44:26 +0200 Subject: [PATCH 2/7] Correct faulty comparison --- src/elli/materials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index 1d3c51bc..a3f30f62 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -542,7 +542,7 @@ def zeta(z): return np.where( np.logical_and( - np.abs(zeta_root1 <= 1), + np.abs(zeta_root1) <= 1, zeta_root1.imag >= np.imag((zeta_1 + zeta_2) / 2), ), root1[mask_general], From 264bf7a808853a8845b95e707d28fb63b44045b6 Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:45:45 +0200 Subject: [PATCH 3/7] Implement Rouseel-Vanhellemont-Meas algorithm --- src/elli/materials.py | 51 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index a3f30f62..4f91630f 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -31,7 +31,7 @@ import numpy as np import numpy.typing as npt -from numpy.lib.scimath import sqrt +from numpy.lib.scimath import sqrt, power from .dispersions.base_dispersion import BaseDispersion @@ -434,6 +434,55 @@ class BruggemanEMA(MixtureMaterial): :math:`\varepsilon_b` is the permittivity of the second mixture material and :math:`f` is the volume fraction of material a in the material b. + References: + * Ph.J. Rouseel; J. Vanhellemont; H.E. Maes. (1993) Thin Solid Films, 234, 423-427 + """ + + def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: + """Gets the permittivity tensor of the material for wavelength 'lbda', + while overwriting the set fraction. + + Args: + lbda (npt.ArrayLike): Single value or array of wavelengths (in nm). + fraction (float): Fraction of the guest material used for evaluation. (Range 0 - 1). + + Returns: + npt.NDArray: Permittivity tensor. + """ + e_h = self.host_material.get_tensor(lbda) + e_g = self.guest_material.get_tensor(lbda) + f = fraction + + mask_equal = np.nonzero(np.equal(e_h, e_g)) + mask_different = np.nonzero(np.not_equal(e_h, e_g)) + + p = sqrt(e_h[mask_different] / e_g[mask_different]) + b = 0.25 * ((3 * f - 1) * (1 / p - p) + p) + z = b + sqrt(b**2 + 0.5) + + e_mix = np.full_like(e_h, np.nan) + e_mix[mask_equal] = e_h[mask_equal] + e_mix[mask_different] = z * sqrt(e_h[mask_different] * e_g[mask_different]) + + return e_mix + + +class BruggemanJanssonEMA(MixtureMaterial): + r"""Mixture Material approximated with the Bruggeman formula + for isotropic spherical inclusions. + + Returns one of the two analytical solutions to this quadratic equation: + + .. math:: + 2 \varepsilon_\text{eff}^2 + + [(3f - 2) \varepsilon_a + (1 - 3f)\varepsilon_b] \varepsilon_\text{eff} + - \varepsilon_a \cdot \varepsilon_b = 0 + + where :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, + :math:`\varepsilon_a` is the permittivity of the first mixture material, + :math:`\varepsilon_b` is the permittivity of the second mixture material + and :math:`f` is the volume fraction of material a in the material b. + References: * Josef Humlicek in Ellipsometry at the Nanoscale, Springer-Verlag Berlin Heidelberg, 2013 """ From a1c11a16c3725d8b74e0eaaf4add15147c552017 Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Tue, 18 Jun 2024 23:18:43 +0200 Subject: [PATCH 4/7] Fix RVM algorithm --- src/elli/materials.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index 4f91630f..0faa13de 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -456,13 +456,15 @@ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArr mask_equal = np.nonzero(np.equal(e_h, e_g)) mask_different = np.nonzero(np.not_equal(e_h, e_g)) - p = sqrt(e_h[mask_different] / e_g[mask_different]) + p = sqrt(e_h[mask_different]) / sqrt(e_g[mask_different]) b = 0.25 * ((3 * f - 1) * (1 / p - p) + p) - z = b + sqrt(b**2 + 0.5) + z = b + sqrt(power(b, 2) + 0.5) e_mix = np.full_like(e_h, np.nan) e_mix[mask_equal] = e_h[mask_equal] - e_mix[mask_different] = z * sqrt(e_h[mask_different] * e_g[mask_different]) + e_mix[mask_different] = ( + z * sqrt(e_h[mask_different]) * sqrt(e_g[mask_different]) + ) return e_mix From f45fe08f92fa93df0ded281ed2784a7971c64d4f Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Tue, 18 Jun 2024 23:24:26 +0200 Subject: [PATCH 5/7] Disable Jansson code for now --- src/elli/materials.py | 276 +++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 138 deletions(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index 0faa13de..5a2612e7 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -469,141 +469,141 @@ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArr return e_mix -class BruggemanJanssonEMA(MixtureMaterial): - r"""Mixture Material approximated with the Bruggeman formula - for isotropic spherical inclusions. - - Returns one of the two analytical solutions to this quadratic equation: - - .. math:: - 2 \varepsilon_\text{eff}^2 + - [(3f - 2) \varepsilon_a + (1 - 3f)\varepsilon_b] \varepsilon_\text{eff} - - \varepsilon_a \cdot \varepsilon_b = 0 - - where :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, - :math:`\varepsilon_a` is the permittivity of the first mixture material, - :math:`\varepsilon_b` is the permittivity of the second mixture material - and :math:`f` is the volume fraction of material a in the material b. - - References: - * Josef Humlicek in Ellipsometry at the Nanoscale, Springer-Verlag Berlin Heidelberg, 2013 - """ - - def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: - """Gets the permittivity tensor of the material for wavelength 'lbda', - while overwriting the set fraction. - - Args: - lbda (npt.ArrayLike): Single value or array of wavelengths (in nm). - fraction (float): Fraction of the guest material used for evaluation. (Range 0 - 1). - - Returns: - npt.NDArray: Permittivity tensor. - """ - e_h = self.host_material.get_tensor(lbda) - e_g = self.guest_material.get_tensor(lbda) - f = fraction - - # fmt: off - root1 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 - sqrt( - 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + - 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 - root2 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 + sqrt( - 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + - 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 - # fmt: on - - return self.jansson_algorithm(e_h, e_g, root1, root2) - - @staticmethod - def jansson_algorithm( - e_h: npt.ArrayLike, - e_g: npt.ArrayLike, - root1: npt.ArrayLike, - root2: npt.ArrayLike, - ): - """Use the algorithm proposed by Jansson and Arwin to find the correct root of - the solution to the Bruggeman formula. - - References: - * Jansson R. , Arwin H. (1994) Optics Communications, 106, 4-6, 133-138, - https://doi.org/10.1016/0030-4018(94)90309-3. - - Args: - e_h (npt.ArrayLike): Dielectric tensor of host material. - e_g (npt.ArrayLike): Dielectric tensor of host material. - root1 (npt.ArrayLike): Solution 1 for dielectric tensor of mixture. - root2 (npt.ArrayLike): Solution 2 for dielectric tensor of mixture. - - Returns: - npt.NDArray: Physically correct permittivity tensor for the mixture. - """ - - # Catch calculation warnings - old_settings = np.geterr() - np.seterr(invalid="ignore", divide="ignore") - - z0 = ( - e_h - * e_g - * (np.conj(e_h) - np.conj(e_g)) - / (np.conj(e_h) * e_g - e_h * np.conj(e_g)) - ) - scaling_factor = np.conj(e_g - e_h) / np.abs(e_g - e_h) - - # Reset numpy settings - np.seterr(**old_settings) - - # Find indices for the three cases - mask_equal = np.nonzero(np.isnan(z0.real)) - mask_straight = np.nonzero(np.isinf(z0.real)) - mask_general = np.nonzero( - np.logical_not(np.logical_or(np.isnan(z0.real), np.isinf(z0.real))) - ) - - def check_straight_line(): - def w(z): - return np.where( - z0[mask_straight].real == np.inf, - z[mask_straight] * scaling_factor[mask_straight], - -1 * z[mask_straight] * scaling_factor[mask_straight], - ) - - return np.where( - np.logical_and( - w(e_h).real < w(root1).real, w(root1).real < w(e_g).real - ), - root1[mask_straight], - root2[mask_straight], - ) - - def check_general_case(): - def zeta(z): - return ( - (z[mask_general] - z0[mask_general]) - / np.abs(z0[mask_general]) - * scaling_factor[mask_general] - ) - - zeta_1, zeta_2, zeta_root1 = np.where( - np.logical_and(zeta(e_h).imag > 0, zeta(e_g).imag > 0), - (zeta(e_h), zeta(e_g), zeta(root1)), - (-zeta(e_h), -zeta(e_g), -zeta(root1)), - ) - - return np.where( - np.logical_and( - np.abs(zeta_root1) <= 1, - zeta_root1.imag >= np.imag((zeta_1 + zeta_2) / 2), - ), - root1[mask_general], - root2[mask_general], - ) - - # Create new array and write correct values into it - correct_root = np.full_like(e_h, np.nan) - correct_root[mask_equal] = e_h[mask_equal] - correct_root[mask_straight] = check_straight_line() - correct_root[mask_general] = check_general_case() - - return correct_root +# class BruggemanJanssonEMA(MixtureMaterial): +# r"""Mixture Material approximated with the Bruggeman formula +# for isotropic spherical inclusions. + +# Returns one of the two analytical solutions to this quadratic equation: + +# .. math:: +# 2 \varepsilon_\text{eff}^2 + +# [(3f - 2) \varepsilon_a + (1 - 3f)\varepsilon_b] \varepsilon_\text{eff} +# - \varepsilon_a \cdot \varepsilon_b = 0 + +# where :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, +# :math:`\varepsilon_a` is the permittivity of the first mixture material, +# :math:`\varepsilon_b` is the permittivity of the second mixture material +# and :math:`f` is the volume fraction of material a in the material b. + +# References: +# * Josef Humlicek in Ellipsometry at the Nanoscale, Springer-Verlag Berlin Heidelberg, 2013 +# """ + +# def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: +# """Gets the permittivity tensor of the material for wavelength 'lbda', +# while overwriting the set fraction. + +# Args: +# lbda (npt.ArrayLike): Single value or array of wavelengths (in nm). +# fraction (float): Fraction of the guest material used for evaluation. (Range 0 - 1). + +# Returns: +# npt.NDArray: Permittivity tensor. +# """ +# e_h = self.host_material.get_tensor(lbda) +# e_g = self.guest_material.get_tensor(lbda) +# f = fraction + +# # fmt: off +# root1 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 - sqrt( +# 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + +# 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 +# root2 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 + sqrt( +# 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + +# 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 +# # fmt: on + +# return self.jansson_algorithm(e_h, e_g, root1, root2) + +# @staticmethod +# def jansson_algorithm( +# e_h: npt.ArrayLike, +# e_g: npt.ArrayLike, +# root1: npt.ArrayLike, +# root2: npt.ArrayLike, +# ): +# """Use the algorithm proposed by Jansson and Arwin to find the correct root of +# the solution to the Bruggeman formula. + +# References: +# * Jansson R. , Arwin H. (1994) Optics Communications, 106, 4-6, 133-138, +# https://doi.org/10.1016/0030-4018(94)90309-3. + +# Args: +# e_h (npt.ArrayLike): Dielectric tensor of host material. +# e_g (npt.ArrayLike): Dielectric tensor of host material. +# root1 (npt.ArrayLike): Solution 1 for dielectric tensor of mixture. +# root2 (npt.ArrayLike): Solution 2 for dielectric tensor of mixture. + +# Returns: +# npt.NDArray: Physically correct permittivity tensor for the mixture. +# """ + +# # Catch calculation warnings +# old_settings = np.geterr() +# np.seterr(invalid="ignore", divide="ignore") + +# z0 = ( +# e_h +# * e_g +# * (np.conj(e_h) - np.conj(e_g)) +# / (np.conj(e_h) * e_g - e_h * np.conj(e_g)) +# ) +# scaling_factor = np.conj(e_g - e_h) / np.abs(e_g - e_h) + +# # Reset numpy settings +# np.seterr(**old_settings) + +# # Find indices for the three cases +# mask_equal = np.nonzero(np.isnan(z0.real)) +# mask_straight = np.nonzero(np.isinf(z0.real)) +# mask_general = np.nonzero( +# np.logical_not(np.logical_or(np.isnan(z0.real), np.isinf(z0.real))) +# ) + +# def check_straight_line(): +# def w(z): +# return np.where( +# z0[mask_straight].real == np.inf, +# z[mask_straight] * scaling_factor[mask_straight], +# -1 * z[mask_straight] * scaling_factor[mask_straight], +# ) + +# return np.where( +# np.logical_and( +# w(e_h).real < w(root1).real, w(root1).real < w(e_g).real +# ), +# root1[mask_straight], +# root2[mask_straight], +# ) + +# def check_general_case(): +# def zeta(z): +# return ( +# (z[mask_general] - z0[mask_general]) +# / np.abs(z0[mask_general]) +# * scaling_factor[mask_general] +# ) + +# zeta_1, zeta_2, zeta_root1 = np.where( +# np.logical_and(zeta(e_h).imag > 0, zeta(e_g).imag > 0), +# (zeta(e_h), zeta(e_g), zeta(root1)), +# (-zeta(e_h), -zeta(e_g), -zeta(root1)), +# ) + +# return np.where( +# np.logical_and( +# np.abs(zeta_root1) <= 1, +# zeta_root1.imag >= np.imag((zeta_1 + zeta_2) / 2), +# ), +# root1[mask_general], +# root2[mask_general], +# ) + +# # Create new array and write correct values into it +# correct_root = np.full_like(e_h, np.nan) +# correct_root[mask_equal] = e_h[mask_equal] +# correct_root[mask_straight] = check_straight_line() +# correct_root[mask_general] = check_general_case() + +# return correct_root From e99d3a195e50306e2174b156095f20151650ca8b Mon Sep 17 00:00:00 2001 From: MarJMue <49639740+MarJMue@users.noreply.github.com> Date: Tue, 18 Jun 2024 23:25:07 +0200 Subject: [PATCH 6/7] Include new tests for mixture materials --- tests/test_materials.py | 17 ++---------- tests/test_mixture_models.py | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 tests/test_mixture_models.py diff --git a/tests/test_materials.py b/tests/test_materials.py index d8df4e06..340d604a 100644 --- a/tests/test_materials.py +++ b/tests/test_materials.py @@ -1,8 +1,7 @@ -"""Tests for the result class""" +"""Tests for the materials classes""" -import numpy as np -from pytest import raises import elli +from pytest import raises class TestMaterials: @@ -25,8 +24,6 @@ def test_materials_typeguard(self): with raises(TypeError): elli.BiaxialMaterial(self.disp, self.disp, 23) - def test_mixture_materials(self): - """Basic mixture material tests""" with raises(TypeError): elli.VCAMaterial(self.mat, self.disp, 0.5) @@ -35,13 +32,3 @@ def test_mixture_materials(self): with raises(ValueError): elli.VCAMaterial(self.mat, self.mat, 10) - - vca = elli.VCAMaterial(self.mat2, self.mat, 0.1) - looyenga = elli.LooyengaEMA(self.mat2, self.mat, 0.1) - mg = elli.MaxwellGarnettEMA(self.mat2, self.mat, 0.1) - brug = elli.BruggemanEMA(self.mat2, self.mat, 0.1) - - for mixture in [looyenga, mg, brug]: - np.testing.assert_array_almost_equal( - mixture.get_tensor(500), vca.get_tensor(500), decimal=-1 - ) diff --git a/tests/test_mixture_models.py b/tests/test_mixture_models.py new file mode 100644 index 00000000..8418c8ff --- /dev/null +++ b/tests/test_mixture_models.py @@ -0,0 +1,52 @@ +"""Tests for the different mixture models""" + +import pytest +import elli +import numpy as np + + +material_list = [ + ("Si", "Aspnes"), + ("GaAs", "Aspnes"), + ("SiO2", "Malitson"), + ("CaF2", "Li"), + ("Rh", "Weaver"), + ("MoS2", "Song-1L"), +] + + +@pytest.fixture +def RII(): + RII = elli.db.RII() + return RII + + +@pytest.mark.parametrize( + "host_book, host_page", + material_list, +) +@pytest.mark.parametrize( + "guest_book, guest_page", + material_list, +) +@pytest.mark.parametrize( + "EMA", + [ + # elli.VCAMaterial, + elli.LooyengaEMA, + elli.MaxwellGarnettEMA, + # elli.BruggemanJanssonEMA, + ], +) +def test_mixture_models(host_book, host_page, guest_book, guest_page, EMA, RII): + host_mat = RII.get_mat(host_book, host_page) + guest_mat = RII.get_mat(guest_book, guest_page) + + lbda = np.arange(250, 800, 25) + + np.testing.assert_allclose( + elli.BruggemanEMA(host_mat, guest_mat, 0.1).get_tensor(lbda), + EMA(host_mat, guest_mat, 0.1).get_tensor(lbda), + rtol=0.5, + atol=0.5 + 0.5j, + ) From d0c458ac0b84581ef0d39f5d41f8f092e94f51a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20M=C3=BCller?= <49639740+MarJMue@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:37:53 +0200 Subject: [PATCH 7/7] Remove commented-out code --- src/elli/materials.py | 140 ----------------------------------- tests/test_mixture_models.py | 2 - 2 files changed, 142 deletions(-) diff --git a/src/elli/materials.py b/src/elli/materials.py index 5a2612e7..868151e2 100755 --- a/src/elli/materials.py +++ b/src/elli/materials.py @@ -467,143 +467,3 @@ def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArr ) return e_mix - - -# class BruggemanJanssonEMA(MixtureMaterial): -# r"""Mixture Material approximated with the Bruggeman formula -# for isotropic spherical inclusions. - -# Returns one of the two analytical solutions to this quadratic equation: - -# .. math:: -# 2 \varepsilon_\text{eff}^2 + -# [(3f - 2) \varepsilon_a + (1 - 3f)\varepsilon_b] \varepsilon_\text{eff} -# - \varepsilon_a \cdot \varepsilon_b = 0 - -# where :math:`\varepsilon_\text{eff}` is the effective permittivity of host/mixture material, -# :math:`\varepsilon_a` is the permittivity of the first mixture material, -# :math:`\varepsilon_b` is the permittivity of the second mixture material -# and :math:`f` is the volume fraction of material a in the material b. - -# References: -# * Josef Humlicek in Ellipsometry at the Nanoscale, Springer-Verlag Berlin Heidelberg, 2013 -# """ - -# def get_tensor_fraction(self, lbda: npt.ArrayLike, fraction: float) -> npt.NDArray: -# """Gets the permittivity tensor of the material for wavelength 'lbda', -# while overwriting the set fraction. - -# Args: -# lbda (npt.ArrayLike): Single value or array of wavelengths (in nm). -# fraction (float): Fraction of the guest material used for evaluation. (Range 0 - 1). - -# Returns: -# npt.NDArray: Permittivity tensor. -# """ -# e_h = self.host_material.get_tensor(lbda) -# e_g = self.guest_material.get_tensor(lbda) -# f = fraction - -# # fmt: off -# root1 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 - sqrt( -# 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + -# 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 -# root2 = 3*e_g*f/4 - e_g/4 - 3*e_h*f/4 + e_h/2 + sqrt( -# 9*e_g**2*f**2 - 6*e_g**2*f + e_g**2 - 18*e_g*e_h*f**2 + -# 18*e_g*e_h*f + 4*e_g*e_h + 9*e_h**2*f**2 - 12*e_h**2*f + 4*e_h**2)/4 -# # fmt: on - -# return self.jansson_algorithm(e_h, e_g, root1, root2) - -# @staticmethod -# def jansson_algorithm( -# e_h: npt.ArrayLike, -# e_g: npt.ArrayLike, -# root1: npt.ArrayLike, -# root2: npt.ArrayLike, -# ): -# """Use the algorithm proposed by Jansson and Arwin to find the correct root of -# the solution to the Bruggeman formula. - -# References: -# * Jansson R. , Arwin H. (1994) Optics Communications, 106, 4-6, 133-138, -# https://doi.org/10.1016/0030-4018(94)90309-3. - -# Args: -# e_h (npt.ArrayLike): Dielectric tensor of host material. -# e_g (npt.ArrayLike): Dielectric tensor of host material. -# root1 (npt.ArrayLike): Solution 1 for dielectric tensor of mixture. -# root2 (npt.ArrayLike): Solution 2 for dielectric tensor of mixture. - -# Returns: -# npt.NDArray: Physically correct permittivity tensor for the mixture. -# """ - -# # Catch calculation warnings -# old_settings = np.geterr() -# np.seterr(invalid="ignore", divide="ignore") - -# z0 = ( -# e_h -# * e_g -# * (np.conj(e_h) - np.conj(e_g)) -# / (np.conj(e_h) * e_g - e_h * np.conj(e_g)) -# ) -# scaling_factor = np.conj(e_g - e_h) / np.abs(e_g - e_h) - -# # Reset numpy settings -# np.seterr(**old_settings) - -# # Find indices for the three cases -# mask_equal = np.nonzero(np.isnan(z0.real)) -# mask_straight = np.nonzero(np.isinf(z0.real)) -# mask_general = np.nonzero( -# np.logical_not(np.logical_or(np.isnan(z0.real), np.isinf(z0.real))) -# ) - -# def check_straight_line(): -# def w(z): -# return np.where( -# z0[mask_straight].real == np.inf, -# z[mask_straight] * scaling_factor[mask_straight], -# -1 * z[mask_straight] * scaling_factor[mask_straight], -# ) - -# return np.where( -# np.logical_and( -# w(e_h).real < w(root1).real, w(root1).real < w(e_g).real -# ), -# root1[mask_straight], -# root2[mask_straight], -# ) - -# def check_general_case(): -# def zeta(z): -# return ( -# (z[mask_general] - z0[mask_general]) -# / np.abs(z0[mask_general]) -# * scaling_factor[mask_general] -# ) - -# zeta_1, zeta_2, zeta_root1 = np.where( -# np.logical_and(zeta(e_h).imag > 0, zeta(e_g).imag > 0), -# (zeta(e_h), zeta(e_g), zeta(root1)), -# (-zeta(e_h), -zeta(e_g), -zeta(root1)), -# ) - -# return np.where( -# np.logical_and( -# np.abs(zeta_root1) <= 1, -# zeta_root1.imag >= np.imag((zeta_1 + zeta_2) / 2), -# ), -# root1[mask_general], -# root2[mask_general], -# ) - -# # Create new array and write correct values into it -# correct_root = np.full_like(e_h, np.nan) -# correct_root[mask_equal] = e_h[mask_equal] -# correct_root[mask_straight] = check_straight_line() -# correct_root[mask_general] = check_general_case() - -# return correct_root diff --git a/tests/test_mixture_models.py b/tests/test_mixture_models.py index 8418c8ff..1ac6a251 100644 --- a/tests/test_mixture_models.py +++ b/tests/test_mixture_models.py @@ -32,10 +32,8 @@ def RII(): @pytest.mark.parametrize( "EMA", [ - # elli.VCAMaterial, elli.LooyengaEMA, elli.MaxwellGarnettEMA, - # elli.BruggemanJanssonEMA, ], ) def test_mixture_models(host_book, host_page, guest_book, guest_page, EMA, RII):