Open grgrgruen opened 3 weeks ago
I think there are two scenarios that could have caused issues:
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.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})
Here are the fitted values. The red n
parameter is simply due to it hitting the upper limit.
Both pyimpspec and DearEIS have been updated.
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!
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).
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
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 Y
parameter 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.
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)