예제 #1
0
def addIdentifiers(model, parent, dictIdentifiers):
    """
    Adds all identifiers (parameters, variables, inlet analogue ports) to the dictionary dictIdentifiers.
    This function is used to parse mathematical equations and conditional expressions and create
    daetools equation residual objects.
    Dictionary keys are relative canonical names (relative to the 'parent' model). For instance, if
    the canonical name of the 'model' is 'model1.model2.param1' and the canonical name of the 'parent'
    is 'model1' then the relative name is 'model2.param1' (the equations can access that parameters
    by using the identifier 'model2.param1').
    Dictionary values are daetools 'adouble' objects obtained by calling the function call operator
    of parameters (daet.daeParameter class) and variables (daet.daeVariable class). adouble class defines all standard 
    mathematical and logical operators and all standard mathematical functions (sqrt, exp, log, sin, cos, ...)
    so that the AST generated from the NineML expressions can be evaluated and equation residuals and
    logical expressions be constructed.
    
    :param model: nineml_daetools_bridge object
    :param parent: daeModel-derived object
    :param dictIdentifiers: python dictionary 'relative name' : adouble object
        
    :rtype: python dictionary (modified dictIdentifiers argument)
    :raises: RuntimeError
    """
    if not model:
        return dictIdentifiers

    for o in model.Parameters:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = o()

    for o in model.Variables:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = o()

    # Inlet analog ports do not have corresponding variable in the model (state or alias)
    # Outlet ports do have
    # Reduce ports have one that is generated by ninemlReduceAnalogPort class
    for port in model.nineml_analog_ports:
        if port.Type == daet.eInletPort:
            if len(port.Variables) != 1:
                raise RuntimeError(
                    'Number of variables has to be 1, in the port ' +
                    port.CanonicalName)
            relName = daet.daeGetRelativeName(parent, port)
            #print('CanonicalName: {0}, RelName: {1}'.format(port.CanonicalName, relName))
            dictIdentifiers[relName] = port.Variables[0]()

    for m in model.Models:
        dictIdentifiers = addIdentifiers(m, model, dictIdentifiers)

    return dictIdentifiers
예제 #2
0
def addIdentifiers(model, parent, dictIdentifiers):
    """
    Adds all identifiers (parameters, variables, inlet analogue ports) to the dictionary dictIdentifiers.
    This function is used to parse mathematical equations and conditional expressions and create
    daetools equation residual objects.
    Dictionary keys are relative canonical names (relative to the 'parent' model). For instance, if
    the canonical name of the 'model' is 'model1.model2.param1' and the canonical name of the 'parent'
    is 'model1' then the relative name is 'model2.param1' (the equations can access that parameters
    by using the identifier 'model2.param1').
    Dictionary values are daetools 'adouble' objects obtained by calling the function call operator
    of parameters (daet.daeParameter class) and variables (daet.daeVariable class). adouble class defines all standard 
    mathematical and logical operators and all standard mathematical functions (sqrt, exp, log, sin, cos, ...)
    so that the AST generated from the NineML expressions can be evaluated and equation residuals and
    logical expressions be constructed.
    
    :param model: nineml_daetools_bridge object
    :param parent: daeModel-derived object
    :param dictIdentifiers: python dictionary 'relative name' : adouble object
        
    :rtype: python dictionary (modified dictIdentifiers argument)
    :raises: RuntimeError
    """
    if not model:
        return dictIdentifiers
    
    for o in model.Parameters:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = o()

    for o in model.Variables:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = o()

    # Inlet analog ports do not have corresponding variable in the model (state or alias)
    # Outlet ports do have
    # Reduce ports have one that is generated by ninemlReduceAnalogPort class
    for port in model.nineml_analog_ports:
        if port.Type == daet.eInletPort:
            if len(port.Variables) != 1:
                raise RuntimeError('Number of variables has to be 1, in the port ' + port.CanonicalName)
            relName = daet.daeGetRelativeName(parent, port)
            #print('CanonicalName: {0}, RelName: {1}'.format(port.CanonicalName, relName))
            dictIdentifiers[relName] = port.Variables[0]()

    for m in model.Models:
        dictIdentifiers = addIdentifiers(m, model, dictIdentifiers)

    return dictIdentifiers
예제 #3
0
def addIdentifiersValues(model, parent, dictIdentifiers):
    """
    Identical to the function *addIdentifiers* except that it adds *identifierValue* objects 
    (and not *adouble* objects) which implement __float__ function so that they can be evaluated. 
    This function is used during initialization step when parsing expressions used to set parameters 
    values and initial conditions (to evaluate a value of an expression). It adds a callable object for 
    parameters'/variables' because values ain't initialized yet at this point.
    
    **Achtung!!** Some values might not be evaluated yet. Perhaps the values with simple numbers should 
    be set first and then expressions that depend on them evaluated.
    
    :param model: nineml_daetools_bridge object
    :param parent: daeModel-derived object
    :param dictIdentifiers: python dictionary 'relative name' : identifierValue object
        
    :rtype: python dictionary (modified dictIdentifiers argument)
    :raises: RuntimeError
    """
    if not model:
        return dictIdentifiers

    for o in model.Parameters:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = identifierValue(o.GetValue)

    for o in model.Variables:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = identifierValue(o.GetValue)

    # Inlet analog ports do not have corresponding variable in the model (state or alias)
    # Outlet ports do have
    # Reduce ports have one that is generated by ninemlReduceAnalogPort class
    if hasattr(model, 'nineml_analog_ports'):
        for port in model.nineml_analog_ports:
            if port.Type == daet.eInletPort:
                if len(port.Variables) != 1:
                    raise RuntimeError(
                        'Number of variables has to be 1, in the port ' +
                        port.CanonicalName)
                relName = daet.daeGetRelativeName(parent, port)
                #print('CanonicalName: {0}, RelName: {1}'.format(port.CanonicalName, relName))
                dictIdentifiers[relName] = identifierValue(
                    port.Variables[0].GetValue)

    for m in model.Models:
        dictIdentifiers = addIdentifiersValues(m, model, dictIdentifiers)

    return dictIdentifiers
