permittivity: calculating complex permittivity

Code author: Peter Kraus

Provides functions for calculating complex permittivity from resonance frequencies and quality factors, as well as and various related corrections.

Functions

ftT_correction(f_mnp, temperature, ...[, ...])

Nodal mode correction of resonance frequencies for temperature effects based on Cuenca et al. [Cuenca2017].

QtT_correction(Q_mnp, temperature, ...[, ...])

Nodal mode correction of quality factors for temperature effects, based on Cuenca et al. [Cuenca2017].

Qec_correction(Q_e, eps, Vs, Vc[, output])

The modified calibration method of Chao and Chang.

real_eps(f_s, f_e, Vc, Vs[, cal_slope, ...])

The MCPT equation for the real part of the permittivity.

imag_eps(Q_s, Q_e, Vc, Vs[, cal_slope, ...])

The MCPT equation for the imaginary part of the permittivity.

log_mixing_rule(eps_eff, Vtot, Vs, ...[, output])

Logarithmic mixing rule for permittivity.

emt_lll(eps_r, eps_i[, delta, ms, Vs, rho, ...])

Effective medium theory of Landau-Lifshitz-Loyenga.

[Dube1970]

Dube, D.C. Study of Landau-Lifshitz-Looyenga’s formula for dielectric correlation between powder and bulk Journal of Physics D: Applied Physics 1970, 3, 1648-1652, DOI: https://doi.org/10.1088/0022-3727/3/11/313

[Chen2005a] (1,2)

Chen, L.F., Ong, C.K., Neo, C.P., Varadan, V.V., Varadan, V.K. Resonant-Perturbation Methods in Microwave Electronics, John Wiley & Sons, 2005, Chichester, UK, DOI: https://doi.org/10.1002/0470020466.ch6

[Chao2013a]

Chao, H.-W., Chang, T.-H. A modified calibration method for complex permittivity measurement, Review of Scientific Instruments 2013, 84, 084704, DOI: https://doi.org/10.1063/1.4817635

[Cuenca2017] (1,2,3,4,5,6)

Cuenca, J.A., Slocombe, D.R., Porch, A. Temperature Correction for Cylindrical Cavity Perturbation Measurements, IEEE Transactions on Microwave Theory and Techniques 2017, 65, 2153-2161, DOI: https://doi.org/10.1109/TMTT.2017.2652462

[Cuenca2017c]

Cuenca, J.A., Slocombe, D.R., Porch, A. Corrections to “Temperature Correction for Cylindrical Cavity Perturbation Measurements”, IEEE Transactions on Microwave Theory and Techniques 2017, 65, 5078, DOI: https://doi.org/10.1109/TMTT.2017.2751550

dgpost.transform.permittivity.ftT_correction(f_mnp: ~pint.registry.Quantity, temperature: ~pint.registry.Quantity, f_0n0_ref: ~pint.registry.Quantity, f_mnp_ref: ~pint.registry.Quantity, temperature_ref: ~pint.registry.Quantity, k_err: float = 0.0, alpha_c: ~pint.registry.Quantity = <Quantity(2.3e-05, '1 / kelvin')>, k_0n0: ~pint.registry.Quantity = <Quantity(0.0, '1 / kelvin')>, k_mnp: ~pint.registry.Quantity = <Quantity(0.0, '1 / kelvin')>, output: str = 'f_e, P') dict[str, Quantity]

Nodal mode correction of resonance frequencies for temperature effects based on Cuenca et al. [Cuenca2017]

The nodal mode correction exploits the fact that the normalized frequency shift \(\frac{f(T) - f(T_\text{ref})}{f(T_\text{ref})}\) over a shift in temperature \(\Delta T = T - T_\text{ref}\) is approximately constant, regardless of the mode studied.

The correction also exploits the fact that the temperature-dependency of the frequency is proportional mainly to the linear thermal expansion coefficient \(\alpha_c\):

\[\frac{f_{mnp}(T) - f_{mnp}(T_\text{ref})}{f_{mnp}(T_\text{ref})} \approx - (\alpha_c + \kappa_{mnp}) \Delta T + \kappa_{err}\]

This makes it possible to approximate the behaviour of the frequency of the sample mode from the behaviour of a nodal mode (i.e. a mode not affected by the sample). This is useful, as the permittivity is related to the shift of the frequency of the sample mode upon insertion of the sample, therefore a proxy for the measurement of the empty cavity is required for operando measurements. This proxy can be calculated from the behaviour of the nodal mode and a few reference & calibration values.

For example, for the TM020 and TM210 modes (sample and nodal modes, respectively):

