Beispiel #1
0
def test_equilibrium():
    mechanism = 'gri30.cti'

    # define states
    initial_gas = Solution(mechanism)
    initial_gas.TPX = 300, 101325, {'H2': 1}

    working_gas = Solution(mechanism)
    working_gas.TPX = 300, 101325 * 2, {'H2': 1}

    velocity_guess = 7

    # errors from hand calculations
    good_errors = [
        -18.375000000,  # enthalpy
        101322.993718076,  # pressure
    ]

    test_errors = calculate_error.equilibrium(
        working_gas=working_gas,
        initial_state_gas=initial_gas,
        initial_velocity_guess=velocity_guess)

    for test, good in zip(test_errors, good_errors):
        assert abs(test - good) / good < 1e-7
Beispiel #2
0
def test_reflected_shock_frozen():
    mechanism = 'gri30.cti'

    # define states
    initial_gas = Solution(mechanism)
    initial_gas.TPX = 300, 101325, {'H2': 1}

    working_gas = Solution(mechanism)
    working_gas.TPX = 300, 101325 * 2, {'H2': 1}

    velocity_guess = 7

    # errors from hand calculations
    good_errors = [
        -73.5,  # enthalpy
        101316.97487230592  # pressure
    ]

    test_errors = calculate_error.reflected_shock_frozen(
        working_gas=working_gas,
        post_shock_gas=initial_gas,
        shock_speed=velocity_guess)

    for test, good in zip(test_errors, good_errors):
        assert abs(test - good) / good < 1e-7
    def test_no_convergence():
        # ensure the proper warning is generated when solution doesn't converge
        mechanism = 'gri30.cti'

        initial_gas = Solution(mechanism)
        initial_gas.TPX = 300, 101325, {'H2': 1}

        working_gas = Solution(mechanism)
        working_gas.TPX = 300, 101325 * 2, {'H2': 1}

        with pytest.warns(Warning, match='No convergence within 1 iterations'):
            sd.Detonation.cj_state(working_gas, initial_gas, 1e-50, 1e-50, 1.5,
                                   1)
Beispiel #4
0
def validate_on_mechanism(mech, temperature, pressure, tau, do_rhs, do_jac):
    xml = join(test_mech_directory, mech + '.xml')
    T = temperature
    Tin = T + 1000.
    p = pressure

    r = ChemicalMechanismSpec(xml, 'gas').griffon

    gas = Solution(xml)
    ns = gas.n_species

    y = np.ones(ns)  # equal masses in the reactor
    gas.TPY = T, p, y
    y = np.copy(gas.Y)

    xin = np.ones(ns)  # equal moles in the feed
    gas.TPX = Tin, p, xin
    yin = np.copy(gas.Y)

    state = hstack((T, y[:-1]))

    rhsCN = rhs_cantera(p, T, y, Tin, yin, tau, gas)
    rhsGR = np.empty(ns)
    r.reactor_rhs_isobaric(state, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, rhsGR)

    if do_rhs:
        return max(abs(rhsGR - rhsCN) / (abs(rhsCN) + 1.)) < 1.e-4

    if do_jac:
        jacGR = np.empty(ns * ns)
        r.reactor_jac_isobaric(state, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, 0, 0, rhsGR, jacGR)
        jacGR = jacGR.reshape((ns, ns), order='F')

        dT = 1.e-6
        dY = 1.e-6
        jacFD = np.empty((ns, ns))
        rhsGR1, rhsGR2 = np.empty(ns), np.empty(ns)
        state_m = hstack((T - dT, y[:-1]))
        state_p = hstack((T + dT, y[:-1]))
        r.reactor_rhs_isobaric(state_m, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, rhsGR1)
        r.reactor_rhs_isobaric(state_p, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, rhsGR2)
        jacFD[:, 0] = (- rhsGR1 + rhsGR2) / (2. * dT)

        for i in range(ns - 1):
            y_m1, y_p1 = np.copy(y), np.copy(y)
            y_m1[i] += - dY
            y_m1[-1] -= - dY
            y_p1[i] += dY
            y_p1[-1] -= dY
            state_m = hstack((T, y_m1[:-1]))
            state_p = hstack((T, y_p1[:-1]))
            r.reactor_rhs_isobaric(state_m, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, rhsGR1)
            r.reactor_rhs_isobaric(state_p, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, True, rhsGR2)
            jacFD[:, 1 + i] = (- rhsGR1 + rhsGR2) / (2. * dY)

        pass_jac = max(abs(jacGR - jacFD) / (abs(jacGR) + 1.)) < 1.e-2

        return pass_jac