예제 #4
0
def getObjectFromCanonicalName(rootModel, canonicalName, **kwargs):
    """
    Recursively looks for and returns the object with the name 'address' in the toplevel daeModel-derived object 'rootModel'.

    :param rootModel: daeModel-derived object
    :param canonicalName: a 'path' to the object ('model1.model2.object')
    :param kwargs: list of boolean flags determining the type of objects to look for
        
    :rtype: python object (depends on kwargs argument)
    :raises: RuntimeError
    """
    relativeName = daet.daeGetRelativeName(rootModel.CanonicalName, canonicalName)
    #print('  relativeName = {0} for root = {1} and canonicalName = {2}'.format(relativeName, rootModel.CanonicalName, canonicalName))
    listCanonicalName = relativeName.split('.')
    objectName = listCanonicalName[-1]
    objectPath = listCanonicalName[:-1]

    root = rootModel
    if len(objectPath) > 0:
        for name in objectPath:
            root = findObjectInModel(root, name, look_for_models = True)
            if root == None:
                raise RuntimeError('Could not locate object {0} in {1}'.format(name, ".".join(objectPath)))

    # Now we have the model where port should be located (root)
    # Search for the 'name' in the 'root' model (in the types of objects given in **kwargs)
    return findObjectInModel(root, objectName, **kwargs)
예제 #5
0
def getObjectFromCanonicalName(rootModel, canonicalName, **kwargs):
    """
    Recursively looks for and returns the object with the name 'address' in the toplevel daeModel-derived object 'rootModel'.

    :param rootModel: daeModel-derived object
    :param canonicalName: a 'path' to the object ('model1.model2.object')
    :param kwargs: list of boolean flags determining the type of objects to look for
        
    :rtype: python object (depends on kwargs argument)
    :raises: RuntimeError
    """
    relativeName = daet.daeGetRelativeName(rootModel.CanonicalName,
                                           canonicalName)
    #print('  relativeName = {0} for root = {1} and canonicalName = {2}'.format(relativeName, rootModel.CanonicalName, canonicalName))
    listCanonicalName = relativeName.split('.')
    objectName = listCanonicalName[-1]
    objectPath = listCanonicalName[:-1]

    root = rootModel
    if len(objectPath) > 0:
        for name in objectPath:
            root = findObjectInModel(root, name, look_for_models=True)
            if root == None:
                raise RuntimeError('Could not locate object {0} in {1}'.format(
                    name, ".".join(objectPath)))

    # Now we have the model where port should be located (root)
    # Search for the 'name' in the 'root' model (in the types of objects given in **kwargs)
    return findObjectInModel(root, objectName, **kwargs)
예제 #6
0
def addIdentifiersValues(model, parent, dictIdentifiers):
    """
    Identical to the function *addIdentifiers* except that it adds *identifierValue* objects 
    (and not *adouble* objects) which implement __float__ function so that they can be evaluated. 
    This function is used during initialization step when parsing expressions used to set parameters 
    values and initial conditions (to evaluate a value of an expression). It adds a callable object for 
    parameters'/variables' because values ain't initialized yet at this point.
    
    **Achtung!!** Some values might not be evaluated yet. Perhaps the values with simple numbers should 
    be set first and then expressions that depend on them evaluated.
    
    :param model: nineml_daetools_bridge object
    :param parent: daeModel-derived object
    :param dictIdentifiers: python dictionary 'relative name' : identifierValue object
        
    :rtype: python dictionary (modified dictIdentifiers argument)
    :raises: RuntimeError
    """
    if not model:
        return dictIdentifiers
    
    for o in model.Parameters:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = identifierValue(o.GetValue)

    for o in model.Variables:
        relName = daet.daeGetRelativeName(parent, o)
        #print('CanonicalName: {0}, RelName: {1}'.format(o.CanonicalName, relName))
        dictIdentifiers[relName] = identifierValue(o.GetValue)

    # Inlet analog ports do not have corresponding variable in the model (state or alias)
    # Outlet ports do have
    # Reduce ports have one that is generated by ninemlReduceAnalogPort class
    if hasattr(model, 'nineml_analog_ports'):
        for port in model.nineml_analog_ports:
            if port.Type == daet.eInletPort:
                if len(port.Variables) != 1:
                    raise RuntimeError('Number of variables has to be 1, in the port ' + port.CanonicalName)
                relName = daet.daeGetRelativeName(parent, port)
                #print('CanonicalName: {0}, RelName: {1}'.format(port.CanonicalName, relName))
                dictIdentifiers[relName] = identifierValue(port.Variables[0].GetValue)

    for m in model.Models:
        dictIdentifiers = addIdentifiersValues(m, model, dictIdentifiers)

    return dictIdentifiers