\[\begin{split}f_\text{020,e,p}(t, T) && \approx f_\text{020,e}(0, T_\text{ref}) \left(1 + \frac{f_\text{210,s}(t, T) - f_\text{210,e}(0, T_\text{ref})} {f_\text{210,e}(0, T_\text{ref})}\right) \\ && + (\kappa_\text{err} - (\alpha_c + \kappa_\text{210})\Delta T) f_\text{210,e}(0, T_\text{ref}) \\ && - (\kappa_\text{err} - (\alpha_c + \kappa_\text{020})\Delta T) f_\text{020,e}(0, T_\text{ref})\end{split}\]
Parameters:
  • f_mnp – The frequency of the nodal mode, \(f_{mnp}(t, T)\). Defaults to Hz.

  • temperature – The temperature \(T\). Defaults to °C.

  • f_0n0_ref – The reference frequency of the sample mode, \(f_{0n0}(0, T_\text{ref})\). Defaults to Hz.

  • f_mnp_ref – The reference frequency of the nodal mode, \(f_{mnp}(0, T_\text{ref})\). Defaults to Hz.

  • temperature_ref – The reference temperature \(T_\text{ref}\). Defaults to °C.

  • k_err – The calibration constant \(\kappa_\text{err}\). Defaults to 0.

  • alpha_c – The linear temperature expansion constant, \(\alpha_c\). Defaults to 23×10⁻⁶ K⁻¹, i.e. aluminium.

  • k_0n0 – The calibration constant of the sample mode, \(\kappa_{0n0}\). Defaults to 0 K⁻¹.

  • k_mnp – The calibration constant of the nodal mode, \(\kappa_{mnp}\). Defaults to 0 K⁻¹.

  • output – Name for the output quantity. Defaults to f_e,p.

Returns:

ret – A dictionary containing the proxy for the frequency of the empty cavity, \(f_{e,p}(t, T)\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.QtT_correction(Q_mnp: ~pint.registry.Quantity, temperature: ~pint.registry.Quantity, Q_mnp_ref: ~pint.registry.Quantity, Q_0n0_ref: ~pint.registry.Quantity, temperature_ref: ~pint.registry.Quantity = None, k_err: float = 0.0, beta_c: ~pint.registry.Quantity = <Quantity(0.004, '1 / kelvin')>, alpha_c: ~pint.registry.Quantity = <Quantity(2.3e-05, '1 / kelvin')>, k_0n0: ~pint.registry.Quantity = <Quantity(0.0, '1 / kelvin')>, k_mnp: ~pint.registry.Quantity = <Quantity(0.0, '1 / kelvin')>, output: str = 'Q_e, P') dict[str, Quantity]

Nodal mode correction of quality factors for temperature effects, based on Cuenca et al. [Cuenca2017]

Similar to ftT_correction(). However, here the temperature effects are modelled using both linear expansion coefficient \(\alpha_c\), as well as coefficient of resistivity \(\beta_c\):

\[\frac{Q_{mnp}(T) - Q_{mnp}(T_\text{ref})}{Q_{mnp}(T_\text{ref})} \approx (\beta_c - 3\alpha_c + \kappa_{mnp}) \Delta T + \kappa_{err}\]

For example, for the TM020 and TM210 modes (sample and nodal modes, respectively):

\[\begin{split}Q_\text{020,e,p}(t, T) && \approx Q_\text{020,e}(0, T_\text{ref}) \left(1 + \frac{Q_\text{210,s}(t, T) - Q_\text{210,e}(0, T_\text{ref})} {Q_\text{210,e}(0, T_\text{ref})}\right) \\ && + (\kappa_\text{err} + (\beta_c - 3\alpha_c + \kappa_\text{210})\Delta T) Q_\text{210,e}(0, T_\text{ref}) \\ && - (\kappa_\text{err} + (\beta_c - 3\alpha_c + \kappa_\text{020})\Delta T) Q_\text{020,e}(0, T_\text{ref})\end{split}\]
Parameters:
  • Q_mnp – The quality factor of the nodal mode, \(Q_{mnp}(t, T)\). Unitless.

  • temperature – The temperature \(T\). Defaults to °C.

  • Q_0n0_ref – The reference quality factor of the sample mode, \(Q_{0n0}(0, T_\text{ref})\). Unitless.

  • Q_mnp_ref – The reference quality factor of the nodal mode, \(Q_{mnp}(0, T_\text{ref})\). Unitless.

  • temperature_ref – The reference temperature \(T_\text{ref}\). Defaults to °C.

  • k_err – The calibration constant \(\kappa_\text{err}\). Defaults to 0.

  • alpha_c – The linear temperature expansion constant, \(\alpha_c\). Defaults to 23×10⁻⁶ K⁻¹, i.e. aluminium.

  • beta_c – The coefficient of resistivity, \(\beta_c\). Defaults to 4×10⁻³ K⁻¹, i.e. aluminium.

  • k_0n0 – The calibration constant of the sample mode, \(\kappa_{0n0}\). Defaults to 0 K⁻¹.

  • k_mnp – The calibration constant of the nodal mode, \(\kappa_{mnp}\). Defaults to 0 K⁻¹.

  • output – Name for the output quantity. Defaults to Q_e,p.

Returns:

ret – A dictionary containing the proxy for the frequency of the empty cavity, \(Q_{e,p}(t, T)\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.Qec_correction(Q_e: Quantity, eps: Quantity, Vs: Quantity, Vc: Quantity, output: str = 'Q_e,c') dict[str, Quantity]

The modified calibration method of Chao and Chang. [Chao2013a]

This formula corrects the quality factor of the empty cavity \(Q_e\) to a corrected value \(Q_{e,c}\) by taking into account the real part of the permittivity \(\varepsilon'\) of the inserted sample, as well as its volume:

\[Q_{e,c} = Q_e \left(1 + (\varepsilon' - 1)\frac{V_s}{V_c}\right)\]
Parameters:
  • Q_e – The quality factor of the empty cavity, \(Q_e\). Unitless.

  • eps – The real part of the permittivity, \(\varepsilon'\). Unitless.

  • Vs – Volume of the sample, \(V_s\). Defaults to mm³.

  • Vc – Volume of the cavity, \(V_c\). Defaults to mm³.

  • output – Name for the output quantity. Defaults to Q_e,c.

Returns:

ret – A dictionary containing the corrected quality factor of the empty cavity, \(Q_{e,c}\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.real_eps(f_s: Quantity, f_e: Quantity, Vc: Quantity, Vs: Quantity, cal_slope: float = 1.0, cal_intercept: float = None, output: str = "eps'") dict[str, Quantity]

The MCPT equation for the real part of the permittivity.

This equation calculates the real part of the permittivity \(\varepsilon'\) from the shift in the resonance frequency of the cavity upon insertion of the sample:

\[\varepsilon' = f_\text{cal}\left(\frac{f_s - f_e}{f_e}\right) \frac{V_c}{V_s} + 1\]

Note that in some literature (e.g. [Chen2005a] or [Cuenca2017]), the denominator in the above equation is specified as \(f_s\). This is not correct, and should be \(f_e\) as in the above equation, see [Cuenca2017c] for details.

In most literature, the calibration function \(f_\text{cal}\) is simply a multiplication by a calibration constant. Here, we allow for specifying a linear calibration function using cal_slope and cal_intercept, which is applied in inverse:

\[f_\text{cal}(y) = \frac{y - \text{cal_intercept}}{\text{cal_slope}}\]
Parameters:
  • f_s – The resonance frequency of the cavity mode with the sample, \(f_s\). Defaults to Hz.

  • f_e – The resonance frequency of the cavity mode without the sample, \(f_e\). Defaults to Hz.

  • Vs – Volume of the sample, \(V_s\). Defaults to mm³.

  • Vc – Volume of the cavity, \(V_c\). Defaults to mm³.

  • cal_slope – The slope of the calibration function.

  • cal_intercept – The intercept of the calibration function.

  • output – Name for the output quantity. Defaults to eps'.

Returns:

ret – A dictionary containing the real part of the permittivity, \(\varepsilon'\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.imag_eps(Q_s: Quantity, Q_e: Quantity, Vc: Quantity, Vs: Quantity, cal_slope: float = 1.0, cal_intercept: float = None, output: str = 'eps"') dict[str, Quantity]

The MCPT equation for the imaginary part of the permittivity. [Chen2005a] [Cuenca2017]

This equation calculates the imaginary part of the permittivity \(\varepsilon''\) from the change of the quality factor of the cavity upon insertion of the sample:

\[\varepsilon'' = f_\text{cal}\left(\frac{1}{Q_s} - \frac{1}{Q_e}\right) \frac{V_c}{V_s}\]

In most literature, the calibration function \(f_\text{cal}\) is simply a multiplication by a calibration constant. Here, we allow for specifying a linear calibration function using cal_slope and cal_intercept, which is applied in inverse:

\[f_\text{cal}(y) = \frac{y - \text{cal_intercept}}{\text{cal_slope}}\]
Parameters:
  • Q_s – The quality factor of the cavity mode with the sample, \(Q_s\). Unitless.

  • Q_e – The quality factor of the cavity mode without the sample, \(Q_e\). Unitless.

  • Vs – Volume of the sample, \(V_s\). Defaults to mm³.

  • Vc – Volume of the cavity, \(V_c\). Defaults to mm³.

  • cal_slope – The slope of the calibration function.

  • cal_intercept – The intercept of the calibration function.

  • output – Name for the output quantity. Defaults to eps".

Returns:

ret – A dictionary containing the real part of the permittivity, \(\varepsilon''\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.log_mixing_rule(eps_eff: Quantity, Vtot: Quantity, Vs: Quantity, permittivities: list[Quantity], volumes: list[Quantity], output: str = 'eps') dict[str, Quantity]

Logarithmic mixing rule for permittivity.

Given an effective permittivity \(\varepsilon_\text{eff}\), and known permittivities and volume fractions of mixture component(s), the unknown permittivity of the sample \(\varepsilon_s\) can be calculated.

The logarithmic mixing rule is used to account for the effects of permittivities of different materials. The effective permittivity is a logarithmic sum, weighted by the volume fractions of the individual materials. For instance, for a sample (\(s\)) supported by a quartz wool (\(qw\)) and enclosed in quartz tubing (\(q\)), the effective permittivity is:

\[\text{log}(\varepsilon_\text{eff}) = \frac{V_s}{V_\text{tot}} \text{log}(\varepsilon_s) + \frac{V_q}{V_\text{tot}} \text{log}(\varepsilon_q) + \frac{V_{qw}}{V_\text{tot}} \text{log}(\varepsilon_{qw})\]

This means, the permittivity of the sample can be calculated if the other parameters are known:

\[\varepsilon_s = \text{exp}\left( \left(\text{log}(\varepsilon_\text{eff}) - \frac{V_q}{V_\text{tot}} \text{log}(\varepsilon_q) - \frac{V_{qw}}{V_\text{tot}} \text{log}(\varepsilon_{qw}) \right)\frac{V_\text{tot}}{V_s} \right)\]

This implementation allows an arbitrary number of components in the mixture, as long as both the permittivity and volume are provided.

Parameters:
  • eps_eff – The effective permittivity, \(\varepsilon_\text{eff}\).

  • Vtot – The total volume of the sample mixture, \(V_\text{tot}\). By default in mm³.

  • Vs – The volume of the sample of unknown permittivity in the mixture, \(V_s\). By default in mm³.

  • permittivities – A list of known permittivities of components in the mixture.

  • volumes – A list of volumes of the components with known permittivities. Note that no comparison checks between the provided volumes, \(V_s\), and \(V_\text{tot}\) are performed.

  • output – The name of the permittivity of the unknown sample, \(\varepsilon_s\)

Returns:

ret – A dictionary containing the permittivity of the unknown sample, \(\varepsilon_s\).

Return type:

dict[str, pint.Quantity]

dgpost.transform.permittivity.emt_lll(eps_r: Quantity, eps_i: Quantity, delta: Quantity = None, ms: Quantity = None, Vs: Quantity = None, rho: Quantity = None, output: str = 'eps_lll') dict[str, Quantity]

Effective medium theory of Landau-Lifshitz-Loyenga. [Dube1970]

This function can be used to convert the complex permittivity of an amount of powdered sample to the permittivity of the solid material, accounting for the packing fraction, assuming the voids are filled by air.

Given the permittivity of a powder, \(\varepsilon_p = \varepsilon_p' - j\varepsilon_p''\), the permittivity of the corresponding solid \(\varepsilon_s\) can be calculated using:

\[\begin{split}\varepsilon_s' &= \left(\frac{\varepsilon_p'^{1/3} - 1}{\delta} + 1\right)^3 \\ \varepsilon_s'' &= \frac{\varepsilon_p''}{\delta}\left(\frac{\varepsilon_s'}{\varepsilon_p'}\right)^{2/3}\end{split}\]

where \(\delta\) is the packing fraction. Note that the equation for \(\varepsilon_s''\) is only valid for samples where \(\varepsilon_p''/\varepsilon_p' >> 1\).

In most cases, the packing fraction can be approximated from bulk bed density and crystallographic density, \(\delta = \frac{m_s/V_s}{\rho}\).

Parameters:
  • eps_r – The real part of the powder permittivity, \(\varepsilon_p'\).

  • eps_i – The imaginary part of the powder permittivity, \(\varepsilon_p''\).

  • delta – The packing fraction, \(\delta\).

  • ms – The mass of the powder sample, \(m_s\), used to calculate \(\delta\). By default in g.

  • Vs – The volume of the powder sample, \(V_s\), used to calculate \(\delta\). By default in cm³.

  • rho – The crystallographic density of the studied material, \(\rho\), used to calculate \(\delta\). By default in g/cm³.

  • output – Prefix for the corrected real and imaginary part of the permittivity.

Returns:

ret – A dictionary containing the real and imaginary parts of the permittivity of the solid, \(\varepsilon_s'\) and \(\varepsilon_s''\).

Return type:

dict[str, pint.Quantity]