Beispiel #1
0
def _validate(conditions, rsys, symbols, odesys, backend=None, transform=None, ignore=('time',)):
    """ For use with create_odesys

    Parameters
    ----------
    conditions : OrderedDict
        Parameters, values with units from ``chempy.units``.
    rsys : ReactionSystem
    symbols : dict
        Mapping variable name to symbols.
    backend : module
        Module for symbolic mathematics. (defaults to SymPy)
    transform : callable for rewriting expressions

    Raises
    ------
    ``KeyError`` if a key in conditions is not in odesys.names or odesys.param_names

    """
    if backend is None:
        from sym import Backend
        backend = Backend(backend)

    if transform is None:
        if backend.__name__ != 'sympy':
            warnings.warn("Backend != SymPy, provide your own transform function.")

        def transform(arg):
            expr = backend.logcombine(arg, force=True)
            v, w = map(backend.Wild, 'v w'.split())
            expr = expr.replace(backend.log(w**v), v*backend.log(w))
            return expr

    args = [symbols[key] for key in conditions]
    seen = [False]*len(args)
    rates = {}
    for k, v in rsys.rates(symbols).items():
        expr = transform(v)
        if expr == 0:
            rate = 0 * u.molar/u.second
        else:
            rate = backend.lambdify(args, expr)(*conditions.values())
            to_unitless(rate, u.molar/u.second)
        rates[k] = rate
        seen = [b or a in expr.free_symbols for b, a in zip(seen, args)]
    not_seen = [a for s, a in zip(seen, args) if not s]
    for k in conditions:
        if k not in odesys.param_names and k not in odesys.names and k not in ignore:
            raise KeyError("Unknown param: %s" % k)
    return {'not_seen': not_seen, 'rates': rates}
Beispiel #2
0
def _validate(
        conditions,
        rsys,
        symbols,
        odesys,
        backend=None,
        transform=None,
        ignore=("time", ),
        check_conditions_no_extra=False,
):
    """For use with create_odesys

    Parameters
    ----------
    conditions : OrderedDict
        Parameters, values with units from ``chempy.units``.
    rsys : ReactionSystem
    symbols : dict
        Mapping variable name to symbols.
    backend : module
        Module for symbolic mathematics. (defaults to SymPy)
    transform : callable for rewriting expressions
    check_conditions_no_extra : bool
        When True, conditions may not contain keys not referenced in any expression.

    Raises
    ------
    ``KeyError`` if a key in conditions is not in odesys.names or odesys.param_names

    """
    if backend is None:
        from sym import Backend

        backend = Backend(backend)

    if transform is None:
        if backend.__name__ != "sympy":
            warnings.warn(
                "Backend != SymPy, provide your own transform function.")

        def transform(arg):
            expr = backend.logcombine(arg, force=True)
            v, w = map(backend.Wild, "v w".split())
            return expr.replace(backend.log(w**v), v * backend.log(w))

    rates = {}
    seen = set()

    for k, v in rsys.rates(symbols).items():
        expr = transform(v)
        if expr == 0:
            rate = 0 * u.molar / u.second
        else:
            rate = None
            for term in (expr.args if hasattr(expr, "is_Add") and expr.is_Add
                         else (expr, )):
                args = sorted(expr.free_symbols, key=lambda e: e.name)
                values = [conditions[s.name] for s in args]
                result = backend.lambdify(args, term)(*map(_exact, values))
                to_unitless(result, u.molar /
                            u.second)  # raises an exception upon unit error
                if rate is None:
                    rate = result
                else:
                    rate += result
        rates[k] = rate
        seen |= set([s.name for s in expr.free_symbols])
    if check_conditions_no_extra:
        for k in conditions:
            if (k not in odesys.param_names and k not in odesys.names
                    and k not in ignore):
                raise KeyError("Unknown param: %s" % k)
    return {
        "not_seen": (set(rsys.substances) | set(conditions)) - seen,
        "rates": rates
    }