Beispiel #5
0
    def test_good_input():
        # compare against SDToolbox results
        mechanism = 'gri30.cti'

        initial_gas = Solution(mechanism)
        initial_gas.TPX = 300, 101325, {'H2': 1}

        working_gas = Solution(mechanism)
        working_gas.TPX = 300, 101325 * 2, {'H2': 1}

        cj_calcs = sd.Detonation.cj_state(
            working_gas,
            initial_gas,
            1e-5,
            1e-5,
            1.5
        )

        good_temp = 355.77590742266216
        good_press = 180244.9690980063
        good_species = {'H': 2.8407416566652653e-30, 'H2': 1.0}

        test_temp = cj_calcs[0].T
        check_temp = abs(test_temp - good_temp) / good_temp < 1e-7

        test_press = cj_calcs[0].P
        check_press = abs(test_press - good_press) / good_press < 1e-7

        good_velocity = 1700.3611387277992
        test_velocity = cj_calcs[1]
        check_velocity = abs(test_velocity - good_velocity) / good_velocity \
            < 1e-7

        checks = [check_temp, check_press, check_velocity]

        # make sure the species in each solution are the same
        test_species = cj_calcs[0].mole_fraction_dict()
        for species in good_species:
            checks.append(
                good_species[species] - test_species[species] < 1e-7
            )

        assert all(checks)
def validate_on_mechanism(mech, temperature, pressure, test_rhs=True, test_jac=True):
    xml = join(test_mech_directory, mech + '.xml')

    T = temperature
    p = pressure

    r = ChemicalMechanismSpec(xml, 'gas').griffon

    gas = Solution(xml)
    ns = gas.n_species

    gas.TPX = T, p, ones(ns)
    y = gas.Y

    state = hstack((T, y[:-1]))

    rhsGR = np.empty(ns)
    r.reactor_rhs_isobaric(state, p, 0., np.ndarray(1), 0, 0, 0, 0, 0, 0, 0, False, rhsGR)

    if test_jac:
        Tin, yin, tau = 0, np.ndarray(1), 0
        rhsTmp = np.empty(ns)
        jacGR = np.empty(ns * ns)
        r.reactor_jac_isobaric(state, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, False, 0, 0, rhsTmp, jacGR)
        jacGR = jacGR.reshape((ns, ns), order='F')

        dT = 1.e-6
        dY = 1.e-6
        jacFD = np.empty((ns, ns))
        rhsGR1, rhsGR2 = np.empty(ns), np.empty(ns)
        state_m = hstack((T - dT, y[:-1]))
        state_p = hstack((T + dT, y[:-1]))
        r.reactor_rhs_isobaric(state_m, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, False, rhsGR1)
        r.reactor_rhs_isobaric(state_p, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, False, rhsGR2)
        jacFD[:, 0] = (- rhsGR1 + rhsGR2) / (2. * dT)

        for i in range(ns - 1):
            y_m1, y_p1 = np.copy(y), np.copy(y)
            y_m1[i] += - dY
            y_m1[-1] -= - dY
            y_p1[i] += dY
            y_p1[-1] -= dY
            state_m = hstack((T, y_m1[:-1]))
            state_p = hstack((T, y_p1[:-1]))
            r.reactor_rhs_isobaric(state_m, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, False, rhsGR1)
            r.reactor_rhs_isobaric(state_p, p, Tin, yin, tau, 0, 0, 0, 0, 0, 0, False, rhsGR2)
            jacFD[:, 1 + i] = (- rhsGR1 + rhsGR2) / (2. * dY)

        pass_jac = max(abs(jacGR - jacFD) / (abs(jacGR) + 1.)) < 1.e-2

    w = gas.net_production_rates * gas.molecular_weights
    h = gas.standard_enthalpies_RT * gas.T * gas_constant / gas.molecular_weights
    rhsCN = zeros(ns)
    rhsCN[1:] = w[:-1] / gas.density
    rhsCN[0] = - sum(w * h) / gas.density / gas.cp_mass
    pass_rhs = max(abs(rhsGR - rhsCN) / (abs(rhsCN) + 1.)) < 100. * sqrt(np.finfo(float).eps)

    if test_rhs and test_jac:
        return pass_rhs and pass_jac
    if test_rhs:
        return pass_rhs
    if test_jac:
        return pass_jac
