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

Documentation User defined element #36

Open
asraelis opened this issue Oct 3, 2015 · 9 comments
Open

Documentation User defined element #36

asraelis opened this issue Oct 3, 2015 · 9 comments

Comments

@asraelis
Copy link

asraelis commented Oct 3, 2015

Hey,

Great package! I am really glad that I found your package. I want to simulate nonlinear devices and their transient behaviour. Therefore, I would need two types of elements CCVS and VCVS. If I understand it correct the CCVS and VCVS are linear elements which cannot be changed (easily).
I thought that a user defined element would be perfect. Unfortunately the documentation is very little so far
" """
Adds a user defined element.

    In order for this to work, you should write a module that supplies the
    elem class.

    XXX WRITE DOC

"
Could you tell me what exactly is meant by elem class? or could you give an example of a user defined element.

Thanks a lot!

BR Stephan

@itdaniher
Copy link
Contributor

Stephan - I'll make time to look into this, see if I can't point you in the right direction. Rgds!

@itdaniher
Copy link
Contributor

Stephan - I believe the documentation you're searching for may be found at http://ahkab.readthedocs.org/en/latest/devices.html. The "elem class" should, as best I can tell, be the "Component" class.

You will need to define a subclass of "Component" and implement a small set of builtin methods.

@asraelis
Copy link
Author

asraelis commented Oct 7, 2015

Many thanks,
I 'll try to create such an element according to the document asap.

BR Stephan

@itdaniher
Copy link
Contributor

@asraelis Any luck?

@asraelis
Copy link
Author

Not yet - Although I think i got a working dummy class, but I could not test it yet since the circuit.add_user_defined() method makes some problems. Tryed to make some changes but I just run into other issues, which seem to be linked with the "imp" module. At the moment i do not know if it is a issue of ahkab or of my coding skill.
I am planning to prepare a better description of the issues but this week I am really busy. I hope I can post a more straight forward report at the end of this week.

BR Stephan

@itdaniher
Copy link
Contributor

Great, I'll keep an eye out for your update, looking forward to helping you work through this!

BR,
Ian

@asraelis
Copy link
Author

Hello again,

here is my short report:

I have saved my classfile own_ahkab_classes.py in my actual wd and I tried to add a userdefined element with:

 mycircuit.add_user_defined(own_ahkab_classes,Butler_Volmer,{'p1':1})

then python says " name 'module_name' is not defined".

As mentioned above I tried to make some little changes to "circuit.py" since "module_name" is used within circuit.py (see below) but I just managed it to get other errors within the imp.py file (after importing it) on my system:

Error:

File "C:\Anaconda3\lib\site-packages\ahkab\circuit.py", line 995, in add_user_defined
fp, pathname, description = imp.find_module(module_name)

File "C:\Anaconda3\lib\imp.py", line 297, in find_module
raise ImportError(_ERR_MSG.format(name), name=name)

ImportError: No module named "<module 'own_ahkab_classes' from 'F:\\Python Scripts\\own_ahkab_classes.py'>

File:

#part of circuit.py including "module_name"

def add_user_defined(self, module, label, param_dict):
    """Adds a user defined element.

    In order for this to work, you should write a module that supplies the
    elem class.

    XXX WRITE DOC
    """
    """
    changed part
    """
    self.user_defined_modules_dict = {"own_ahkab_classes" : own_ahkab_classes}
    module_name = str(module)
    circuit = self
    """
    end of changed part
    """
    if module_name in circuit.user_defined_modules_dict:
        module = circuit.user_defined_modules_dict[module_name]
    else:
        fp, pathname, description = imp.find_module(module_name)
        module = imp.load_module(module_name, fp, pathname, description)
        circuit.user_defined_modules_dict.update({module_name: module})

    elem_class = getattr(module, label)

    param_dict.update({"convert_units": convert_units})
    param_dict.update({"circuit_node": self.add_node})

    elem = elem_class(**param_dict)
    elem.part_id = "y%s" % part_id[1:]

    # call check() if supported
    if hasattr(elem, "check"):
        selfcheck_result, error_msg = elem.check()
        if not selfcheck_result:
            raise NetlistParseError("module: " + module_name + \
                                    " elem type: " + elem_type_name + \
                                    " error: " + error_msg)

    self.append(elem)

APPENDIX:

own_ahkab_classes.py is basically a capacitor elem with little changes to test "add_user_defined()" and has no special purpose yet. It looks like this right now:

DEBUG = True

import ahkab

class Butler_Volmer(ahkab.devices.Component):
    """
    see
    http://ahkab.readthedocs.org/en/latest/devices.html#ahkab.devices.Component
    """
    """A capacitor.

    .. image:: images/elem/capacitor.svg

    **Parameters:**

    part_id : string
        The unique identifier of this element. The first letter should be
        ``'C'``.
    n1 : int
        *Internal* node to be connected to the anode.
   n2 : int
        *Internal* node to be connected to the cathode.
    value : float
        The capacitance in Farads.
    ic : float
        The initial condition (IC) to be used for time-based simulations,
        such as TRAN analyses, when requested, expressed in Volt.

    """
    #
    def __init__(self, part_id, n1, n2, value, ic=None):
        self.part_id = part_id
        self.value = value
        self.n1 = n1
        self.n2 = n2
        self.ic = ic
        self.is_nonlinear = True
        self.is_symbolic = False


    def get_ports(self):
        return ((self.n1,self.n2))


    def g(self, v, time=0):
        return 0


    def i(self, v, time=0):
        return 3*self.value**v


    def d(self, v, time=0):
        return self.value


    def get_op_info(self, ports_v):
        """Information regarding the Operating Point (OP)

        **Parameters:**

        ports_v : list of lists
            The parameter is to be set to ``[[v]]``, where ``v`` is the voltage
            applied to the capacitor terminals.

        **Returns:**

        op_keys : list of strings
            The labels corresponding to the numeric values in ``op_info``.
        op_info : list of floats
            The values corresponding to ``op_keys``.
        """
        vn1n2 = float(ports_v[0][0])
        qn1n2 = float(ports_v[0][0] * self.value)
        energy = float(.5 * ports_v[0][0] ** 2 * self.value)

        op_keys = ['Part ID', "V(n1-n2) [V]", "Q [C]", "E [J]"]
        op_info = [self.part_id.upper(), vn1n2, qn1n2, energy]
        return op_keys, op_info

if DEBUG:
    """
    First Test of class
    """
    bv1 = Butler_Volmer('BV1', 'n1', 'n2', 2)
    print ("DEBUG = True line 98 of DLSEC.py ==> str(bv1.d(1)) = " 
            + str(bv1.d(1)) + "\n")  
"""

BR Stephan

@AnthonyFraser
Copy link

Not sure whether this is still open, but I was successful in adding my own element using the original method, e.g. below I add the element ant.ant to the circuit.

cir = ahkab.Circuit('testbench_ant_device')
n1=cir.add_node('n1')
n2=cir.add_node('n2')
gnd=cir.add_node(cir.gnd)
elem1 = ahkab.devices.Resistor(part_id='R1',n1=n1,n2=n2,value=100)
cir.append(elem1)
elem2 = ant.ant(part_id='R2',n1=n2,n2=gnd,value=100)
cir.append(elem2)

cir.add_vsource('Vref','n1',cir.gnd,dc_value=10)
op = ahkab.new_op()
res = ahkab.run(cir,op)

Cheers,
Anthony

@asraelis
Copy link
Author

Yes it is still open for me altough i found a workaround by means of ltspice.

I am testing your solution at the moment hopefully figuring out how it works

BR stephan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants