ECSHackWeek / impedance.py

A Python package for working with electrochemical impedance data
MIT License
212 stars 103 forks source link

Nested Parallel Circuit Fit #145

Closed Rblack999 closed 3 years ago

Rblack999 commented 3 years ago

Hello,

Sorry, not really and issue or a bug, but moreso a "usability" request with some circuit fitting. Excellent library you have here and have very much enjoyed using it. untitled

The attached images show a circuit I am using to try and fit the attached data. The fit works well with Biologic Z-fit, but my attempts at obtaining similar results with impedance.py are giving the following results. a) Is my definition of the circuit correct? This may be my error as it is unclear in the documentation how to do nested parallel b) Any experience with a fit just not working, or any other parameters I can adjust to obtain a good fit? As an example, constrain R to fit within a certain range?

Circuit string: R0-p(CPE1,R1-p(CPE2,R2)) Fit: True

Initial guesses: R0 = 1.00e+03 [Ohm] CPE1_0 = 1.00e-05 [Ohm^-1 sec^a] CPE1_1 = 8.00e-01 [] R1 = 1.00e+01 [Ohm] CPE2_0 = 1.00e-05 [Ohm^-1 sec^a] CPE2_1 = 8.00e-01 [] R2 = 1.00e+01 [Ohm]

Fit parameters: R0 = 3.84e+01 (+/- 4.47e-01) [Ohm] CPE1_0 = 2.82e-03 (+/- 1.83e-04) [Ohm^-1 sec^a] CPE1_1 = 8.72e-01 (+/- 2.54e-02) [] R1 = 1.44e+02 (+/- 1.25e+01) [Ohm] CPE2_0 = 9.35e-01 (+/- 4.25e+00) [Ohm^-1 sec^a] CPE2_1 = 1.00e+00 (+/- 7.76e+00) [] R2 = 2.10e+05 (+/- 4.08e-10) [Ohm]

Thanks!

mdmurbach commented 3 years ago

Hi @Rblack999,

Interesting. It looks like your circuit definition is correct.

As you mention, another thing to try is to add bounds to the fit if you know them. You can add bounds to the .fit() method by passing bounds=((0, 0.1, etc.),(np.inf, 1, etc.)) where the first tuple is the lower bound for each of the elements and the second is the upper bound.

MyPyDavid commented 3 years ago

Hi @Rblack999,

I think that you should adjust the initial guesses for this fit to work well, mainly the R0 should not be at 1E3 but around 1E1.

With impedance.py you can easily check out the predicted curve from the initial guesses, like this: circuit = CustomCircuit(initial_guess=[20, 1E-4, 0.7, 20, 1E-03, 0.8, 150], circuit='R0-p(CPE1,R1-p(CPE2,R2))') Z_predict = circuit.predict(np.logspace(4,-1)) fig, ax = plt.subplots(figsize=(5,5)) plot_nyquist(ax, Z_predict, fmt='-')

Try to fit your data again with those guesses for example, it might work even without using bounds.

Rblack999 commented 3 years ago

Fitting with much tighter initial guesses seems to do the trick....thanks for catching that as I thought I did try making closer initial guesses, but looks like they may not have been tight enough.

Issue resolved, seems to be working well now. Thanks!