Beispiel #7
0
def validate_on_mechanism(mech, temperature, pressure, tau, do_rhs, do_jac):
    xml = join(test_mech_directory, mech + '.xml')
    T = temperature
    Tin = T + 1000.
    p = pressure

    r = ChemicalMechanismSpec(xml, 'gas').griffon

    gas = Solution(xml)
    ns = gas.n_species

    y = np.ones(ns)  # equal masses in the reactor
    gas.TPY = T, p, y
    y = np.copy(gas.Y)
    rho = gas.density_mass

    xin = np.ones(ns)  # equal moles in the feed
    gas.TPX = Tin, p, xin
    yin = np.copy(gas.Y)
    rhoin = gas.density_mass

    state = hstack((rho, T, y[:-1]))

    rhsGRChemOnly = np.zeros(ns + 1)
    r.reactor_rhs_isochoric(state, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0, 0,
                            False, rhsGRChemOnly)
    rhsCN = rhs_cantera(p, T, y, rhoin, Tin, yin, tau, gas, rhsGRChemOnly)
    rhsGR = np.empty(ns + 1)
    r.reactor_rhs_isochoric(state, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0, 0,
                            True, rhsGR)

    if do_rhs:
        return max(abs(rhsGR - rhsCN) /
                   (abs(rhsCN) + 1.)) < 100. * sqrt(np.finfo(float).eps)

    if do_jac:
        jacGR = np.empty((ns + 1) * (ns + 1))
        r.reactor_jac_isochoric(state, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0, 0,
                                True, 0, rhsGR, jacGR)
        jacGR = jacGR.reshape((ns + 1, ns + 1), order='F')

        drho = 1.e-6
        dT = 1.e-6
        dY = 1.e-6
        jacFD = np.empty((ns + 1, ns + 1))
        rhsGR1, rhsGR2 = np.empty(ns + 1), np.empty(ns + 1)

        state_m = hstack((rho - drho, T, y[:-1]))
        state_p = hstack((rho + drho, T, y[:-1]))
        r.reactor_rhs_isochoric(state_m, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0,
                                0, True, rhsGR1)
        r.reactor_rhs_isochoric(state_p, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0,
                                0, True, rhsGR2)
        jacFD[:, 0] = (-rhsGR1 + rhsGR2) / (2. * drho)

        state_m = hstack((rho, T - dT, y[:-1]))
        state_p = hstack((rho, T + dT, y[:-1]))
        r.reactor_rhs_isochoric(state_m, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0,
                                0, True, rhsGR1)
        r.reactor_rhs_isochoric(state_p, rhoin, Tin, yin, tau, 0, 0, 0, 0, 0,
                                0, True, rhsGR2)
        jacFD[:, 1] = (-rhsGR1 + rhsGR2) / (2. * dT)

        for i in range(ns - 1):
            y_m1, y_p1 = np.copy(y), np.copy(y)
            y_m1[i] += -dY
            y_m1[-1] -= -dY
            y_p1[i] += dY
            y_p1[-1] -= dY
            state_m = hstack((rho, T, y_m1[:-1]))
            state_p = hstack((rho, T, y_p1[:-1]))
            r.reactor_rhs_isochoric(state_m, rhoin, Tin, yin, tau, 0, 0, 0, 0,
                                    0, 0, True, rhsGR1)
            r.reactor_rhs_isochoric(state_p, rhoin, Tin, yin, tau, 0, 0, 0, 0,
                                    0, 0, True, rhsGR2)
            jacFD[:, 2 + i] = (-rhsGR1 + rhsGR2) / (2. * dY)

        return max(abs(jacGR - jacFD) / (abs(jacGR) + 1.)) < 1.e-4
Beispiel #8
0
def validate_on_mechanism(mech, temperature, pressure, full_Jacobian,
                          isochoric):
    xml = join(test_mech_directory, mech + '.xml')

    r = ChemicalMechanismSpec(xml, 'gas').griffon

    gas = Solution(xml)
    ns = gas.n_species

    T = temperature
    p = pressure

    gas.TPX = T, p, ones(ns)
    y = gas.Y
    rho = gas.density_mass

    if full_Jacobian and isochoric:
        state = hstack((rho, T, y[:-1]))
        rhsGRTemporary = np.empty(ns + 1)
        jac_dense = np.empty((ns + 1) * (ns + 1))
        jac_sparse = np.empty((ns + 1) * (ns + 1))
        r.reactor_jac_isochoric(state, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, 0, rhsGRTemporary, jac_dense)
        r.reactor_jac_isochoric(state, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, 2, rhsGRTemporary, jac_sparse)
        jac_dense = jac_dense.reshape((ns + 1, ns + 1), order='F')
        jac_sparse = jac_sparse.reshape((ns + 1, ns + 1), order='F')

    elif full_Jacobian and not isochoric:
        state = hstack((T, y[:-1]))
        k = np.empty(ns)
        jac_dense = np.empty(ns * ns)
        jac_sparse = np.empty(ns * ns)
        r.reactor_jac_isobaric(state, p, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0, 0,
                               False, 0, 0, k, jac_dense)
        r.reactor_jac_isobaric(state, p, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0, 0,
                               False, 2, 0, k, jac_sparse)

        jac_dense = jac_dense.reshape((ns, ns), order='F')
        jac_sparse = jac_sparse.reshape((ns, ns), order='F')

    else:
        jac_dense = np.zeros((ns + 1) * (ns + 1))
        jac_sparse = np.zeros((ns + 1) * (ns + 1))
        r.prod_rates_primitive_sensitivities(rho, T, y, 0, jac_dense)
        r.prod_rates_primitive_sensitivities(rho, T, y, 2, jac_sparse)
        jac_dense = jac_dense.reshape((ns + 1, ns + 1), order='F')[:-1, :]
        jac_sparse = jac_sparse.reshape((ns + 1, ns + 1), order='F')[:-1, :]

        jac_fd = np.zeros_like(jac_dense)
        rhsGR1 = np.zeros(ns)
        rhsGR2 = np.zeros(ns)
        dT = 1.e-4
        dr = 1.e-4
        dY = 1.e-4
        r.production_rates(T, rho + dr, y, rhsGR1)
        r.production_rates(T, rho - dr, y, rhsGR2)
        jac_fd[:, 0] = (rhsGR1 - rhsGR2) / dr * 0.5
        r.production_rates(T + dT, rho, y, rhsGR1)
        r.production_rates(T - dT, rho, y, rhsGR2)
        jac_fd[:, 1] = (rhsGR1 - rhsGR2) / dT * 0.5

        for spec_idx in range(ns - 1):
            Yp = np.copy(y)
            Yp[spec_idx] += dY
            Yp[-1] -= dY
            Ym = np.copy(y)
            Ym[spec_idx] -= dY
            Ym[-1] += dY
            r.production_rates(T, rho, Yp, rhsGR1)
            r.production_rates(T, rho, Ym, rhsGR2)
            jac_fd[:, 2 + spec_idx] = (rhsGR1 - rhsGR2) / dY * 0.5

    pass_sparse_vs_dense_jac = np.linalg.norm(
        jac_dense.ravel() - jac_sparse.ravel(), ord=np.Inf) < 1.e-10

    # if not pass_sparse_vs_dense_jac:
    #     print(mech)
    #     diff = abs(jac_dense - jac_sparse) / (abs(jac_dense) + 1.)
    #     nr, nc = jac_dense.shape
    #     print('dense')
    #     for ir in range(nr):
    #         for ic in range(nc):
    #             print(f'{jac_dense[ir, ic]:8.0e}', end=', ')
    #         print('')
    #     print('sparse')
    #     for ir in range(nr):
    #         for ic in range(nc):
    #             print(f'{jac_sparse[ir, ic]:8.0e}', end=', ')
    #         print('')
    #     print('finite difference')
    #     for ir in range(nr):
    #         for ic in range(nc):
    #             print(f'{jac_fd[ir, ic]:8.0e}', end=', ')
    #         print('')
    #     print('diff')
    #     for ir in range(nr):
    #         for ic in range(nc):
    #             print(f'{diff[ir, ic]:8.0e}' if diff[ir, ic] > 1.e-12 else f'{"":8}', end=', ')
    #         print('')
    return pass_sparse_vs_dense_jac
Beispiel #9
0
def validate_on_mechanism(mech,
                          temperature,
                          pressure,
                          test_rhs=True,
                          test_jac=True):
    xml = join(test_mech_directory, mech + '.xml')

    r = ChemicalMechanismSpec(xml, 'gas').griffon

    gas = Solution(xml)
    ns = gas.n_species

    T = temperature
    p = pressure

    gas.TPX = T, p, ones(ns)
    y = gas.Y
    rho = gas.density_mass

    state = hstack((rho, T, y[:-1]))

    rhsGR = np.empty(ns + 1)
    rhsGRTemporary = np.empty(ns + 1)
    jacGR = np.empty((ns + 1) * (ns + 1))
    r.reactor_rhs_isochoric(state, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0, 0,
                            False, rhsGR)
    r.reactor_jac_isochoric(state, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0, 0,
                            False, 0, rhsGRTemporary, jacGR)
    jacGR = jacGR.reshape((ns + 1, ns + 1), order='F')

    def cantera_rhs(rho_arg, T_arg, Y_arg):
        gas.TDY = T_arg, rho_arg, Y_arg
        w = gas.net_production_rates * gas.molecular_weights
        e = gas.standard_int_energies_RT * gas.T * gas_constant / gas.molecular_weights
        cv = gas.cv_mass
        rhs = zeros(ns + 1)
        rhs[0] = 0.
        rhs[1] = -sum(w * e) / (rho_arg * cv)
        rhs[2:] = w[:-1] / rho
        return rhs

    rhsCN = cantera_rhs(rho, T, y)

    if test_rhs:
        pass_rhs = max(abs(rhsGR - rhsCN) /
                       (abs(rhsCN) + 1.)) < 100. * sqrt(np.finfo(float).eps)

    if test_jac:
        jacFD = zeros((ns + 1, ns + 1))
        wm1 = zeros(ns + 1)
        wp1 = zeros(ns + 1)
        drho = 1.e-4
        dT = 1.e-2
        dY = 1.e-6

        state_m = hstack((rho - drho, T, y[:-1]))
        state_p = hstack((rho + drho, T, y[:-1]))
        r.reactor_rhs_isochoric(state_m, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, wm1)
        r.reactor_rhs_isochoric(state_p, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, wp1)
        jacFD[:, 0] = (-wm1 + wp1) / (2. * drho)

        state_m = hstack((rho, T - dT, y[:-1]))
        state_p = hstack((rho, T + dT, y[:-1]))
        r.reactor_rhs_isochoric(state_m, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, wm1)
        r.reactor_rhs_isochoric(state_p, 0, 0, np.ndarray(1), 0, 0, 0, 0, 0, 0,
                                0, False, wp1)
        jacFD[:, 1] = (-wm1 + wp1) / (2. * dT)

        for i in range(ns - 1):
            y_m1, y_p1 = copy(y), copy(y)
            y_m1[i] += -dY
            y_m1[-1] -= -dY
            y_p1[i] += dY
            y_p1[-1] -= dY
            state_m = hstack((rho, T, y_m1[:-1]))
            state_p = hstack((rho, T, y_p1[:-1]))
            r.reactor_rhs_isochoric(state_m, 0, 0, np.ndarray(1), 0, 0, 0, 0,
                                    0, 0, 0, False, wm1)
            r.reactor_rhs_isochoric(state_p, 0, 0, np.ndarray(1), 0, 0, 0, 0,
                                    0, 0, 0, False, wp1)
            jacFD[:, 2 + i] = (-wm1 + wp1) / (2. * dY)

        gas.TDY = T, rho, y
        cv = gas.cv_mass
        cvi = gas.standard_cp_R * gas_constant / gas.molecular_weights
        w = gas.net_production_rates * gas.molecular_weights
        e = gas.standard_int_energies_RT * gas.T * gas_constant / gas.molecular_weights

        gas.TDY = T + dT, rho, y
        wp = gas.net_production_rates * gas.molecular_weights
        cvp = gas.cv_mass

        gas.TDY = T - dT, rho, y
        wm = gas.net_production_rates * gas.molecular_weights
        cvm = gas.cv_mass

        wsensT = (wp - wm) / (2. * dT)
        cvsensT = (cvp - cvm) / (2. * dT)

        jacFD11 = np.copy(jacFD[1, 1])
        jacSemiFD11 = -1. / cv * (1. / rho * (sum(wsensT * e) + sum(cvi * w)) +
                                  cvsensT * rhsGR[1])
        pass_jac = max(abs(jacGR - jacFD) / (abs(jacGR) + 1.)) < 1.e-4

    if test_rhs:
        return pass_rhs
    if test_jac:
        if not pass_jac:
            print(jacGR[1, 1])
            print(jacSemiFD11)
            print(jacFD11)
            print(abs(jacGR - jacFD) / (abs(jacGR) + 1.))
        return pass_jac