Skip to content

use execution graph and add additional fitting methods #308

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 166 additions & 158 deletions impedance/models/circuits/circuits.py

Large diffs are not rendered by default.

63 changes: 30 additions & 33 deletions impedance/models/circuits/elements.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import numpy as np


class ElementError(Exception):
...
class ElementError(Exception): ...


class OverwriteError(ElementError):
...
class OverwriteError(ElementError): ...


def element(num_params, units, overwrite=False):
Expand Down Expand Up @@ -35,22 +33,17 @@ def wrapper(p, f):

global circuit_elements
if func.__name__ in ["s", "p"]:
raise ElementError("cannot redefine elements 's' (series)" +
"or 'p' (parallel)")
raise ElementError(
"cannot redefine elements 's' (series)" + "or 'p' (parallel)"
)
elif func.__name__ in circuit_elements and not overwrite:
raise OverwriteError(
f"element {func.__name__} already exists. " +
"If you want to overwrite the existing element," +
"use `overwrite=True`."
f"element {func.__name__} already exists. "
+ "If you want to overwrite the existing element,"
+ "use `overwrite=True`."
)
else:
circuit_elements[func.__name__] = wrapper
# Adding numpy to circuit_elements for proper evaluation with
# numpy>=2.0.0 because the scalar representation was changed.
# "Scalars are now printed as np.float64(3.0) rather than just 3.0."
# https://numpy.org/doc/2.0/release/2.0.0-notes.html
# #representation-of-numpy-scalars-changed
circuit_elements["np"] = np

return wrapper

Expand Down Expand Up @@ -319,9 +312,9 @@ def K(p, f):
return Z


@element(num_params=3, units=['Ohm', 'sec', ''])
@element(num_params=3, units=["Ohm", "sec", ""])
def Zarc(p, f):
""" An RQ element rewritten with resistance and
"""An RQ element rewritten with resistance and
and time constant as paramenters. Equivalent to a
Cole-Cole relaxation in dielectrics.

Expand All @@ -332,9 +325,9 @@ def Zarc(p, f):
Z = \\frac{R}{1 + (j \\omega \\tau_k)^\\gamma }

"""
omega = 2*np.pi*np.array(f)
omega = 2 * np.pi * np.array(f)
R, tau_k, gamma = p[0], p[1], p[2]
Z = R/(1 + ((1j*omega*tau_k)**gamma))
Z = R / (1 + ((1j * omega * tau_k) ** gamma))
return Z


Expand Down Expand Up @@ -412,17 +405,21 @@ def get_element_from_name(name):


def typeChecker(p, f, name, length):
assert isinstance(p, list), \
"in {}, input must be of type list".format(name)
for i in p:
assert isinstance(
i, (float, int, np.int32, np.float64)
), "in {}, value {} in {} is not a number".format(name, i, p)
for i in f:
assert isinstance(
i, (float, int, np.int32, np.float64)
), "in {}, value {} in {} is not a number".format(name, i, f)
assert len(p) == length, "in {}, input list must be length {}".format(
name, length
)
return
if not np.all(np.isreal(p)):
raise TypeError(f"In {name} all of the parameters are not real ({p})")
if not np.all(np.isreal(f)):
raise TypeError(f"In {name} all of the frequencies are not ({f})")
if len(p) != length:
raise TypeError(f"In {name} length of parameters is not {length} ")


def get_element_parameter_names_and_units_from_name(name):
elem = get_element_from_name(name)
n_params = circuit_elements[elem].num_params
return [
format_parameter_name(name, j, n_params) for j in range(n_params)
], circuit_elements[elem].units


def format_parameter_name(name, j, n_params):
return f"{name}_{j}" if n_params > 1 else f"{name}"
Loading