Skip to content
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

DRT of EIS data with inductive loop #20

Open
grgrgruen opened this issue Oct 31, 2024 · 6 comments
Open

DRT of EIS data with inductive loop #20

grgrgruen opened this issue Oct 31, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@grgrgruen
Copy link

grgrgruen commented Oct 31, 2024

  • DearEIS version: 5.0.1
  • Python version: 3.12
  • OS: Windows

We have EIS data with inductive loop and we try to calculate DRT of the EIS data. I use the method m(RQ)fit. Negative RC or RQ elements are possible, but if I try to calculate the DRT then I get different error messages like down below.

Is there any quick solution for them, so I can change the code and work further?

Thank you for your support!

Error messages:

An exception has been raised! The very end of the traceback (see below) may offer a hint on how to solve the cause for the error that just occurred. If it doesn't, then please copy the traceback to your clipboard and include it in a bug report. Bug reports can be submitted at github.com/vyrjana/DearEIS/issues.

Traceback (most recent call last):
File "\deareis\signals.py", line 185, in emit
func(*args, **kwargs)
File "\deareis\program\drt.py", line 107, in perform_drt
drt: DRTResult = api.calculate_drt(
^^^^^^^^^^^^^^^^^^
File "\deareis\api\drt.py", line 87, in calculate_drt
result: _pyimpspec.DRTResult = pyimpspec.calculate_drt(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "\pyimpspec\analysis\drt_init
.py", line 90, in calculate_drt
return {
^
File "\pyimpspec\analysis\drt\mrq_fit.py", line 577, in calculate_drt_mrq_fit
tau, gamma = _calculate_tau_gamma(
^^^^^^^^^^^^^^^^^^^^^
File "\pyimpspec\analysis\drt\mrq_fit.py", line 420, in _calculate_tau_gamma
gamma += R / (W * sqrt(pi)) * exp(-((ln(tau / tau_0) / W) ** 2))
numpy._core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('complex128') to dtype('float64') with casting rule 'same_kind'


An exception has been raised! The very end of the traceback (see below) may offer a hint on how to solve the cause for the error that just occurred. If it doesn't, then please copy the traceback to your clipboard and include it in a bug report. Bug reports can be submitted at github.com/vyrjana/DearEIS/issues.

Traceback (most recent call last):
File "\deareis\signals.py", line 185, in emit
func(*args, **kwargs)
File "\deareis\program\drt.py", line 107, in perform_drt
drt: DRTResult = api.calculate_drt(
^^^^^^^^^^^^^^^^^^
File "\deareis\api\drt.py", line 87, in calculate_drt
result: _pyimpspec.DRTResult = pyimpspec.calculate_drt(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "\pyimpspec\analysis\drt_init
.py", line 90, in calculate_drt
return {
^
File "\pyimpspec\analysis\drt\mrq_fit.py", line 577, in calculate_drt_mrq_fit
tau, gamma = _calculate_tau_gamma(
^^^^^^^^^^^^^^^^^^^^^
File "\pyimpspec\analysis\drt\mrq_fit.py", line 418, in _calculate_tau_gamma
tau_0: float = (R * Y) ** (1.0 / n)
~~~~~~~~^~~~~~~~~~~~
OverflowError: (34, 'Result too large')


\pyimpspec\analysis\drt\mrq_fit.py:420: RuntimeWarning: invalid value encountered in log
gamma += R / (W * sqrt(pi)) * exp(-((ln(tau / tau_0) / W) ** 2))

@grgrgruen grgrgruen added the bug Something isn't working label Oct 31, 2024
@vyrjana
Copy link
Owner

vyrjana commented Nov 2, 2024

I think there are two scenarios that could have caused issues:

  • If R or Y was negative, then tau_0: float = (R * Y) ** (1.0 / n) would have been negative and caused issues on the last line (gamma += R / (W * sqrt(pi)) * exp(-((ln(tau / tau_0) / W) ** 2))) since the logarithm of a negative value is undefined, which will cause NumPy to return a nan (or "not a number") value.
  • If R or Y was negative and the value of n was also less than one, then tau_0: float = (R * Y) ** (1.0 / n) would return a negative complex value instead of a positive float.

I've pushed a commit to the release candidate branch of the upcoming pyimpspec update that makes the m(RQ)-fit implementation support cases where the constant phase element has -1.0 <= n < 0.0 (i.e., when it is behaving like a (modified) inductance). The upcoming update has been on the back burner for a while now, but I will hopefully be able to finish up the update and publish it to PyPI during this weekend. There will also be a minor update to DearEIS to go along with it.

Below is an example where I fitted an R(RQ)(RQ)(RQ) circuit, which had the n parameter of one of the constant phase elements adjusted appropriately, to an impedance spectrum that is based on the following circuit:

R{R=70}(R{R=200}C{C=2.5e-3})(R{R=100}C{C=1e-4})(R{R=50}L{L=3e2})

deareis-resistive-inductive-drt

Here are the fitted values. The red n parameter is simply due to it hitting the upper limit.

deareis-resistive-inductive-fit

@vyrjana
Copy link
Owner

vyrjana commented Nov 3, 2024

Both pyimpspec and DearEIS have been updated.

@grgrgruen
Copy link
Author

DearEIS version: 5.1.0
Python version: 3.12
OS: Windows

Thanks for your rapid response!

I tried it with the updated versions.

If I try to calculate DRT with our measurement data and with this simulated data I don't get any error message but the DRT calculation is empty. I know this simulated data does not make much sense.

I used this simulated date:

[R{R=2.2600E-02/0.0000E+00/inf}(R{R=1.8000E-03/0.0000E+00/inf}C{C=-4.3000E-04/inf/0.0000E+00})(R{R=3.7000E-03/0.0000E+00/inf}Q{Y=5.5000E+01/1.0000E-24/1.0000E+06,n=2.9000E-01/0.0000E+00/1.0000E+00})(R{R=1.1000E-03/0.0000E+00/inf}Q{Y=4.0000E+00/1.0000E-24/1.0000E+06,n=8.1000E-01/0.0000E+00/1.0000E+00})(R{R=1.4000E-03/inf/inf}Q{Y=3.9600E+03/inf/inf,n=-6.9400E-01/-1.0000E+00/-5.0000E-01})]

And it gives a perfect fit but no DRT data, like on the screenshot below. If I copy the DRT data points as CSV, I only get the frequency points and no values in the second column.

What can be the reason for this?

Thank you very much!

image

@vyrjana
Copy link
Owner

vyrjana commented Nov 5, 2024

What is happening is that the parallel RC with the negative capacitance produces a negative time constant (tau_0: float = (R * Y) ** (1.0 / n) in the source code), which results in undefined values (i.e., numpy.nan) when the DRT is calculated since the relevant equations include ln(tau/tau_0).

I'm not familiar with the concept of negative capacitance. Do you have any examples of relevant literature? I tried performing a quick search and I got the impression that "negative capacitance" should be treated as more of a description of the apparent effect that can can be observed rather than as an accurate description of the underlying phenomenon.

Have you been able to validate your experimental data? I ask because both the linear Kramers-Kronig test and Z-HIT have issues reproducing your simulated impedance spectrum (I used the frequency range 1 MHz to 1 mHz, 10 points per decade, and a little bit of added noise (normal distribution with std. dev. equal to 0.01 % of |Z|)). Kramers-Kronig failing to reproduce the high-frequency portion makes sense given that the range of time constants is the reciprocal of the measured angular frequency range with some optional extension/contraction (i.e., a range which would never encompass a negative time constant). Z-HIT is able to reproduce most of the impedance spectrum fairly well except for the high-frequency portion where it instead produces an inductive loop (see the figure below).

simulated-spectrum-zhit

@grgrgruen
Copy link
Author

Unfortunately I may not share our measurement data here, but KK Test shows very small residuals with different test methods. (I attached the screenshot of one of them down below.)

It is not possible to include inductance in m(RQ)fit methode, that's why I used an additional RC element with negative capacitance to fit the high frequent inductance. Maybe I should just mask the part with the high frequent inductance.

Our measurement data look like very similar to those in this publication and they could calculate DRT with an equivalent circuit model with four RQ-elements. This is exactly what I try to do with DearEIS. Again in the publication it looks like that the high frequent inductive part is masked.

https://www.sciencedirect.com/science/article/pii/S0378775324013272

In this publication it is discussed about low frequent inductance:

https://www.sciencedirect.com/science/article/pii/S1388248118303084

image

@vyrjana
Copy link
Owner

vyrjana commented Nov 6, 2024

Brinker et al. actually used another DRT method since they discuss the need to select an appropriate Tikhonov regularization parameter (subsection 2.10), which is not a parameter in the m(RQ)-fit method. They then used the obtained DRT, and the insight it provided, to construct the equivalent circuit model (ECM, subsection 2.11). The DRT method is described here (ref. 44) by Ivers-Tiffée and Weber and then it was adapted here (ref. 17) by Schiefer et al. to handle the low-frequency inductive behavior.

The updated implementation of m(RQ)-fit can handle resistive-inductive (RQ) if you set n < 0.0. In that case, the resistance and "inductance" (in quotes since the Yparameter is expressed in terms of of S*s^n) values would be positive. However, it seems that Klotz and Schiefer et al. used ECMs where the low-frequency inductive loop was modeled as an (RQ) with both negative resistance and negative "capacitance", which would result in a positive time constant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants