Пример #1
0
def gap_irka_time(Re=110, level=2, palpha=1e-3, control='bc', r_list=[5]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    fom = load_fom(Re, level, palpha, control)

    disable_caching()

    reductor = GapIRKAReductor(fom)

    with open(setup_str + '/gap_irka_runtime.csv', 'w') as file:
        file.write('r,time\n')

    for r in r_list:
        times = timeit.repeat(
            stmt=
            """reductor.reduce(r, tol=1e-3, maxit=100, num_prev=1, conv_crit='htwogap',
                                  projection='Eorth', compute_errors=False)""",
            globals=locals(),
            repeat=3,
            number=1,
        )
        with open(setup_str + '/gap_irka_runtime.csv', 'a') as file:
            file.write(str(r) + ',' + '{:.3f}'.format(min(times)) + '\n')

    enable_caching()
Пример #2
0
def lqgbt_simulation(Re=110, level=2, palpha=1e-3, control='bc', r_list=[5]):
    fom = load_fom(Re, level, palpha, control)

    reductor = LQGBTReductor(fom, solver_options=ricc_lrcf_solver_options()['lrnadi'])

    for r in r_list:
        rom = reductor.reduce(r=r, projection='biorth')
        run_cl_simulation(rom, 'lqgbt', Re=110, level=2, palpha=1e-3, control='bc')
Пример #3
0
def gap_irka_convergence(Re=110,
                         level=2,
                         palpha=1e-3,
                         control='bc',
                         r_list=[10, 20, 30]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    disable_caching()
    fom = load_fom(Re, level, palpha, control)
    cl_fom = load_cl_fom(Re, level, palpha, control)

    for r in r_list:
        reductor = GapIRKAReductor(fom)
        _ = reductor.reduce(r,
                            tol=-1,
                            maxit=50,
                            num_prev=1,
                            conv_crit='htwogap',
                            projection='Eorth',
                            compute_errors=True,
                            closed_loop_fom=cl_fom)

        iter_num = len(reductor.conv_crit)
        sigmas = reductor.sigma_list

        with open(setup_str + '/conv_crit_' + str(r) + '.csv', 'w') as file:
            file.write('iter,sigma,sigmatwo,romhtwogap,htwogap,absolute\n')

        for i in range(iter_num):
            sigma_change_1 = spla.norm(
                (sigmas[i + 1] - sigmas[i]) / sigmas[i + 1], ord=np.inf)

            if i > 0:
                sigma_change_2 = min(
                    spla.norm((sigmas[i - 1] - sigmas[i + 1]) / sigmas[i + 1],
                              ord=np.inf),
                    spla.norm((sigmas[i] - sigmas[i + 1]) / sigmas[i + 1],
                              ord=np.inf))
            else:
                sigma_change_2 = sigma_change_1

            if i > 0:
                error_change = spla.norm(reductor.errors[i] -
                                         reductor.errors[i - 1]) / spla.norm(
                                             reductor.errors[0])
            else:
                error_change = ''

            with open(setup_str + '/conv_crit_' + str(r) + '.csv',
                      'a') as file:
                file.write(
                    str(i + 1) + ',' + str(sigma_change_1) + ',' +
                    str(sigma_change_2) + ',' + str(reductor.conv_crit[i]) +
                    ',' + str(error_change) + ',' + str(reductor.errors[i]) +
                    '\n')
    enable_caching()
Пример #4
0
def lqgbt_errors(Re=110, level=2, palpha=1e-3, control='bc', r_list=[5, 10, 15, 20, 25, 30, 35, 40]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    fom = load_fom(Re, level, palpha, control)

    reductor = LQGBTReductor(fom, solver_options=ricc_lrcf_solver_options()['lrnadi'])

    for r in r_list:
        rom = reductor.reduce(r=r, projection='biorth')

        write_freq_errors(fom, rom, 'lqgbt', setup_str, r)
Пример #5
0
def bernoulli_bt_errors(Re=110,
                        level=2,
                        palpha=1e-3,
                        control='bc',
                        r_list=[5, 10, 15, 20, 25, 30, 35, 40]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    fom = load_fom(Re, level, palpha, control)

    reductor = StabilizingBTReductor(fom)

    for r in r_list:
        rom = reductor.reduce(r=r, projection='biorth')

        write_freq_errors(fom, rom, 'bernoulli_bt', setup_str, r)
Пример #6
0
def bernoulli_bt_simulation(Re=110,
                            level=2,
                            palpha=1e-3,
                            control='bc',
                            r_list=[5]):
    fom = load_fom(Re, level, palpha, control)

    reductor = StabilizingBTReductor(fom)

    for r in r_list:
        rom = reductor.reduce(r=r, projection='biorth')
        run_cl_simulation(rom,
                          'bernoulli_bt',
                          Re=110,
                          level=2,
                          palpha=1e-3,
                          control='bc')
Пример #7
0
def gap_irka_errors(Re=110,
                    level=2,
                    palpha=1e-3,
                    control='bc',
                    r_list=[5, 10, 15, 20, 25, 30, 35, 40]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    fom = load_fom(Re, level, palpha, control)

    for r in r_list:
        reductor = GapIRKAReductor(fom)
        rom = reductor.reduce(r,
                              tol=1e-3,
                              maxit=100,
                              num_prev=1,
                              conv_crit='htwogap',
                              projection='Eorth',
                              compute_errors=False)

        write_freq_errors(fom, rom, 'gap_irka', setup_str, r)
Пример #8
0
def gap_irka_simulation(Re=110,
                        level=2,
                        palpha=1e-3,
                        control='bc',
                        r_list=[5]):
    fom = load_fom(Re, level, palpha, control)

    reductor = GapIRKAReductor(fom)

    for r in r_list:
        rom = reductor.reduce(r,
                              tol=1e-3,
                              maxit=100,
                              num_prev=1,
                              conv_crit='htwogap',
                              projection='Eorth',
                              compute_errors=False)
        run_cl_simulation(rom,
                          'gap_irka',
                          Re=110,
                          level=2,
                          palpha=1e-3,
                          control='bc')
Пример #9
0
def lqgbt_time(Re=110, level=2, palpha=1e-3, control='bc', r_list=[5]):
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')

    fom = load_fom(Re, level, palpha, control)

    disable_caching()

    reductor = LQGBTReductor(fom, solver_options=ricc_lrcf_solver_options()['lrnadi'])

    with open(setup_str + '/lqgbt_runtime.csv', 'w') as file:
        file.write('r,time\n')

    for r in r_list:
        times = timeit.repeat(
            stmt="""reductor.reduce(r=r, projection='biorth')""",
            globals=locals(),
            repeat=3,
            number=1,
        )
        with open(setup_str + '/lqgbt_runtime.csv', 'a') as file:
            file.write(str(r) + ',' + '{:.3f}'.format(min(times)) + '\n')

    enable_caching()
Пример #10
0
def run_fom_cl_simulation(Re=110, level=2, palpha=1e-3, control='bc'):
    """Run the closed-loop simulation with full order LQG controller."""

    # define strings, directories and paths for data storage
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')
    data_path = '../data/' + 'lvl_' + str(level) + ('_' + control if control
                                                    is not None else '')
    setup_path = data_path + '/re_' + str(Re) + ('_palpha_' + str(palpha)
                                                 if control == 'bc' else '')

    with open(setup_str + '/fom_simulation.csv', 'w') as file:
        file.write('t, yerr \n')

    # define first order model and matrices for simulation
    fom = load_fom(Re=110, level=2, palpha=1e-3, control='bc')

    mats = spio.loadmat(data_path + '/mats')

    M = mats['M']
    J = mats['J']
    hmat = mats['H']
    fv = mats['fv'] + 1. / Re * mats['fv_diff'] + mats['fv_conv']
    fp = mats['fp'] + mats['fp_div']
    vcmat = mats['Cv']
    NV, NP = fv.shape[0], fp.shape[0]

    if control == 'bc':
        A = 1. / Re * mats['A'] + mats['L1'] + mats[
            'L2'] + 1. / palpha * mats['Arob']
        B = 1. / palpha * mats['Brob']
    else:
        A = 1. / Re * mats['A'] + mats['L1'] + mats['L2']
        B = mats['B']
        # restrict to less dofs in the input
        NU = B.shape[1]
        B = B[:, [0, NU // 2]]

    # compute steady-state solution and linearized convection
    if not os.path.isfile(setup_path + '/ss_nse_sol'):
        ss_nse_v, _ = solve_steadystate_nse(mats, Re, control, palpha=palpha)
        conv_mat = linearized_convection(mats['H'], ss_nse_v)
        spio.savemat(setup_path + '/ss_nse_sol', {
            'ss_nse_v': ss_nse_v,
            'conv_mat': conv_mat
        })
    else:
        ss_nse_sol = spio.loadmat(setup_path + '/ss_nse_sol')
        ss_nse_v, conv_mat = ss_nse_sol['ss_nse_v'], ss_nse_sol['conv_mat']

    # Define parameters for time stepping
    t0 = 0.
    tE = 8.
    Nts = 2**12
    DT = (tE - t0) / Nts
    trange = np.linspace(t0, tE, Nts + 1)

    # Define functions that represent the system inputs
    if control is None:

        def bbcu(ko_state):
            return np.zeros((NV, 1))

        def update_ko_state(ko_state, Cv, DT):
            return ko_state

    else:
        _, Kc = solve_ricc_lrcf(fom.A,
                                fom.E,
                                fom.B.as_range_array(),
                                fom.C.as_source_array(),
                                trans=True,
                                return_K=True)
        _, Ko = solve_ricc_lrcf(fom.A,
                                fom.E,
                                fom.B.as_range_array(),
                                fom.C.as_source_array(),
                                trans=False,
                                return_K=True)

        Kc = Kc.to_numpy().T
        Ko = Ko.to_numpy().T

        Aconv = -1. / Re * mats['A'] - 1. / palpha * mats['Arob'] - conv_mat
        BK = sps.bmat(
            [[B, Ko],
             [sps.csc_matrix((NP, len(B.T))),
              sps.csc_matrix((NP, len(Ko.T)))]]).todense()

        KC = sps.bmat([[Kc.T, sps.csc_matrix((len(Kc.T), NP))],
                       [vcmat,
                        sps.csc_matrix(
                            (len(vcmat.todense()), NP))]]).todense()

        def bbcu(ko_state):
            uvec = -Kc.T @ ko_state
            return B @ uvec

        EmA = sps.vstack([
            sps.hstack([M - DT * Aconv, J.T]),
            sps.hstack([J, sps.csc_matrix((NP, NP))])
        ]).tocsc()

        EmAlu = spsla.factorized(EmA)
        S = EmAlu(BK)
        IKS = spla.solve(np.eye(len(KC)) + DT * KC @ S, KC)

        Css = vcmat @ ss_nse_v

        # function that determines the next state of the Kalman observer via implicit euler step
        def update_ko_state(ko_state, Cv):
            rhs = M @ ko_state + DT * (Ko @ (Cv - Css))
            rhs_block = np.vstack([rhs, np.zeros((NP, 1))])
            EmAluko = EmAlu(rhs_block)
            ko_new_block = EmAluko - (DT * (S @ (IKS @ EmAluko)))
            return ko_new_block[:NV]

    # introduce small perturbation to steady-state solution as initial value
    pert = fom.A.source.project_onto_subspace(fom.A.operator.source.ones(),
                                              trans=True).to_numpy().T
    old_v = ss_nse_v + 1e-3 * pert

    # initialize state for observer
    ko_state = np.zeros((NV, 1))

    sysmat = sps.vstack([
        sps.hstack([M + DT * A, -J.T]),
        sps.hstack([J, sps.csc_matrix((NP, NP))])
    ]).tocsc()
    sysmati = spsla.factorized(sysmat)

    for k, t in enumerate(trange):
        crhsv = M * old_v + DT * (fv - eva_quadterm(hmat, old_v) +
                                  bbcu(ko_state))
        crhs = np.vstack([crhsv, fp])
        vp_new = np.atleast_2d(sysmati(np.squeeze(np.asarray(crhs)))).T
        old_v = vp_new[:NV]
        Cv = vcmat @ old_v
        ko_state = update_ko_state(ko_state, Cv)

        print(k, '/', Nts)
        print(spla.norm(Cv - Css, 2))

        with open(setup_str + '/fom_simulation.csv', 'a') as file:
            file.write(str(t) + ',' + str(spla.norm(Cv - Css, 2)) + '\n')
Пример #11
0
def run_cl_simulation(rom, name, Re=110, level=2, palpha=1e-3, control='bc'):
    """Run the closed-loop simulation with reduced LQG controller."""

    # define strings, directories and paths for data storage
    setup_str = 'lvl_' + str(level) + ('_' + control if control is not None else '') \
                + '_re_' + str(Re) + ('_palpha_' + str(palpha) if control == 'bc' else '')
    data_path = '../data/' + 'lvl_' + str(level) + ('_' + control if control
                                                    is not None else '')
    setup_path = data_path + '/re_' + str(Re) + ('_palpha_' + str(palpha)
                                                 if control == 'bc' else '')
    simulation_path = setup_str + '/' + name + '_simulation'

    if not os.path.exists(simulation_path):
        os.makedirs(simulation_path)

    with open(simulation_path + '/rom_' + str(rom.order) + '.csv',
              'w') as file:
        file.write('t, yerr \n')

    # define first order model and matrices for simulation
    fom = load_fom(Re=110, level=2, palpha=1e-3, control='bc')

    mats = spio.loadmat(data_path + '/mats')

    M = mats['M']
    J = mats['J']
    hmat = mats['H']
    fv = mats['fv'] + 1. / Re * mats['fv_diff'] + mats['fv_conv']
    fp = mats['fp'] + mats['fp_div']
    vcmat = mats['Cv']
    NV, NP = fv.shape[0], fp.shape[0]

    if control == 'bc':
        A = 1. / Re * mats['A'] + mats['L1'] + mats[
            'L2'] + 1. / palpha * mats['Arob']
        B = 1. / palpha * mats['Brob']
    else:
        A = 1. / Re * mats['A'] + mats['L1'] + mats['L2']
        B = mats['B']
        # restrict to less dofs in the input
        NU = B.shape[1]
        B = B[:, [0, NU // 2]]

    # compute steady-state solution and linearized convection
    if not os.path.isfile(setup_path + '/ss_nse_sol'):
        ss_nse_v, _ = solve_steadystate_nse(mats, Re, control, palpha=palpha)
        conv_mat = linearized_convection(mats['H'], ss_nse_v)
        spio.savemat(setup_path + '/ss_nse_sol', {
            'ss_nse_v': ss_nse_v,
            'conv_mat': conv_mat
        })
    else:
        ss_nse_sol = spio.loadmat(setup_path + '/ss_nse_sol')
        ss_nse_v, conv_mat = ss_nse_sol['ss_nse_v'], ss_nse_sol['conv_mat']

    # Define parameters for time stepping
    t0 = 0.
    tE = 8.
    Nts = 2**12
    DT = (tE - t0) / Nts
    trange = np.linspace(t0, tE, Nts + 1)

    # Define functions that represent the system inputs
    if control is None:

        def bbcu(ko_state):
            return np.zeros((NV, 1))

        def update_ko_state(ko_state, Cv, DT):
            return ko_state

    else:
        Arom = to_matrix(rom.A, format='dense')  # .real?
        Brom = to_matrix(rom.B, format='dense')
        Crom = to_matrix(rom.C, format='dense')

        XCARE = spla.solve_continuous_are(Arom,
                                          Brom,
                                          Crom.T @ Crom,
                                          np.eye(Brom.shape[1]),
                                          balanced=False)
        XFARE = spla.solve_continuous_are(Arom.T,
                                          Crom.T,
                                          Brom @ Brom.T,
                                          np.eye(Crom.shape[0]),
                                          balanced=False)

        # define control based on Kalman observer state
        def bbcu(ko_state):
            uvec = -Brom.T @ XCARE @ ko_state
            return B @ uvec

        ko1_mat = Arom - XFARE @ Crom.T @ Crom - Brom @ Brom.T @ XCARE
        ko2_mat = XFARE @ Crom.T
        lu_piv = spla.lu_factor(np.eye(rom.order) - DT * ko1_mat)

        Css = vcmat @ ss_nse_v

        # function that determines the next state of the Kalman observer via implicit euler step
        def update_ko_state(ko_state, Cv, DT):
            return spla.lu_solve(lu_piv, ko_state + DT * ko2_mat @ (Cv - Css))

    # introduce small perturbation to steady-state solution as initial value
    pert = fom.A.source.project_onto_subspace(fom.A.operator.source.ones(),
                                              trans=True).to_numpy().T
    old_v = ss_nse_v + 1e-3 * pert

    # initialize state for observer
    ko_state = np.zeros((rom.order, 1))

    sysmat = sps.vstack([
        sps.hstack([M + DT * A, -J.T]),
        sps.hstack([J, sps.csc_matrix((NP, NP))])
    ]).tocsc()
    sysmati = spsla.factorized(sysmat)

    try:
        for k, t in enumerate(trange):
            crhsv = M * old_v + DT * (fv - eva_quadterm(hmat, old_v) +
                                      bbcu(ko_state))
            crhs = np.vstack([crhsv, fp])
            vp_new = np.atleast_2d(sysmati(crhs.flatten())).T
            old_v = vp_new[:NV]
            Cv = vcmat @ old_v
            ko_state = update_ko_state(ko_state, Cv, DT)

            print(k, '/', Nts)
            print(spla.norm(Cv - Css, 2))

            with open(simulation_path + '/rom_' + str(rom.order) + '.csv',
                      'a') as file:
                file.write(str(t) + ',' + str(spla.norm(Cv - Css, 2)) + '\n')
    except:
        with open('simulation_error_log.txt', 'a') as file:
            file.write(name + '_' + str(rom.order) + '\n')
Пример #12
0
def run_no_control_simulation(Re=110, level=2, palpha=1e-3):
    """Run the simulation with no control."""

    # define strings, directories and paths for data storage
    setup_str = 'lvl_' + str(level) + '_re_' + str(Re)
    data_path = '../data/' + 'lvl_' + str(level)
    setup_path = data_path + '/re_' + str(Re)

    if not os.path.exists(setup_str):
        os.makedirs(setup_str)

    with open(setup_str + '/no_control_simulation.csv', 'w') as file:
        file.write('t, yerr \n')

    # use fom to project initial velocity onto hidden manifold later
    fom = load_fom(Re=110, level=2, palpha=1e-3, control=None)

    mats = spio.loadmat(data_path + '/mats')

    M = mats['M']
    J = mats['J']
    hmat = mats['H']
    fv = mats['fv'] + 1. / Re * mats['fv_diff'] + mats['fv_conv']
    fp = mats['fp'] + mats['fp_div']
    vcmat = mats['Cv']
    NV, NP = fv.shape[0], fp.shape[0]

    A = 1. / Re * mats['A'] + mats['L1'] + mats['L2']

    # compute steady-state solution and linearized convection
    if not os.path.isfile(setup_path + '/ss_nse_sol'):
        ss_nse_v, _ = solve_steadystate_nse(mats, Re, None, palpha=palpha)
        conv_mat = linearized_convection(mats['H'], ss_nse_v)
        spio.savemat(setup_path + '/ss_nse_sol', {
            'ss_nse_v': ss_nse_v,
            'conv_mat': conv_mat
        })
    else:
        ss_nse_sol = spio.loadmat(setup_path + '/ss_nse_sol')
        ss_nse_v, conv_mat = ss_nse_sol['ss_nse_v'], ss_nse_sol['conv_mat']

    # Define parameters for time stepping
    t0 = 0.
    tE = 8.
    Nts = 2**12
    DT = (tE - t0) / Nts
    trange = np.linspace(t0, tE, Nts + 1)

    Css = vcmat @ ss_nse_v

    # introduce small perturbation to steady-state solution as initial value
    pert = fom.A.source.project_onto_subspace(fom.A.operator.source.ones(),
                                              trans=True).to_numpy().T
    old_v = ss_nse_v + 1e-3 * pert

    sysmat = sps.vstack([
        sps.hstack([M + DT * A, -J.T]),
        sps.hstack([J, sps.csc_matrix((NP, NP))])
    ]).tocsc()
    sysmati = spsla.factorized(sysmat)

    for k, t in enumerate(trange):
        crhsv = M * old_v + DT * (fv - eva_quadterm(hmat, old_v))
        crhs = np.vstack([crhsv, fp])
        vp_new = np.atleast_2d(sysmati(np.squeeze(np.asarray(crhs)))).T
        old_v = vp_new[:NV]
        Cv = vcmat @ old_v

        print(k, '/', Nts)
        print(spla.norm(Cv - Css, 2))

        with open(setup_str + '/no_control_simulation.csv', 'a') as file:
            file.write(str(t) + ',' + str(spla.norm(Cv - Css, 2)) + '\n')